From ac8b63675613c026058367a36855b32f18b2108d Mon Sep 17 00:00:00 2001 From: "hpayer@chromium.org" Date: Tue, 8 Jul 2014 08:44:45 +0000 Subject: [PATCH] Reland "Precisely sweep scan on scavenge pages and use heap iterator to iterate over them." BUG= R=bmeurer@chromium.org Review URL: https://codereview.chromium.org/377863003 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22270 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/mark-compact.cc | 21 ++++++++++++++++----- src/objects-inl.h | 16 ++++++++++++++++ src/objects.h | 6 +++++- src/spaces.cc | 9 ++++++--- src/store-buffer.cc | 33 +++++++++++++++------------------ 5 files changed, 58 insertions(+), 27 deletions(-) diff --git a/src/mark-compact.cc b/src/mark-compact.cc index fafc9e1fae..9192c58820 100644 --- a/src/mark-compact.cc +++ b/src/mark-compact.cc @@ -4146,12 +4146,23 @@ void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) { pages_swept++; parallel_sweeping_active = true; } else { - if (FLAG_gc_verbose) { - PrintF("Sweeping 0x%" V8PRIxPTR " conservatively in parallel.\n", - reinterpret_cast(p)); + if (p->scan_on_scavenge()) { + SweepPrecisely( + space, p, NULL); + pages_swept++; + if (FLAG_gc_verbose) { + PrintF("Sweeping 0x%" V8PRIxPTR + " scan on scavenge page precisely.\n", + reinterpret_cast(p)); + } + } else { + if (FLAG_gc_verbose) { + PrintF("Sweeping 0x%" V8PRIxPTR " conservatively in parallel.\n", + reinterpret_cast(p)); + } + p->set_parallel_sweeping(MemoryChunk::PARALLEL_SWEEPING_PENDING); + space->IncreaseUnsweptFreeBytes(p); } - p->set_parallel_sweeping(MemoryChunk::PARALLEL_SWEEPING_PENDING); - space->IncreaseUnsweptFreeBytes(p); } space->set_end_of_unswept_pages(p); break; diff --git a/src/objects-inl.h b/src/objects-inl.h index 0b500089c4..434ae95ac6 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -1480,6 +1480,22 @@ int HeapObject::Size() { } +bool HeapObject::ContainsPointers() { + InstanceType type = map()->instance_type(); + if (type <= LAST_NAME_TYPE) { + if (type == SYMBOL_TYPE) { + return true; + } + ASSERT(type < FIRST_NONSTRING_TYPE); + // There are four string representations: sequential strings, external + // strings, cons strings, and sliced strings. + // Only the latter two contain non-map-word pointers to heap objects. + return ((type & kIsIndirectStringMask) == kIsIndirectStringTag); + } + return (type > LAST_DATA_TYPE); +} + + void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) { v->VisitPointers(reinterpret_cast(FIELD_ADDR(this, start)), reinterpret_cast(FIELD_ADDR(this, end))); diff --git a/src/objects.h b/src/objects.h index edc489cdb3..a5a312bd9c 100644 --- a/src/objects.h +++ b/src/objects.h @@ -714,6 +714,7 @@ enum InstanceType { FIXED_UINT8_CLAMPED_ARRAY_TYPE, // LAST_FIXED_TYPED_ARRAY_TYPE FIXED_DOUBLE_ARRAY_TYPE, + CONSTANT_POOL_ARRAY_TYPE, FILLER_TYPE, // LAST_DATA_TYPE // Structs. @@ -740,7 +741,6 @@ enum InstanceType { BREAK_POINT_INFO_TYPE, FIXED_ARRAY_TYPE, - CONSTANT_POOL_ARRAY_TYPE, SHARED_FUNCTION_INFO_TYPE, // All the following types are subtypes of JSReceiver, which corresponds to @@ -1716,6 +1716,10 @@ class HeapObject: public Object { // Returns the heap object's size in bytes inline int Size(); + // Returns true if this heap object contains only references to other + // heap objects. + inline bool ContainsPointers(); + // Given a heap object's map pointer, returns the heap size in bytes // Useful when the map pointer field is used for other purposes. // GC internal. diff --git a/src/spaces.cc b/src/spaces.cc index 560c7d8718..12613c7cb0 100644 --- a/src/spaces.cc +++ b/src/spaces.cc @@ -18,6 +18,9 @@ namespace internal { // HeapObjectIterator HeapObjectIterator::HeapObjectIterator(PagedSpace* space) { + // Check that we actually can iterate this space. + ASSERT(space->is_iterable()); + // You can't actually iterate over the anchor page. It is not a real page, // just an anchor for the double linked page list. Initialize as if we have // reached the end of the anchor page, then the first iteration will move on @@ -32,6 +35,9 @@ HeapObjectIterator::HeapObjectIterator(PagedSpace* space) { HeapObjectIterator::HeapObjectIterator(PagedSpace* space, HeapObjectCallback size_func) { + // Check that we actually can iterate this space. + ASSERT(space->is_iterable()); + // You can't actually iterate over the anchor page. It is not a real page, // just an anchor for the double linked page list. Initialize the current // address and end as NULL, then the first iteration will move on @@ -66,9 +72,6 @@ void HeapObjectIterator::Initialize(PagedSpace* space, Address cur, Address end, HeapObjectIterator::PageMode mode, HeapObjectCallback size_f) { - // Check that we actually can iterate this space. - ASSERT(space->is_iterable()); - space_ = space; cur_addr_ = cur; cur_end_ = end; diff --git a/src/store-buffer.cc b/src/store-buffer.cc index 7ee4fa2d40..a7575ae328 100644 --- a/src/store-buffer.cc +++ b/src/store-buffer.cc @@ -519,25 +519,22 @@ void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback, FindPointersToNewSpaceInRegion(start, end, slot_callback, clear_maps); } else { Page* page = reinterpret_cast(chunk); - PagedSpace* owner = reinterpret_cast(page->owner()); - Address start = page->area_start(); - Address end = page->area_end(); - if (owner == heap_->map_space()) { - ASSERT(page->WasSweptPrecisely()); - HeapObjectIterator iterator(page, NULL); - for (HeapObject* heap_object = iterator.Next(); heap_object != NULL; - heap_object = iterator.Next()) { - // We skip free space objects. - if (!heap_object->IsFiller()) { - FindPointersToNewSpaceInRegion( - heap_object->address() + HeapObject::kHeaderSize, - heap_object->address() + heap_object->Size(), slot_callback, - clear_maps); - } + ASSERT(page->owner() == heap_->map_space() || + page->owner() == heap_->old_pointer_space()); + CHECK(page->WasSweptPrecisely()); + + HeapObjectIterator iterator(page, NULL); + for (HeapObject* heap_object = iterator.Next(); + heap_object != NULL; + heap_object = iterator.Next()) { + // We iterate over objects that contain pointers only. + if (heap_object->ContainsPointers()) { + FindPointersToNewSpaceInRegion( + heap_object->address() + HeapObject::kHeaderSize, + heap_object->address() + heap_object->Size(), + slot_callback, + clear_maps); } - } else { - FindPointersToNewSpaceInRegion( - start, end, slot_callback, clear_maps); } } }