| Index: src/mark-compact.cc
|
| diff --git a/src/mark-compact.cc b/src/mark-compact.cc
|
| index 6d14463c00953867f4dc2f4f605244279b2c6752..70b36809d920a792f46d3cacedb1ef7329744301 100644
|
| --- a/src/mark-compact.cc
|
| +++ b/src/mark-compact.cc
|
| @@ -2661,6 +2661,50 @@ static void SweepPrecisely(PagedSpace* space, Page* p, SweepingMode mode) {
|
| }
|
|
|
|
|
| +// Sweep a page of a space which contains objects of fixed size. This is used
|
| +// for map space and cell space, it always sweeps those spaces precisely.
|
| +template<int size>
|
| +static void SweepSpecialized(PagedSpace* space, Page* p) {
|
| + ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept());
|
| + MarkBit::CellType* cells = p->markbits()->cells();
|
| + p->MarkSweptPrecisely();
|
| +
|
| + int last_cell_index =
|
| + Bitmap::IndexToCell(
|
| + Bitmap::CellAlignIndex(
|
| + p->AddressToMarkbitIndex(p->ObjectAreaEnd())));
|
| +
|
| + int cell_index = Page::kFirstUsedCell;
|
| + Address free_start = p->ObjectAreaStart();
|
| + Address free_end = p->ObjectAreaStart();
|
| + uint32_t mark_mask = 0;
|
| + uint32_t mark_bits;
|
| +
|
| + ASSERT(size % kPointerSize == 0);
|
| + int bits_per_object = size / kPointerSize;
|
| +
|
| + for (cell_index = Page::kFirstUsedCell;
|
| + cell_index < last_cell_index || mark_mask != 0;
|
| + free_end += size, mark_mask <<= bits_per_object) {
|
| + if (mark_mask == 0) {
|
| + mark_mask = 1 << (p->AddressToMarkbitIndex(free_end) % 32);
|
| + mark_bits = cells[cell_index];
|
| + cells[cell_index] = 0;
|
| + cell_index++;
|
| + }
|
| + if ((mark_bits & mark_mask) != 0) {
|
| + if (free_end != free_start) {
|
| + space->Free(free_start, static_cast<int>(free_end - free_start));
|
| + }
|
| + free_start = free_end + size;
|
| + }
|
| + }
|
| + if (free_start != p->ObjectAreaEnd()) {
|
| + space->Free(free_start, static_cast<int>(p->ObjectAreaEnd() - free_start));
|
| + }
|
| +}
|
| +
|
| +
|
| void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
|
| EvacuateNewSpace();
|
| EvacuatePages();
|
| @@ -3241,6 +3285,14 @@ void MarkCompactCollector::SweepSpace(PagedSpace* space,
|
| SweepPrecisely(space, p, SWEEP_ONLY);
|
| break;
|
| }
|
| + case PRECISE_CELLS: {
|
| + SweepSpecialized<JSGlobalPropertyCell::kSize>(space, p);
|
| + break;
|
| + }
|
| + case PRECISE_MAPS: {
|
| + SweepSpecialized<Map::kSize>(space, p);
|
| + break;
|
| + }
|
| default: {
|
| UNREACHABLE();
|
| }
|
| @@ -3265,14 +3317,14 @@ void MarkCompactCollector::SweepSpaces() {
|
| SweepSpace(heap()->old_pointer_space(), how_to_sweep);
|
| SweepSpace(heap()->old_data_space(), how_to_sweep);
|
| SweepSpace(heap()->code_space(), PRECISE);
|
| - SweepSpace(heap()->cell_space(), PRECISE);
|
| + SweepSpace(heap()->cell_space(), PRECISE_CELLS);
|
| { GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP_NEWSPACE);
|
| EvacuateNewSpaceAndCandidates();
|
| }
|
| // ClearNonLiveTransitions depends on precise sweeping of map space to
|
| // detect whether unmarked map became dead in this collection or in one
|
| // of the previous ones.
|
| - SweepSpace(heap()->map_space(), PRECISE);
|
| + SweepSpace(heap()->map_space(), PRECISE_MAPS);
|
|
|
| ASSERT(live_map_objects_size_ <= heap()->map_space()->Size());
|
|
|
|
|