Commit 9340b3fb authored by Igor Sheludko's avatar Igor Sheludko Committed by V8 LUCI CQ

[ext-code-space] Add ObjectVisitor::VisitCodePointer()

... for visiting slots containing pointers to Code objects when
external code space mode is enabled.
These slots will require different handling once the code space is
moved out of the V8 heap cage.

This CL also introduces IsValidCodeObject() predicate similar to
IsValidHeapObject() for checking if given HeapObject is a valid Code
object.

Tbr: cbruni@chromium.org
Bug: v8:11880
Change-Id: I430940f4503cebfd2a6d387e44349810991a93e9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3032085Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75787}
parent ccfd2933
......@@ -750,11 +750,15 @@ struct SlotTraits {
using TMaybeObjectSlot = CompressedMaybeObjectSlot;
using THeapObjectSlot = CompressedHeapObjectSlot;
using TOffHeapObjectSlot = OffHeapCompressedObjectSlot;
// TODO(v8:11880): switch to OffHeapCompressedObjectSlot.
using TCodeObjectSlot = CompressedObjectSlot;
#else
using TObjectSlot = FullObjectSlot;
using TMaybeObjectSlot = FullMaybeObjectSlot;
using THeapObjectSlot = FullHeapObjectSlot;
using TOffHeapObjectSlot = OffHeapFullObjectSlot;
// TODO(v8:11880): switch to OffHeapFullObjectSlot.
using TCodeObjectSlot = FullObjectSlot;
#endif
};
......@@ -776,6 +780,12 @@ using HeapObjectSlot = SlotTraits::THeapObjectSlot;
// off-heap.
using OffHeapObjectSlot = SlotTraits::TOffHeapObjectSlot;
// A CodeObjectSlot instance describes a kTaggedSize-sized field ("slot")
// holding a strong pointer to a Code object. The Code object slots might be
// compressed and since code space might be allocated off the main heap
// the load operations require explicit cage base value for code space.
using CodeObjectSlot = SlotTraits::TCodeObjectSlot;
using WeakSlotCallback = bool (*)(FullObjectSlot pointer);
using WeakSlotCallbackWithHeap = bool (*)(Heap* heap, FullObjectSlot pointer);
......
......@@ -311,7 +311,7 @@ void HeapObject::VerifyHeapPointer(Isolate* isolate, Object p) {
// static
void HeapObject::VerifyCodePointer(Isolate* isolate, Object p) {
CHECK(p.IsHeapObject());
CHECK(isolate->heap()->InCodeSpace(HeapObject::cast(p)));
CHECK(IsValidCodeObject(isolate->heap(), HeapObject::cast(p)));
CHECK(HeapObject::cast(p).IsCode());
}
......
......@@ -33,11 +33,20 @@ class V8_EXPORT_PRIVATE CombinedHeapObjectIterator final {
V8_WARN_UNUSED_RESULT inline bool IsValidHeapObject(Heap* heap,
HeapObject object) {
if (V8_ENABLE_THIRD_PARTY_HEAP_BOOL)
if (V8_ENABLE_THIRD_PARTY_HEAP_BOOL) {
return third_party_heap::Heap::IsValidHeapObject(object);
else
return ReadOnlyHeap::Contains(object) || heap->Contains(object) ||
heap->SharedHeapContains(object);
}
return ReadOnlyHeap::Contains(object) || heap->Contains(object) ||
heap->SharedHeapContains(object);
}
V8_WARN_UNUSED_RESULT inline bool IsValidCodeObject(Heap* heap,
HeapObject object) {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
if (V8_ENABLE_THIRD_PARTY_HEAP_BOOL) {
return third_party_heap::Heap::IsValidCodeObject(object);
}
return heap->ContainsCode(object);
}
} // namespace internal
......
......@@ -183,6 +183,12 @@ class ConcurrentMarkingVisitor final
}
}
void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// TODO(v8:11880): support external code space.
VisitPointers(host, ObjectSlot(slot), ObjectSlot(slot + 1));
}
void VisitPointers(HeapObject host, MaybeObjectSlot start,
MaybeObjectSlot end) override {
// This should never happen, because we don't use snapshotting for objects
......
......@@ -492,13 +492,6 @@ bool Heap::InOldSpace(Object object) {
return old_space_->Contains(object);
}
bool Heap::InCodeSpace(HeapObject object) {
if (V8_ENABLE_THIRD_PARTY_HEAP_BOOL) {
return third_party_heap::Heap::InCodeSpace(object.ptr());
}
return code_space_->Contains(object) || code_lo_space_->Contains(object);
}
// static
Heap* Heap::FromWritableHeapObject(HeapObject obj) {
if (V8_ENABLE_THIRD_PARTY_HEAP_BOOL) {
......
......@@ -3828,6 +3828,11 @@ class SlotCollectingVisitor final : public ObjectVisitor {
}
}
void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
slots_.push_back(MaybeObjectSlot(slot));
}
void VisitCodeTarget(Code host, RelocInfo* rinfo) final { UNREACHABLE(); }
void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) override {
......@@ -4278,6 +4283,18 @@ bool Heap::Contains(HeapObject value) const {
(new_lo_space_ && new_lo_space_->Contains(value)));
}
bool Heap::ContainsCode(HeapObject value) const {
if (V8_ENABLE_THIRD_PARTY_HEAP_BOOL) {
return true;
}
// TODO(v8:11880): support external code space.
if (memory_allocator()->IsOutsideAllocatedSpace(value.address())) {
return false;
}
return HasBeenSetUp() &&
(code_space_->Contains(value) || code_lo_space_->Contains(value));
}
bool Heap::SharedHeapContains(HeapObject value) const {
if (shared_old_space_)
return shared_old_space_->Contains(value) ||
......@@ -4433,6 +4450,12 @@ class SlotVerifyingVisitor : public ObjectVisitor {
}
}
void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// TODO(v8:11880): support external code space.
VisitPointers(host, MaybeObjectSlot(slot), MaybeObjectSlot(slot + 1));
}
void VisitCodeTarget(Code host, RelocInfo* rinfo) override {
Object target = Code::GetCodeFromTargetAddress(rinfo->target_address());
if (ShouldHaveBeenRecorded(host, MaybeObject::FromObject(target))) {
......@@ -6303,6 +6326,12 @@ class UnreachableObjectsFilter : public HeapObjectsFilter {
MarkPointers(start, end);
}
void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// TODO(v8:11880): support external code space.
VisitPointers(host, MaybeObjectSlot(slot), MaybeObjectSlot(slot + 1));
}
void VisitCodeTarget(Code host, RelocInfo* rinfo) final {
Code target = Code::GetCodeFromTargetAddress(rinfo->target_address());
MarkHeapObject(target);
......@@ -6775,6 +6804,20 @@ void VerifyPointersVisitor::VisitPointers(HeapObject host,
VerifyPointers(host, start, end);
}
void VerifyPointersVisitor::VisitCodePointer(HeapObject host,
CodeObjectSlot slot) {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// TODO(v8:11880): support external code space.
PtrComprCageBase code_cage_base = GetPtrComprCageBase(host);
Object maybe_code = slot.load(code_cage_base);
HeapObject code;
if (maybe_code.GetHeapObject(&code)) {
VerifyCodeObjectImpl(code);
} else {
CHECK(maybe_code.IsSmi());
}
}
void VerifyPointersVisitor::VisitRootPointers(Root root,
const char* description,
FullObjectSlot start,
......@@ -6794,6 +6837,14 @@ void VerifyPointersVisitor::VerifyHeapObjectImpl(HeapObject heap_object) {
CHECK(heap_object.map().IsMap());
}
void VerifyPointersVisitor::VerifyCodeObjectImpl(HeapObject heap_object) {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
CHECK(IsValidCodeObject(heap_, heap_object));
PtrComprCageBase cage_base(heap_->isolate());
CHECK(heap_object.map(cage_base).IsMap(cage_base));
CHECK(heap_object.map(cage_base).instance_type() == CODE_TYPE);
}
template <typename TSlot>
void VerifyPointersVisitor::VerifyPointersImpl(TSlot start, TSlot end) {
Isolate* isolate = heap_->isolate();
......
......@@ -1270,13 +1270,13 @@ class Heap {
// Returns whether the object resides in old space.
inline bool InOldSpace(Object object);
// Returns whether the object resides in any of the code spaces.
inline bool InCodeSpace(HeapObject object);
// Checks whether an address/object is in the non-read-only heap (including
// auxiliary area and unused area). Use IsValidHeapObject if checking both
// heaps is required.
V8_EXPORT_PRIVATE bool Contains(HeapObject value) const;
// Same as above, but checks whether the object resides in any of the code
// spaces.
V8_EXPORT_PRIVATE bool ContainsCode(HeapObject value) const;
// Checks whether an address/object is in the non-read-only heap (including
// auxiliary area and unused area). Use IsValidHeapObject if checking both
......@@ -2650,6 +2650,7 @@ class VerifyPointersVisitor : public ObjectVisitor, public RootVisitor {
ObjectSlot end) override;
void VisitPointers(HeapObject host, MaybeObjectSlot start,
MaybeObjectSlot end) override;
void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override;
void VisitCodeTarget(Code host, RelocInfo* rinfo) override;
void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) override;
......@@ -2661,6 +2662,7 @@ class VerifyPointersVisitor : public ObjectVisitor, public RootVisitor {
protected:
V8_INLINE void VerifyHeapObjectImpl(HeapObject heap_object);
V8_INLINE void VerifyCodeObjectImpl(HeapObject heap_object);
template <typename TSlot>
V8_INLINE void VerifyPointersImpl(TSlot start, TSlot end);
......
......@@ -88,6 +88,7 @@ class MarkingVerifier : public ObjectVisitor, public RootVisitor {
virtual void VerifyMap(Map map) = 0;
virtual void VerifyPointers(ObjectSlot start, ObjectSlot end) = 0;
virtual void VerifyPointers(MaybeObjectSlot start, MaybeObjectSlot end) = 0;
virtual void VerifyCodePointer(CodeObjectSlot slot) = 0;
virtual void VerifyRootPointers(FullObjectSlot start, FullObjectSlot end) = 0;
virtual bool IsMarked(HeapObject object) = 0;
......@@ -104,6 +105,11 @@ class MarkingVerifier : public ObjectVisitor, public RootVisitor {
VerifyPointers(start, end);
}
void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
VerifyCodePointer(slot);
}
void VisitRootPointers(Root root, const char* description,
FullObjectSlot start, FullObjectSlot end) override {
VerifyRootPointers(start, end);
......@@ -227,6 +233,12 @@ class FullMarkingVerifier : public MarkingVerifier {
VerifyPointersImpl(start, end);
}
void VerifyCodePointer(CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// TODO(v8:11880): support external code space.
VerifyPointersImpl(MaybeObjectSlot(slot), MaybeObjectSlot(slot + 1));
}
void VerifyRootPointers(FullObjectSlot start, FullObjectSlot end) override {
VerifyPointersImpl(start, end);
}
......@@ -281,6 +293,11 @@ class EvacuationVerifier : public ObjectVisitor, public RootVisitor {
VerifyPointers(start, end);
}
void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
VerifyCodePointer(slot);
}
void VisitRootPointers(Root root, const char* description,
FullObjectSlot start, FullObjectSlot end) override {
VerifyRootPointers(start, end);
......@@ -296,6 +313,7 @@ class EvacuationVerifier : public ObjectVisitor, public RootVisitor {
virtual void VerifyMap(Map map) = 0;
virtual void VerifyPointers(ObjectSlot start, ObjectSlot end) = 0;
virtual void VerifyPointers(MaybeObjectSlot start, MaybeObjectSlot end) = 0;
virtual void VerifyCodePointer(CodeObjectSlot slot) = 0;
virtual void VerifyRootPointers(FullObjectSlot start, FullObjectSlot end) = 0;
void VerifyRoots();
......@@ -385,6 +403,11 @@ class FullEvacuationVerifier : public EvacuationVerifier {
void VerifyPointers(MaybeObjectSlot start, MaybeObjectSlot end) override {
VerifyPointersImpl(start, end);
}
void VerifyCodePointer(CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// TODO(v8:11880): support external code space.
VerifyPointersImpl(MaybeObjectSlot(slot), MaybeObjectSlot(slot + 1));
}
void VisitCodeTarget(Code host, RelocInfo* rinfo) override {
Code target = Code::GetCodeFromTargetAddress(rinfo->target_address());
VerifyHeapObjectImpl(target);
......@@ -1046,6 +1069,13 @@ class MarkCompactCollector::CustomRootBodyMarkingVisitor final
}
}
void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// At the moment, custom roots cannot contain CodeDataContainers - the only
// objects that can contain Code pointers.
UNREACHABLE();
}
void VisitPointers(HeapObject host, MaybeObjectSlot start,
MaybeObjectSlot end) final {
// At the moment, custom roots cannot contain weak pointers.
......@@ -1213,6 +1243,12 @@ class RecordMigratedSlotVisitor : public ObjectVisitor {
}
}
inline void VisitCodePointer(HeapObject host, CodeObjectSlot slot) final {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// TODO(v8:11880): support external code space.
VisitPointer(host, MaybeObjectSlot(slot));
}
inline void VisitEphemeron(HeapObject host, int index, ObjectSlot key,
ObjectSlot value) override {
DCHECK(host.IsEphemeronHashTable());
......@@ -2816,6 +2852,12 @@ class PointersUpdatingVisitor : public ObjectVisitor, public RootVisitor {
}
}
void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// TODO(v8:11880): support external code space.
VisitPointer(host, ObjectSlot(slot));
}
void VisitRootPointer(Root root, const char* description,
FullObjectSlot p) override {
DCHECK(!MapWord::IsPacked(p.Relaxed_Load().ptr()));
......@@ -4231,6 +4273,13 @@ class YoungGenerationMarkingVerifier : public MarkingVerifier {
void VerifyPointers(MaybeObjectSlot start, MaybeObjectSlot end) override {
VerifyPointersImpl(start, end);
}
void VerifyCodePointer(CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// Code slots never appear in new space because CodeDataContainers, the
// only object that can contain code pointers, are always allocated in
// the old space.
UNREACHABLE();
}
void VisitCodeTarget(Code host, RelocInfo* rinfo) override {
Code target = Code::GetCodeFromTargetAddress(rinfo->target_address());
......@@ -4299,6 +4348,11 @@ class YoungGenerationEvacuationVerifier : public EvacuationVerifier {
void VerifyPointers(MaybeObjectSlot start, MaybeObjectSlot end) override {
VerifyPointersImpl(start, end);
}
void VerifyCodePointer(CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// TODO(v8:11880): support external code space.
VerifyPointersImpl(MaybeObjectSlot(slot), MaybeObjectSlot(slot + 1));
}
void VisitCodeTarget(Code host, RelocInfo* rinfo) override {
Code target = Code::GetCodeFromTargetAddress(rinfo->target_address());
VerifyHeapObjectImpl(target);
......@@ -4340,6 +4394,15 @@ class YoungGenerationMarkingVisitor final
VisitPointersImpl(host, start, end);
}
V8_INLINE void VisitCodePointer(HeapObject host,
CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// Code slots never appear in new space because CodeDataContainers, the
// only object that can contain code pointers, are always allocated in
// the old space.
UNREACHABLE();
}
V8_INLINE void VisitPointer(HeapObject host, ObjectSlot slot) final {
VisitPointerImpl(host, slot);
}
......
......@@ -153,6 +153,11 @@ class MarkingVisitorBase : public HeapVisitor<int, ConcreteVisitor> {
MaybeObjectSlot end) final {
VisitPointersImpl(host, start, end);
}
V8_INLINE void VisitCodePointer(HeapObject host, CodeObjectSlot slot) final {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// TODO(v8:11880): support external code space.
VisitPointer(host, MaybeObjectSlot(slot));
}
V8_INLINE void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) final;
V8_INLINE void VisitCodeTarget(Code host, RelocInfo* rinfo) final;
void VisitCustomWeakPointers(HeapObject host, ObjectSlot start,
......
......@@ -93,6 +93,12 @@ class FieldStatsCollector : public ObjectVisitor {
*tagged_fields_count_ += (end - start);
}
V8_INLINE void VisitCodePointer(HeapObject host,
CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
*tagged_fields_count_ += 1;
}
void VisitCodeTarget(Code host, RelocInfo* rinfo) override {
// Code target is most likely encoded as a relative 32-bit offset and not
// as a full tagged value, so there's nothing to count.
......
......@@ -453,6 +453,14 @@ void ScavengeVisitor::VisitPointers(HeapObject host, MaybeObjectSlot start,
return VisitPointersImpl(host, start, end);
}
void ScavengeVisitor::VisitCodePointer(HeapObject host, CodeObjectSlot slot) {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// Code slots never appear in new space because CodeDataContainers, the
// only object that can contain code pointers, are always allocated in
// the old space.
UNREACHABLE();
}
void ScavengeVisitor::VisitCodeTarget(Code host, RelocInfo* rinfo) {
Code target = Code::GetCodeFromTargetAddress(rinfo->target_address());
#ifdef DEBUG
......
......@@ -41,6 +41,14 @@ class IterateAndScavengePromotedObjectsVisitor final : public ObjectVisitor {
VisitPointersImpl(host, start, end);
}
V8_INLINE void VisitCodePointer(HeapObject host, CodeObjectSlot slot) final {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// Code slots never appear in new space because CodeDataContainers, the
// only object that can contain code pointers, are always allocated in
// the old space.
UNREACHABLE();
}
V8_INLINE void VisitCodeTarget(Code host, RelocInfo* rinfo) final {
Code target = Code::GetCodeFromTargetAddress(rinfo->target_address());
HandleSlot(host, FullHeapObjectSlot(&target), target);
......@@ -114,6 +122,13 @@ class IterateAndScavengePromotedObjectsVisitor final : public ObjectVisitor {
HeapObject::cast(target))) {
// We should never try to record off-heap slots.
DCHECK((std::is_same<THeapObjectSlot, HeapObjectSlot>::value));
// Code slots never appear in new space because CodeDataContainers, the
// only object that can contain code pointers, are always allocated in
// the old space.
DCHECK_IMPLIES(V8_EXTERNAL_CODE_SPACE_BOOL,
!MemoryChunk::FromHeapObject(target)->IsFlagSet(
MemoryChunk::IS_EXECUTABLE));
// We cannot call MarkCompactCollector::RecordSlot because that checks
// that the host page is not in young generation, which does not hold
// for pending large pages.
......
......@@ -235,6 +235,7 @@ class ScavengeVisitor final : public NewSpaceVisitor<ScavengeVisitor> {
V8_INLINE void VisitPointers(HeapObject host, MaybeObjectSlot start,
MaybeObjectSlot end) final;
V8_INLINE void VisitCodePointer(HeapObject host, CodeObjectSlot slot) final;
V8_INLINE void VisitCodeTarget(Code host, RelocInfo* rinfo) final;
V8_INLINE void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) final;
......
......@@ -47,15 +47,15 @@ bool Heap::InSpace(Address, AllocationSpace) { return false; }
// static
bool Heap::InOldSpace(Address) { return false; }
// static
bool Heap::InCodeSpace(Address) { return false; }
// static
bool Heap::InReadOnlySpace(Address) { return false; }
// static
bool Heap::IsValidHeapObject(HeapObject) { return false; }
// static
bool Heap::IsValidCodeObject(HeapObject) { return false; }
bool Heap::CollectGarbage() { return false; }
} // namespace third_party_heap
......
......@@ -34,8 +34,6 @@ class Heap {
static bool InOldSpace(Address address);
static bool InCodeSpace(Address address);
static bool InReadOnlySpace(Address address);
static bool InLargeObjectSpace(Address address);
......@@ -44,6 +42,8 @@ class Heap {
static bool IsImmovable(HeapObject object);
static bool IsValidCodeObject(HeapObject object);
void ResetIterator();
HeapObject NextObject();
......
......@@ -77,11 +77,13 @@ class CodeDataContainer : public HeapObject {
// Layout description.
#define CODE_DATA_FIELDS(V) \
/* Strong pointer fields. */ \
V(kCodeOffset, V8_EXTERNAL_CODE_SPACE_BOOL ? kTaggedSize : 0) \
V(kPointerFieldsStrongEndOffset, 0) \
/* Weak pointer fields. */ \
V(kNextCodeLinkOffset, kTaggedSize) \
V(kPointerFieldsWeakEndOffset, 0) \
/* Strong Code pointer fields. */ \
V(kCodeOffset, V8_EXTERNAL_CODE_SPACE_BOOL ? kTaggedSize : 0) \
V(kCodePointerFieldsStrongEndOffset, 0) \
/* Raw data fields. */ \
V(kCodeEntryPointOffset, \
V8_EXTERNAL_CODE_SPACE_BOOL ? kExternalPointerSize : 0) \
......
......@@ -893,9 +893,7 @@ class CodeDataContainer::BodyDescriptor final : public BodyDescriptorBase {
CodeDataContainer::kPointerFieldsWeakEndOffset, v);
if (V8_EXTERNAL_CODE_SPACE_BOOL) {
// TODO(v8:11880): Currently, the |code| field is still compressed and
// the |code_entry_point| field doesn't require custom visitation, so
// nothing to do here yet.
v->VisitCodePointer(obj, obj.RawField(kCodeOffset));
}
}
......
......@@ -110,6 +110,12 @@ class ObjectVisitor {
ObjectSlot end) = 0;
virtual void VisitPointers(HeapObject host, MaybeObjectSlot start,
MaybeObjectSlot end) = 0;
// When V8_EXTERNAL_CODE_SPACE is enabled, visits a Code pointer slot.
// The values may be modified on return.
// Not used when V8_EXTERNAL_CODE_SPACE is not enabled (the Code pointer
// slots are visited as a part of on-heap slot visitation - via
// VisitPointers()).
virtual void VisitCodePointer(HeapObject host, CodeObjectSlot slot) = 0;
// Custom weak pointers must be ignored by the GC but not other
// visitors. They're used for e.g., lists that are recreated after GC. The
......
......@@ -758,6 +758,11 @@ class IndexedReferencesExtractor : public ObjectVisitor {
}
}
void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
VisitPointers(host, MaybeObjectSlot(slot), MaybeObjectSlot(slot + 1));
}
void VisitCodeTarget(Code host, RelocInfo* rinfo) override {
Code target = Code::GetCodeFromTargetAddress(rinfo->target_address());
VisitHeapObjectImpl(target, -1);
......
......@@ -890,6 +890,12 @@ void Serializer::ObjectSerializer::VisitPointers(HeapObject host,
}
}
void Serializer::ObjectSerializer::VisitCodePointer(HeapObject host,
CodeObjectSlot slot) {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
VisitPointers(host, ObjectSlot(slot), ObjectSlot(slot + 1));
}
void Serializer::ObjectSerializer::OutputExternalReference(Address target,
int target_size,
bool sandboxify) {
......
......@@ -425,6 +425,7 @@ class Serializer::ObjectSerializer : public ObjectVisitor {
ObjectSlot end) override;
void VisitPointers(HeapObject host, MaybeObjectSlot start,
MaybeObjectSlot end) override;
void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override;
void VisitEmbeddedPointer(Code host, RelocInfo* target) override;
void VisitExternalReference(Foreign host, Address* p) override;
void VisitExternalReference(Code host, RelocInfo* rinfo) override;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment