1 2module core.internal.gc.impl.proto.gc; 3 4import core.gc.gcinterface; 5 6import core.internal.container.array; 7 8import cstdlib = core.stdc.stdlib : calloc, free, malloc, realloc; 9static import core.memory; 10 11extern (C) void onOutOfMemoryError(void* pretend_sideffect = null) @trusted pure nothrow @nogc; /* dmd @@@BUG11461@@@ */ 12 13private 14{ 15 extern (C) void gc_init_nothrow() nothrow @nogc; 16 extern (C) void gc_term(); 17 18 extern (C) void gc_enable() nothrow; 19 extern (C) void gc_disable() nothrow; 20 21 extern (C) void* gc_malloc( size_t sz, uint ba = 0, const scope TypeInfo = null ) pure nothrow; 22 extern (C) void* gc_calloc( size_t sz, uint ba = 0, const scope TypeInfo = null ) pure nothrow; 23 extern (C) BlkInfo gc_qalloc( size_t sz, uint ba = 0, const scope TypeInfo = null ) pure nothrow; 24 extern (C) void* gc_realloc(return scope void* p, size_t sz, uint ba = 0, const scope TypeInfo = null ) pure nothrow; 25 extern (C) size_t gc_reserve( size_t sz ) nothrow; 26 27 extern (C) void gc_addRange(const void* p, size_t sz, const scope TypeInfo ti = null ) nothrow @nogc; 28 extern (C) void gc_addRoot(const void* p ) nothrow @nogc; 29} 30 31class ProtoGC : GC 32{ 33 Array!Root roots; 34 Array!Range ranges; 35 36 // Call this function when initializing the real GC 37 // upon ProtoGC term. This function should be called 38 // after the real GC is in place. 39 void transferRangesAndRoots() 40 { 41 // Transfer all ranges 42 foreach (ref r; ranges) 43 { 44 // Range(p, p + sz, cast() ti) 45 gc_addRange(r.pbot, r.ptop - r.pbot, r.ti); 46 } 47 48 // Transfer all roots 49 foreach (ref r; roots) 50 { 51 gc_addRoot(r.proot); 52 } 53 } 54 55 this() 56 { 57 } 58 59 void Dtor() 60 { 61 } 62 63 void enable() 64 { 65 .gc_init_nothrow(); 66 .gc_enable(); 67 } 68 69 void disable() 70 { 71 .gc_init_nothrow(); 72 .gc_disable(); 73 } 74 75 void collect() nothrow 76 { 77 } 78 79 void collectNoStack() nothrow 80 { 81 } 82 83 void minimize() nothrow 84 { 85 } 86 87 uint getAttr(void* p) nothrow 88 { 89 return 0; 90 } 91 92 uint setAttr(void* p, uint mask) nothrow 93 { 94 return 0; 95 } 96 97 uint clrAttr(void* p, uint mask) nothrow 98 { 99 return 0; 100 } 101 102 void* malloc(size_t size, uint bits, const scope TypeInfo ti) nothrow 103 { 104 .gc_init_nothrow(); 105 return .gc_malloc(size, bits, ti); 106 } 107 108 BlkInfo qalloc(size_t size, uint bits, const scope TypeInfo ti) nothrow 109 { 110 .gc_init_nothrow(); 111 return .gc_qalloc(size, bits, ti); 112 } 113 114 void* calloc(size_t size, uint bits, const scope TypeInfo ti) nothrow 115 { 116 .gc_init_nothrow(); 117 return .gc_calloc(size, bits, ti); 118 } 119 120 void* realloc(void* p, size_t size, uint bits, const scope TypeInfo ti) nothrow 121 { 122 .gc_init_nothrow(); 123 return .gc_realloc(p, size, bits, ti); 124 } 125 126 size_t extend(void* p, size_t minsize, size_t maxsize, const scope TypeInfo ti) nothrow 127 { 128 return 0; 129 } 130 131 size_t reserve(size_t size) nothrow 132 { 133 .gc_init_nothrow(); 134 return .gc_reserve(size); 135 } 136 137 void free(void* p) nothrow @nogc 138 { 139 if (p) assert(false, "Invalid memory deallocation"); 140 } 141 142 void* addrOf(void* p) nothrow @nogc 143 { 144 return null; 145 } 146 147 size_t sizeOf(void* p) nothrow @nogc 148 { 149 return 0; 150 } 151 152 BlkInfo query(void* p) nothrow 153 { 154 return BlkInfo.init; 155 } 156 157 core.memory.GC.Stats stats() nothrow 158 { 159 return typeof(return).init; 160 } 161 162 163 core.memory.GC.ProfileStats profileStats() nothrow 164 { 165 return typeof(return).init; 166 } 167 168 169 void addRoot(void* p) nothrow @nogc 170 { 171 roots.insertBack(Root(p)); 172 } 173 174 void removeRoot(void* p) nothrow @nogc 175 { 176 foreach (ref r; roots) 177 { 178 if (r is p) 179 { 180 r = roots.back; 181 roots.popBack(); 182 return; 183 } 184 } 185 } 186 187 @property RootIterator rootIter() return @nogc 188 { 189 return &rootsApply; 190 } 191 192 private int rootsApply(scope int delegate(ref Root) nothrow dg) 193 { 194 foreach (ref r; roots) 195 { 196 if (auto result = dg(r)) 197 return result; 198 } 199 return 0; 200 } 201 202 void addRange(void* p, size_t sz, const TypeInfo ti = null) nothrow @nogc 203 { 204 ranges.insertBack(Range(p, p + sz, cast() ti)); 205 } 206 207 void removeRange(void* p) nothrow @nogc 208 { 209 foreach (ref r; ranges) 210 { 211 if (r.pbot is p) 212 { 213 r = ranges.back; 214 ranges.popBack(); 215 return; 216 } 217 } 218 } 219 220 @property RangeIterator rangeIter() return @nogc 221 { 222 return &rangesApply; 223 } 224 225 private int rangesApply(scope int delegate(ref Range) nothrow dg) 226 { 227 foreach (ref r; ranges) 228 { 229 if (auto result = dg(r)) 230 return result; 231 } 232 return 0; 233 } 234 235 void runFinalizers(const scope void[] segment) nothrow 236 { 237 } 238 239 bool inFinalizer() nothrow 240 { 241 return false; 242 } 243 244 ulong allocatedInCurrentThread() nothrow 245 { 246 return stats().allocatedInCurrentThread; 247 } 248} 249