Now D_GC_OPTS accepts a new boolean option: conservative. When true, the
heap is scanned conservatively, even when type information is available.
The option defaults to false.
+package bool has_pointermap(uint attrs)
+{
+ return !opts.options.conservative && !(attrs & BlkAttr.NO_SCAN);
+}
+
if (opts.options.sentinel)
size += SENTINEL_EXTRA;
if (opts.options.sentinel)
size += SENTINEL_EXTRA;
- bool has_pm = !(attrs & BlkAttr.NO_SCAN);
- size_t pm_bitmask_size;
+ bool has_pm = has_pointermap(attrs);
- pm_bitmask_size = (size_t*).sizeof;
- size += pm_bitmask_size;
// Compute size bin
// Cache previous binsize lookup - Dave Fladebo.
// Compute size bin
// Cache previous binsize lookup - Dave Fladebo.
// Return next item from free list
gcx.bucket[bin] = (cast(List*)p).next;
// Return next item from free list
gcx.bucket[bin] = (cast(List*)p).next;
- if( !(attrs & BlkAttr.NO_SCAN) )
+ if (!(attrs & BlkAttr.NO_SCAN))
memset(p + size, 0, capacity - size);
if (opts.options.mem_stomp)
memset(p, 0xF0, size);
memset(p + size, 0, capacity - size);
if (opts.options.mem_stomp)
memset(p, 0xF0, size);
// Store the bit mask AFTER SENTINEL_POST
// TODO: store it BEFORE, so the bitmask is protected too
if (has_pm) {
// 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 - pm_bitmask_size);
+ auto end_of_blk = cast(size_t**)(p + capacity - size_t.sizeof);
*end_of_blk = pm_bitmask;
*end_of_blk = pm_bitmask;
- size -= pm_bitmask_size;
}
if (opts.options.sentinel) {
}
if (opts.options.sentinel) {
void* blk_base_addr = gcx.findBase(p);
size_t blk_size = gcx.findSize(p);
void* blk_base_addr = gcx.findBase(p);
size_t blk_size = gcx.findSize(p);
- bool has_pm = !(attrs & BlkAttr.NO_SCAN);
+ bool has_pm = has_pointermap(attrs);
size_t pm_bitmask_size = 0;
if (has_pm) {
size_t pm_bitmask_size = 0;
if (has_pm) {
- pm_bitmask_size = (size_t*).sizeof;
+ pm_bitmask_size = size_t.sizeof;
// Retrieve pointer map bit mask if appropriate
if (pm_bitmask is null) {
auto end_of_blk = cast(size_t**)(blk_base_addr +
// Retrieve pointer map bit mask if appropriate
if (pm_bitmask is null) {
auto end_of_blk = cast(size_t**)(blk_base_addr +
- blk_size - pm_bitmask_size);
+ blk_size - size_t.sizeof);
pm_bitmask = *end_of_blk;
}
}
pm_bitmask = *end_of_blk;
}
}
void* blk_base_addr = gcx.findBase(p);
size_t blk_size = gcx.findSize(p);
void* blk_base_addr = gcx.findBase(p);
size_t blk_size = gcx.findSize(p);
- bool has_pm = !(attrs & BlkAttr.NO_SCAN);
+ bool has_pm = has_pointermap(attrs);
size_t* pm_bitmask = null;
size_t pm_bitmask_size = 0;
if (has_pm) {
size_t* pm_bitmask = null;
size_t pm_bitmask_size = 0;
if (has_pm) {
- pm_bitmask_size = (size_t*).sizeof;
+ pm_bitmask_size = size_t.sizeof;
// Retrieve pointer map bit mask
auto end_of_blk = cast(size_t**)(blk_base_addr +
// Retrieve pointer map bit mask
auto end_of_blk = cast(size_t**)(blk_base_addr +
- blk_size - pm_bitmask_size);
+ blk_size - size_t.sizeof);
pm_bitmask = *end_of_blk;
pm_bitmask = *end_of_blk;
+
+ minsize += size_t.sizeof;
+ maxsize += size_t.sizeof;
}
if (blk_size < PAGESIZE)
return 0; // cannot extend buckets
}
if (blk_size < PAGESIZE)
return 0; // cannot extend buckets
- minsize += pm_bitmask_size;
- maxsize += pm_bitmask_size;
-
auto psz = blk_size / PAGESIZE;
auto minsz = (minsize + PAGESIZE - 1) / PAGESIZE;
auto maxsz = (maxsize + PAGESIZE - 1) / PAGESIZE;
auto psz = blk_size / PAGESIZE;
auto minsz = (minsize + PAGESIZE - 1) / PAGESIZE;
auto maxsz = (maxsize + PAGESIZE - 1) / PAGESIZE;
gcx.size_cache = 0;
if (has_pm) {
gcx.size_cache = 0;
if (has_pm) {
- new_size -= pm_bitmask_size;
+ new_size -= size_t.sizeof;
auto end_of_blk = cast(size_t**)(blk_base_addr + new_size);
*end_of_blk = pm_bitmask;
}
auto end_of_blk = cast(size_t**)(blk_base_addr + new_size);
*end_of_blk = pm_bitmask;
}
uint attrs = gcx.getAttr(pool, biti);
size_t size = gcx.findSize(p);
uint attrs = gcx.getAttr(pool, biti);
size_t size = gcx.findSize(p);
- bool has_pm = !(attrs & BlkAttr.NO_SCAN);
size_t pm_bitmask_size = 0;
size_t pm_bitmask_size = 0;
- if (has_pm)
- pm_bitmask_size = (size_t*).sizeof;
+ if (has_pointermap(attrs))
+ pm_bitmask_size = size_t.sizeof;
if (opts.options.sentinel) {
// Check for interior pointer
if (opts.options.sentinel) {
// Check for interior pointer
size_t pcache = 0;
uint changes = 0;
size_t pcache = 0;
uint changes = 0;
- // TODO: add option to be conservative
- // force conservative scanning
- //pm_bitmask = PointerMap.init.bits.ptr;
-
size_t type_size = pm_bitmask[0];
size_t* pm_bits = pm_bitmask + 1;
size_t type_size = pm_bitmask[0];
size_t* pm_bits = pm_bitmask + 1;
pn = cast(size_t)(o - pool.baseAddr) / PAGESIZE;
bin = cast(Bins)pool.pagetable[pn];
if (bin < B_PAGE) {
pn = cast(size_t)(o - pool.baseAddr) / PAGESIZE;
bin = cast(Bins)pool.pagetable[pn];
if (bin < B_PAGE) {
- auto end_of_blk = cast(size_t**)(o + binsize[bin] -
- (size_t*).sizeof);
- size_t* pm_bitmask = *end_of_blk;
- mark(o, end_of_blk, pm_bitmask);
+ if (opts.options.conservative)
+ mark_conservative(o, o + binsize[bin]);
+ else {
+ auto end_of_blk = cast(size_t**)(o +
+ binsize[bin] - size_t.sizeof);
+ size_t* pm_bitmask = *end_of_blk;
+ mark(o, end_of_blk, pm_bitmask);
+ }
}
else if (bin == B_PAGE || bin == B_PAGEPLUS)
{
}
else if (bin == B_PAGE || bin == B_PAGEPLUS)
{
u++;
size_t blk_size = u * PAGESIZE;
u++;
size_t blk_size = u * PAGESIZE;
- auto end_of_blk = cast(size_t**)(o + blk_size -
- (size_t*).sizeof);
- size_t* pm_bitmask = *end_of_blk;
- mark(o, end_of_blk, pm_bitmask);
+ if (opts.options.conservative)
+ mark_conservative(o, o + blk_size);
+ else {
+ auto end_of_blk = cast(size_t**)(o + blk_size -
+ size_t.sizeof);
+ size_t* pm_bitmask = *end_of_blk;
+ mark(o, end_of_blk, pm_bitmask);
+ }
char[MAX_OPT_LEN] collect_stats_file = "";
bool sentinel = false;
bool mem_stomp = false;
char[MAX_OPT_LEN] collect_stats_file = "";
bool sentinel = false;
bool mem_stomp = false;
+ bool conservative = false;
}
package Options options;
}
package Options options;
options.sentinel = parse_bool(opt_value);
else if (cstr_eq(opt_name, "mem_stomp"))
options.mem_stomp = parse_bool(opt_value);
options.sentinel = parse_bool(opt_value);
else if (cstr_eq(opt_name, "mem_stomp"))
options.mem_stomp = parse_bool(opt_value);
+ else if (cstr_eq(opt_name, "conservative"))
+ options.conservative = parse_bool(opt_value);
assert (log_file[0] == '\0');
assert (sentinel == false);
assert (mem_stomp == false);
assert (log_file[0] == '\0');
assert (sentinel == false);
assert (mem_stomp == false);
+ assert (conservative == false);
}
parse("mem_stomp");
with (options) {
}
parse("mem_stomp");
with (options) {
assert (log_file[0] == '\0');
assert (sentinel == false);
assert (mem_stomp == true);
assert (log_file[0] == '\0');
assert (sentinel == false);
assert (mem_stomp == true);
+ assert (conservative == false);
- parse("mem_stomp=0:verbose=2");
+ parse("mem_stomp=0:verbose=2:conservative");
with (options) {
assert (verbose == 2);
assert (log_file[0] == '\0');
assert (sentinel == false);
assert (mem_stomp == false);
with (options) {
assert (verbose == 2);
assert (log_file[0] == '\0');
assert (sentinel == false);
assert (mem_stomp == false);
+ assert (conservative == true);
}
parse("log_file=12345 67890:verbose=1:sentinel=4:mem_stomp=1");
with (options) {
}
parse("log_file=12345 67890:verbose=1:sentinel=4:mem_stomp=1");
with (options) {
assert (cstring.strcmp(log_file.ptr, "12345 67890".ptr) == 0);
assert (sentinel == true);
assert (mem_stomp == true);
assert (cstring.strcmp(log_file.ptr, "12345 67890".ptr) == 0);
assert (sentinel == true);
assert (mem_stomp == true);
+ assert (conservative == true);
}
parse(null);
with (options) {
}
parse(null);
with (options) {
assert (cstring.strcmp(log_file.ptr, "12345 67890".ptr) == 0);
assert (sentinel == true);
assert (mem_stomp == true);
assert (cstring.strcmp(log_file.ptr, "12345 67890".ptr) == 0);
assert (sentinel == true);
assert (mem_stomp == true);
+ assert (conservative == true);