aarch64: Fix sve/acle/general/ldff1_8.c failures
[gcc.git] / libphobos / libdruntime / core / internal / gc / proxy.d
blobd46cb8cd775b888334d2ed6ad6b2fb60880cb7d7
1 /**
2 * Contains the external GC interface.
4 * Copyright: D Language Foundation 2005 - 2021.
5 * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 * Authors: Walter Bright, Sean Kelly
7 */
8 module core.internal.gc.proxy;
10 import core.internal.gc.impl.proto.gc;
11 import core.gc.config;
12 import core.gc.gcinterface;
13 import core.gc.registry : createGCInstance;
15 static import core.memory;
17 private
19 static import core.memory;
20 alias BlkInfo = core.memory.GC.BlkInfo;
22 import core.internal.spinlock;
23 static SpinLock instanceLock;
25 __gshared bool isInstanceInit = false;
26 __gshared GC _instance = new ProtoGC();
27 __gshared GC proxiedGC; // used to iterate roots of Windows DLLs
29 pragma (inline, true) @trusted @nogc nothrow
30 GC instance() { return _instance; }
33 extern (C)
35 import core.attribute : weak;
37 // do not import GC modules, they might add a dependency to this whole module
38 void _d_register_conservative_gc();
39 void _d_register_manual_gc();
41 // if you don't want to include the default GCs, replace during link by another implementation
42 void* register_default_gcs() @weak
44 pragma(inline, false);
45 // do not call, they register implicitly through pragma(crt_constructor)
46 // avoid being optimized away
47 auto reg1 = &_d_register_conservative_gc;
48 auto reg2 = &_d_register_manual_gc;
49 return reg1 < reg2 ? reg1 : reg2;
52 void gc_init()
54 instanceLock.lock();
55 if (!isInstanceInit)
57 register_default_gcs();
58 config.initialize();
59 auto protoInstance = instance;
60 auto newInstance = createGCInstance(config.gc);
61 if (newInstance is null)
63 import core.stdc.stdio : fprintf, stderr;
64 import core.stdc.stdlib : exit;
65 import core.atomic : atomicLoad;
67 fprintf(atomicLoad(stderr), "No GC was initialized, please recheck the name of the selected GC ('%.*s').\n", cast(int)config.gc.length, config.gc.ptr);
68 instanceLock.unlock();
69 exit(1);
71 // Shouldn't get here.
72 assert(0);
74 _instance = newInstance;
75 // Transfer all ranges and roots to the real GC.
76 (cast(ProtoGC) protoInstance).transferRangesAndRoots();
77 isInstanceInit = true;
79 instanceLock.unlock();
82 void gc_init_nothrow() nothrow
84 scope(failure)
86 import core.internal.abort;
87 abort("Cannot initialize the garbage collector.\n");
88 assert(0);
90 gc_init();
93 void gc_term()
95 if (isInstanceInit)
97 switch (config.cleanup)
99 default:
100 import core.stdc.stdio : fprintf, stderr;
101 import core.atomic : atomicLoad;
103 fprintf(atomicLoad(stderr), "Unknown GC cleanup method, please recheck ('%.*s').\n",
104 cast(int)config.cleanup.length, config.cleanup.ptr);
105 break;
106 case "none":
107 break;
108 case "collect":
109 instance.collect();
110 break;
111 case "finalize":
112 instance.runFinalizers((cast(ubyte*)null)[0 .. size_t.max]);
113 break;
115 destroy(instance);
119 void gc_enable()
121 instance.enable();
124 void gc_disable()
126 instance.disable();
129 void gc_collect() nothrow
131 instance.collect();
134 void gc_minimize() nothrow
136 instance.minimize();
139 uint gc_getAttr( void* p ) nothrow
141 return instance.getAttr(p);
144 uint gc_setAttr( void* p, uint a ) nothrow
146 return instance.setAttr(p, a);
149 uint gc_clrAttr( void* p, uint a ) nothrow
151 return instance.clrAttr(p, a);
154 void* gc_malloc( size_t sz, uint ba = 0, const scope TypeInfo ti = null ) nothrow
156 return instance.malloc(sz, ba, ti);
159 BlkInfo gc_qalloc( size_t sz, uint ba = 0, const scope TypeInfo ti = null ) nothrow
161 return instance.qalloc( sz, ba, ti );
164 void* gc_calloc( size_t sz, uint ba = 0, const scope TypeInfo ti = null ) nothrow
166 return instance.calloc( sz, ba, ti );
169 void* gc_realloc( void* p, size_t sz, uint ba = 0, const scope TypeInfo ti = null ) nothrow
171 return instance.realloc( p, sz, ba, ti );
174 size_t gc_extend( void* p, size_t mx, size_t sz, const scope TypeInfo ti = null ) nothrow
176 return instance.extend( p, mx, sz,ti );
179 size_t gc_reserve( size_t sz ) nothrow
181 return instance.reserve( sz );
184 void gc_free( void* p ) nothrow @nogc
186 return instance.free( p );
189 void* gc_addrOf( void* p ) nothrow @nogc
191 return instance.addrOf( p );
194 size_t gc_sizeOf( void* p ) nothrow @nogc
196 return instance.sizeOf( p );
199 BlkInfo gc_query( void* p ) nothrow
201 return instance.query( p );
204 core.memory.GC.Stats gc_stats() @safe nothrow @nogc
206 return instance.stats();
209 core.memory.GC.ProfileStats gc_profileStats() @safe nothrow @nogc
211 return instance.profileStats();
214 void gc_addRoot( void* p ) nothrow @nogc
216 return instance.addRoot( p );
219 void gc_addRange( void* p, size_t sz, const TypeInfo ti = null ) nothrow @nogc
221 return instance.addRange( p, sz, ti );
224 void gc_removeRoot( void* p ) nothrow
226 return instance.removeRoot( p );
229 void gc_removeRange( void* p ) nothrow
231 return instance.removeRange( p );
234 void gc_runFinalizers(const scope void[] segment ) nothrow
236 return instance.runFinalizers( segment );
239 bool gc_inFinalizer() nothrow @nogc @safe
241 return instance.inFinalizer();
244 ulong gc_allocatedInCurrentThread() nothrow
246 return instance.allocatedInCurrentThread();
249 void[] gc_getArrayUsed(void *ptr, bool atomic) nothrow
251 return instance.getArrayUsed( ptr, atomic );
254 bool gc_expandArrayUsed(void[] slice, size_t newUsed, bool atomic) nothrow
256 return instance.expandArrayUsed( slice, newUsed, atomic );
259 size_t gc_reserveArrayCapacity(void[] slice, size_t request, bool atomic) nothrow
261 return instance.reserveArrayCapacity( slice, request, atomic );
264 bool gc_shrinkArrayUsed(void[] slice, size_t existingUsed, bool atomic) nothrow
266 return instance.shrinkArrayUsed( slice, existingUsed, atomic );
269 GC gc_getProxy() nothrow
271 return instance;
274 export
276 void gc_setProxy( GC proxy )
278 foreach (root; instance.rootIter)
280 proxy.addRoot(root);
283 foreach (range; instance.rangeIter)
285 proxy.addRange(range.pbot, range.ptop - range.pbot, range.ti);
288 proxiedGC = instance; // remember initial GC to later remove roots
289 _instance = proxy;
292 void gc_clrProxy()
294 foreach (root; proxiedGC.rootIter)
296 instance.removeRoot(root);
299 foreach (range; proxiedGC.rangeIter)
301 instance.removeRange(range);
304 _instance = proxiedGC;
305 proxiedGC = null;