Index: src/heap/mark-compact.cc |
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc |
index 4e9fdc864c171a1db30eae0df8cf2443c75354bb..9de8006946ebc6e3908fd5341974f7ba5a26abe1 100644 |
--- a/src/heap/mark-compact.cc |
+++ b/src/heap/mark-compact.cc |
@@ -1569,6 +1569,9 @@ class RecordMigratedSlotVisitor final : public ObjectVisitor { |
DCHECK(RelocInfo::IsCodeTarget(rinfo->rmode())); |
Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); |
Code* host = rinfo->host(); |
+ // The target is always in old space, we don't have to record the slot in |
+ // the old-to-new remembered set. |
+ DCHECK(!collector_->heap()->InNewSpace(target)); |
collector_->RecordRelocSlot(host, rinfo, target); |
} |
@@ -1577,6 +1580,9 @@ class RecordMigratedSlotVisitor final : public ObjectVisitor { |
rinfo->IsPatchedDebugBreakSlotSequence()); |
Code* target = Code::GetCodeFromTargetAddress(rinfo->debug_call_address()); |
Code* host = rinfo->host(); |
+ // The target is always in old space, we don't have to record the slot in |
+ // the old-to-new remembered set. |
+ DCHECK(!collector_->heap()->InNewSpace(target)); |
collector_->RecordRelocSlot(host, rinfo, target); |
} |
@@ -1584,6 +1590,7 @@ class RecordMigratedSlotVisitor final : public ObjectVisitor { |
DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); |
HeapObject* object = HeapObject::cast(rinfo->target_object()); |
Code* host = rinfo->host(); |
+ collector_->heap()->RecordWriteIntoCode(host, rinfo, object); |
collector_->RecordRelocSlot(host, rinfo, object); |
} |
@@ -1591,6 +1598,9 @@ class RecordMigratedSlotVisitor final : public ObjectVisitor { |
DCHECK(rinfo->rmode() == RelocInfo::CELL); |
Cell* cell = rinfo->target_cell(); |
Code* host = rinfo->host(); |
+ // The cell is always in old space, we don't have to record the slot in |
+ // the old-to-new remembered set. |
+ DCHECK(!collector_->heap()->InNewSpace(cell)); |
collector_->RecordRelocSlot(host, rinfo, cell); |
} |
@@ -2456,6 +2466,35 @@ void MarkCompactCollector::MarkDependentCodeForDeoptimization( |
current = current->next_link(); |
} |
+ { |
+ ArrayList* list = heap_->weak_new_space_object_to_code_list(); |
+ int counter = 0; |
+ for (int i = 0; i < list->Length(); i += 2) { |
+ WeakCell* obj = WeakCell::cast(list->Get(i)); |
+ WeakCell* dep = WeakCell::cast(list->Get(i + 1)); |
+ if (obj->cleared() || dep->cleared()) { |
+ if (!dep->cleared()) { |
+ Code* code = Code::cast(dep->value()); |
+ if (!code->marked_for_deoptimization()) { |
+ DependentCode::SetMarkedForDeoptimization( |
+ code, DependentCode::DependencyGroup::kWeakCodeGroup); |
+ code->InvalidateEmbeddedObjects(); |
+ have_code_to_deoptimize_ = true; |
+ } |
+ } |
+ } else { |
+ // We record the slot manually because marking is finished at this |
+ // point and the write barrier would bailout. |
+ list->Set(counter, obj, SKIP_WRITE_BARRIER); |
+ RecordSlot(list, list->Slot(counter), obj); |
+ counter++; |
+ list->Set(counter, dep, SKIP_WRITE_BARRIER); |
+ RecordSlot(list, list->Slot(counter), dep); |
+ counter++; |
+ } |
+ } |
+ } |
+ |
WeakHashTable* table = heap_->weak_object_to_code_table(); |
uint32_t capacity = table->Capacity(); |
for (uint32_t i = 0; i < capacity; i++) { |
@@ -2800,30 +2839,16 @@ void MarkCompactCollector::AbortTransitionArrays() { |
heap()->set_encountered_transition_arrays(Smi::FromInt(0)); |
} |
-static inline SlotType SlotTypeForRMode(RelocInfo::Mode rmode) { |
- if (RelocInfo::IsCodeTarget(rmode)) { |
- return CODE_TARGET_SLOT; |
- } else if (RelocInfo::IsCell(rmode)) { |
- return CELL_TARGET_SLOT; |
- } else if (RelocInfo::IsEmbeddedObject(rmode)) { |
- return EMBEDDED_OBJECT_SLOT; |
- } else if (RelocInfo::IsDebugBreakSlot(rmode)) { |
- return DEBUG_TARGET_SLOT; |
- } |
- UNREACHABLE(); |
- return NUMBER_OF_SLOT_TYPES; |
-} |
- |
void MarkCompactCollector::RecordRelocSlot(Code* host, RelocInfo* rinfo, |
Object* target) { |
Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target)); |
Page* source_page = Page::FromAddress(reinterpret_cast<Address>(host)); |
- RelocInfo::Mode rmode = rinfo->rmode(); |
if (target_page->IsEvacuationCandidate() && |
(rinfo->host() == NULL || |
!ShouldSkipEvacuationSlotRecording(rinfo->host()))) { |
+ RelocInfo::Mode rmode = rinfo->rmode(); |
Address addr = rinfo->pc(); |
- SlotType slot_type = SlotTypeForRMode(rmode); |
+ SlotType slot_type = SlotTypeForRelocInfoMode(rmode); |
if (rinfo->IsInConstantPool()) { |
addr = rinfo->constant_pool_entry_address(); |
if (RelocInfo::IsCodeTarget(rmode)) { |
@@ -3447,6 +3472,12 @@ int MarkCompactCollector::Sweeper::RawSweep(PagedSpace* space, Page* p, |
} |
void MarkCompactCollector::InvalidateCode(Code* code) { |
+ Page* page = Page::FromAddress(code->address()); |
+ Address start = code->instruction_start(); |
+ Address end = code->address() + code->Size(); |
+ |
+ RememberedSet<OLD_TO_NEW>::RemoveRangeTyped(page, start, end); |
+ |
if (heap_->incremental_marking()->IsCompacting() && |
!ShouldSkipEvacuationSlotRecording(code)) { |
DCHECK(compacting_); |
@@ -3458,11 +3489,7 @@ void MarkCompactCollector::InvalidateCode(Code* code) { |
// Ignore all slots that might have been recorded in the body of the |
// deoptimized code object. Assumption: no slots will be recorded for |
// this object after invalidating it. |
- Page* page = Page::FromAddress(code->address()); |
- Address start = code->instruction_start(); |
- Address end = code->address() + code->Size(); |
RememberedSet<OLD_TO_OLD>::RemoveRangeTyped(page, start, end); |
- RememberedSet<OLD_TO_NEW>::RemoveRangeTyped(page, start, end); |
} |
} |
@@ -3503,6 +3530,10 @@ bool MarkCompactCollector::VisitLiveObjects(MemoryChunk* page, Visitor* visitor, |
page->old_to_new_slots()->RemoveRange( |
0, static_cast<int>(object->address() - page->address())); |
} |
+ if (page->typed_old_to_new_slots() != nullptr) { |
+ RememberedSet<OLD_TO_NEW>::RemoveRangeTyped(page, page->address(), |
+ object->address()); |
+ } |
RecomputeLiveBytes(page); |
} |
return false; |
@@ -3684,11 +3715,10 @@ class PointerUpdateJobTraits { |
return KEEP_SLOT; |
} |
} else if (heap->InToSpace(*slot)) { |
- DCHECK(Page::FromAddress(reinterpret_cast<HeapObject*>(*slot)->address()) |
- ->IsFlagSet(Page::PAGE_NEW_NEW_PROMOTION)); |
- // Slots can be in "to" space after a page has been moved. Since there is |
- // no forwarding information present we need to check the markbits to |
- // determine liveness. |
+ // Slots can point to "to" space if the page has been moved, or if the |
+ // slot has been recorded multiple times in the remembered set. Since |
+ // there is no forwarding information present we need to check the |
+ // markbits to determine liveness. |
if (Marking::IsBlack( |
Marking::MarkBitFrom(reinterpret_cast<HeapObject*>(*slot)))) |
return KEEP_SLOT; |
@@ -4063,6 +4093,9 @@ void MarkCompactCollector::RecordCodeTargetPatch(Address pc, Code* target) { |
MarkBit mark_bit = Marking::MarkBitFrom(host); |
if (Marking::IsBlack(mark_bit)) { |
RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); |
+ // The target is always in old space, we don't have to record the slot in |
+ // the old-to-new remembered set. |
+ DCHECK(!heap()->InNewSpace(target)); |
RecordRelocSlot(host, &rinfo, target); |
} |
} |