* Return null if not in a Pool.
* Assume pools is sorted.
*/
-Pool *findPool(void *p)
+Pool* findPool(void* p)
{
- if (p >= gc.min_addr && p < gc.max_addr)
- {
- if (gc.pools.length == 1)
- {
- return gc.pools[0];
- }
-
- for (size_t i = 0; i < gc.pools.length; i++)
- {
- Pool* pool = gc.pools[i];
- if (p < pool.topAddr)
- {
- if (pool.baseAddr <= p)
- return pool;
- break;
- }
- }
+ if (p < gc.min_addr || p >= gc.max_addr)
+ return null;
+ if (gc.pools.length == 0)
+ return null;
+ if (gc.pools.length == 1)
+ return gc.pools[0];
+ /// The pooltable[] is sorted by address, so do a binary search
+ size_t low = 0;
+ size_t high = gc.pools.length - 1;
+ while (low <= high) {
+ size_t mid = (low + high) / 2;
+ auto pool = gc.pools[mid];
+ if (p < pool.baseAddr)
+ high = mid - 1;
+ else if (p >= pool.topAddr)
+ low = mid + 1;
+ else
+ return pool;
}
+ // Not found
return null;
}
info.base = pool.findBase(p);
info.size = pool.findSize(info.base);
info.attr = getAttr(pool, cast(size_t)(info.base - pool.baseAddr) / 16u);
- if (!opts.options.conservative && !(info.attr & BlkAttr.NO_SCAN))
+ if (has_pointermap(info.attr)) {
info.size -= size_t.sizeof; // PointerMap bitmask
+ // Points to the PointerMap bitmask pointer, not user data
+ if (p >= (info.base + info.size)) {
+ return BlkInfo.init;
+ }
+ }
+ if (opts.options.sentinel) {
+ info.base = sentinel_add(info.base);
+ // points to sentinel data, not user data
+ if (p < info.base || p >= sentinel_post(info.base))
+ return BlkInfo.init;
+ info.size -= SENTINEL_EXTRA;
+ }
return info;
}
size_t type_size = pm_bitmask[0];
size_t* pm_bits = pm_bitmask + 1;
+ bool has_type_info = type_size != 1 || pm_bits[0] != 1 || pm_bits[1] != 0;
//printf("marking range: %p -> %p\n", pbot, ptop);
for (; p1 + type_size <= p2; p1 += type_size) {
- for (size_t n = 0; n < type_size; n++) {
+ size_t n = 0;
+ if (has_type_info) {
+ while (n < type_size && pm_bits[n / BITS_PER_WORD] == 0)
+ n += BITS_PER_WORD;
+ if (n < type_size && (pm_bits[n / BITS_PER_WORD] &
+ ((1 << (BITS_PER_WORD / 2)) - 1)) == 0)
+ n += BITS_PER_WORD / 2;
+ else if (n < type_size && (pm_bits[n / BITS_PER_WORD] &
+ ((1 << (BITS_PER_WORD / 4)) - 1)) == 0)
+ n += BITS_PER_WORD / 4;
+ }
+ for (; n < type_size; n++) {
// scan bit set for this word
- if (!(pm_bits[n / BITS_PER_WORD] & (1 << (n % BITS_PER_WORD))))
+ if (has_type_info &&
+ !(pm_bits[n / BITS_PER_WORD] & (1 << (n % BITS_PER_WORD))))
continue;
void* p = *(p1 + n);