void Heap::freeUnmarked() { long bytes_freed = 0; for (int bidx = 0; bidx < NUM_BUCKETS; bidx++) { bytes_freed += freeChain(heads[bidx]); bytes_freed += freeChain(full_heads[bidx]); } LargeObj *cur = large_head; while (cur) { void *p = cur->data; GCObjectHeader* header = headerFromObject(p); if (isMarked(header)) { clearMark(header); } else { if (VERBOSITY() >= 2) printf("Freeing %p\n", p); bytes_freed += cur->mmap_size(); *cur->prev = cur->next; if (cur->next) cur->next->prev = cur->prev; LargeObj *to_free = cur; cur = cur->next; _freeLargeObj(to_free); continue; } cur = cur->next; } if (VERBOSITY("gc") >= 2) if (bytes_freed) printf("Freed %ld bytes\n", bytes_freed); }
static long freeChain(Block* head) { long bytes_freed = 0; while (head) { int num_objects = head->numObjects(); int first_obj = head->minObjIndex(); int atoms_per_obj = head->atomsPerObj(); for (int obj_idx = first_obj; obj_idx < num_objects; obj_idx++) { int atom_idx = obj_idx * atoms_per_obj; int bitmap_idx = atom_idx / 64; int bitmap_bit = atom_idx % 64; uint64_t mask = 1L << bitmap_bit; if (head->isfree[bitmap_idx] & mask) continue; void *p = &head->atoms[atom_idx]; GCObjectHeader* header = headerFromObject(p); if (isMarked(header)) { clearMark(header); } else { if (VERBOSITY() >= 2) printf("Freeing %p\n", p); //assert(p != (void*)0x127000d960); // the main module bytes_freed += head->size; head->isfree[bitmap_idx] |= mask; } } head = head->next; } return bytes_freed; }
inline void sweepList(ListT* head, std::list<Box*, StlCompatAllocator<Box*>>& weakly_referenced, Free free_func) { auto cur = head; while (cur) { GCAllocation* al = cur->data; if (isMarked(al)) { clearMark(al); cur = cur->next; } else { if (_doFree(al, &weakly_referenced)) { removeFromLL(cur); auto to_free = cur; cur = cur->next; free_func(to_free); } } } }