comparison druntime/src/gc/basic/gc.d @ 1458:e0b2d67cfe7c

Added druntime (this should be removed once it works).
author Robert Clipsham <robert@octarineparrot.com>
date Tue, 02 Jun 2009 17:43:06 +0100
parents
children
comparison
equal deleted inserted replaced
1456:7b218ec1044f 1458:e0b2d67cfe7c
1 /**
2 * Contains the external GC interface.
3 *
4 * Copyright: Copyright Digital Mars 2005 - 2009.
5 * License: <a href="http://www.boost.org/LICENSE_1_0.txt>Boost License 1.0</a>.
6 * Authors: Walter Bright, Sean Kelly
7 *
8 * Copyright Digital Mars 2005 - 2009.
9 * Distributed under the Boost Software License, Version 1.0.
10 * (See accompanying file LICENSE_1_0.txt or copy at
11 * http://www.boost.org/LICENSE_1_0.txt)
12 */
13 module gc.gc;
14
15 private
16 {
17 import gc.gcx;
18 import gc.gcstats;
19 import core.stdc.stdlib;
20
21 version = GCCLASS;
22
23 version( GCCLASS )
24 alias GC gc_t;
25 else
26 alias GC* gc_t;
27
28 __gshared gc_t _gc;
29
30 extern (C) void thread_init();
31
32 struct Proxy
33 {
34 extern (C) void function() gc_enable;
35 extern (C) void function() gc_disable;
36 extern (C) void function() gc_collect;
37 extern (C) void function() gc_minimize;
38
39 extern (C) uint function(void*) gc_getAttr;
40 extern (C) uint function(void*, uint) gc_setAttr;
41 extern (C) uint function(void*, uint) gc_clrAttr;
42
43 extern (C) void* function(size_t, uint) gc_malloc;
44 extern (C) void* function(size_t, uint) gc_calloc;
45 extern (C) void* function(void*, size_t, uint ba) gc_realloc;
46 extern (C) size_t function(void*, size_t, size_t) gc_extend;
47 extern (C) size_t function(size_t) gc_reserve;
48 extern (C) void function(void*) gc_free;
49
50 extern (C) void* function(void*) gc_addrOf;
51 extern (C) size_t function(void*) gc_sizeOf;
52
53 extern (C) BlkInfo function(void*) gc_query;
54
55 extern (C) void function(void*) gc_addRoot;
56 extern (C) void function(void*, size_t) gc_addRange;
57
58 extern (C) void function(void*) gc_removeRoot;
59 extern (C) void function(void*) gc_removeRange;
60 }
61
62 __gshared Proxy pthis;
63 __gshared Proxy* proxy;
64
65 void initProxy()
66 {
67 pthis.gc_enable = &gc_enable;
68 pthis.gc_disable = &gc_disable;
69 pthis.gc_collect = &gc_collect;
70 pthis.gc_minimize = &gc_minimize;
71
72 pthis.gc_getAttr = &gc_getAttr;
73 pthis.gc_setAttr = &gc_setAttr;
74 pthis.gc_clrAttr = &gc_clrAttr;
75
76 pthis.gc_malloc = &gc_malloc;
77 pthis.gc_calloc = &gc_calloc;
78 pthis.gc_realloc = &gc_realloc;
79 pthis.gc_extend = &gc_extend;
80 pthis.gc_reserve = &gc_reserve;
81 pthis.gc_free = &gc_free;
82
83 pthis.gc_addrOf = &gc_addrOf;
84 pthis.gc_sizeOf = &gc_sizeOf;
85
86 pthis.gc_query = &gc_query;
87
88 pthis.gc_addRoot = &gc_addRoot;
89 pthis.gc_addRange = &gc_addRange;
90
91 pthis.gc_removeRoot = &gc_removeRoot;
92 pthis.gc_removeRange = &gc_removeRange;
93 }
94 }
95
96 extern (C) void gc_init()
97 {
98 version (GCCLASS)
99 { void* p;
100 ClassInfo ci = GC.classinfo;
101
102 p = malloc(ci.init.length);
103 (cast(byte*)p)[0 .. ci.init.length] = ci.init[];
104 _gc = cast(GC)p;
105 }
106 else
107 {
108 _gc = cast(GC*) calloc(1, GC.sizeof);
109 }
110 _gc.initialize();
111 // NOTE: The GC must initialize the thread library
112 // before its first collection.
113 thread_init();
114 initProxy();
115 }
116
117 extern (C) void gc_term()
118 {
119 // NOTE: There may be daemons threads still running when this routine is
120 // called. If so, cleaning memory out from under then is a good
121 // way to make them crash horribly. This probably doesn't matter
122 // much since the app is supposed to be shutting down anyway, but
123 // I'm disabling cleanup for now until I can think about it some
124 // more.
125 //
126 // NOTE: Due to popular demand, this has been re-enabled. It still has
127 // the problems mentioned above though, so I guess we'll see.
128 _gc.fullCollectNoStack(); // not really a 'collect all' -- still scans
129 // static data area, roots, and ranges.
130 _gc.Dtor();
131 }
132
133 extern (C) void gc_enable()
134 {
135 if( proxy is null )
136 return _gc.enable();
137 return proxy.gc_enable();
138 }
139
140 extern (C) void gc_disable()
141 {
142 if( proxy is null )
143 return _gc.disable();
144 return proxy.gc_disable();
145 }
146
147 extern (C) void gc_collect()
148 {
149 if( proxy is null )
150 return _gc.fullCollect();
151 return proxy.gc_collect();
152 }
153
154
155 extern (C) void gc_minimize()
156 {
157 if( proxy is null )
158 return _gc.minimize();
159 return proxy.gc_minimize();
160 }
161
162 extern (C) uint gc_getAttr( void* p )
163 {
164 if( proxy is null )
165 return _gc.getAttr( p );
166 return proxy.gc_getAttr( p );
167 }
168
169 extern (C) uint gc_setAttr( void* p, uint a )
170 {
171 if( proxy is null )
172 return _gc.setAttr( p, a );
173 return proxy.gc_setAttr( p, a );
174 }
175
176 extern (C) uint gc_clrAttr( void* p, uint a )
177 {
178 if( proxy is null )
179 return _gc.clrAttr( p, a );
180 return proxy.gc_clrAttr( p, a );
181 }
182
183 extern (C) void* gc_malloc( size_t sz, uint ba = 0 )
184 {
185 if( proxy is null )
186 return _gc.malloc( sz, ba );
187 return proxy.gc_malloc( sz, ba );
188 }
189
190 extern (C) void* gc_calloc( size_t sz, uint ba = 0 )
191 {
192 if( proxy is null )
193 return _gc.calloc( sz, ba );
194 return proxy.gc_calloc( sz, ba );
195 }
196
197 extern (C) void* gc_realloc( void* p, size_t sz, uint ba = 0 )
198 {
199 if( proxy is null )
200 return _gc.realloc( p, sz, ba );
201 return proxy.gc_realloc( p, sz, ba );
202 }
203
204 extern (C) size_t gc_extend( void* p, size_t mx, size_t sz )
205 {
206 if( proxy is null )
207 return _gc.extend( p, mx, sz );
208 return proxy.gc_extend( p, mx, sz );
209 }
210
211 extern (C) size_t gc_reserve( size_t sz )
212 {
213 if( proxy is null )
214 return _gc.reserve( sz );
215 return proxy.gc_reserve( sz );
216 }
217
218 extern (C) void gc_free( void* p )
219 {
220 if( proxy is null )
221 return _gc.free( p );
222 return proxy.gc_free( p );
223 }
224
225 extern (C) void* gc_addrOf( void* p )
226 {
227 if( proxy is null )
228 return _gc.addrOf( p );
229 return proxy.gc_addrOf( p );
230 }
231
232 extern (C) size_t gc_sizeOf( void* p )
233 {
234 if( proxy is null )
235 return _gc.sizeOf( p );
236 return proxy.gc_sizeOf( p );
237 }
238
239 extern (C) BlkInfo gc_query( void* p )
240 {
241 if( proxy is null )
242 return _gc.query( p );
243 return proxy.gc_query( p );
244 }
245
246 // NOTE: This routine is experimental. The stats or function name may change
247 // before it is made officially available.
248 extern (C) GCStats gc_stats()
249 {
250 if( proxy is null )
251 {
252 GCStats stats = void;
253 _gc.getStats( stats );
254 return stats;
255 }
256 // TODO: Add proxy support for this once the layout of GCStats is
257 // finalized.
258 //return proxy.gc_stats();
259 return GCStats.init;
260 }
261
262 extern (C) void gc_addRoot( void* p )
263 {
264 if( proxy is null )
265 return _gc.addRoot( p );
266 return proxy.gc_addRoot( p );
267 }
268
269 extern (C) void gc_addRange( void* p, size_t sz )
270 {
271 if( proxy is null )
272 return _gc.addRange( p, sz );
273 return proxy.gc_addRange( p, sz );
274 }
275
276 extern (C) void gc_removeRoot( void* p )
277 {
278 if( proxy is null )
279 return _gc.removeRoot( p );
280 return proxy.gc_removeRoot( p );
281 }
282
283 extern (C) void gc_removeRange( void* p )
284 {
285 if( proxy is null )
286 return _gc.removeRange( p );
287 return proxy.gc_removeRange( p );
288 }
289
290 extern (C) Proxy* gc_getProxy()
291 {
292 return &pthis;
293 }
294
295 export extern (C) void gc_setProxy( Proxy* p )
296 {
297 if( proxy !is null )
298 {
299 // TODO: Decide if this is an error condition.
300 }
301 proxy = p;
302 foreach( r; _gc.rootIter )
303 proxy.gc_addRoot( r );
304 foreach( r; _gc.rangeIter )
305 proxy.gc_addRange( r.pbot, r.ptop - r.pbot );
306 }
307
308 export extern (C) void gc_clrProxy()
309 {
310 foreach( r; _gc.rangeIter )
311 proxy.gc_removeRange( r.pbot );
312 foreach( r; _gc.rootIter )
313 proxy.gc_removeRoot( r );
314 proxy = null;
315 }