xref: /netbsd-src/external/gpl3/gcc.old/dist/libphobos/libdruntime/gc/proxy.d (revision 627f7eb200a4419d89b531d55fccd2ee3ffdcde0)
1*627f7eb2Smrg /**
2*627f7eb2Smrg  * Contains the external GC interface.
3*627f7eb2Smrg  *
4*627f7eb2Smrg  * Copyright: Copyright Digital Mars 2005 - 2016.
5*627f7eb2Smrg  * License:   $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6*627f7eb2Smrg  * Authors:   Walter Bright, Sean Kelly
7*627f7eb2Smrg  */
8*627f7eb2Smrg 
9*627f7eb2Smrg /*          Copyright Digital Mars 2005 - 2016.
10*627f7eb2Smrg  * Distributed under the Boost Software License, Version 1.0.
11*627f7eb2Smrg  *    (See accompanying file LICENSE or copy at
12*627f7eb2Smrg  *          http://www.boost.org/LICENSE_1_0.txt)
13*627f7eb2Smrg  */
14*627f7eb2Smrg module gc.proxy;
15*627f7eb2Smrg 
16*627f7eb2Smrg import gc.impl.conservative.gc;
17*627f7eb2Smrg import gc.impl.manual.gc;
18*627f7eb2Smrg import gc.config;
19*627f7eb2Smrg import gc.gcinterface;
20*627f7eb2Smrg 
21*627f7eb2Smrg static import core.memory;
22*627f7eb2Smrg 
23*627f7eb2Smrg private
24*627f7eb2Smrg {
25*627f7eb2Smrg     static import core.memory;
26*627f7eb2Smrg     alias BlkInfo = core.memory.GC.BlkInfo;
27*627f7eb2Smrg 
28*627f7eb2Smrg     extern (C) void thread_init();
29*627f7eb2Smrg     extern (C) void thread_term();
30*627f7eb2Smrg 
31*627f7eb2Smrg     __gshared GC instance;
32*627f7eb2Smrg     __gshared GC proxiedGC; // used to iterate roots of Windows DLLs
33*627f7eb2Smrg 
34*627f7eb2Smrg }
35*627f7eb2Smrg 
36*627f7eb2Smrg 
37*627f7eb2Smrg extern (C)
38*627f7eb2Smrg {
39*627f7eb2Smrg 
gc_init()40*627f7eb2Smrg     void gc_init()
41*627f7eb2Smrg     {
42*627f7eb2Smrg         config.initialize();
43*627f7eb2Smrg         ManualGC.initialize(instance);
44*627f7eb2Smrg         ConservativeGC.initialize(instance);
45*627f7eb2Smrg         if (instance is null)
46*627f7eb2Smrg         {
47*627f7eb2Smrg             import core.stdc.stdio : fprintf, stderr;
48*627f7eb2Smrg             import core.stdc.stdlib : exit;
49*627f7eb2Smrg 
50*627f7eb2Smrg             fprintf(stderr, "No GC was initialized, please recheck the name of the selected GC ('%.*s').\n", cast(int)config.gc.length, config.gc.ptr);
51*627f7eb2Smrg             exit(1);
52*627f7eb2Smrg         }
53*627f7eb2Smrg 
54*627f7eb2Smrg         // NOTE: The GC must initialize the thread library
55*627f7eb2Smrg         //       before its first collection.
56*627f7eb2Smrg         thread_init();
57*627f7eb2Smrg     }
58*627f7eb2Smrg 
gc_term()59*627f7eb2Smrg     void gc_term()
60*627f7eb2Smrg     {
61*627f7eb2Smrg         // NOTE: There may be daemons threads still running when this routine is
62*627f7eb2Smrg         //       called.  If so, cleaning memory out from under then is a good
63*627f7eb2Smrg         //       way to make them crash horribly.  This probably doesn't matter
64*627f7eb2Smrg         //       much since the app is supposed to be shutting down anyway, but
65*627f7eb2Smrg         //       I'm disabling cleanup for now until I can think about it some
66*627f7eb2Smrg         //       more.
67*627f7eb2Smrg         //
68*627f7eb2Smrg         // NOTE: Due to popular demand, this has been re-enabled.  It still has
69*627f7eb2Smrg         //       the problems mentioned above though, so I guess we'll see.
70*627f7eb2Smrg 
71*627f7eb2Smrg         instance.collectNoStack(); // not really a 'collect all' -- still scans
72*627f7eb2Smrg                                     // static data area, roots, and ranges.
73*627f7eb2Smrg 
74*627f7eb2Smrg         thread_term();
75*627f7eb2Smrg 
76*627f7eb2Smrg         ManualGC.finalize(instance);
77*627f7eb2Smrg         ConservativeGC.finalize(instance);
78*627f7eb2Smrg     }
79*627f7eb2Smrg 
gc_enable()80*627f7eb2Smrg     void gc_enable()
81*627f7eb2Smrg     {
82*627f7eb2Smrg         instance.enable();
83*627f7eb2Smrg     }
84*627f7eb2Smrg 
gc_disable()85*627f7eb2Smrg     void gc_disable()
86*627f7eb2Smrg     {
87*627f7eb2Smrg         instance.disable();
88*627f7eb2Smrg     }
89*627f7eb2Smrg 
gc_collect()90*627f7eb2Smrg     void gc_collect() nothrow
91*627f7eb2Smrg     {
92*627f7eb2Smrg         instance.collect();
93*627f7eb2Smrg     }
94*627f7eb2Smrg 
gc_minimize()95*627f7eb2Smrg     void gc_minimize() nothrow
96*627f7eb2Smrg     {
97*627f7eb2Smrg         instance.minimize();
98*627f7eb2Smrg     }
99*627f7eb2Smrg 
gc_getAttr(void * p)100*627f7eb2Smrg     uint gc_getAttr( void* p ) nothrow
101*627f7eb2Smrg     {
102*627f7eb2Smrg         return instance.getAttr(p);
103*627f7eb2Smrg     }
104*627f7eb2Smrg 
gc_setAttr(void * p,uint a)105*627f7eb2Smrg     uint gc_setAttr( void* p, uint a ) nothrow
106*627f7eb2Smrg     {
107*627f7eb2Smrg         return instance.setAttr(p, a);
108*627f7eb2Smrg     }
109*627f7eb2Smrg 
gc_clrAttr(void * p,uint a)110*627f7eb2Smrg     uint gc_clrAttr( void* p, uint a ) nothrow
111*627f7eb2Smrg     {
112*627f7eb2Smrg         return instance.clrAttr(p, a);
113*627f7eb2Smrg     }
114*627f7eb2Smrg 
115*627f7eb2Smrg     void* gc_malloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) nothrow
116*627f7eb2Smrg     {
117*627f7eb2Smrg         return instance.malloc(sz, ba, ti);
118*627f7eb2Smrg     }
119*627f7eb2Smrg 
120*627f7eb2Smrg     BlkInfo gc_qalloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) nothrow
121*627f7eb2Smrg     {
122*627f7eb2Smrg         return instance.qalloc( sz, ba, ti );
123*627f7eb2Smrg     }
124*627f7eb2Smrg 
125*627f7eb2Smrg     void* gc_calloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) nothrow
126*627f7eb2Smrg     {
127*627f7eb2Smrg         return instance.calloc( sz, ba, ti );
128*627f7eb2Smrg     }
129*627f7eb2Smrg 
130*627f7eb2Smrg     void* gc_realloc( void* p, size_t sz, uint ba = 0, const TypeInfo ti = null ) nothrow
131*627f7eb2Smrg     {
132*627f7eb2Smrg         return instance.realloc( p, sz, ba, ti );
133*627f7eb2Smrg     }
134*627f7eb2Smrg 
135*627f7eb2Smrg     size_t gc_extend( void* p, size_t mx, size_t sz, const TypeInfo ti = null ) nothrow
136*627f7eb2Smrg     {
137*627f7eb2Smrg         return instance.extend( p, mx, sz,ti );
138*627f7eb2Smrg     }
139*627f7eb2Smrg 
gc_reserve(size_t sz)140*627f7eb2Smrg     size_t gc_reserve( size_t sz ) nothrow
141*627f7eb2Smrg     {
142*627f7eb2Smrg         return instance.reserve( sz );
143*627f7eb2Smrg     }
144*627f7eb2Smrg 
gc_free(void * p)145*627f7eb2Smrg     void gc_free( void* p ) nothrow
146*627f7eb2Smrg     {
147*627f7eb2Smrg         return instance.free( p );
148*627f7eb2Smrg     }
149*627f7eb2Smrg 
gc_addrOf(void * p)150*627f7eb2Smrg     void* gc_addrOf( void* p ) nothrow
151*627f7eb2Smrg     {
152*627f7eb2Smrg         return instance.addrOf( p );
153*627f7eb2Smrg     }
154*627f7eb2Smrg 
gc_sizeOf(void * p)155*627f7eb2Smrg     size_t gc_sizeOf( void* p ) nothrow
156*627f7eb2Smrg     {
157*627f7eb2Smrg         return instance.sizeOf( p );
158*627f7eb2Smrg     }
159*627f7eb2Smrg 
gc_query(void * p)160*627f7eb2Smrg     BlkInfo gc_query( void* p ) nothrow
161*627f7eb2Smrg     {
162*627f7eb2Smrg         return instance.query( p );
163*627f7eb2Smrg     }
164*627f7eb2Smrg 
gc_stats()165*627f7eb2Smrg     core.memory.GC.Stats gc_stats() nothrow
166*627f7eb2Smrg     {
167*627f7eb2Smrg         return instance.stats();
168*627f7eb2Smrg     }
169*627f7eb2Smrg 
gc_addRoot(void * p)170*627f7eb2Smrg     void gc_addRoot( void* p ) nothrow
171*627f7eb2Smrg     {
172*627f7eb2Smrg         return instance.addRoot( p );
173*627f7eb2Smrg     }
174*627f7eb2Smrg 
175*627f7eb2Smrg     void gc_addRange( void* p, size_t sz, const TypeInfo ti = null ) nothrow
176*627f7eb2Smrg     {
177*627f7eb2Smrg         return instance.addRange( p, sz, ti );
178*627f7eb2Smrg     }
179*627f7eb2Smrg 
gc_removeRoot(void * p)180*627f7eb2Smrg     void gc_removeRoot( void* p ) nothrow
181*627f7eb2Smrg     {
182*627f7eb2Smrg         return instance.removeRoot( p );
183*627f7eb2Smrg     }
184*627f7eb2Smrg 
gc_removeRange(void * p)185*627f7eb2Smrg     void gc_removeRange( void* p ) nothrow
186*627f7eb2Smrg     {
187*627f7eb2Smrg         return instance.removeRange( p );
188*627f7eb2Smrg     }
189*627f7eb2Smrg 
gc_runFinalizers(in void[]segment)190*627f7eb2Smrg     void gc_runFinalizers( in void[] segment ) nothrow
191*627f7eb2Smrg     {
192*627f7eb2Smrg         return instance.runFinalizers( segment );
193*627f7eb2Smrg     }
194*627f7eb2Smrg 
gc_inFinalizer()195*627f7eb2Smrg     bool gc_inFinalizer() nothrow
196*627f7eb2Smrg     {
197*627f7eb2Smrg         return instance.inFinalizer();
198*627f7eb2Smrg     }
199*627f7eb2Smrg 
gc_getProxy()200*627f7eb2Smrg     GC gc_getProxy() nothrow
201*627f7eb2Smrg     {
202*627f7eb2Smrg         return instance;
203*627f7eb2Smrg     }
204*627f7eb2Smrg 
205*627f7eb2Smrg     export
206*627f7eb2Smrg     {
gc_setProxy(GC proxy)207*627f7eb2Smrg         void gc_setProxy( GC proxy )
208*627f7eb2Smrg         {
209*627f7eb2Smrg             foreach (root; instance.rootIter)
210*627f7eb2Smrg             {
211*627f7eb2Smrg                 proxy.addRoot(root);
212*627f7eb2Smrg             }
213*627f7eb2Smrg 
214*627f7eb2Smrg             foreach (range; instance.rangeIter)
215*627f7eb2Smrg             {
216*627f7eb2Smrg                 proxy.addRange(range.pbot, range.ptop - range.pbot, range.ti);
217*627f7eb2Smrg             }
218*627f7eb2Smrg 
219*627f7eb2Smrg             proxiedGC = instance; // remember initial GC to later remove roots
220*627f7eb2Smrg             instance = proxy;
221*627f7eb2Smrg         }
222*627f7eb2Smrg 
gc_clrProxy()223*627f7eb2Smrg         void gc_clrProxy()
224*627f7eb2Smrg         {
225*627f7eb2Smrg             foreach (root; proxiedGC.rootIter)
226*627f7eb2Smrg             {
227*627f7eb2Smrg                 instance.removeRoot(root);
228*627f7eb2Smrg             }
229*627f7eb2Smrg 
230*627f7eb2Smrg             foreach (range; proxiedGC.rangeIter)
231*627f7eb2Smrg             {
232*627f7eb2Smrg                 instance.removeRange(range);
233*627f7eb2Smrg             }
234*627f7eb2Smrg 
235*627f7eb2Smrg             instance = proxiedGC;
236*627f7eb2Smrg             proxiedGC = null;
237*627f7eb2Smrg         }
238*627f7eb2Smrg     }
239*627f7eb2Smrg }
240