Example #1
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);
         }
     }
 }
 inline void ThreadLocalCollector::scan_local_block(Subzone *subzone, usword_t q, void *block) {
     Range range(block, subzone->size(q));
     const unsigned char *map = (subzone->layout(q) & AUTO_OBJECT) ? _zone->layout_map_for_block(block) : NULL;
     if (map)
         scan_with_layout(range, map);
     else
         scan_range(range);
 }