Reviewers: Vyacheslav Egorov,
Description:
Add specialized sweeper for cell and map space.
[email protected]
BUG=v8:1613
Please review this at http://codereview.chromium.org/7784001/
SVN Base: https://v8.googlecode.com/svn/branches/experimental/gc
Affected files:
M src/mark-compact.h
M src/mark-compact.cc
Index: src/mark-compact.cc
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index
6d14463c00953867f4dc2f4f605244279b2c6752..124ec59455b4db58676c430ec9965271802e8034
100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -2661,6 +2661,49 @@ 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_bits;
+
+ int bits_per_object = size / kPointerSize;
+ ASSERT(size % kPointerSize == 0);
+ ASSERT(Bitmap::kBitsPerCell % bits_per_object == 0);
+
+ for (cell_index = Page::kFirstUsedCell;
+ cell_index < last_cell_index;
+ free_end += size, mark_bits >>= bits_per_object) {
+ if (IsAddressAligned(free_end, Bitmap::kBitsPerCell * kPointerSize)) {
+ mark_bits = cells[cell_index];
+ cells[cell_index] = 0;
+ cell_index++;
+ }
+ if ((mark_bits & 1) != 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();
@@ -2728,6 +2771,7 @@ void
MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
cell = cell_iterator.Next()) {
if (cell->IsJSGlobalPropertyCell()) {
Address value_address =
+
reinterpret_cast<Address>(cell) +
(JSGlobalPropertyCell::kValueOffset - kHeapObjectTag);
updating_visitor.VisitPointer(reinterpret_cast<Object**>(value_address));
@@ -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());
Index: src/mark-compact.h
diff --git a/src/mark-compact.h b/src/mark-compact.h
index
6b5d4c9e182a4a5bfb1ba24fe101056db19a7182..294c8d93b795ecbb8daa5fa05294daa29ef524df
100644
--- a/src/mark-compact.h
+++ b/src/mark-compact.h
@@ -437,7 +437,9 @@ class MarkCompactCollector {
enum SweeperType {
CONSERVATIVE,
LAZY_CONSERVATIVE,
- PRECISE
+ PRECISE,
+ PRECISE_CELLS,
+ PRECISE_MAPS
};
#ifdef DEBUG
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev