- }
-
-
-
- void initialize()
- {
- int dummy;
- stackBottom = cast(char*)&dummy;
- opts.parse(cstdlib.getenv("D_GC_OPTS"));
- lock = GCLock.classinfo;
- inited = 1;
- setStackBottom(rt_stackBottom());
- stats = Stats(this);
- }
-
-
- /**
- *
- */
- void enable()
- {
- if (!thread_needLock())
- {
- assert(this.disabled > 0);
- this.disabled--;
- }
- else synchronized (lock)
- {
- assert(this.disabled > 0);
- this.disabled--;
- }
- }
-
-
- /**
- *
- */
- void disable()
- {
- if (!thread_needLock())
- {
- this.disabled++;
- }
- else synchronized (lock)
- {
- this.disabled++;
- }
- }
-
-
- /**
- *
- */
- uint getAttr(void* p)
- {
- if (!p)
- {
- return 0;
- }
-
- uint go()
- {
- Pool* pool = this.findPool(p);
- uint old_attrs = 0;
-
- if (pool)
- {
- auto bit_i = cast(size_t)(p - pool.baseAddr) / 16;
-
- old_attrs = this.getAttr(pool, bit_i);
- }
- return old_attrs;
- }
-
- if (!thread_needLock())
- {
- return go();
- }
- else synchronized (lock)
- {
- return go();
- }
- }
-
-
- /**
- *
- */
- uint setAttr(void* p, uint mask)
- {
- if (!p)
- {
- return 0;
- }
-
- uint go()
- {
- Pool* pool = this.findPool(p);
- uint old_attrs = 0;
-
- if (pool)
- {
- auto bit_i = cast(size_t)(p - pool.baseAddr) / 16;
-
- old_attrs = this.getAttr(pool, bit_i);
- this.setAttr(pool, bit_i, mask);
- }
- return old_attrs;
- }
-
- if (!thread_needLock())
- {
- return go();
- }
- else synchronized (lock)
- {
- return go();
- }
- }
-
-
- /**
- *
- */
- uint clrAttr(void* p, uint mask)
- {
- if (!p)
- {
- return 0;
- }
-
- uint go()
- {
- Pool* pool = this.findPool(p);
- uint old_attrs = 0;
-
- if (pool)
- {
- auto bit_i = cast(size_t)(p - pool.baseAddr) / 16;
-
- old_attrs = this.getAttr(pool, bit_i);
- this.clrAttr(pool, bit_i, mask);
- }
- return old_attrs;
- }
-
- if (!thread_needLock())
- {
- return go();
- }
- else synchronized (lock)
- {
- return go();
- }
- }
-
-
- /**
- *
- */
- void *malloc(size_t size, uint attrs, PointerMap ptrmap)
- {
- if (!size)
- {
- return null;
- }
-
- if (!thread_needLock())
- {
- return mallocNoSync(size, attrs, ptrmap.bits.ptr);
- }
- else synchronized (lock)
- {
- return mallocNoSync(size, attrs, ptrmap.bits.ptr);
- }
- }
-
-
- //
- //
- //
- private void *mallocNoSync(size_t size, uint attrs, size_t* pm_bitmask)
- {
- assert(size != 0);
-
- stats.malloc_started(size, attrs, pm_bitmask);
- scope (exit)
- stats.malloc_finished(p);
-
- void *p = null;
- Bins bin;
-
- if (opts.options.sentinel)
- size += SENTINEL_EXTRA;
-
- bool has_pm = has_pointermap(attrs);
- if (has_pm)
- size += size_t.sizeof;
-
- // Compute size bin
- // Cache previous binsize lookup - Dave Fladebo.
- static size_t lastsize = -1;
- static Bins lastbin;
- if (size == lastsize)
- bin = lastbin;
- else
- {
- bin = this.findBin(size);
- lastsize = size;
- lastbin = bin;
- }
-
- size_t capacity; // to figure out where to store the bitmask
- if (bin < B_PAGE)
- {
- p = this.bucket[bin];
- if (p is null)
- {
- if (!this.allocPage(bin) && !this.disabled) // try to find a new page
- {
- if (!thread_needLock())
- {
- /* Then we haven't locked it yet. Be sure
- * and lock for a collection, since a finalizer
- * may start a new thread.
- */
- synchronized (lock)
- {
- this.fullcollectshell();
- }
- }
- else if (!this.fullcollectshell()) // collect to find a new page
- {
- //this.newPool(1);
- }
- }
- if (!this.bucket[bin] && !this.allocPage(bin))
- {
- this.newPool(1); // allocate new pool to find a new page
- int result = this.allocPage(bin);
- if (!result)
- onOutOfMemoryError();
- }
- p = this.bucket[bin];
- }
- capacity = binsize[bin];
-
- // Return next item from free list
- this.bucket[bin] = (cast(List*)p).next;
- if (!(attrs & BlkAttr.NO_SCAN))
- memset(p + size, 0, capacity - size);
- if (opts.options.mem_stomp)
- memset(p, 0xF0, size);
- }
- else
- {
- p = this.bigAlloc(size);
- if (!p)
- onOutOfMemoryError();
- // Round the size up to the number of pages needed to store it
- size_t npages = (size + PAGESIZE - 1) / PAGESIZE;
- capacity = npages * PAGESIZE;
- }
-
- // Store the bit mask AFTER SENTINEL_POST
- // TODO: store it BEFORE, so the bitmask is protected too
- if (has_pm) {
- auto end_of_blk = cast(size_t**)(p + capacity - size_t.sizeof);
- *end_of_blk = pm_bitmask;
- size -= size_t.sizeof;
- }
-
- if (opts.options.sentinel) {
- size -= SENTINEL_EXTRA;
- p = sentinel_add(p);
- sentinel_init(p, size);
- }