diff --git a/src/arm/assembler-arm-inl.h b/src/arm/assembler-arm-inl.h index 5cb41cab4e..54c291d412 100644 --- a/src/arm/assembler-arm-inl.h +++ b/src/arm/assembler-arm-inl.h @@ -215,7 +215,7 @@ bool RelocInfo::IsPatchedDebugBreakSlotSequence() { void RelocInfo::Visit(ObjectVisitor* visitor) { RelocInfo::Mode mode = rmode(); if (mode == RelocInfo::EMBEDDED_OBJECT) { - visitor->VisitPointer(target_object_address()); + visitor->VisitEmbeddedPointer(host(), target_object_address()); } else if (RelocInfo::IsCodeTarget(mode)) { visitor->VisitCodeTarget(this); } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) { @@ -241,7 +241,7 @@ template void RelocInfo::Visit(Heap* heap) { RelocInfo::Mode mode = rmode(); if (mode == RelocInfo::EMBEDDED_OBJECT) { - StaticVisitor::VisitPointer(heap, target_object_address()); + StaticVisitor::VisitEmbeddedPointer(heap, host(), target_object_address()); } else if (RelocInfo::IsCodeTarget(mode)) { StaticVisitor::VisitCodeTarget(heap, this); } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) { diff --git a/src/ia32/assembler-ia32-inl.h b/src/ia32/assembler-ia32-inl.h index abb437f3b1..ed277e5da2 100644 --- a/src/ia32/assembler-ia32-inl.h +++ b/src/ia32/assembler-ia32-inl.h @@ -214,7 +214,7 @@ bool RelocInfo::IsPatchedDebugBreakSlotSequence() { void RelocInfo::Visit(ObjectVisitor* visitor) { RelocInfo::Mode mode = rmode(); if (mode == RelocInfo::EMBEDDED_OBJECT) { - visitor->VisitPointer(target_object_address()); + visitor->VisitEmbeddedPointer(host(), target_object_address()); CPU::FlushICache(pc_, sizeof(Address)); } else if (RelocInfo::IsCodeTarget(mode)) { visitor->VisitCodeTarget(this); @@ -242,7 +242,7 @@ template void RelocInfo::Visit(Heap* heap) { RelocInfo::Mode mode = rmode(); if (mode == RelocInfo::EMBEDDED_OBJECT) { - StaticVisitor::VisitPointer(heap, target_object_address()); + StaticVisitor::VisitEmbeddedPointer(heap, host(), target_object_address()); CPU::FlushICache(pc_, sizeof(Address)); } else if (RelocInfo::IsCodeTarget(mode)) { StaticVisitor::VisitCodeTarget(heap, this); diff --git a/src/incremental-marking.cc b/src/incremental-marking.cc index d9725244a8..95642e90f1 100644 --- a/src/incremental-marking.cc +++ b/src/incremental-marking.cc @@ -115,6 +115,17 @@ class IncrementalMarkingMarkingVisitor : public ObjectVisitor { incremental_marking_(incremental_marking) { } + void VisitEmbeddedPointer(Code* host, Object** p) { + Object* obj = *p; + if (obj->NonFailureIsHeapObject()) { + heap_->mark_compact_collector()->RecordSlot( + reinterpret_cast(host), + p, + obj); + MarkObject(obj); + } + } + void VisitCodeTarget(RelocInfo* rinfo) { ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); @@ -218,10 +229,18 @@ class IncrementalMarkingRootMarkingVisitor : public ObjectVisitor { void IncrementalMarking::SetOldSpacePageFlags(MemoryChunk* chunk, - bool is_marking) { + bool is_marking, + bool is_compacting) { if (is_marking) { chunk->SetFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING); chunk->SetFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING); + + // It's difficult to filter out slots recorded for large objects. + if (chunk->owner()->identity() == LO_SPACE && + chunk->size() > static_cast(Page::kPageSize) && + is_compacting) { + chunk->SetFlag(MemoryChunk::RESCAN_ON_EVACUATION); + } } else if (chunk->owner()->identity() == CELL_SPACE || chunk->scan_on_scavenge()) { chunk->ClearFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING); @@ -250,7 +269,7 @@ void IncrementalMarking::DeactivateIncrementalWriteBarrierForSpace( PageIterator it(space); while (it.has_next()) { Page* p = it.next(); - SetOldSpacePageFlags(p, false); + SetOldSpacePageFlags(p, false, false); } } @@ -275,7 +294,7 @@ void IncrementalMarking::DeactivateIncrementalWriteBarrier() { LargePage* lop = heap_->lo_space()->first_page(); while (lop->is_valid()) { - SetOldSpacePageFlags(lop, false); + SetOldSpacePageFlags(lop, false, false); lop = lop->next_page(); } } @@ -285,7 +304,7 @@ void IncrementalMarking::ActivateIncrementalWriteBarrier(PagedSpace* space) { PageIterator it(space); while (it.has_next()) { Page* p = it.next(); - SetOldSpacePageFlags(p, true); + SetOldSpacePageFlags(p, true, is_compacting_); } } @@ -309,7 +328,7 @@ void IncrementalMarking::ActivateIncrementalWriteBarrier() { LargePage* lop = heap_->lo_space()->first_page(); while (lop->is_valid()) { - SetOldSpacePageFlags(lop, true); + SetOldSpacePageFlags(lop, true, is_compacting_); lop = lop->next_page(); } } @@ -453,19 +472,6 @@ void IncrementalMarking::StartMarking() { MarkObjectGreyDoNotEnqueue(heap_->polymorphic_code_cache()); } - if (is_compacting_) { - // It's difficult to filter out slots recorded for large objects. - LargeObjectIterator it(heap_->lo_space()); - for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { - if (obj->IsFixedArray() || obj->IsCode()) { - Page* p = Page::FromAddress(obj->address()); - if (p->size() > static_cast(Page::kPageSize)) { - p->SetFlag(Page::RESCAN_ON_EVACUATION); - } - } - } - } - // Mark strong roots grey. IncrementalMarkingRootMarkingVisitor visitor(heap_, this); heap_->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG); diff --git a/src/incremental-marking.h b/src/incremental-marking.h index cd1a411421..30dbbc1605 100644 --- a/src/incremental-marking.h +++ b/src/incremental-marking.h @@ -172,7 +172,7 @@ class IncrementalMarking { } inline void SetOldSpacePageFlags(MemoryChunk* chunk) { - SetOldSpacePageFlags(chunk, IsMarking()); + SetOldSpacePageFlags(chunk, IsMarking(), IsCompacting()); } inline void SetNewSpacePageFlags(NewSpacePage* chunk) { @@ -208,7 +208,7 @@ class IncrementalMarking { void StartMarking(); - static void ActivateIncrementalWriteBarrier(PagedSpace* space); + void ActivateIncrementalWriteBarrier(PagedSpace* space); static void ActivateIncrementalWriteBarrier(NewSpace* space); void ActivateIncrementalWriteBarrier(); @@ -216,7 +216,10 @@ class IncrementalMarking { static void DeactivateIncrementalWriteBarrierForSpace(NewSpace* space); void DeactivateIncrementalWriteBarrier(); - static void SetOldSpacePageFlags(MemoryChunk* chunk, bool is_marking); + static void SetOldSpacePageFlags(MemoryChunk* chunk, + bool is_marking, + bool is_compacting); + static void SetNewSpacePageFlags(NewSpacePage* chunk, bool is_marking); void EnsureMarkingDequeIsCommitted(); diff --git a/src/mark-compact.cc b/src/mark-compact.cc index 4b0f7e232c..4fc9fdba5e 100644 --- a/src/mark-compact.cc +++ b/src/mark-compact.cc @@ -841,6 +841,12 @@ class StaticMarkingVisitor : public StaticVisitorBase { heap->mark_compact_collector()->MarkObject(cell, mark); } + static inline void VisitEmbeddedPointer(Heap* heap, Code* host, Object** p) { + MarkObjectByPointer(heap->mark_compact_collector(), + reinterpret_cast(host), + p); + } + static inline void VisitCodeTarget(Heap* heap, RelocInfo* rinfo) { ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); @@ -2441,6 +2447,10 @@ class PointersUpdatingVisitor: public ObjectVisitor { for (Object** p = start; p < end; p++) UpdatePointer(p); } + void VisitEmbeddedPointer(Code* host, Object** p) { + UpdatePointer(p); + } + void VisitCodeTarget(RelocInfo* rinfo) { ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); diff --git a/src/mips/assembler-mips-inl.h b/src/mips/assembler-mips-inl.h index c4c4fd2590..0cbe533398 100644 --- a/src/mips/assembler-mips-inl.h +++ b/src/mips/assembler-mips-inl.h @@ -244,7 +244,7 @@ void RelocInfo::Visit(ObjectVisitor* visitor) { if (mode == RelocInfo::EMBEDDED_OBJECT) { Object** p = target_object_address(); Object* orig = *p; - visitor->VisitPointer(p); + visitor->VisitEmbeddedPointer(host(), p); if (*p != orig) { set_target_object(*p); } @@ -273,7 +273,7 @@ template void RelocInfo::Visit(Heap* heap) { RelocInfo::Mode mode = rmode(); if (mode == RelocInfo::EMBEDDED_OBJECT) { - StaticVisitor::VisitPointer(heap, target_object_address()); + StaticVisitor::VisitEmbeddedPointer(heap, host(), target_object_address()); } else if (RelocInfo::IsCodeTarget(mode)) { StaticVisitor::VisitCodeTarget(heap, this); } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) { diff --git a/src/objects.h b/src/objects.h index 2bf99f3139..ef9fad5950 100644 --- a/src/objects.h +++ b/src/objects.h @@ -7502,6 +7502,13 @@ class ObjectVisitor BASE_EMBEDDED { // Handy shorthand for visiting a single pointer. virtual void VisitPointer(Object** p) { VisitPointers(p, p + 1); } + // Visit pointer embedded into a code object. + virtual void VisitEmbeddedPointer(Code* host, Object** p) { + // Default implementation for the convenience of users that do + // not care about the host object. + VisitPointer(p); + } + // Visits a contiguous arrays of external references (references to the C++ // heap) in the half-open range [start, end). Any or all of the values // may be modified on return. diff --git a/src/x64/assembler-x64-inl.h b/src/x64/assembler-x64-inl.h index 254795a941..fabaf259b3 100644 --- a/src/x64/assembler-x64-inl.h +++ b/src/x64/assembler-x64-inl.h @@ -388,7 +388,7 @@ Object** RelocInfo::call_object_address() { void RelocInfo::Visit(ObjectVisitor* visitor) { RelocInfo::Mode mode = rmode(); if (mode == RelocInfo::EMBEDDED_OBJECT) { - visitor->VisitPointer(target_object_address()); + visitor->VisitEmbeddedPointer(host(), target_object_address()); CPU::FlushICache(pc_, sizeof(Address)); } else if (RelocInfo::IsCodeTarget(mode)) { visitor->VisitCodeTarget(this); @@ -416,7 +416,7 @@ template void RelocInfo::Visit(Heap* heap) { RelocInfo::Mode mode = rmode(); if (mode == RelocInfo::EMBEDDED_OBJECT) { - StaticVisitor::VisitPointer(heap, target_object_address()); + StaticVisitor::VisitEmbeddedPointer(heap, host(), target_object_address()); CPU::FlushICache(pc_, sizeof(Address)); } else if (RelocInfo::IsCodeTarget(mode)) { StaticVisitor::VisitCodeTarget(heap, this);