// 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);
 }
Exemplo n.º 2
0
 void ThreadLocalCollector::evict_local_garbage(size_t count, vm_address_t garbage[]) {
     set_marked_blocks_buffer(NULL);
     // scan the garbage blocks first.
     _markedBlocksCounter = 0;
     for (size_t i = 0; i < count; ++i) {
         void *block = (void*)garbage[i];
         Subzone *sz = Subzone::subzone(block);
         usword_t layout = sz->layout(block);
         if (!(layout & AUTO_UNSCANNED)) {
             Range range(block, sz->size(block));
             const unsigned char *map = (layout & AUTO_OBJECT) ? _zone->layout_map_for_block(block) : NULL;
             if (map)
                 scan_with_layout(range, map, NULL); // TLC doesn't need the write barrier.
             else
                 scan_range(range, NULL);
          }
     }
     
     // if no blocks were marked, then no evicitions needed.
     if (_markedBlocksCounter == 0) return;
     
     // now, mark all blocks reachable from the garbage blocks themselves.
     scan_marked_blocks();
     for (uint32_t i = _localBlocks.firstOccupiedSlot(); i <= _localBlocks.lastOccupiedSlot(); i++) {
         if (!_localBlocks.validPointerAtIndex(i))
             continue;
         if (_localBlocks.wasMarked(i)) {
             void *block = _localBlocks[i];
             Subzone *subzone = Subzone::subzone(block);
             // evict this block, since it is reachable from garbage, but not itself garbage.
             subzone->make_global(block);
             _localBlocks.remove(i);
         }
     }
 }