Add a host parameter to ObjectVisitor methods.

This makes an ObjectVisitor as powerful as a StaticVisitor and allows
slots recording in ObjectVisitor.

This patch also renames VisitCell method of ObjectVisitor to
VisitCellPointer, so that VisitCell is free to be used for actually
visiting a cell.

BUG=chromium:709075

Review-Url: https://codereview.chromium.org/2810653002
Cr-Commit-Position: refs/heads/master@{#44860}
This commit is contained in:
ulan 2017-04-25 07:18:52 -07:00 committed by Commit bot
parent ef99f6667d
commit c59f78f611
25 changed files with 233 additions and 216 deletions

View File

@ -234,22 +234,22 @@ template <typename ObjectVisitor>
void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
RelocInfo::Mode mode = rmode();
if (mode == RelocInfo::EMBEDDED_OBJECT) {
visitor->VisitEmbeddedPointer(this);
visitor->VisitEmbeddedPointer(host(), this);
} else if (RelocInfo::IsCodeTarget(mode)) {
visitor->VisitCodeTarget(this);
visitor->VisitCodeTarget(host(), this);
} else if (mode == RelocInfo::CELL) {
visitor->VisitCell(this);
visitor->VisitCellPointer(host(), this);
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
visitor->VisitExternalReference(this);
visitor->VisitExternalReference(host(), this);
} else if (mode == RelocInfo::INTERNAL_REFERENCE) {
visitor->VisitInternalReference(this);
visitor->VisitInternalReference(host(), this);
} else if (RelocInfo::IsCodeAgeSequence(mode)) {
visitor->VisitCodeAgeSequence(this);
visitor->VisitCodeAgeSequence(host(), this);
} else if (RelocInfo::IsDebugBreakSlot(mode) &&
IsPatchedDebugBreakSlotSequence()) {
visitor->VisitDebugTarget(this);
visitor->VisitDebugTarget(host(), this);
} else if (RelocInfo::IsRuntimeEntry(mode)) {
visitor->VisitRuntimeEntry(this);
visitor->VisitRuntimeEntry(host(), this);
}
}

View File

@ -832,20 +832,20 @@ template <typename ObjectVisitor>
void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
RelocInfo::Mode mode = rmode();
if (mode == RelocInfo::EMBEDDED_OBJECT) {
visitor->VisitEmbeddedPointer(this);
visitor->VisitEmbeddedPointer(host(), this);
} else if (RelocInfo::IsCodeTarget(mode)) {
visitor->VisitCodeTarget(this);
visitor->VisitCodeTarget(host(), this);
} else if (mode == RelocInfo::CELL) {
visitor->VisitCell(this);
visitor->VisitCellPointer(host(), this);
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
visitor->VisitExternalReference(this);
visitor->VisitExternalReference(host(), this);
} else if (mode == RelocInfo::INTERNAL_REFERENCE) {
visitor->VisitInternalReference(this);
visitor->VisitInternalReference(host(), this);
} else if (RelocInfo::IsDebugBreakSlot(mode) &&
IsPatchedDebugBreakSlotSequence()) {
visitor->VisitDebugTarget(this);
visitor->VisitDebugTarget(host(), this);
} else if (RelocInfo::IsRuntimeEntry(mode)) {
visitor->VisitRuntimeEntry(this);
visitor->VisitRuntimeEntry(host(), this);
}
}

View File

@ -54,7 +54,7 @@ class ConcurrentMarkingVisitor : public ObjectVisitor {
public:
ConcurrentMarkingVisitor() : bytes_marked_(0) {}
void VisitPointers(Object** start, Object** end) override {
void VisitPointers(HeapObject* host, Object** start, Object** end) override {
for (Object** p = start; p < end; p++) {
if (!(*p)->IsHeapObject()) continue;
MarkObject(HeapObject::cast(*p));

View File

@ -856,7 +856,8 @@ AlwaysAllocateScope::~AlwaysAllocateScope() {
heap_->always_allocate_scope_count_.Decrement(1);
}
void VerifyPointersVisitor::VisitPointers(Object** start, Object** end) {
void VerifyPointersVisitor::VisitPointers(HeapObject* host, Object** start,
Object** end) {
VerifyPointers(start, end);
}

View File

@ -1137,7 +1137,7 @@ void Heap::MoveElements(FixedArray* array, int dst_index, int src_index,
// Helper class for verifying the string table.
class StringTableVerifier : public ObjectVisitor {
public:
void VisitPointers(Object** start, Object** end) override {
void VisitPointers(HeapObject* host, Object** start, Object** end) override {
// Visit all HeapObject pointers in [start, end).
for (Object** p = start; p < end; p++) {
if ((*p)->IsHeapObject()) {
@ -1758,8 +1758,9 @@ void Heap::Scavenge() {
TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_CODE_FLUSH_CANDIDATES);
MarkCompactCollector* collector = mark_compact_collector();
if (collector->is_code_flushing_enabled()) {
collector->code_flusher()->IteratePointersToFromSpace(
&root_scavenge_visitor);
collector->code_flusher()->VisitListHeads(&root_scavenge_visitor);
collector->code_flusher()
->IteratePointersToFromSpace<StaticScavengeVisitor>();
}
}
@ -4816,7 +4817,9 @@ class IterateAndScavengePromotedObjectsVisitor final : public ObjectVisitor {
bool record_slots)
: heap_(heap), target_(target), record_slots_(record_slots) {}
inline void VisitPointers(Object** start, Object** end) override {
inline void VisitPointers(HeapObject* host, Object** start,
Object** end) override {
DCHECK_EQ(host, target_);
Address slot_address = reinterpret_cast<Address>(start);
Page* page = Page::FromAddress(slot_address);
@ -4847,7 +4850,8 @@ class IterateAndScavengePromotedObjectsVisitor final : public ObjectVisitor {
}
}
inline void VisitCodeEntry(Address code_entry_slot) override {
inline void VisitCodeEntry(JSFunction* host,
Address code_entry_slot) override {
// Black allocation requires us to process objects referenced by
// promoted objects.
if (heap_->incremental_marking()->black_allocation()) {
@ -4876,6 +4880,8 @@ void Heap::IterateAndScavengePromotedObject(HeapObject* target, int size,
ObjectMarking::IsBlack(target, MarkingState::Internal(target));
}
// TODO(ulan): remove the target, the visitor now gets the host object
// in each visit method.
IterateAndScavengePromotedObjectsVisitor visitor(this, target, record_slots);
if (target->IsJSFunction()) {
// JSFunctions reachable through kNextFunctionLinkOffset are weak. Slots for
@ -6124,7 +6130,8 @@ class UnreachableObjectsFilter : public HeapObjectsFilter {
public:
MarkingVisitor() : marking_stack_(10) {}
void VisitPointers(Object** start, Object** end) override {
void VisitPointers(HeapObject* host, Object** start,
Object** end) override {
MarkPointers(start, end);
}

View File

@ -2489,7 +2489,8 @@ class AlwaysAllocateScope {
// objects in a heap space but above the allocation pointer.
class VerifyPointersVisitor : public ObjectVisitor, public RootVisitor {
public:
inline void VisitPointers(Object** start, Object** end) override;
inline void VisitPointers(HeapObject* host, Object** start,
Object** end) override;
inline void VisitRootPointers(Root root, Object** start,
Object** end) override;

View File

@ -127,6 +127,28 @@ void CodeFlusher::ClearNextCandidate(SharedFunctionInfo* candidate) {
candidate->code()->set_gc_metadata(NULL, SKIP_WRITE_BARRIER);
}
void CodeFlusher::VisitListHeads(RootVisitor* visitor) {
visitor->VisitRootPointer(
Root::kCodeFlusher,
reinterpret_cast<Object**>(&jsfunction_candidates_head_));
visitor->VisitRootPointer(
Root::kCodeFlusher,
reinterpret_cast<Object**>(&shared_function_info_candidates_head_));
}
template <typename StaticVisitor>
void CodeFlusher::IteratePointersToFromSpace() {
Heap* heap = isolate_->heap();
JSFunction* candidate = jsfunction_candidates_head_;
while (candidate != nullptr) {
JSFunction** slot = GetNextCandidateSlot(candidate);
if (heap->InFromSpace(*slot)) {
StaticVisitor::VisitPointer(heap, candidate,
reinterpret_cast<Object**>(slot));
}
candidate = GetNextCandidate(candidate);
}
}
template <LiveObjectIterationMode T>
HeapObject* LiveObjectIterator<T>::Next() {

View File

@ -62,7 +62,7 @@ class MarkingVerifier : public ObjectVisitor, public RootVisitor {
virtual void VerifyPointers(Object** start, Object** end) = 0;
void VisitPointers(Object** start, Object** end) override {
void VisitPointers(HeapObject* host, Object** start, Object** end) override {
VerifyPointers(start, end);
}
@ -171,19 +171,18 @@ class FullMarkingVerifier : public MarkingVerifier {
}
}
void VisitEmbeddedPointer(RelocInfo* rinfo) override {
void VisitEmbeddedPointer(Code* host, RelocInfo* rinfo) override {
DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
if (!rinfo->host()->IsWeakObject(rinfo->target_object())) {
if (!host->IsWeakObject(rinfo->target_object())) {
Object* p = rinfo->target_object();
VisitPointer(&p);
VisitPointer(host, &p);
}
}
void VisitCell(RelocInfo* rinfo) override {
Code* code = rinfo->host();
void VisitCellPointer(Code* host, RelocInfo* rinfo) override {
DCHECK(rinfo->rmode() == RelocInfo::CELL);
if (!code->IsWeakObject(rinfo->target_cell())) {
ObjectVisitor::VisitCell(rinfo);
if (!host->IsWeakObject(rinfo->target_cell())) {
ObjectVisitor::VisitCellPointer(host, rinfo);
}
}
};
@ -220,7 +219,7 @@ class EvacuationVerifier : public ObjectVisitor, public RootVisitor {
public:
virtual void Run() = 0;
void VisitPointers(Object** start, Object** end) override {
void VisitPointers(HeapObject* host, Object** start, Object** end) override {
VerifyPointers(start, end);
}
@ -1148,20 +1147,6 @@ void CodeFlusher::EvictCandidate(JSFunction* function) {
}
void CodeFlusher::IteratePointersToFromSpace(ObjectVisitor* v) {
Heap* heap = isolate_->heap();
JSFunction** slot = &jsfunction_candidates_head_;
JSFunction* candidate = jsfunction_candidates_head_;
while (candidate != NULL) {
if (heap->InFromSpace(candidate)) {
v->VisitPointer(reinterpret_cast<Object**>(slot));
}
candidate = GetNextCandidate(*slot);
slot = GetNextCandidateSlot(*slot);
}
}
class StaticYoungGenerationMarkingVisitor
: public StaticNewSpaceVisitor<StaticYoungGenerationMarkingVisitor> {
public:
@ -1381,11 +1366,13 @@ class SharedFunctionInfoMarkingVisitor : public ObjectVisitor,
explicit SharedFunctionInfoMarkingVisitor(MarkCompactCollector* collector)
: collector_(collector) {}
void VisitPointers(Object** start, Object** end) override {
void VisitPointers(HeapObject* host, Object** start, Object** end) override {
for (Object** p = start; p < end; p++) MarkObject(p);
}
void VisitPointer(Object** slot) override { MarkObject(slot); }
void VisitPointer(HeapObject* host, Object** slot) override {
MarkObject(slot);
}
void VisitRootPointers(Root root, Object** start, Object** end) override {
for (Object** p = start; p < end; p++) MarkObject(p);
@ -1491,9 +1478,11 @@ class MarkCompactCollector::RootMarkingVisitor : public ObjectVisitor,
explicit RootMarkingVisitor(Heap* heap)
: collector_(heap->mark_compact_collector()) {}
void VisitPointer(Object** p) override { MarkObjectByPointer(p); }
void VisitPointer(HeapObject* host, Object** p) override {
MarkObjectByPointer(p);
}
void VisitPointers(Object** start, Object** end) override {
void VisitPointers(HeapObject* host, Object** start, Object** end) override {
for (Object** p = start; p < end; p++) MarkObjectByPointer(p);
}
@ -1507,7 +1496,7 @@ class MarkCompactCollector::RootMarkingVisitor : public ObjectVisitor,
// Skip the weak next code link in a code object, which is visited in
// ProcessTopOptimizedFrame.
void VisitNextCodeLink(Object** p) override {}
void VisitNextCodeLink(Code* host, Object** p) override {}
private:
void MarkObjectByPointer(Object** p) {
@ -1541,7 +1530,7 @@ class InternalizedStringTableCleaner : public ObjectVisitor {
InternalizedStringTableCleaner(Heap* heap, HeapObject* table)
: heap_(heap), pointers_removed_(0), table_(table) {}
void VisitPointers(Object** start, Object** end) override {
void VisitPointers(HeapObject* host, Object** start, Object** end) override {
// Visit all HeapObject pointers in [start, end).
MarkCompactCollector* collector = heap_->mark_compact_collector();
Object* the_hole = heap_->the_hole_value();
@ -1666,18 +1655,19 @@ class RecordMigratedSlotVisitor final : public ObjectVisitor {
explicit RecordMigratedSlotVisitor(MarkCompactCollector* collector)
: collector_(collector) {}
inline void VisitPointer(Object** p) final {
inline void VisitPointer(HeapObject* host, Object** p) final {
RecordMigratedSlot(*p, reinterpret_cast<Address>(p));
}
inline void VisitPointers(Object** start, Object** end) final {
inline void VisitPointers(HeapObject* host, Object** start,
Object** end) final {
while (start < end) {
RecordMigratedSlot(*start, reinterpret_cast<Address>(start));
++start;
}
}
inline void VisitCodeEntry(Address code_entry_slot) final {
inline void VisitCodeEntry(JSFunction* host, Address code_entry_slot) final {
Address code_entry = Memory::Address_at(code_entry_slot);
if (Page::FromAddress(code_entry)->IsEvacuationCandidate()) {
RememberedSet<OLD_TO_OLD>::InsertTyped(Page::FromAddress(code_entry_slot),
@ -1686,39 +1676,39 @@ class RecordMigratedSlotVisitor final : public ObjectVisitor {
}
}
inline void VisitCodeTarget(RelocInfo* rinfo) final {
inline void VisitCodeTarget(Code* host, RelocInfo* rinfo) final {
DCHECK_EQ(host, rinfo->host());
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);
}
inline void VisitDebugTarget(RelocInfo* rinfo) final {
inline void VisitDebugTarget(Code* host, RelocInfo* rinfo) final {
DCHECK_EQ(host, rinfo->host());
DCHECK(RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
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);
}
inline void VisitEmbeddedPointer(RelocInfo* rinfo) final {
inline void VisitEmbeddedPointer(Code* host, RelocInfo* rinfo) final {
DCHECK_EQ(host, rinfo->host());
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);
}
inline void VisitCell(RelocInfo* rinfo) final {
inline void VisitCellPointer(Code* host, RelocInfo* rinfo) final {
DCHECK_EQ(host, rinfo->host());
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));
@ -1726,7 +1716,8 @@ class RecordMigratedSlotVisitor final : public ObjectVisitor {
}
// Entries that will never move.
inline void VisitCodeAgeSequence(RelocInfo* rinfo) final {
inline void VisitCodeAgeSequence(Code* host, RelocInfo* rinfo) final {
DCHECK_EQ(host, rinfo->host());
DCHECK(RelocInfo::IsCodeAgeSequence(rinfo->rmode()));
Code* stub = rinfo->code_age_stub();
USE(stub);
@ -1734,10 +1725,10 @@ class RecordMigratedSlotVisitor final : public ObjectVisitor {
}
// Entries that are skipped for recording.
inline void VisitExternalReference(RelocInfo* rinfo) final {}
inline void VisitExternalReference(Address* p) final {}
inline void VisitRuntimeEntry(RelocInfo* rinfo) final {}
inline void VisitInternalReference(RelocInfo* rinfo) final {}
inline void VisitExternalReference(Code* host, RelocInfo* rinfo) final {}
inline void VisitExternalReference(Foreign* host, Address* p) final {}
inline void VisitRuntimeEntry(Code* host, RelocInfo* rinfo) final {}
inline void VisitInternalReference(Code* host, RelocInfo* rinfo) final {}
private:
inline void RecordMigratedSlot(Object* value, Address slot) {
@ -3092,9 +3083,9 @@ static inline SlotCallbackResult UpdateSlot(Object** slot) {
// nevers visits code objects.
class PointersUpdatingVisitor : public ObjectVisitor, public RootVisitor {
public:
void VisitPointer(Object** p) override { UpdateSlot(p); }
void VisitPointer(HeapObject* host, Object** p) override { UpdateSlot(p); }
void VisitPointers(Object** start, Object** end) override {
void VisitPointers(HeapObject* host, Object** start, Object** end) override {
for (Object** p = start; p < end; p++) UpdateSlot(p);
}
@ -3104,23 +3095,23 @@ class PointersUpdatingVisitor : public ObjectVisitor, public RootVisitor {
for (Object** p = start; p < end; p++) UpdateSlot(p);
}
void VisitCell(RelocInfo* rinfo) override {
void VisitCellPointer(Code* host, RelocInfo* rinfo) override {
UpdateTypedSlotHelper::UpdateCell(rinfo, UpdateSlot);
}
void VisitEmbeddedPointer(RelocInfo* rinfo) override {
void VisitEmbeddedPointer(Code* host, RelocInfo* rinfo) override {
UpdateTypedSlotHelper::UpdateEmbeddedPointer(rinfo, UpdateSlot);
}
void VisitCodeTarget(RelocInfo* rinfo) override {
void VisitCodeTarget(Code* host, RelocInfo* rinfo) override {
UpdateTypedSlotHelper::UpdateCodeTarget(rinfo, UpdateSlot);
}
void VisitCodeEntry(Address entry_address) override {
void VisitCodeEntry(JSFunction* host, Address entry_address) override {
UpdateTypedSlotHelper::UpdateCodeEntry(entry_address, UpdateSlot);
}
void VisitDebugTarget(RelocInfo* rinfo) override {
void VisitDebugTarget(Code* host, RelocInfo* rinfo) override {
UpdateTypedSlotHelper::UpdateDebugTarget(rinfo, UpdateSlot);
}
};

View File

@ -277,7 +277,10 @@ class CodeFlusher {
ProcessJSFunctionCandidates();
}
void IteratePointersToFromSpace(ObjectVisitor* v);
inline void VisitListHeads(RootVisitor* v);
template <typename StaticVisitor>
inline void IteratePointersToFromSpace();
private:
void ProcessJSFunctionCandidates();

View File

@ -460,13 +460,6 @@ void Scavenger::SelectScavengingVisitorsTable() {
Isolate* Scavenger::isolate() { return heap()->isolate(); }
void RootScavengeVisitor::VisitPointer(Object** p) { ScavengePointer(p); }
void RootScavengeVisitor::VisitPointers(Object** start, Object** end) {
// Copy all HeapObject pointers in [start, end)
for (Object** p = start; p < end; p++) ScavengePointer(p);
}
void RootScavengeVisitor::VisitRootPointer(Root root, Object** p) {
ScavengePointer(p);
}

View File

@ -46,15 +46,10 @@ class Scavenger {
// Helper class for turning the scavenger into an object visitor that is also
// filtering out non-HeapObjects and objects which do not reside in new space.
// TODO(ulan): ObjectVisitor is needed only for code flusher. Remove it after
// changing the scanvenger to treat JSFunction->next_link strongly.
class RootScavengeVisitor : public ObjectVisitor, public RootVisitor {
class RootScavengeVisitor : public RootVisitor {
public:
explicit RootScavengeVisitor(Heap* heap) : heap_(heap) {}
void VisitPointer(Object** p) override;
void VisitPointers(Object** start, Object** end) override;
void VisitRootPointer(Root root, Object** p) override;
void VisitRootPointers(Root root, Object** start, Object** end) override;

View File

@ -248,23 +248,23 @@ template <typename ObjectVisitor>
void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
RelocInfo::Mode mode = rmode();
if (mode == RelocInfo::EMBEDDED_OBJECT) {
visitor->VisitEmbeddedPointer(this);
visitor->VisitEmbeddedPointer(host(), this);
Assembler::FlushICache(isolate, pc_, sizeof(Address));
} else if (RelocInfo::IsCodeTarget(mode)) {
visitor->VisitCodeTarget(this);
visitor->VisitCodeTarget(host(), this);
} else if (mode == RelocInfo::CELL) {
visitor->VisitCell(this);
visitor->VisitCellPointer(host(), this);
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
visitor->VisitExternalReference(this);
visitor->VisitExternalReference(host(), this);
} else if (mode == RelocInfo::INTERNAL_REFERENCE) {
visitor->VisitInternalReference(this);
visitor->VisitInternalReference(host(), this);
} else if (RelocInfo::IsCodeAgeSequence(mode)) {
visitor->VisitCodeAgeSequence(this);
visitor->VisitCodeAgeSequence(host(), this);
} else if (RelocInfo::IsDebugBreakSlot(mode) &&
IsPatchedDebugBreakSlotSequence()) {
visitor->VisitDebugTarget(this);
visitor->VisitDebugTarget(host(), this);
} else if (IsRuntimeEntry(mode)) {
visitor->VisitRuntimeEntry(this);
visitor->VisitRuntimeEntry(host(), this);
}
}

View File

@ -366,23 +366,23 @@ template <typename ObjectVisitor>
void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
RelocInfo::Mode mode = rmode();
if (mode == RelocInfo::EMBEDDED_OBJECT) {
visitor->VisitEmbeddedPointer(this);
visitor->VisitEmbeddedPointer(host(), this);
} else if (RelocInfo::IsCodeTarget(mode)) {
visitor->VisitCodeTarget(this);
visitor->VisitCodeTarget(host(), this);
} else if (mode == RelocInfo::CELL) {
visitor->VisitCell(this);
visitor->VisitCellPointer(host(), this);
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
visitor->VisitExternalReference(this);
visitor->VisitExternalReference(host(), this);
} else if (mode == RelocInfo::INTERNAL_REFERENCE ||
mode == RelocInfo::INTERNAL_REFERENCE_ENCODED) {
visitor->VisitInternalReference(this);
visitor->VisitInternalReference(host(), this);
} else if (RelocInfo::IsCodeAgeSequence(mode)) {
visitor->VisitCodeAgeSequence(this);
visitor->VisitCodeAgeSequence(host(), this);
} else if (RelocInfo::IsDebugBreakSlot(mode) &&
IsPatchedDebugBreakSlotSequence()) {
visitor->VisitDebugTarget(this);
visitor->VisitDebugTarget(host(), this);
} else if (RelocInfo::IsRuntimeEntry(mode)) {
visitor->VisitRuntimeEntry(this);
visitor->VisitRuntimeEntry(host(), this);
}
}

View File

@ -341,23 +341,23 @@ template <typename ObjectVisitor>
void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
RelocInfo::Mode mode = rmode();
if (mode == RelocInfo::EMBEDDED_OBJECT) {
visitor->VisitEmbeddedPointer(this);
visitor->VisitEmbeddedPointer(host(), this);
} else if (RelocInfo::IsCodeTarget(mode)) {
visitor->VisitCodeTarget(this);
visitor->VisitCodeTarget(host(), this);
} else if (mode == RelocInfo::CELL) {
visitor->VisitCell(this);
visitor->VisitCellPointer(host(), this);
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
visitor->VisitExternalReference(this);
visitor->VisitExternalReference(host(), this);
} else if (mode == RelocInfo::INTERNAL_REFERENCE ||
mode == RelocInfo::INTERNAL_REFERENCE_ENCODED) {
visitor->VisitInternalReference(this);
visitor->VisitInternalReference(host(), this);
} else if (RelocInfo::IsCodeAgeSequence(mode)) {
visitor->VisitCodeAgeSequence(this);
visitor->VisitCodeAgeSequence(host(), this);
} else if (RelocInfo::IsDebugBreakSlot(mode) &&
IsPatchedDebugBreakSlotSequence()) {
visitor->VisitDebugTarget(this);
visitor->VisitDebugTarget(host(), this);
} else if (RelocInfo::IsRuntimeEntry(mode)) {
visitor->VisitRuntimeEntry(this);
visitor->VisitRuntimeEntry(host(), this);
}
}

View File

@ -79,7 +79,7 @@ DISABLE_CFI_PERF void BodyDescriptorBase::IteratePointers(HeapObject* obj,
int start_offset,
int end_offset,
ObjectVisitor* v) {
v->VisitPointers(HeapObject::RawField(obj, start_offset),
v->VisitPointers(obj, HeapObject::RawField(obj, start_offset),
HeapObject::RawField(obj, end_offset));
}
@ -96,7 +96,7 @@ DISABLE_CFI_PERF void BodyDescriptorBase::IteratePointers(Heap* heap,
template <typename ObjectVisitor>
void BodyDescriptorBase::IteratePointer(HeapObject* obj, int offset,
ObjectVisitor* v) {
v->VisitPointer(HeapObject::RawField(obj, offset));
v->VisitPointer(obj, HeapObject::RawField(obj, offset));
}
template <typename StaticVisitor>
@ -175,7 +175,8 @@ class JSFunction::BodyDescriptorImpl final : public BodyDescriptorBase {
IteratePointers(obj, kPropertiesOffset, kNonWeakFieldsEndOffset, v);
if (body_visiting_policy & kVisitCodeEntry) {
v->VisitCodeEntry(obj->address() + kCodeEntryOffset);
v->VisitCodeEntry(JSFunction::cast(obj),
obj->address() + kCodeEntryOffset);
}
if (body_visiting_policy & kVisitNextFunction) {
@ -334,8 +335,9 @@ class Foreign::BodyDescriptor final : public BodyDescriptorBase {
template <typename ObjectVisitor>
static inline void IterateBody(HeapObject* obj, int object_size,
ObjectVisitor* v) {
v->VisitExternalReference(reinterpret_cast<Address*>(
HeapObject::RawField(obj, kForeignAddressOffset)));
v->VisitExternalReference(Foreign::cast(obj),
reinterpret_cast<Address*>(HeapObject::RawField(
obj, kForeignAddressOffset)));
}
template <typename StaticVisitor>
@ -408,9 +410,10 @@ class Code::BodyDescriptor final : public BodyDescriptorBase {
RelocInfo::kDebugBreakSlotMask;
IteratePointers(obj, kRelocationInfoOffset, kNextCodeLinkOffset, v);
v->VisitNextCodeLink(HeapObject::RawField(obj, kNextCodeLinkOffset));
v->VisitNextCodeLink(Code::cast(obj),
HeapObject::RawField(obj, kNextCodeLinkOffset));
RelocIterator it(reinterpret_cast<Code*>(obj), mode_mask);
RelocIterator it(Code::cast(obj), mode_mask);
Isolate* isolate = obj->GetIsolate();
for (; !it.done(); it.next()) {
it.rinfo()->Visit(isolate, v);
@ -440,7 +443,7 @@ class Code::BodyDescriptor final : public BodyDescriptorBase {
StaticVisitor::VisitNextCodeLink(
heap, HeapObject::RawField(obj, kNextCodeLinkOffset));
RelocIterator it(reinterpret_cast<Code*>(obj), mode_mask);
RelocIterator it(Code::cast(obj), mode_mask);
for (; !it.done(); it.next()) {
it.rinfo()->template Visit<StaticVisitor>(heap);
}

View File

@ -13881,72 +13881,58 @@ Code* SharedFunctionInfo::SearchOptimizedCodeMap(Context* native_context,
return result;
}
void ObjectVisitor::VisitCodeTarget(RelocInfo* rinfo) {
void ObjectVisitor::VisitCodeTarget(Code* host, RelocInfo* rinfo) {
DCHECK(RelocInfo::IsCodeTarget(rinfo->rmode()));
Object* old_pointer = Code::GetCodeFromTargetAddress(rinfo->target_address());
Object* new_pointer = old_pointer;
VisitPointer(&new_pointer);
VisitPointer(host, &new_pointer);
DCHECK_EQ(old_pointer, new_pointer);
}
void ObjectVisitor::VisitCodeAgeSequence(RelocInfo* rinfo) {
void ObjectVisitor::VisitCodeAgeSequence(Code* host, RelocInfo* rinfo) {
DCHECK(RelocInfo::IsCodeAgeSequence(rinfo->rmode()));
Object* old_pointer = rinfo->code_age_stub();
Object* new_pointer = old_pointer;
if (old_pointer != nullptr) {
VisitPointer(&new_pointer);
VisitPointer(host, &new_pointer);
DCHECK_EQ(old_pointer, new_pointer);
}
}
void ObjectVisitor::VisitCodeEntry(Address entry_address) {
void ObjectVisitor::VisitCodeEntry(JSFunction* host, Address entry_address) {
Object* old_pointer = Code::GetObjectFromEntryAddress(entry_address);
Object* new_pointer = old_pointer;
VisitPointer(&new_pointer);
VisitPointer(host, &new_pointer);
DCHECK_EQ(old_pointer, new_pointer);
}
void ObjectVisitor::VisitCell(RelocInfo* rinfo) {
void ObjectVisitor::VisitCellPointer(Code* host, RelocInfo* rinfo) {
DCHECK(rinfo->rmode() == RelocInfo::CELL);
Object* old_pointer = rinfo->target_cell();
Object* new_pointer = old_pointer;
VisitPointer(&new_pointer);
VisitPointer(host, &new_pointer);
DCHECK_EQ(old_pointer, new_pointer);
}
void ObjectVisitor::VisitDebugTarget(RelocInfo* rinfo) {
void ObjectVisitor::VisitDebugTarget(Code* host, RelocInfo* rinfo) {
DCHECK(RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
rinfo->IsPatchedDebugBreakSlotSequence());
Object* old_pointer =
Code::GetCodeFromTargetAddress(rinfo->debug_call_address());
Object* new_pointer = old_pointer;
VisitPointer(&new_pointer);
VisitPointer(host, &new_pointer);
DCHECK_EQ(old_pointer, new_pointer);
}
void ObjectVisitor::VisitEmbeddedPointer(RelocInfo* rinfo) {
void ObjectVisitor::VisitEmbeddedPointer(Code* host, RelocInfo* rinfo) {
DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
Object* old_pointer = rinfo->target_object();
Object* new_pointer = old_pointer;
VisitPointer(&new_pointer);
VisitPointer(host, &new_pointer);
DCHECK_EQ(old_pointer, new_pointer);
}
void ObjectVisitor::VisitExternalReference(RelocInfo* rinfo) {
Address old_reference = rinfo->target_external_reference();
Address new_reference = old_reference;
VisitExternalReference(&new_reference);
DCHECK_EQ(old_reference, new_reference);
}
void Code::InvalidateRelocation() {
InvalidateEmbeddedObjects();
set_relocation_info(GetHeap()->empty_byte_array());

View File

@ -10205,47 +10205,52 @@ class ObjectVisitor BASE_EMBEDDED {
// Visits a contiguous arrays of pointers in the half-open range
// [start, end). Any or all of the values may be modified on return.
virtual void VisitPointers(Object** start, Object** end) = 0;
virtual void VisitPointers(HeapObject* host, Object** start,
Object** end) = 0;
// Handy shorthand for visiting a single pointer.
virtual void VisitPointer(Object** p) { VisitPointers(p, p + 1); }
virtual void VisitPointer(HeapObject* host, Object** p) {
VisitPointers(host, p, p + 1);
}
// Visit weak next_code_link in Code object.
virtual void VisitNextCodeLink(Object** p) { VisitPointers(p, p + 1); }
virtual void VisitNextCodeLink(Code* host, Object** p) {
VisitPointers(host, p, p + 1);
}
// To allow lazy clearing of inline caches the visitor has
// a rich interface for iterating over Code objects..
// Visits a code target in the instruction stream.
virtual void VisitCodeTarget(RelocInfo* rinfo);
virtual void VisitCodeTarget(Code* host, RelocInfo* rinfo);
// Visits a code entry in a JS function.
virtual void VisitCodeEntry(Address entry_address);
virtual void VisitCodeEntry(JSFunction* host, Address entry_address);
// Visits a global property cell reference in the instruction stream.
virtual void VisitCell(RelocInfo* rinfo);
virtual void VisitCellPointer(Code* host, RelocInfo* rinfo);
// Visits a runtime entry in the instruction stream.
virtual void VisitRuntimeEntry(RelocInfo* rinfo) {}
virtual void VisitRuntimeEntry(Code* host, RelocInfo* rinfo) {}
// Visits a debug call target in the instruction stream.
virtual void VisitDebugTarget(RelocInfo* rinfo);
virtual void VisitDebugTarget(Code* host, RelocInfo* rinfo);
// Visits the byte sequence in a function's prologue that contains information
// about the code's age.
virtual void VisitCodeAgeSequence(RelocInfo* rinfo);
virtual void VisitCodeAgeSequence(Code* host, RelocInfo* rinfo);
// Visit pointer embedded into a code object.
virtual void VisitEmbeddedPointer(RelocInfo* rinfo);
virtual void VisitEmbeddedPointer(Code* host, RelocInfo* rinfo);
// Visits an external reference embedded into a code object.
virtual void VisitExternalReference(RelocInfo* rinfo);
virtual void VisitExternalReference(Code* host, RelocInfo* rinfo) {}
// Visits an external reference.
virtual void VisitExternalReference(Address* p) {}
virtual void VisitExternalReference(Foreign* host, Address* p) {}
// Visits an (encoded) internal reference.
virtual void VisitInternalReference(RelocInfo* rinfo) {}
virtual void VisitInternalReference(Code* host, RelocInfo* rinfo) {}
};

View File

@ -321,23 +321,23 @@ template <typename ObjectVisitor>
void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
RelocInfo::Mode mode = rmode();
if (mode == RelocInfo::EMBEDDED_OBJECT) {
visitor->VisitEmbeddedPointer(this);
visitor->VisitEmbeddedPointer(host(), this);
} else if (RelocInfo::IsCodeTarget(mode)) {
visitor->VisitCodeTarget(this);
visitor->VisitCodeTarget(host(), this);
} else if (mode == RelocInfo::CELL) {
visitor->VisitCell(this);
visitor->VisitCellPointer(host(), this);
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
visitor->VisitExternalReference(this);
visitor->VisitExternalReference(host(), this);
} else if (mode == RelocInfo::INTERNAL_REFERENCE ||
mode == RelocInfo::INTERNAL_REFERENCE_ENCODED) {
visitor->VisitInternalReference(this);
visitor->VisitInternalReference(host(), this);
} else if (RelocInfo::IsCodeAgeSequence(mode)) {
visitor->VisitCodeAgeSequence(this);
visitor->VisitCodeAgeSequence(host(), this);
} else if (RelocInfo::IsDebugBreakSlot(mode) &&
IsPatchedDebugBreakSlotSequence()) {
visitor->VisitDebugTarget(this);
visitor->VisitDebugTarget(host(), this);
} else if (IsRuntimeEntry(mode)) {
visitor->VisitRuntimeEntry(this);
visitor->VisitRuntimeEntry(host(), this);
}
}

View File

@ -973,12 +973,12 @@ class IndexedReferencesExtractor : public ObjectVisitor {
parent_end_(HeapObject::RawField(parent_obj_, parent_obj_->Size())),
parent_(parent),
next_index_(0) {}
void VisitCodeEntry(Address entry_address) override {
Code* code = Code::cast(Code::GetObjectFromEntryAddress(entry_address));
generator_->SetInternalReference(parent_obj_, parent_, "code", code);
generator_->TagCodeObject(code);
void VisitCodeEntry(JSFunction* host, Address entry_address) override {
Code* code = Code::cast(Code::GetObjectFromEntryAddress(entry_address));
generator_->SetInternalReference(parent_obj_, parent_, "code", code);
generator_->TagCodeObject(code);
}
void VisitPointers(Object** start, Object** end) override {
void VisitPointers(HeapObject* host, Object** start, Object** end) override {
for (Object** p = start; p < end; p++) {
int index = static_cast<int>(p - HeapObject::RawField(parent_obj_, 0));
++next_index_;

View File

@ -300,22 +300,22 @@ template <typename ObjectVisitor>
void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
RelocInfo::Mode mode = rmode();
if (mode == RelocInfo::EMBEDDED_OBJECT) {
visitor->VisitEmbeddedPointer(this);
visitor->VisitEmbeddedPointer(host(), this);
} else if (RelocInfo::IsCodeTarget(mode)) {
visitor->VisitCodeTarget(this);
visitor->VisitCodeTarget(host(), this);
} else if (mode == RelocInfo::CELL) {
visitor->VisitCell(this);
visitor->VisitCellPointer(host(), this);
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
visitor->VisitExternalReference(this);
visitor->VisitExternalReference(host(), this);
} else if (mode == RelocInfo::INTERNAL_REFERENCE) {
visitor->VisitInternalReference(this);
visitor->VisitInternalReference(host(), this);
} else if (RelocInfo::IsCodeAgeSequence(mode)) {
visitor->VisitCodeAgeSequence(this);
visitor->VisitCodeAgeSequence(host(), this);
} else if (RelocInfo::IsDebugBreakSlot(mode) &&
IsPatchedDebugBreakSlotSequence()) {
visitor->VisitDebugTarget(this);
visitor->VisitDebugTarget(host(), this);
} else if (IsRuntimeEntry(mode)) {
visitor->VisitRuntimeEntry(this);
visitor->VisitRuntimeEntry(host(), this);
}
}

View File

@ -598,7 +598,8 @@ void Serializer::ObjectSerializer::SerializeDeferred() {
OutputRawData(object_->address() + size);
}
void Serializer::ObjectSerializer::VisitPointers(Object** start, Object** end) {
void Serializer::ObjectSerializer::VisitPointers(HeapObject* host,
Object** start, Object** end) {
Object** current = start;
while (current < end) {
while (current < end && (*current)->IsSmi()) current++;
@ -636,7 +637,8 @@ void Serializer::ObjectSerializer::VisitPointers(Object** start, Object** end) {
}
}
void Serializer::ObjectSerializer::VisitEmbeddedPointer(RelocInfo* rinfo) {
void Serializer::ObjectSerializer::VisitEmbeddedPointer(Code* host,
RelocInfo* rinfo) {
int skip = OutputRawData(rinfo->target_address_address(),
kCanReturnSkipInsteadOfSkipping);
HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain;
@ -646,7 +648,8 @@ void Serializer::ObjectSerializer::VisitEmbeddedPointer(RelocInfo* rinfo) {
bytes_processed_so_far_ += rinfo->target_address_size();
}
void Serializer::ObjectSerializer::VisitExternalReference(Address* p) {
void Serializer::ObjectSerializer::VisitExternalReference(Foreign* host,
Address* p) {
int skip = OutputRawData(reinterpret_cast<Address>(p),
kCanReturnSkipInsteadOfSkipping);
Address target = *p;
@ -658,7 +661,8 @@ void Serializer::ObjectSerializer::VisitExternalReference(Address* p) {
bytes_processed_so_far_ += kPointerSize;
}
void Serializer::ObjectSerializer::VisitExternalReference(RelocInfo* rinfo) {
void Serializer::ObjectSerializer::VisitExternalReference(Code* host,
RelocInfo* rinfo) {
int skip = OutputRawData(rinfo->target_address_address(),
kCanReturnSkipInsteadOfSkipping);
HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain;
@ -673,7 +677,8 @@ void Serializer::ObjectSerializer::VisitExternalReference(RelocInfo* rinfo) {
bytes_processed_so_far_ += rinfo->target_address_size();
}
void Serializer::ObjectSerializer::VisitInternalReference(RelocInfo* rinfo) {
void Serializer::ObjectSerializer::VisitInternalReference(Code* host,
RelocInfo* rinfo) {
// We can only reference to internal references of code that has been output.
DCHECK(object_->IsCode() && code_has_been_output_);
// We do not use skip from last patched pc to find the pc to patch, since
@ -697,7 +702,8 @@ void Serializer::ObjectSerializer::VisitInternalReference(RelocInfo* rinfo) {
sink_->PutInt(static_cast<uintptr_t>(target_offset), "internal ref value");
}
void Serializer::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) {
void Serializer::ObjectSerializer::VisitRuntimeEntry(Code* host,
RelocInfo* rinfo) {
int skip = OutputRawData(rinfo->target_address_address(),
kCanReturnSkipInsteadOfSkipping);
HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain;
@ -711,7 +717,8 @@ void Serializer::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) {
bytes_processed_so_far_ += rinfo->target_address_size();
}
void Serializer::ObjectSerializer::VisitCodeTarget(RelocInfo* rinfo) {
void Serializer::ObjectSerializer::VisitCodeTarget(Code* host,
RelocInfo* rinfo) {
int skip = OutputRawData(rinfo->target_address_address(),
kCanReturnSkipInsteadOfSkipping);
Code* object = Code::GetCodeFromTargetAddress(rinfo->target_address());
@ -719,14 +726,16 @@ void Serializer::ObjectSerializer::VisitCodeTarget(RelocInfo* rinfo) {
bytes_processed_so_far_ += rinfo->target_address_size();
}
void Serializer::ObjectSerializer::VisitCodeEntry(Address entry_address) {
void Serializer::ObjectSerializer::VisitCodeEntry(JSFunction* host,
Address entry_address) {
int skip = OutputRawData(entry_address, kCanReturnSkipInsteadOfSkipping);
Code* object = Code::cast(Code::GetObjectFromEntryAddress(entry_address));
serializer_->SerializeObject(object, kPlain, kInnerPointer, skip);
bytes_processed_so_far_ += kPointerSize;
}
void Serializer::ObjectSerializer::VisitCell(RelocInfo* rinfo) {
void Serializer::ObjectSerializer::VisitCellPointer(Code* host,
RelocInfo* rinfo) {
int skip = OutputRawData(rinfo->pc(), kCanReturnSkipInsteadOfSkipping);
Cell* object = Cell::cast(rinfo->target_cell());
serializer_->SerializeObject(object, kPlain, kInnerPointer, skip);

View File

@ -282,15 +282,15 @@ class Serializer::ObjectSerializer : public ObjectVisitor {
void Serialize();
void SerializeContent();
void SerializeDeferred();
void VisitPointers(Object** start, Object** end) override;
void VisitEmbeddedPointer(RelocInfo* target) override;
void VisitExternalReference(Address* p) override;
void VisitExternalReference(RelocInfo* rinfo) override;
void VisitInternalReference(RelocInfo* rinfo) override;
void VisitCodeTarget(RelocInfo* target) override;
void VisitCodeEntry(Address entry_address) override;
void VisitCell(RelocInfo* rinfo) override;
void VisitRuntimeEntry(RelocInfo* reloc) override;
void VisitPointers(HeapObject* host, Object** start, Object** end) override;
void VisitEmbeddedPointer(Code* host, RelocInfo* target) override;
void VisitExternalReference(Foreign* host, Address* p) override;
void VisitExternalReference(Code* host, RelocInfo* rinfo) override;
void VisitInternalReference(Code* host, RelocInfo* rinfo) override;
void VisitCodeTarget(Code* host, RelocInfo* target) override;
void VisitCodeEntry(JSFunction* host, Address entry_address) override;
void VisitCellPointer(Code* host, RelocInfo* rinfo) override;
void VisitRuntimeEntry(Code* host, RelocInfo* reloc) override;
private:
bool TryEncodeDeoptimizationEntry(HowToCode how_to_code, Address target,

View File

@ -46,6 +46,7 @@ enum class Root {
ROOT_ID_LIST(DECLARE_ENUM)
#undef DECLARE_ENUM
// TODO(ulan): Merge with the ROOT_ID_LIST.
kCodeFlusher,
kPartialSnapshotCache,
kWeakCollections
};

View File

@ -521,23 +521,23 @@ template <typename ObjectVisitor>
void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
RelocInfo::Mode mode = rmode();
if (mode == RelocInfo::EMBEDDED_OBJECT) {
visitor->VisitEmbeddedPointer(this);
visitor->VisitEmbeddedPointer(host(), this);
Assembler::FlushICache(isolate, pc_, sizeof(Address));
} else if (RelocInfo::IsCodeTarget(mode)) {
visitor->VisitCodeTarget(this);
visitor->VisitCodeTarget(host(), this);
} else if (mode == RelocInfo::CELL) {
visitor->VisitCell(this);
visitor->VisitCellPointer(host(), this);
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
visitor->VisitExternalReference(this);
visitor->VisitExternalReference(host(), this);
} else if (mode == RelocInfo::INTERNAL_REFERENCE) {
visitor->VisitInternalReference(this);
visitor->VisitInternalReference(host(), this);
} else if (RelocInfo::IsCodeAgeSequence(mode)) {
visitor->VisitCodeAgeSequence(this);
visitor->VisitCodeAgeSequence(host(), this);
} else if (RelocInfo::IsDebugBreakSlot(mode) &&
IsPatchedDebugBreakSlotSequence()) {
visitor->VisitDebugTarget(this);
visitor->VisitDebugTarget(host(), this);
} else if (RelocInfo::IsRuntimeEntry(mode)) {
visitor->VisitRuntimeEntry(this);
visitor->VisitRuntimeEntry(host(), this);
}
}

View File

@ -248,23 +248,23 @@ template <typename ObjectVisitor>
void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
RelocInfo::Mode mode = rmode();
if (mode == RelocInfo::EMBEDDED_OBJECT) {
visitor->VisitEmbeddedPointer(this);
visitor->VisitEmbeddedPointer(host(), this);
Assembler::FlushICache(isolate, pc_, sizeof(Address));
} else if (RelocInfo::IsCodeTarget(mode)) {
visitor->VisitCodeTarget(this);
visitor->VisitCodeTarget(host(), this);
} else if (mode == RelocInfo::CELL) {
visitor->VisitCell(this);
visitor->VisitCellPointer(host(), this);
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
visitor->VisitExternalReference(this);
visitor->VisitExternalReference(host(), this);
} else if (mode == RelocInfo::INTERNAL_REFERENCE) {
visitor->VisitInternalReference(this);
visitor->VisitInternalReference(host(), this);
} else if (RelocInfo::IsCodeAgeSequence(mode)) {
visitor->VisitCodeAgeSequence(this);
visitor->VisitCodeAgeSequence(host(), this);
} else if (RelocInfo::IsDebugBreakSlot(mode) &&
IsPatchedDebugBreakSlotSequence()) {
visitor->VisitDebugTarget(this);
visitor->VisitDebugTarget(host(), this);
} else if (IsRuntimeEntry(mode)) {
visitor->VisitRuntimeEntry(this);
visitor->VisitRuntimeEntry(host(), this);
}
}