// Assumes _tlcBuffer/_tlcBufferCount hold the garbage list void ThreadLocalCollector::evict_local_garbage() { // scan the garbage blocks to evict all blocks reachable from the garbage list size_t evict_cursor = _tlcBufferCount; size_t scan_cursor = 0; while (scan_cursor < _tlcBufferCount) { void *block = _tlcBuffer[scan_cursor++]; Subzone *subzone = Subzone::subzone(block); usword_t q = subzone->quantum_index_unchecked(block); if (subzone->is_scanned(q)) { scan_local_block(subzone, q, block); } } usword_t global_size = 0; while (evict_cursor < _tlcBufferCount) { void *block = _tlcBuffer[evict_cursor++]; // evict this block, since it is reachable from garbage, but not itself garbage. Subzone *subzone = Subzone::subzone(block); usword_t q = subzone->quantum_index_unchecked(block); subzone->make_global(q); _localBlocks.remove(block); global_size += subzone->size(q); } if (global_size != 0) _zone->adjust_allocation_counter(global_size); }