2 * This module contains the garbage collector front-end.
4 * Copyright: Copyright (C) 2005-2006 Digital Mars, www.digitalmars.com.
7 * This software is provided 'as-is', without any express or implied
8 * warranty. In no event will the authors be held liable for any damages
9 * arising from the use of this software.
11 * Permission is granted to anyone to use this software for any purpose,
12 * including commercial applications, and to alter it and redistribute it
13 * freely, in both source and binary form, subject to the following
16 * o The origin of this software must not be misrepresented; you must not
17 * claim that you wrote the original software. If you use this software
18 * in a product, an acknowledgment in the product documentation would be
19 * appreciated but is not required.
20 * o Altered source versions must be plainly marked as such, and must not
21 * be misrepresented as being the original software.
22 * o This notice may not be removed or altered from any source
24 * Authors: Walter Bright, Sean Kelly
33 import core.stdc.stdlib;
44 extern (C) void thread_init();
48 extern (C) void function() gc_enable;
49 extern (C) void function() gc_disable;
50 extern (C) void function() gc_collect;
51 extern (C) void function() gc_minimize;
53 extern (C) uint function(void*) gc_getAttr;
54 extern (C) uint function(void*, uint) gc_setAttr;
55 extern (C) uint function(void*, uint) gc_clrAttr;
57 extern (C) void* function(size_t, uint) gc_malloc;
58 extern (C) void* function(size_t, uint) gc_calloc;
59 extern (C) void* function(void*, size_t, uint ba) gc_realloc;
60 extern (C) size_t function(void*, size_t, size_t) gc_extend;
61 extern (C) size_t function(size_t) gc_reserve;
62 extern (C) void function(void*) gc_free;
64 extern (C) void* function(void*) gc_addrOf;
65 extern (C) size_t function(void*) gc_sizeOf;
67 extern (C) BlkInfo function(void*) gc_query;
69 extern (C) void function(void*) gc_addRoot;
70 extern (C) void function(void*, size_t) gc_addRange;
72 extern (C) void function(void*) gc_removeRoot;
73 extern (C) void function(void*) gc_removeRange;
81 pthis.gc_enable = &gc_enable;
82 pthis.gc_disable = &gc_disable;
83 pthis.gc_collect = &gc_collect;
84 pthis.gc_minimize = &gc_minimize;
86 pthis.gc_getAttr = &gc_getAttr;
87 pthis.gc_setAttr = &gc_setAttr;
88 pthis.gc_clrAttr = &gc_clrAttr;
90 pthis.gc_malloc = &gc_malloc;
91 pthis.gc_calloc = &gc_calloc;
92 pthis.gc_realloc = &gc_realloc;
93 pthis.gc_extend = &gc_extend;
94 pthis.gc_reserve = &gc_reserve;
95 pthis.gc_free = &gc_free;
97 pthis.gc_addrOf = &gc_addrOf;
98 pthis.gc_sizeOf = &gc_sizeOf;
100 pthis.gc_query = &gc_query;
102 pthis.gc_addRoot = &gc_addRoot;
103 pthis.gc_addRange = &gc_addRange;
105 pthis.gc_removeRoot = &gc_removeRoot;
106 pthis.gc_removeRange = &gc_removeRange;
110 extern (C) void gc_init()
114 ClassInfo ci = GC.classinfo;
116 p = malloc(ci.init.length);
117 (cast(byte*)p)[0 .. ci.init.length] = ci.init[];
122 _gc = cast(GC*) calloc(1, GC.sizeof);
125 // NOTE: The GC must initialize the thread library
126 // before its first collection.
131 extern (C) void gc_term()
133 // NOTE: There may be daemons threads still running when this routine is
134 // called. If so, cleaning memory out from under then is a good
135 // way to make them crash horribly. This probably doesn't matter
136 // much since the app is supposed to be shutting down anyway, but
137 // I'm disabling cleanup for now until I can think about it some
140 // NOTE: Due to popular demand, this has been re-enabled. It still has
141 // the problems mentioned above though, so I guess we'll see.
142 _gc.fullCollectNoStack(); // not really a 'collect all' -- still scans
143 // static data area, roots, and ranges.
147 extern (C) void gc_enable()
151 return proxy.gc_enable();
154 extern (C) void gc_disable()
157 return _gc.disable();
158 return proxy.gc_disable();
161 extern (C) void gc_collect()
164 return _gc.fullCollect();
165 return proxy.gc_collect();
169 extern (C) void gc_minimize()
172 return _gc.minimize();
173 return proxy.gc_minimize();
176 extern (C) uint gc_getAttr( void* p )
179 return _gc.getAttr( p );
180 return proxy.gc_getAttr( p );
183 extern (C) uint gc_setAttr( void* p, uint a )
186 return _gc.setAttr( p, a );
187 return proxy.gc_setAttr( p, a );
190 extern (C) uint gc_clrAttr( void* p, uint a )
193 return _gc.clrAttr( p, a );
194 return proxy.gc_clrAttr( p, a );
197 extern (C) void* gc_malloc( size_t sz, uint ba = 0 )
200 return _gc.malloc( sz, ba );
201 return proxy.gc_malloc( sz, ba );
204 extern (C) void* gc_calloc( size_t sz, uint ba = 0 )
207 return _gc.calloc( sz, ba );
208 return proxy.gc_calloc( sz, ba );
211 extern (C) void* gc_realloc( void* p, size_t sz, uint ba = 0 )
214 return _gc.realloc( p, sz, ba );
215 return proxy.gc_realloc( p, sz, ba );
218 extern (C) size_t gc_extend( void* p, size_t mx, size_t sz )
221 return _gc.extend( p, mx, sz );
222 return proxy.gc_extend( p, mx, sz );
225 extern (C) size_t gc_reserve( size_t sz )
228 return _gc.reserve( sz );
229 return proxy.gc_reserve( sz );
232 extern (C) void gc_free( void* p )
235 return _gc.free( p );
236 return proxy.gc_free( p );
239 extern (C) void* gc_addrOf( void* p )
242 return _gc.addrOf( p );
243 return proxy.gc_addrOf( p );
246 extern (C) size_t gc_sizeOf( void* p )
249 return _gc.sizeOf( p );
250 return proxy.gc_sizeOf( p );
253 extern (C) BlkInfo gc_query( void* p )
256 return _gc.query( p );
257 return proxy.gc_query( p );
260 // NOTE: This routine is experimental. The stats or function name may change
261 // before it is made officially available.
262 extern (C) GCStats gc_stats()
266 GCStats stats = void;
267 _gc.getStats( stats );
270 // TODO: Add proxy support for this once the layout of GCStats is
272 //return proxy.gc_stats();
276 extern (C) void gc_addRoot( void* p )
279 return _gc.addRoot( p );
280 return proxy.gc_addRoot( p );
283 extern (C) void gc_addRange( void* p, size_t sz )
286 return _gc.addRange( p, sz );
287 return proxy.gc_addRange( p, sz );
290 extern (C) void gc_removeRoot( void* p )
293 return _gc.removeRoot( p );
294 return proxy.gc_removeRoot( p );
297 extern (C) void gc_removeRange( void* p )
300 return _gc.removeRange( p );
301 return proxy.gc_removeRange( p );
304 extern (C) Proxy* gc_getProxy()
308 import core.stdc.stdio;
309 export extern (C) void gc_setProxy( Proxy* p )
313 // TODO: Decide if this is an error condition.
316 foreach( r; _gc.rootIter )
317 proxy.gc_addRoot( r );
318 foreach( r; _gc.rangeIter )
319 proxy.gc_addRange( r.pbot, r.ptop - r.pbot );
322 export extern (C) void gc_clrProxy()
324 foreach( r; _gc.rangeIter )
325 proxy.gc_removeRange( r.pbot );
326 foreach( r; _gc.rootIter )
327 proxy.gc_removeRoot( r );