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:
parent
ef99f6667d
commit
c59f78f611
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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) {}
|
||||
};
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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_;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user