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