// 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); }
// // scan_marked_blocks // // scans all the blocks in _tlcBuffer // void ThreadLocalCollector::scan_marked_blocks() { size_t index = 0; while (index < _tlcBufferCount) { void *block = _tlcBuffer[index++]; Subzone *subzone = Subzone::subzone(block); usword_t q = subzone->quantum_index_unchecked(block); if (subzone->should_scan_local_block(q)) { scan_local_block(subzone, q, block); } } }
// // scan_marked_blocks // void ThreadLocalCollector::scan_marked_blocks() { for (uint32_t i = _localBlocks.firstOccupiedSlot(), last = _localBlocks.lastOccupiedSlot(); i <= last; i++) { void *block = _localBlocks.markedUnscannedPointerAtIndex(i); if (block) { Subzone *subzone = Subzone::subzone(block); if (subzone->should_scan_local_block(block)) { scan_local_block(block); } } } }