Commit 36ae5f38 authored by vegorov@chromium.org's avatar vegorov@chromium.org

Pass correct anchor_slot for EMBEDDED_OBJECT pointers from code objects.

Correctly initialize newly created large-object pages when incremental marking with compaction is in progress.

R=erik.corry@gmail.com
BUG=v8:1737

Review URL: http://codereview.chromium.org/8070002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9475 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 90b1e509
...@@ -215,7 +215,7 @@ bool RelocInfo::IsPatchedDebugBreakSlotSequence() { ...@@ -215,7 +215,7 @@ bool RelocInfo::IsPatchedDebugBreakSlotSequence() {
void RelocInfo::Visit(ObjectVisitor* visitor) { void RelocInfo::Visit(ObjectVisitor* visitor) {
RelocInfo::Mode mode = rmode(); RelocInfo::Mode mode = rmode();
if (mode == RelocInfo::EMBEDDED_OBJECT) { if (mode == RelocInfo::EMBEDDED_OBJECT) {
visitor->VisitPointer(target_object_address()); visitor->VisitEmbeddedPointer(host(), target_object_address());
} else if (RelocInfo::IsCodeTarget(mode)) { } else if (RelocInfo::IsCodeTarget(mode)) {
visitor->VisitCodeTarget(this); visitor->VisitCodeTarget(this);
} else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) { } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
...@@ -241,7 +241,7 @@ template<typename StaticVisitor> ...@@ -241,7 +241,7 @@ template<typename StaticVisitor>
void RelocInfo::Visit(Heap* heap) { void RelocInfo::Visit(Heap* heap) {
RelocInfo::Mode mode = rmode(); RelocInfo::Mode mode = rmode();
if (mode == RelocInfo::EMBEDDED_OBJECT) { if (mode == RelocInfo::EMBEDDED_OBJECT) {
StaticVisitor::VisitPointer(heap, target_object_address()); StaticVisitor::VisitEmbeddedPointer(heap, host(), target_object_address());
} else if (RelocInfo::IsCodeTarget(mode)) { } else if (RelocInfo::IsCodeTarget(mode)) {
StaticVisitor::VisitCodeTarget(heap, this); StaticVisitor::VisitCodeTarget(heap, this);
} else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) { } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
......
...@@ -214,7 +214,7 @@ bool RelocInfo::IsPatchedDebugBreakSlotSequence() { ...@@ -214,7 +214,7 @@ bool RelocInfo::IsPatchedDebugBreakSlotSequence() {
void RelocInfo::Visit(ObjectVisitor* visitor) { void RelocInfo::Visit(ObjectVisitor* visitor) {
RelocInfo::Mode mode = rmode(); RelocInfo::Mode mode = rmode();
if (mode == RelocInfo::EMBEDDED_OBJECT) { if (mode == RelocInfo::EMBEDDED_OBJECT) {
visitor->VisitPointer(target_object_address()); visitor->VisitEmbeddedPointer(host(), target_object_address());
CPU::FlushICache(pc_, sizeof(Address)); CPU::FlushICache(pc_, sizeof(Address));
} else if (RelocInfo::IsCodeTarget(mode)) { } else if (RelocInfo::IsCodeTarget(mode)) {
visitor->VisitCodeTarget(this); visitor->VisitCodeTarget(this);
...@@ -242,7 +242,7 @@ template<typename StaticVisitor> ...@@ -242,7 +242,7 @@ template<typename StaticVisitor>
void RelocInfo::Visit(Heap* heap) { void RelocInfo::Visit(Heap* heap) {
RelocInfo::Mode mode = rmode(); RelocInfo::Mode mode = rmode();
if (mode == RelocInfo::EMBEDDED_OBJECT) { if (mode == RelocInfo::EMBEDDED_OBJECT) {
StaticVisitor::VisitPointer(heap, target_object_address()); StaticVisitor::VisitEmbeddedPointer(heap, host(), target_object_address());
CPU::FlushICache(pc_, sizeof(Address)); CPU::FlushICache(pc_, sizeof(Address));
} else if (RelocInfo::IsCodeTarget(mode)) { } else if (RelocInfo::IsCodeTarget(mode)) {
StaticVisitor::VisitCodeTarget(heap, this); StaticVisitor::VisitCodeTarget(heap, this);
......
...@@ -115,6 +115,17 @@ class IncrementalMarkingMarkingVisitor : public ObjectVisitor { ...@@ -115,6 +115,17 @@ class IncrementalMarkingMarkingVisitor : public ObjectVisitor {
incremental_marking_(incremental_marking) { incremental_marking_(incremental_marking) {
} }
void VisitEmbeddedPointer(Code* host, Object** p) {
Object* obj = *p;
if (obj->NonFailureIsHeapObject()) {
heap_->mark_compact_collector()->RecordSlot(
reinterpret_cast<Object**>(host),
p,
obj);
MarkObject(obj);
}
}
void VisitCodeTarget(RelocInfo* rinfo) { void VisitCodeTarget(RelocInfo* rinfo) {
ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
...@@ -218,10 +229,18 @@ class IncrementalMarkingRootMarkingVisitor : public ObjectVisitor { ...@@ -218,10 +229,18 @@ class IncrementalMarkingRootMarkingVisitor : public ObjectVisitor {
void IncrementalMarking::SetOldSpacePageFlags(MemoryChunk* chunk, void IncrementalMarking::SetOldSpacePageFlags(MemoryChunk* chunk,
bool is_marking) { bool is_marking,
bool is_compacting) {
if (is_marking) { if (is_marking) {
chunk->SetFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING); chunk->SetFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING);
chunk->SetFlag(MemoryChunk::POINTERS_FROM_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<size_t>(Page::kPageSize) &&
is_compacting) {
chunk->SetFlag(MemoryChunk::RESCAN_ON_EVACUATION);
}
} else if (chunk->owner()->identity() == CELL_SPACE || } else if (chunk->owner()->identity() == CELL_SPACE ||
chunk->scan_on_scavenge()) { chunk->scan_on_scavenge()) {
chunk->ClearFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING); chunk->ClearFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING);
...@@ -250,7 +269,7 @@ void IncrementalMarking::DeactivateIncrementalWriteBarrierForSpace( ...@@ -250,7 +269,7 @@ void IncrementalMarking::DeactivateIncrementalWriteBarrierForSpace(
PageIterator it(space); PageIterator it(space);
while (it.has_next()) { while (it.has_next()) {
Page* p = it.next(); Page* p = it.next();
SetOldSpacePageFlags(p, false); SetOldSpacePageFlags(p, false, false);
} }
} }
...@@ -275,7 +294,7 @@ void IncrementalMarking::DeactivateIncrementalWriteBarrier() { ...@@ -275,7 +294,7 @@ void IncrementalMarking::DeactivateIncrementalWriteBarrier() {
LargePage* lop = heap_->lo_space()->first_page(); LargePage* lop = heap_->lo_space()->first_page();
while (lop->is_valid()) { while (lop->is_valid()) {
SetOldSpacePageFlags(lop, false); SetOldSpacePageFlags(lop, false, false);
lop = lop->next_page(); lop = lop->next_page();
} }
} }
...@@ -285,7 +304,7 @@ void IncrementalMarking::ActivateIncrementalWriteBarrier(PagedSpace* space) { ...@@ -285,7 +304,7 @@ void IncrementalMarking::ActivateIncrementalWriteBarrier(PagedSpace* space) {
PageIterator it(space); PageIterator it(space);
while (it.has_next()) { while (it.has_next()) {
Page* p = it.next(); Page* p = it.next();
SetOldSpacePageFlags(p, true); SetOldSpacePageFlags(p, true, is_compacting_);
} }
} }
...@@ -309,7 +328,7 @@ void IncrementalMarking::ActivateIncrementalWriteBarrier() { ...@@ -309,7 +328,7 @@ void IncrementalMarking::ActivateIncrementalWriteBarrier() {
LargePage* lop = heap_->lo_space()->first_page(); LargePage* lop = heap_->lo_space()->first_page();
while (lop->is_valid()) { while (lop->is_valid()) {
SetOldSpacePageFlags(lop, true); SetOldSpacePageFlags(lop, true, is_compacting_);
lop = lop->next_page(); lop = lop->next_page();
} }
} }
...@@ -453,19 +472,6 @@ void IncrementalMarking::StartMarking() { ...@@ -453,19 +472,6 @@ void IncrementalMarking::StartMarking() {
MarkObjectGreyDoNotEnqueue(heap_->polymorphic_code_cache()); 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<size_t>(Page::kPageSize)) {
p->SetFlag(Page::RESCAN_ON_EVACUATION);
}
}
}
}
// Mark strong roots grey. // Mark strong roots grey.
IncrementalMarkingRootMarkingVisitor visitor(heap_, this); IncrementalMarkingRootMarkingVisitor visitor(heap_, this);
heap_->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG); heap_->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG);
......
...@@ -172,7 +172,7 @@ class IncrementalMarking { ...@@ -172,7 +172,7 @@ class IncrementalMarking {
} }
inline void SetOldSpacePageFlags(MemoryChunk* chunk) { inline void SetOldSpacePageFlags(MemoryChunk* chunk) {
SetOldSpacePageFlags(chunk, IsMarking()); SetOldSpacePageFlags(chunk, IsMarking(), IsCompacting());
} }
inline void SetNewSpacePageFlags(NewSpacePage* chunk) { inline void SetNewSpacePageFlags(NewSpacePage* chunk) {
...@@ -208,7 +208,7 @@ class IncrementalMarking { ...@@ -208,7 +208,7 @@ class IncrementalMarking {
void StartMarking(); void StartMarking();
static void ActivateIncrementalWriteBarrier(PagedSpace* space); void ActivateIncrementalWriteBarrier(PagedSpace* space);
static void ActivateIncrementalWriteBarrier(NewSpace* space); static void ActivateIncrementalWriteBarrier(NewSpace* space);
void ActivateIncrementalWriteBarrier(); void ActivateIncrementalWriteBarrier();
...@@ -216,7 +216,10 @@ class IncrementalMarking { ...@@ -216,7 +216,10 @@ class IncrementalMarking {
static void DeactivateIncrementalWriteBarrierForSpace(NewSpace* space); static void DeactivateIncrementalWriteBarrierForSpace(NewSpace* space);
void DeactivateIncrementalWriteBarrier(); 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); static void SetNewSpacePageFlags(NewSpacePage* chunk, bool is_marking);
void EnsureMarkingDequeIsCommitted(); void EnsureMarkingDequeIsCommitted();
......
...@@ -841,6 +841,12 @@ class StaticMarkingVisitor : public StaticVisitorBase { ...@@ -841,6 +841,12 @@ class StaticMarkingVisitor : public StaticVisitorBase {
heap->mark_compact_collector()->MarkObject(cell, mark); heap->mark_compact_collector()->MarkObject(cell, mark);
} }
static inline void VisitEmbeddedPointer(Heap* heap, Code* host, Object** p) {
MarkObjectByPointer(heap->mark_compact_collector(),
reinterpret_cast<Object**>(host),
p);
}
static inline void VisitCodeTarget(Heap* heap, RelocInfo* rinfo) { static inline void VisitCodeTarget(Heap* heap, RelocInfo* rinfo) {
ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
...@@ -2441,6 +2447,10 @@ class PointersUpdatingVisitor: public ObjectVisitor { ...@@ -2441,6 +2447,10 @@ class PointersUpdatingVisitor: public ObjectVisitor {
for (Object** p = start; p < end; p++) UpdatePointer(p); for (Object** p = start; p < end; p++) UpdatePointer(p);
} }
void VisitEmbeddedPointer(Code* host, Object** p) {
UpdatePointer(p);
}
void VisitCodeTarget(RelocInfo* rinfo) { void VisitCodeTarget(RelocInfo* rinfo) {
ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
......
...@@ -244,7 +244,7 @@ void RelocInfo::Visit(ObjectVisitor* visitor) { ...@@ -244,7 +244,7 @@ void RelocInfo::Visit(ObjectVisitor* visitor) {
if (mode == RelocInfo::EMBEDDED_OBJECT) { if (mode == RelocInfo::EMBEDDED_OBJECT) {
Object** p = target_object_address(); Object** p = target_object_address();
Object* orig = *p; Object* orig = *p;
visitor->VisitPointer(p); visitor->VisitEmbeddedPointer(host(), p);
if (*p != orig) { if (*p != orig) {
set_target_object(*p); set_target_object(*p);
} }
...@@ -273,7 +273,7 @@ template<typename StaticVisitor> ...@@ -273,7 +273,7 @@ template<typename StaticVisitor>
void RelocInfo::Visit(Heap* heap) { void RelocInfo::Visit(Heap* heap) {
RelocInfo::Mode mode = rmode(); RelocInfo::Mode mode = rmode();
if (mode == RelocInfo::EMBEDDED_OBJECT) { if (mode == RelocInfo::EMBEDDED_OBJECT) {
StaticVisitor::VisitPointer(heap, target_object_address()); StaticVisitor::VisitEmbeddedPointer(heap, host(), target_object_address());
} else if (RelocInfo::IsCodeTarget(mode)) { } else if (RelocInfo::IsCodeTarget(mode)) {
StaticVisitor::VisitCodeTarget(heap, this); StaticVisitor::VisitCodeTarget(heap, this);
} else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) { } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
......
...@@ -7502,6 +7502,13 @@ class ObjectVisitor BASE_EMBEDDED { ...@@ -7502,6 +7502,13 @@ class ObjectVisitor BASE_EMBEDDED {
// Handy shorthand for visiting a single pointer. // Handy shorthand for visiting a single pointer.
virtual void VisitPointer(Object** p) { VisitPointers(p, p + 1); } 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++ // 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 // heap) in the half-open range [start, end). Any or all of the values
// may be modified on return. // may be modified on return.
......
...@@ -388,7 +388,7 @@ Object** RelocInfo::call_object_address() { ...@@ -388,7 +388,7 @@ Object** RelocInfo::call_object_address() {
void RelocInfo::Visit(ObjectVisitor* visitor) { void RelocInfo::Visit(ObjectVisitor* visitor) {
RelocInfo::Mode mode = rmode(); RelocInfo::Mode mode = rmode();
if (mode == RelocInfo::EMBEDDED_OBJECT) { if (mode == RelocInfo::EMBEDDED_OBJECT) {
visitor->VisitPointer(target_object_address()); visitor->VisitEmbeddedPointer(host(), target_object_address());
CPU::FlushICache(pc_, sizeof(Address)); CPU::FlushICache(pc_, sizeof(Address));
} else if (RelocInfo::IsCodeTarget(mode)) { } else if (RelocInfo::IsCodeTarget(mode)) {
visitor->VisitCodeTarget(this); visitor->VisitCodeTarget(this);
...@@ -416,7 +416,7 @@ template<typename StaticVisitor> ...@@ -416,7 +416,7 @@ template<typename StaticVisitor>
void RelocInfo::Visit(Heap* heap) { void RelocInfo::Visit(Heap* heap) {
RelocInfo::Mode mode = rmode(); RelocInfo::Mode mode = rmode();
if (mode == RelocInfo::EMBEDDED_OBJECT) { if (mode == RelocInfo::EMBEDDED_OBJECT) {
StaticVisitor::VisitPointer(heap, target_object_address()); StaticVisitor::VisitEmbeddedPointer(heap, host(), target_object_address());
CPU::FlushICache(pc_, sizeof(Address)); CPU::FlushICache(pc_, sizeof(Address));
} else if (RelocInfo::IsCodeTarget(mode)) { } else if (RelocInfo::IsCodeTarget(mode)) {
StaticVisitor::VisitCodeTarget(heap, this); StaticVisitor::VisitCodeTarget(heap, this);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment