1 /** 2 * This module contains the garbage collector front-end. 3 * 4 * Copyright: Copyright (C) 2005-2006 Digital Mars, www.digitalmars.com. 5 * All rights reserved. 6 * License: 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. 10 * 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 14 * restrictions: 15 * 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 23 * distribution. 24 * Authors: Walter Bright, Sean Kelly, Kris 25 */ 26 module rt.gc.basic.gc; 27 28 private import rt.gc.basic.gcx; 29 private import rt.gc.basic.gcstats; 30 private import tango.stdc.stdlib; 31 32 version=GCCLASS; 33 34 version (GCCLASS) 35 alias GC gc_t; 36 else 37 alias GC* gc_t; 38 39 gc_t _gc; 40 41 private int _termCleanupLevel=1; 42 43 /// sets the cleanup level done by gc 44 /// (0: none, 1: fullCollect, 2: fullCollectNoStack (might crash daemonThreads)) 45 /// result !=0 if the value was invalid 46 extern (C) int gc_setTermCleanupLevel(int cLevel){ 47 if (cLevel<0 || cLevel>2) return cLevel; 48 _termCleanupLevel=cLevel; 49 return 0; 50 } 51 52 /// returns the cleanup level done by gc 53 extern (C) int gc_getTermCleanupLevel(){ 54 return _termCleanupLevel; 55 } 56 57 version (DigitalMars) version(OSX) { 58 extern(C) void _d_osx_image_init(); 59 } 60 61 extern (C) void thread_init(); 62 63 extern (C) void gc_init() 64 { 65 version (GCCLASS) 66 { void* p; 67 ClassInfo ci = GC.classinfo; 68 69 p = tango.stdc.stdlib.malloc(ci.init.length); 70 (cast(byte*)p)[0 .. ci.init.length] = ci.init[]; 71 _gc = cast(GC)p; 72 } 73 else 74 { 75 _gc = cast(GC*) tango.stdc.stdlib.calloc(1, GC.sizeof); 76 } 77 _gc.initialize(); 78 version (DigitalMars) version(OSX) { 79 _d_osx_image_init(); 80 } 81 // NOTE: The GC must initialize the thread library 82 // before its first collection. 83 thread_init(); 84 } 85 86 extern (C) void gc_term() 87 { 88 if (_termCleanupLevel<1) { 89 // no cleanup 90 } else if (_termCleanupLevel==2){ 91 // a more complete cleanup 92 // NOTE: There may be daemons threads still running when this routine is 93 // called. If so, cleaning memory out from under then is a good 94 // way to make them crash horribly. 95 // Often this probably doesn't matter much since the app is 96 // supposed to be shutting down anyway, but for example tests might 97 // crash (and be considerd failed even if the test was ok). 98 // thus this is not the default and should be enabled by 99 // I'm disabling cleanup for now until I can think about it some 100 // more. 101 // 102 _gc.fullCollectNoStack(); // not really a 'collect all' -- still scans 103 // static data area, roots, and ranges. 104 _gc.Dtor(); 105 } else { 106 // default (safe) clenup 107 _gc.fullCollect(); 108 } 109 } 110 111 extern (C) void gc_enable() 112 { 113 _gc.enable(); 114 } 115 116 extern (C) void gc_disable() 117 { 118 _gc.disable(); 119 } 120 121 extern (C) void gc_collect() 122 { 123 _gc.fullCollect(); 124 } 125 126 127 extern (C) void gc_minimize() 128 { 129 _gc.minimize(); 130 } 131 132 extern (C) uint gc_getAttr( void* p ) 133 { 134 return _gc.getAttr( p ); 135 } 136 137 extern (C) uint gc_setAttr( void* p, uint a ) 138 { 139 return _gc.setAttr( p, a ); 140 } 141 142 extern (C) uint gc_clrAttr( void* p, uint a ) 143 { 144 return _gc.clrAttr( p, a ); 145 } 146 147 extern (C) void* gc_malloc( size_t sz, uint ba = 0, PointerMap bitMask = PointerMap.init) 148 { 149 return _gc.malloc( sz, ba ); 150 } 151 152 extern (C) void* gc_calloc( size_t sz, uint ba = 0, PointerMap bitMask = PointerMap.init) 153 { 154 return _gc.calloc( sz, ba ); 155 } 156 157 extern (C) void* gc_realloc( void* p, size_t sz, uint ba = 0, PointerMap bitMask = PointerMap.init) 158 { 159 return _gc.realloc( p, sz, ba ); 160 } 161 162 extern (C) size_t gc_extend( void* p, size_t mx, size_t sz ) 163 { 164 return _gc.extend( p, mx, sz ); 165 } 166 167 extern (C) size_t gc_reserve( size_t sz ) 168 { 169 return _gc.reserve( sz ); 170 } 171 172 extern (C) void gc_free( void* p ) 173 { 174 _gc.free( p ); 175 } 176 177 extern (C) void* gc_addrOf( void* p ) 178 { 179 return _gc.addrOf( p ); 180 } 181 182 extern (C) size_t gc_sizeOf( void* p ) 183 { 184 return _gc.sizeOf( p ); 185 } 186 187 extern (C) BlkInfo gc_query( void* p ) 188 { 189 return _gc.query( p ); 190 } 191 192 // NOTE: This routine is experimental. The stats or function name may change 193 // before it is made officially available. 194 extern (C) GCStats gc_stats() 195 { 196 GCStats stats = void; 197 _gc.getStats( stats ); 198 return stats; 199 } 200 201 extern (C) void gc_addRoot( void* p ) 202 { 203 _gc.addRoot( p ); 204 } 205 206 extern (C) void gc_addRange( void* p, size_t sz ) 207 { 208 _gc.addRange( p, sz ); 209 } 210 211 extern (C) void gc_removeRoot( void *p ) 212 { 213 _gc.removeRoot( p ); 214 } 215 216 extern (C) void gc_removeRange( void *p ) 217 { 218 _gc.removeRange( p ); 219 } 220 221 extern (C) void* gc_weakpointerCreate( Object r ) 222 { 223 return _gc.weakpointerCreate(r); 224 } 225 226 extern (C) void gc_weakpointerDestroy( void* wp ) 227 { 228 _gc.weakpointerDestroy(wp); 229 } 230 231 extern (C) Object gc_weakpointerGet( void* wp ) 232 { 233 return _gc.weakpointerGet(wp); 234 } 235 236 private alias extern(D) void delegate() ddel; 237 private alias extern(D) void delegate(int, int) dint; 238 239 extern (C) void gc_monitor( ddel begin, dint end ) 240 { 241 _gc.monitor (begin,end); 242 }