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