2 * This module contains a minimal garbage collector implementation according to
3 * published requirements. This library is mostly intended to serve as an
4 * example, but it is usable in applications which do not rely on a garbage
5 * collector to clean up memory (ie. when dynamic array resizing is not used,
6 * and all memory allocated with 'new' is freed deterministically with
9 * Please note that block attribute data must be tracked, or at a minimum, the
10 * FINALIZE bit must be tracked for any allocated memory block because calling
11 * rt_finalize on a non-object block can result in an access violation. In the
12 * allocator below, this tracking is done via a leading uint bitmask. A real
13 * allocator may do better to store this data separately, similar to the basic
16 * Copyright: Public Domain
17 * License: Public Domain
23 private import core.stdc.stdlib;
29 FINALIZE = 0b0000_0001,
30 NO_SCAN = 0b0000_0010,
31 NO_MOVE = 0b0000_0100,
32 ALL_BITS = 0b1111_1111
42 extern (C) void thread_init();
43 extern (C) void onOutOfMemoryError();
46 extern (C) void gc_init()
48 // NOTE: The GC must initialize the thread library before its first
49 // collection, and always before returning from gc_init().
53 extern (C) void gc_term()
58 extern (C) void gc_enable()
62 return proxy.gc_enable();
65 extern (C) void gc_disable()
69 return proxy.gc_disable();
72 extern (C) void gc_collect()
76 return proxy.gc_collect();
79 extern (C) void gc_minimize()
83 return proxy.gc_minimize();
86 extern (C) uint gc_getAttr( void* p )
90 return proxy.gc_getAttr( p );
93 extern (C) uint gc_setAttr( void* p, uint a )
97 return proxy.gc_setAttr( p, a );
100 extern (C) uint gc_clrAttr( void* p, uint a )
104 return proxy.gc_clrAttr( p, a );
107 extern (C) void* gc_malloc( size_t sz, uint ba = 0 )
111 void* p = malloc( sz );
113 if( sz && p is null )
114 onOutOfMemoryError();
117 return proxy.gc_malloc( sz, ba );
120 extern (C) void* gc_calloc( size_t sz, uint ba = 0 )
124 void* p = calloc( 1, sz );
126 if( sz && p is null )
127 onOutOfMemoryError();
130 return proxy.gc_calloc( sz, ba );
133 extern (C) void* gc_realloc( void* p, size_t sz, uint ba = 0 )
137 p = realloc( p, sz );
139 if( sz && p is null )
140 onOutOfMemoryError();
143 return proxy.gc_realloc( p, sz, ba );
146 extern (C) size_t gc_extend( void* p, size_t mx, size_t sz )
150 return proxy.gc_extend( p, mx, sz );
153 extern (C) size_t gc_reserve( size_t sz )
157 return proxy.gc_reserve( sz );
160 extern (C) void gc_free( void* p )
164 return proxy.gc_free( p );
167 extern (C) void* gc_addrOf( void* p )
171 return proxy.gc_addrOf( p );
174 extern (C) size_t gc_sizeOf( void* p )
178 return proxy.gc_sizeOf( p );
181 extern (C) BlkInfo gc_query( void* p )
185 return proxy.gc_query( p );
188 // TODO: Implement range storage.
189 // TODO: Implement root storage.
191 extern (C) void gc_addRoot( void* p )
195 return proxy.gc_addRoot( p );
198 extern (C) void gc_addRange( void* p, size_t sz )
202 return proxy.gc_addRange( p, sz );
205 extern (C) void gc_removeRoot( void *p )
209 return proxy.gc_removeRoot( p );
212 extern (C) void gc_removeRange( void *p )
216 return proxy.gc_removeRange( p );
221 extern (C) void function() gc_enable;
222 extern (C) void function() gc_disable;
223 extern (C) void function() gc_collect;
224 extern (C) void function() gc_minimize;
226 extern (C) uint function(void*) gc_getAttr;
227 extern (C) uint function(void*, uint) gc_setAttr;
228 extern (C) uint function(void*, uint) gc_clrAttr;
230 extern (C) void* function(size_t, uint) gc_malloc;
231 extern (C) void* function(size_t, uint) gc_calloc;
232 extern (C) void* function(void*, size_t, uint ba) gc_realloc;
233 extern (C) size_t function(void*, size_t, size_t) gc_extend;
234 extern (C) size_t function(size_t) gc_reserve;
235 extern (C) void function(void*) gc_free;
237 extern (C) void* function(void*) gc_addrOf;
238 extern (C) size_t function(void*) gc_sizeOf;
240 extern (C) BlkInfo function(void*) gc_query;
242 extern (C) void function(void*) gc_addRoot;
243 extern (C) void function(void*, size_t) gc_addRange;
245 extern (C) void function(void*) gc_removeRoot;
246 extern (C) void function(void*) gc_removeRange;
254 pthis.gc_enable = &gc_enable;
255 pthis.gc_disable = &gc_disable;
256 pthis.gc_collect = &gc_collect;
257 pthis.gc_minimize = &gc_minimize;
259 pthis.gc_getAttr = &gc_getAttr;
260 pthis.gc_setAttr = &gc_setAttr;
261 pthis.gc_clrAttr = &gc_clrAttr;
263 pthis.gc_malloc = &gc_malloc;
264 pthis.gc_calloc = &gc_calloc;
265 pthis.gc_realloc = &gc_realloc;
266 pthis.gc_extend = &gc_extend;
267 pthis.gc_reserve = &gc_reserve;
268 pthis.gc_free = &gc_free;
270 pthis.gc_addrOf = &gc_addrOf;
271 pthis.gc_sizeOf = &gc_sizeOf;
273 pthis.gc_query = &gc_query;
275 pthis.gc_addRoot = &gc_addRoot;
276 pthis.gc_addRange = &gc_addRange;
278 pthis.gc_removeRoot = &gc_removeRoot;
279 pthis.gc_removeRange = &gc_removeRange;
282 extern (C) Proxy* gc_getProxy()
287 export extern (C) void gc_setProxy( Proxy* p )
300 export extern (C) void gc_clrProxy()
303 // proxy.removeRoot();
305 // proxy.removeReange();