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 { ...@@ -750,11 +750,15 @@ struct SlotTraits {
using TMaybeObjectSlot = CompressedMaybeObjectSlot; using TMaybeObjectSlot = CompressedMaybeObjectSlot;
using THeapObjectSlot = CompressedHeapObjectSlot; using THeapObjectSlot = CompressedHeapObjectSlot;
using TOffHeapObjectSlot = OffHeapCompressedObjectSlot; using TOffHeapObjectSlot = OffHeapCompressedObjectSlot;
// TODO(v8:11880): switch to OffHeapCompressedObjectSlot.
using TCodeObjectSlot = CompressedObjectSlot;
#else #else
using TObjectSlot = FullObjectSlot; using TObjectSlot = FullObjectSlot;
using TMaybeObjectSlot = FullMaybeObjectSlot; using TMaybeObjectSlot = FullMaybeObjectSlot;
using THeapObjectSlot = FullHeapObjectSlot; using THeapObjectSlot = FullHeapObjectSlot;
using TOffHeapObjectSlot = OffHeapFullObjectSlot; using TOffHeapObjectSlot = OffHeapFullObjectSlot;
// TODO(v8:11880): switch to OffHeapFullObjectSlot.
using TCodeObjectSlot = FullObjectSlot;
#endif #endif
}; };
...@@ -776,6 +780,12 @@ using HeapObjectSlot = SlotTraits::THeapObjectSlot; ...@@ -776,6 +780,12 @@ using HeapObjectSlot = SlotTraits::THeapObjectSlot;
// off-heap. // off-heap.
using OffHeapObjectSlot = SlotTraits::TOffHeapObjectSlot; 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 WeakSlotCallback = bool (*)(FullObjectSlot pointer);
using WeakSlotCallbackWithHeap = bool (*)(Heap* heap, FullObjectSlot pointer); using WeakSlotCallbackWithHeap = bool (*)(Heap* heap, FullObjectSlot pointer);
......
...@@ -311,7 +311,7 @@ void HeapObject::VerifyHeapPointer(Isolate* isolate, Object p) { ...@@ -311,7 +311,7 @@ void HeapObject::VerifyHeapPointer(Isolate* isolate, Object p) {
// static // static
void HeapObject::VerifyCodePointer(Isolate* isolate, Object p) { void HeapObject::VerifyCodePointer(Isolate* isolate, Object p) {
CHECK(p.IsHeapObject()); CHECK(p.IsHeapObject());
CHECK(isolate->heap()->InCodeSpace(HeapObject::cast(p))); CHECK(IsValidCodeObject(isolate->heap(), HeapObject::cast(p)));
CHECK(HeapObject::cast(p).IsCode()); CHECK(HeapObject::cast(p).IsCode());
} }
......
...@@ -33,11 +33,20 @@ class V8_EXPORT_PRIVATE CombinedHeapObjectIterator final { ...@@ -33,11 +33,20 @@ class V8_EXPORT_PRIVATE CombinedHeapObjectIterator final {
V8_WARN_UNUSED_RESULT inline bool IsValidHeapObject(Heap* heap, V8_WARN_UNUSED_RESULT inline bool IsValidHeapObject(Heap* heap,
HeapObject object) { HeapObject object) {
if (V8_ENABLE_THIRD_PARTY_HEAP_BOOL) if (V8_ENABLE_THIRD_PARTY_HEAP_BOOL) {
return third_party_heap::Heap::IsValidHeapObject(object); return third_party_heap::Heap::IsValidHeapObject(object);
else }
return ReadOnlyHeap::Contains(object) || heap->Contains(object) || return ReadOnlyHeap::Contains(object) || heap->Contains(object) ||
heap->SharedHeapContains(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 } // namespace internal
......
...@@ -183,6 +183,12 @@ class ConcurrentMarkingVisitor final ...@@ -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, void VisitPointers(HeapObject host, MaybeObjectSlot start,
MaybeObjectSlot end) override { MaybeObjectSlot end) override {
// This should never happen, because we don't use snapshotting for objects // This should never happen, because we don't use snapshotting for objects
......
...@@ -492,13 +492,6 @@ bool Heap::InOldSpace(Object object) { ...@@ -492,13 +492,6 @@ bool Heap::InOldSpace(Object object) {
return old_space_->Contains(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 // static
Heap* Heap::FromWritableHeapObject(HeapObject obj) { Heap* Heap::FromWritableHeapObject(HeapObject obj) {
if (V8_ENABLE_THIRD_PARTY_HEAP_BOOL) { if (V8_ENABLE_THIRD_PARTY_HEAP_BOOL) {
......
...@@ -3828,6 +3828,11 @@ class SlotCollectingVisitor final : public ObjectVisitor { ...@@ -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 VisitCodeTarget(Code host, RelocInfo* rinfo) final { UNREACHABLE(); }
void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) override { void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) override {
...@@ -4278,6 +4283,18 @@ bool Heap::Contains(HeapObject value) const { ...@@ -4278,6 +4283,18 @@ bool Heap::Contains(HeapObject value) const {
(new_lo_space_ && new_lo_space_->Contains(value))); (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 { bool Heap::SharedHeapContains(HeapObject value) const {
if (shared_old_space_) if (shared_old_space_)
return shared_old_space_->Contains(value) || return shared_old_space_->Contains(value) ||
...@@ -4433,6 +4450,12 @@ class SlotVerifyingVisitor : public ObjectVisitor { ...@@ -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 { void VisitCodeTarget(Code host, RelocInfo* rinfo) override {
Object target = Code::GetCodeFromTargetAddress(rinfo->target_address()); Object target = Code::GetCodeFromTargetAddress(rinfo->target_address());
if (ShouldHaveBeenRecorded(host, MaybeObject::FromObject(target))) { if (ShouldHaveBeenRecorded(host, MaybeObject::FromObject(target))) {
...@@ -6303,6 +6326,12 @@ class UnreachableObjectsFilter : public HeapObjectsFilter { ...@@ -6303,6 +6326,12 @@ class UnreachableObjectsFilter : public HeapObjectsFilter {
MarkPointers(start, end); 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 { void VisitCodeTarget(Code host, RelocInfo* rinfo) final {
Code target = Code::GetCodeFromTargetAddress(rinfo->target_address()); Code target = Code::GetCodeFromTargetAddress(rinfo->target_address());
MarkHeapObject(target); MarkHeapObject(target);
...@@ -6775,6 +6804,20 @@ void VerifyPointersVisitor::VisitPointers(HeapObject host, ...@@ -6775,6 +6804,20 @@ void VerifyPointersVisitor::VisitPointers(HeapObject host,
VerifyPointers(host, start, end); 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, void VerifyPointersVisitor::VisitRootPointers(Root root,
const char* description, const char* description,
FullObjectSlot start, FullObjectSlot start,
...@@ -6794,6 +6837,14 @@ void VerifyPointersVisitor::VerifyHeapObjectImpl(HeapObject heap_object) { ...@@ -6794,6 +6837,14 @@ void VerifyPointersVisitor::VerifyHeapObjectImpl(HeapObject heap_object) {
CHECK(heap_object.map().IsMap()); 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> template <typename TSlot>
void VerifyPointersVisitor::VerifyPointersImpl(TSlot start, TSlot end) { void VerifyPointersVisitor::VerifyPointersImpl(TSlot start, TSlot end) {
Isolate* isolate = heap_->isolate(); Isolate* isolate = heap_->isolate();
......
...@@ -1270,13 +1270,13 @@ class Heap { ...@@ -1270,13 +1270,13 @@ class Heap {
// Returns whether the object resides in old space. // Returns whether the object resides in old space.
inline bool InOldSpace(Object object); 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 // Checks whether an address/object is in the non-read-only heap (including
// auxiliary area and unused area). Use IsValidHeapObject if checking both // auxiliary area and unused area). Use IsValidHeapObject if checking both
// heaps is required. // heaps is required.
V8_EXPORT_PRIVATE bool Contains(HeapObject value) const; 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 // Checks whether an address/object is in the non-read-only heap (including
// auxiliary area and unused area). Use IsValidHeapObject if checking both // auxiliary area and unused area). Use IsValidHeapObject if checking both
...@@ -2650,6 +2650,7 @@ class VerifyPointersVisitor : public ObjectVisitor, public RootVisitor { ...@@ -2650,6 +2650,7 @@ class VerifyPointersVisitor : public ObjectVisitor, public RootVisitor {
ObjectSlot end) override; ObjectSlot end) override;
void VisitPointers(HeapObject host, MaybeObjectSlot start, void VisitPointers(HeapObject host, MaybeObjectSlot start,
MaybeObjectSlot end) override; MaybeObjectSlot end) override;
void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override;
void VisitCodeTarget(Code host, RelocInfo* rinfo) override; void VisitCodeTarget(Code host, RelocInfo* rinfo) override;
void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) override; void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) override;
...@@ -2661,6 +2662,7 @@ class VerifyPointersVisitor : public ObjectVisitor, public RootVisitor { ...@@ -2661,6 +2662,7 @@ class VerifyPointersVisitor : public ObjectVisitor, public RootVisitor {
protected: protected:
V8_INLINE void VerifyHeapObjectImpl(HeapObject heap_object); V8_INLINE void VerifyHeapObjectImpl(HeapObject heap_object);
V8_INLINE void VerifyCodeObjectImpl(HeapObject heap_object);
template <typename TSlot> template <typename TSlot>
V8_INLINE void VerifyPointersImpl(TSlot start, TSlot end); V8_INLINE void VerifyPointersImpl(TSlot start, TSlot end);
......
...@@ -88,6 +88,7 @@ class MarkingVerifier : public ObjectVisitor, public RootVisitor { ...@@ -88,6 +88,7 @@ class MarkingVerifier : public ObjectVisitor, public RootVisitor {
virtual void VerifyMap(Map map) = 0; virtual void VerifyMap(Map map) = 0;
virtual void VerifyPointers(ObjectSlot start, ObjectSlot end) = 0; virtual void VerifyPointers(ObjectSlot start, ObjectSlot end) = 0;
virtual void VerifyPointers(MaybeObjectSlot start, MaybeObjectSlot 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 void VerifyRootPointers(FullObjectSlot start, FullObjectSlot end) = 0;
virtual bool IsMarked(HeapObject object) = 0; virtual bool IsMarked(HeapObject object) = 0;
...@@ -104,6 +105,11 @@ class MarkingVerifier : public ObjectVisitor, public RootVisitor { ...@@ -104,6 +105,11 @@ class MarkingVerifier : public ObjectVisitor, public RootVisitor {
VerifyPointers(start, end); 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, void VisitRootPointers(Root root, const char* description,
FullObjectSlot start, FullObjectSlot end) override { FullObjectSlot start, FullObjectSlot end) override {
VerifyRootPointers(start, end); VerifyRootPointers(start, end);
...@@ -227,6 +233,12 @@ class FullMarkingVerifier : public MarkingVerifier { ...@@ -227,6 +233,12 @@ class FullMarkingVerifier : public MarkingVerifier {
VerifyPointersImpl(start, end); 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 { void VerifyRootPointers(FullObjectSlot start, FullObjectSlot end) override {
VerifyPointersImpl(start, end); VerifyPointersImpl(start, end);
} }
...@@ -281,6 +293,11 @@ class EvacuationVerifier : public ObjectVisitor, public RootVisitor { ...@@ -281,6 +293,11 @@ class EvacuationVerifier : public ObjectVisitor, public RootVisitor {
VerifyPointers(start, end); 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, void VisitRootPointers(Root root, const char* description,
FullObjectSlot start, FullObjectSlot end) override { FullObjectSlot start, FullObjectSlot end) override {
VerifyRootPointers(start, end); VerifyRootPointers(start, end);
...@@ -296,6 +313,7 @@ class EvacuationVerifier : public ObjectVisitor, public RootVisitor { ...@@ -296,6 +313,7 @@ class EvacuationVerifier : public ObjectVisitor, public RootVisitor {
virtual void VerifyMap(Map map) = 0; virtual void VerifyMap(Map map) = 0;
virtual void VerifyPointers(ObjectSlot start, ObjectSlot end) = 0; virtual void VerifyPointers(ObjectSlot start, ObjectSlot end) = 0;
virtual void VerifyPointers(MaybeObjectSlot start, MaybeObjectSlot 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 void VerifyRootPointers(FullObjectSlot start, FullObjectSlot end) = 0;
void VerifyRoots(); void VerifyRoots();
...@@ -385,6 +403,11 @@ class FullEvacuationVerifier : public EvacuationVerifier { ...@@ -385,6 +403,11 @@ class FullEvacuationVerifier : public EvacuationVerifier {
void VerifyPointers(MaybeObjectSlot start, MaybeObjectSlot end) override { void VerifyPointers(MaybeObjectSlot start, MaybeObjectSlot end) override {
VerifyPointersImpl(start, end); 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 { void VisitCodeTarget(Code host, RelocInfo* rinfo) override {
Code target = Code::GetCodeFromTargetAddress(rinfo->target_address()); Code target = Code::GetCodeFromTargetAddress(rinfo->target_address());
VerifyHeapObjectImpl(target); VerifyHeapObjectImpl(target);
...@@ -1046,6 +1069,13 @@ class MarkCompactCollector::CustomRootBodyMarkingVisitor final ...@@ -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, void VisitPointers(HeapObject host, MaybeObjectSlot start,
MaybeObjectSlot end) final { MaybeObjectSlot end) final {
// At the moment, custom roots cannot contain weak pointers. // At the moment, custom roots cannot contain weak pointers.
...@@ -1213,6 +1243,12 @@ class RecordMigratedSlotVisitor : public ObjectVisitor { ...@@ -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, inline void VisitEphemeron(HeapObject host, int index, ObjectSlot key,
ObjectSlot value) override { ObjectSlot value) override {
DCHECK(host.IsEphemeronHashTable()); DCHECK(host.IsEphemeronHashTable());
...@@ -2816,6 +2852,12 @@ class PointersUpdatingVisitor : public ObjectVisitor, public RootVisitor { ...@@ -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, void VisitRootPointer(Root root, const char* description,
FullObjectSlot p) override { FullObjectSlot p) override {
DCHECK(!MapWord::IsPacked(p.Relaxed_Load().ptr())); DCHECK(!MapWord::IsPacked(p.Relaxed_Load().ptr()));
...@@ -4231,6 +4273,13 @@ class YoungGenerationMarkingVerifier : public MarkingVerifier { ...@@ -4231,6 +4273,13 @@ class YoungGenerationMarkingVerifier : public MarkingVerifier {
void VerifyPointers(MaybeObjectSlot start, MaybeObjectSlot end) override { void VerifyPointers(MaybeObjectSlot start, MaybeObjectSlot end) override {
VerifyPointersImpl(start, end); 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 { void VisitCodeTarget(Code host, RelocInfo* rinfo) override {
Code target = Code::GetCodeFromTargetAddress(rinfo->target_address()); Code target = Code::GetCodeFromTargetAddress(rinfo->target_address());
...@@ -4299,6 +4348,11 @@ class YoungGenerationEvacuationVerifier : public EvacuationVerifier { ...@@ -4299,6 +4348,11 @@ class YoungGenerationEvacuationVerifier : public EvacuationVerifier {
void VerifyPointers(MaybeObjectSlot start, MaybeObjectSlot end) override { void VerifyPointers(MaybeObjectSlot start, MaybeObjectSlot end) override {
VerifyPointersImpl(start, end); 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 { void VisitCodeTarget(Code host, RelocInfo* rinfo) override {
Code target = Code::GetCodeFromTargetAddress(rinfo->target_address()); Code target = Code::GetCodeFromTargetAddress(rinfo->target_address());
VerifyHeapObjectImpl(target); VerifyHeapObjectImpl(target);
...@@ -4340,6 +4394,15 @@ class YoungGenerationMarkingVisitor final ...@@ -4340,6 +4394,15 @@ class YoungGenerationMarkingVisitor final
VisitPointersImpl(host, start, end); 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 { V8_INLINE void VisitPointer(HeapObject host, ObjectSlot slot) final {
VisitPointerImpl(host, slot); VisitPointerImpl(host, slot);
} }
......
...@@ -153,6 +153,11 @@ class MarkingVisitorBase : public HeapVisitor<int, ConcreteVisitor> { ...@@ -153,6 +153,11 @@ class MarkingVisitorBase : public HeapVisitor<int, ConcreteVisitor> {
MaybeObjectSlot end) final { MaybeObjectSlot end) final {
VisitPointersImpl(host, start, end); 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 VisitEmbeddedPointer(Code host, RelocInfo* rinfo) final;
V8_INLINE void VisitCodeTarget(Code host, RelocInfo* rinfo) final; V8_INLINE void VisitCodeTarget(Code host, RelocInfo* rinfo) final;
void VisitCustomWeakPointers(HeapObject host, ObjectSlot start, void VisitCustomWeakPointers(HeapObject host, ObjectSlot start,
......
...@@ -93,6 +93,12 @@ class FieldStatsCollector : public ObjectVisitor { ...@@ -93,6 +93,12 @@ class FieldStatsCollector : public ObjectVisitor {
*tagged_fields_count_ += (end - start); *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 { void VisitCodeTarget(Code host, RelocInfo* rinfo) override {
// Code target is most likely encoded as a relative 32-bit offset and not // 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. // as a full tagged value, so there's nothing to count.
......
...@@ -453,6 +453,14 @@ void ScavengeVisitor::VisitPointers(HeapObject host, MaybeObjectSlot start, ...@@ -453,6 +453,14 @@ void ScavengeVisitor::VisitPointers(HeapObject host, MaybeObjectSlot start,
return VisitPointersImpl(host, start, end); 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) { void ScavengeVisitor::VisitCodeTarget(Code host, RelocInfo* rinfo) {
Code target = Code::GetCodeFromTargetAddress(rinfo->target_address()); Code target = Code::GetCodeFromTargetAddress(rinfo->target_address());
#ifdef DEBUG #ifdef DEBUG
......
...@@ -41,6 +41,14 @@ class IterateAndScavengePromotedObjectsVisitor final : public ObjectVisitor { ...@@ -41,6 +41,14 @@ class IterateAndScavengePromotedObjectsVisitor final : public ObjectVisitor {
VisitPointersImpl(host, start, end); 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 { V8_INLINE void VisitCodeTarget(Code host, RelocInfo* rinfo) final {
Code target = Code::GetCodeFromTargetAddress(rinfo->target_address()); Code target = Code::GetCodeFromTargetAddress(rinfo->target_address());
HandleSlot(host, FullHeapObjectSlot(&target), target); HandleSlot(host, FullHeapObjectSlot(&target), target);
...@@ -114,6 +122,13 @@ class IterateAndScavengePromotedObjectsVisitor final : public ObjectVisitor { ...@@ -114,6 +122,13 @@ class IterateAndScavengePromotedObjectsVisitor final : public ObjectVisitor {
HeapObject::cast(target))) { HeapObject::cast(target))) {
// We should never try to record off-heap slots. // We should never try to record off-heap slots.
DCHECK((std::is_same<THeapObjectSlot, HeapObjectSlot>::value)); 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 // We cannot call MarkCompactCollector::RecordSlot because that checks
// that the host page is not in young generation, which does not hold // that the host page is not in young generation, which does not hold
// for pending large pages. // for pending large pages.
......
...@@ -235,6 +235,7 @@ class ScavengeVisitor final : public NewSpaceVisitor<ScavengeVisitor> { ...@@ -235,6 +235,7 @@ class ScavengeVisitor final : public NewSpaceVisitor<ScavengeVisitor> {
V8_INLINE void VisitPointers(HeapObject host, MaybeObjectSlot start, V8_INLINE void VisitPointers(HeapObject host, MaybeObjectSlot start,
MaybeObjectSlot end) final; MaybeObjectSlot end) final;
V8_INLINE void VisitCodePointer(HeapObject host, CodeObjectSlot slot) final;
V8_INLINE void VisitCodeTarget(Code host, RelocInfo* rinfo) final; V8_INLINE void VisitCodeTarget(Code host, RelocInfo* rinfo) final;
V8_INLINE void VisitEmbeddedPointer(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; } ...@@ -47,15 +47,15 @@ bool Heap::InSpace(Address, AllocationSpace) { return false; }
// static // static
bool Heap::InOldSpace(Address) { return false; } bool Heap::InOldSpace(Address) { return false; }
// static
bool Heap::InCodeSpace(Address) { return false; }
// static // static
bool Heap::InReadOnlySpace(Address) { return false; } bool Heap::InReadOnlySpace(Address) { return false; }
// static // static
bool Heap::IsValidHeapObject(HeapObject) { return false; } bool Heap::IsValidHeapObject(HeapObject) { return false; }
// static
bool Heap::IsValidCodeObject(HeapObject) { return false; }
bool Heap::CollectGarbage() { return false; } bool Heap::CollectGarbage() { return false; }
} // namespace third_party_heap } // namespace third_party_heap
......
...@@ -34,8 +34,6 @@ class Heap { ...@@ -34,8 +34,6 @@ class Heap {
static bool InOldSpace(Address address); static bool InOldSpace(Address address);
static bool InCodeSpace(Address address);
static bool InReadOnlySpace(Address address); static bool InReadOnlySpace(Address address);
static bool InLargeObjectSpace(Address address); static bool InLargeObjectSpace(Address address);
...@@ -44,6 +42,8 @@ class Heap { ...@@ -44,6 +42,8 @@ class Heap {
static bool IsImmovable(HeapObject object); static bool IsImmovable(HeapObject object);
static bool IsValidCodeObject(HeapObject object);
void ResetIterator(); void ResetIterator();
HeapObject NextObject(); HeapObject NextObject();
......
...@@ -77,11 +77,13 @@ class CodeDataContainer : public HeapObject { ...@@ -77,11 +77,13 @@ class CodeDataContainer : public HeapObject {
// Layout description. // Layout description.
#define CODE_DATA_FIELDS(V) \ #define CODE_DATA_FIELDS(V) \
/* Strong pointer fields. */ \ /* Strong pointer fields. */ \
V(kCodeOffset, V8_EXTERNAL_CODE_SPACE_BOOL ? kTaggedSize : 0) \
V(kPointerFieldsStrongEndOffset, 0) \ V(kPointerFieldsStrongEndOffset, 0) \
/* Weak pointer fields. */ \ /* Weak pointer fields. */ \
V(kNextCodeLinkOffset, kTaggedSize) \ V(kNextCodeLinkOffset, kTaggedSize) \
V(kPointerFieldsWeakEndOffset, 0) \ V(kPointerFieldsWeakEndOffset, 0) \
/* Strong Code pointer fields. */ \
V(kCodeOffset, V8_EXTERNAL_CODE_SPACE_BOOL ? kTaggedSize : 0) \
V(kCodePointerFieldsStrongEndOffset, 0) \
/* Raw data fields. */ \ /* Raw data fields. */ \
V(kCodeEntryPointOffset, \ V(kCodeEntryPointOffset, \
V8_EXTERNAL_CODE_SPACE_BOOL ? kExternalPointerSize : 0) \ V8_EXTERNAL_CODE_SPACE_BOOL ? kExternalPointerSize : 0) \
......
...@@ -893,9 +893,7 @@ class CodeDataContainer::BodyDescriptor final : public BodyDescriptorBase { ...@@ -893,9 +893,7 @@ class CodeDataContainer::BodyDescriptor final : public BodyDescriptorBase {
CodeDataContainer::kPointerFieldsWeakEndOffset, v); CodeDataContainer::kPointerFieldsWeakEndOffset, v);
if (V8_EXTERNAL_CODE_SPACE_BOOL) { if (V8_EXTERNAL_CODE_SPACE_BOOL) {
// TODO(v8:11880): Currently, the |code| field is still compressed and v->VisitCodePointer(obj, obj.RawField(kCodeOffset));
// the |code_entry_point| field doesn't require custom visitation, so
// nothing to do here yet.
} }
} }
......
...@@ -110,6 +110,12 @@ class ObjectVisitor { ...@@ -110,6 +110,12 @@ class ObjectVisitor {
ObjectSlot end) = 0; ObjectSlot end) = 0;
virtual void VisitPointers(HeapObject host, MaybeObjectSlot start, virtual void VisitPointers(HeapObject host, MaybeObjectSlot start,
MaybeObjectSlot end) = 0; 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 // 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 // visitors. They're used for e.g., lists that are recreated after GC. The
......
...@@ -758,6 +758,11 @@ class IndexedReferencesExtractor : public ObjectVisitor { ...@@ -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 { void VisitCodeTarget(Code host, RelocInfo* rinfo) override {
Code target = Code::GetCodeFromTargetAddress(rinfo->target_address()); Code target = Code::GetCodeFromTargetAddress(rinfo->target_address());
VisitHeapObjectImpl(target, -1); VisitHeapObjectImpl(target, -1);
......
...@@ -890,6 +890,12 @@ void Serializer::ObjectSerializer::VisitPointers(HeapObject host, ...@@ -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, void Serializer::ObjectSerializer::OutputExternalReference(Address target,
int target_size, int target_size,
bool sandboxify) { bool sandboxify) {
......
...@@ -425,6 +425,7 @@ class Serializer::ObjectSerializer : public ObjectVisitor { ...@@ -425,6 +425,7 @@ class Serializer::ObjectSerializer : public ObjectVisitor {
ObjectSlot end) override; ObjectSlot end) override;
void VisitPointers(HeapObject host, MaybeObjectSlot start, void VisitPointers(HeapObject host, MaybeObjectSlot start,
MaybeObjectSlot end) override; MaybeObjectSlot end) override;
void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override;
void VisitEmbeddedPointer(Code host, RelocInfo* target) override; void VisitEmbeddedPointer(Code host, RelocInfo* target) override;
void VisitExternalReference(Foreign host, Address* p) override; void VisitExternalReference(Foreign host, Address* p) override;
void VisitExternalReference(Code host, RelocInfo* rinfo) 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