Commit 3ac59282 authored by Igor Sheludko's avatar Igor Sheludko Committed by V8 LUCI CQ

[ext-code-space] Introduce ObjectVisitorWithCageBases

... an ObjectVisitor subclass that takes care of caching values of
both the main pointer compression cage base and code cage base
(when the external code space is enabled).

Drive-by: this CL also changes signature of
RelocInfo::target_object_no_host(...) to accept PtrComprCageBase
instead of Isolate*.

Bug: v8:11880
Change-Id: I3fbb382e0a0170e28542bc495d8fecfd24da8a07
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3182231
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/main@{#77088}
parent 14cc79cc
...@@ -3125,6 +3125,7 @@ v8_header_set("v8_internal_headers") { ...@@ -3125,6 +3125,7 @@ v8_header_set("v8_internal_headers") {
"src/objects/transitions.h", "src/objects/transitions.h",
"src/objects/type-hints.h", "src/objects/type-hints.h",
"src/objects/value-serializer.h", "src/objects/value-serializer.h",
"src/objects/visitors-inl.h",
"src/objects/visitors.h", "src/objects/visitors.h",
"src/parsing/expression-scope.h", "src/parsing/expression-scope.h",
"src/parsing/func-name-inferrer.h", "src/parsing/func-name-inferrer.h",
......
...@@ -101,7 +101,7 @@ HeapObject RelocInfo::target_object() { ...@@ -101,7 +101,7 @@ HeapObject RelocInfo::target_object() {
Object(Assembler::target_address_at(pc_, constant_pool_))); Object(Assembler::target_address_at(pc_, constant_pool_)));
} }
HeapObject RelocInfo::target_object_no_host(Isolate* isolate) { HeapObject RelocInfo::target_object_no_host(PtrComprCageBase cage_base) {
return target_object(); return target_object();
} }
......
...@@ -670,10 +670,10 @@ HeapObject RelocInfo::target_object() { ...@@ -670,10 +670,10 @@ HeapObject RelocInfo::target_object() {
} }
} }
HeapObject RelocInfo::target_object_no_host(Isolate* isolate) { HeapObject RelocInfo::target_object_no_host(PtrComprCageBase cage_base) {
if (IsCompressedEmbeddedObject(rmode_)) { if (IsCompressedEmbeddedObject(rmode_)) {
return HeapObject::cast(Object(DecompressTaggedAny( return HeapObject::cast(Object(DecompressTaggedAny(
isolate, cage_base,
Assembler::target_compressed_address_at(pc_, constant_pool_)))); Assembler::target_compressed_address_at(pc_, constant_pool_))));
} else { } else {
return target_object(); return target_object();
......
...@@ -86,7 +86,7 @@ HeapObject RelocInfo::target_object() { ...@@ -86,7 +86,7 @@ HeapObject RelocInfo::target_object() {
return HeapObject::cast(Object(ReadUnalignedValue<Address>(pc_))); return HeapObject::cast(Object(ReadUnalignedValue<Address>(pc_)));
} }
HeapObject RelocInfo::target_object_no_host(Isolate* isolate) { HeapObject RelocInfo::target_object_no_host(PtrComprCageBase cage_base) {
return target_object(); return target_object();
} }
......
...@@ -95,7 +95,7 @@ HeapObject RelocInfo::target_object() { ...@@ -95,7 +95,7 @@ HeapObject RelocInfo::target_object() {
Object(Assembler::target_address_at(pc_, constant_pool_))); Object(Assembler::target_address_at(pc_, constant_pool_)));
} }
HeapObject RelocInfo::target_object_no_host(Isolate* isolate) { HeapObject RelocInfo::target_object_no_host(PtrComprCageBase cage_base) {
return target_object(); return target_object();
} }
......
...@@ -166,7 +166,7 @@ HeapObject RelocInfo::target_object() { ...@@ -166,7 +166,7 @@ HeapObject RelocInfo::target_object() {
Object(Assembler::target_address_at(pc_, constant_pool_))); Object(Assembler::target_address_at(pc_, constant_pool_)));
} }
HeapObject RelocInfo::target_object_no_host(Isolate* isolate) { HeapObject RelocInfo::target_object_no_host(PtrComprCageBase cage_base) {
return target_object(); return target_object();
} }
......
...@@ -145,7 +145,7 @@ HeapObject RelocInfo::target_object() { ...@@ -145,7 +145,7 @@ HeapObject RelocInfo::target_object() {
Object(Assembler::target_address_at(pc_, constant_pool_))); Object(Assembler::target_address_at(pc_, constant_pool_)));
} }
HeapObject RelocInfo::target_object_no_host(Isolate* isolate) { HeapObject RelocInfo::target_object_no_host(PtrComprCageBase cage_base) {
return target_object(); return target_object();
} }
......
...@@ -159,10 +159,10 @@ HeapObject RelocInfo::target_object() { ...@@ -159,10 +159,10 @@ HeapObject RelocInfo::target_object() {
} }
} }
HeapObject RelocInfo::target_object_no_host(Isolate* isolate) { HeapObject RelocInfo::target_object_no_host(PtrComprCageBase cage_base) {
if (IsCompressedEmbeddedObject(rmode_)) { if (IsCompressedEmbeddedObject(rmode_)) {
return HeapObject::cast(Object(DecompressTaggedAny( return HeapObject::cast(Object(DecompressTaggedAny(
isolate, cage_base,
Assembler::target_compressed_address_at(pc_, constant_pool_)))); Assembler::target_compressed_address_at(pc_, constant_pool_))));
} else { } else {
return target_object(); return target_object();
......
...@@ -255,8 +255,9 @@ class RelocInfo { ...@@ -255,8 +255,9 @@ class RelocInfo {
V8_INLINE HeapObject target_object(); V8_INLINE HeapObject target_object();
// In GC operations, we don't have a host_ pointer. Retrieving a target // In GC operations, we don't have a host_ pointer. Retrieving a target
// for COMPRESSED_EMBEDDED_OBJECT mode requires an isolate. // for COMPRESSED_EMBEDDED_OBJECT mode requires a pointer compression cage
V8_INLINE HeapObject target_object_no_host(Isolate* isolate); // base value.
V8_INLINE HeapObject target_object_no_host(PtrComprCageBase cage_base);
V8_INLINE Handle<HeapObject> target_object_handle(Assembler* origin); V8_INLINE Handle<HeapObject> target_object_handle(Assembler* origin);
V8_INLINE void set_target_object( V8_INLINE void set_target_object(
......
...@@ -170,10 +170,10 @@ HeapObject RelocInfo::target_object() { ...@@ -170,10 +170,10 @@ HeapObject RelocInfo::target_object() {
} }
} }
HeapObject RelocInfo::target_object_no_host(Isolate* isolate) { HeapObject RelocInfo::target_object_no_host(PtrComprCageBase cage_base) {
if (IsCompressedEmbeddedObject(rmode_)) { if (IsCompressedEmbeddedObject(rmode_)) {
return HeapObject::cast(Object(DecompressTaggedAny( return HeapObject::cast(Object(DecompressTaggedAny(
isolate, cage_base,
Assembler::target_compressed_address_at(pc_, constant_pool_)))); Assembler::target_compressed_address_at(pc_, constant_pool_))));
} else { } else {
return target_object(); return target_object();
......
...@@ -153,10 +153,10 @@ HeapObject RelocInfo::target_object() { ...@@ -153,10 +153,10 @@ HeapObject RelocInfo::target_object() {
} }
} }
HeapObject RelocInfo::target_object_no_host(Isolate* isolate) { HeapObject RelocInfo::target_object_no_host(PtrComprCageBase cage_base) {
if (IsCompressedEmbeddedObject(rmode_)) { if (IsCompressedEmbeddedObject(rmode_)) {
return HeapObject::cast(Object(DecompressTaggedAny( return HeapObject::cast(Object(DecompressTaggedAny(
isolate, cage_base,
Assembler::target_compressed_address_at(pc_, constant_pool_)))); Assembler::target_compressed_address_at(pc_, constant_pool_))));
} else { } else {
return target_object(); return target_object();
......
...@@ -342,12 +342,12 @@ HeapObject RelocInfo::target_object() { ...@@ -342,12 +342,12 @@ HeapObject RelocInfo::target_object() {
return HeapObject::cast(Object(ReadUnalignedValue<Address>(pc_))); return HeapObject::cast(Object(ReadUnalignedValue<Address>(pc_)));
} }
HeapObject RelocInfo::target_object_no_host(Isolate* isolate) { HeapObject RelocInfo::target_object_no_host(PtrComprCageBase cage_base) {
DCHECK(IsCodeTarget(rmode_) || IsEmbeddedObjectMode(rmode_)); DCHECK(IsCodeTarget(rmode_) || IsEmbeddedObjectMode(rmode_));
if (IsCompressedEmbeddedObject(rmode_)) { if (IsCompressedEmbeddedObject(rmode_)) {
Tagged_t compressed = ReadUnalignedValue<Tagged_t>(pc_); Tagged_t compressed = ReadUnalignedValue<Tagged_t>(pc_);
DCHECK(!HAS_SMI_TAG(compressed)); DCHECK(!HAS_SMI_TAG(compressed));
Object obj(DecompressTaggedPointer(isolate, compressed)); Object obj(DecompressTaggedPointer(cage_base, compressed));
return HeapObject::cast(obj); return HeapObject::cast(obj);
} }
DCHECK(IsFullEmbeddedObject(rmode_) || IsDataEmbeddedObject(rmode_)); DCHECK(IsFullEmbeddedObject(rmode_) || IsDataEmbeddedObject(rmode_));
......
...@@ -1076,6 +1076,8 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory { ...@@ -1076,6 +1076,8 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
return isolate_data()->cage_base(); return isolate_data()->cage_base();
} }
Address code_cage_base() const { return cage_base(); }
// When pointer compression is on, the PtrComprCage used by this // When pointer compression is on, the PtrComprCage used by this
// Isolate. Otherwise nullptr. // Isolate. Otherwise nullptr.
VirtualMemoryCage* GetPtrComprCage() { VirtualMemoryCage* GetPtrComprCage() {
......
...@@ -13,6 +13,11 @@ namespace v8 { ...@@ -13,6 +13,11 @@ namespace v8 {
namespace internal { namespace internal {
Address LocalIsolate::cage_base() const { return isolate_->cage_base(); } Address LocalIsolate::cage_base() const { return isolate_->cage_base(); }
Address LocalIsolate::code_cage_base() const {
return isolate_->code_cage_base();
}
ReadOnlyHeap* LocalIsolate::read_only_heap() const { ReadOnlyHeap* LocalIsolate::read_only_heap() const {
return isolate_->read_only_heap(); return isolate_->read_only_heap();
} }
......
...@@ -58,6 +58,7 @@ class V8_EXPORT_PRIVATE LocalIsolate final : private HiddenLocalFactory { ...@@ -58,6 +58,7 @@ class V8_EXPORT_PRIVATE LocalIsolate final : private HiddenLocalFactory {
LocalHeap* heap() { return &heap_; } LocalHeap* heap() { return &heap_; }
inline Address cage_base() const; inline Address cage_base() const;
inline Address code_cage_base() const;
inline ReadOnlyHeap* read_only_heap() const; inline ReadOnlyHeap* read_only_heap() const;
inline Object root(RootIndex index) const; inline Object root(RootIndex index) const;
inline Handle<Object> root_handle(RootIndex index) const; inline Handle<Object> root_handle(RootIndex index) const;
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "src/objects/js-array-buffer-inl.h" #include "src/objects/js-array-buffer-inl.h"
#include "src/objects/slots-inl.h" #include "src/objects/slots-inl.h"
#include "src/objects/transitions-inl.h" #include "src/objects/transitions-inl.h"
#include "src/objects/visitors.h"
#include "src/utils/utils-inl.h" #include "src/utils/utils-inl.h"
#include "src/utils/utils.h" #include "src/utils/utils.h"
...@@ -168,28 +169,28 @@ class ConcurrentMarkingVisitor final ...@@ -168,28 +169,28 @@ class ConcurrentMarkingVisitor final
private: private:
// Helper class for collecting in-object slot addresses and values. // Helper class for collecting in-object slot addresses and values.
class SlotSnapshottingVisitor final : public ObjectVisitor { class SlotSnapshottingVisitor final : public ObjectVisitorWithCageBases {
public: public:
explicit SlotSnapshottingVisitor(SlotSnapshot* slot_snapshot) explicit SlotSnapshottingVisitor(SlotSnapshot* slot_snapshot,
: slot_snapshot_(slot_snapshot) { PtrComprCageBase cage_base,
PtrComprCageBase code_cage_base)
: ObjectVisitorWithCageBases(cage_base, code_cage_base),
slot_snapshot_(slot_snapshot) {
slot_snapshot_->clear(); slot_snapshot_->clear();
} }
void VisitPointers(HeapObject host, ObjectSlot start, void VisitPointers(HeapObject host, ObjectSlot start,
ObjectSlot end) override { ObjectSlot end) override {
PtrComprCageBase cage_base = GetPtrComprCageBase(host);
for (ObjectSlot p = start; p < end; ++p) { for (ObjectSlot p = start; p < end; ++p) {
Object object = p.Relaxed_Load(cage_base); Object object = p.Relaxed_Load(cage_base());
slot_snapshot_->add(p, object); slot_snapshot_->add(p, object);
} }
} }
void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override { void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL); CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// TODO(v8:11880): support external code space. Object code = slot.Relaxed_Load(code_cage_base());
PtrComprCageBase code_cage_base = GetPtrComprCageBase(host); slot_snapshot_->add(ObjectSlot(slot.address()), code);
Object code = slot.Relaxed_Load(code_cage_base);
slot_snapshot_->add(slot, code);
} }
void VisitPointers(HeapObject host, MaybeObjectSlot start, void VisitPointers(HeapObject host, MaybeObjectSlot start,
...@@ -280,7 +281,8 @@ class ConcurrentMarkingVisitor final ...@@ -280,7 +281,8 @@ class ConcurrentMarkingVisitor final
template <typename T, typename TBodyDescriptor> template <typename T, typename TBodyDescriptor>
const SlotSnapshot& MakeSlotSnapshot(Map map, T object, int size) { const SlotSnapshot& MakeSlotSnapshot(Map map, T object, int size) {
SlotSnapshottingVisitor visitor(&slot_snapshot_); SlotSnapshottingVisitor visitor(&slot_snapshot_, cage_base(),
code_cage_base());
visitor.VisitPointer(object, object.map_slot()); visitor.VisitPointer(object, object.map_slot());
TBodyDescriptor::IterateBody(map, object, size, &visitor); TBodyDescriptor::IterateBody(map, object, size, &visitor);
return slot_snapshot_; return slot_snapshot_;
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include "src/objects/scope-info.h" #include "src/objects/scope-info.h"
#include "src/objects/slots-inl.h" #include "src/objects/slots-inl.h"
#include "src/objects/struct-inl.h" #include "src/objects/struct-inl.h"
#include "src/objects/visitors-inl.h"
#include "src/profiler/heap-profiler.h" #include "src/profiler/heap-profiler.h"
#include "src/strings/string-hasher.h" #include "src/strings/string-hasher.h"
#include "src/utils/ostreams.h" #include "src/utils/ostreams.h"
...@@ -769,6 +770,9 @@ bool Heap::HasDirtyJSFinalizationRegistries() { ...@@ -769,6 +770,9 @@ bool Heap::HasDirtyJSFinalizationRegistries() {
return !dirty_js_finalization_registries_list().IsUndefined(isolate()); return !dirty_js_finalization_registries_list().IsUndefined(isolate());
} }
VerifyPointersVisitor::VerifyPointersVisitor(Heap* heap)
: ObjectVisitorWithCageBases(heap), heap_(heap) {}
AlwaysAllocateScope::AlwaysAllocateScope(Heap* heap) : heap_(heap) { AlwaysAllocateScope::AlwaysAllocateScope(Heap* heap) : heap_(heap) {
heap_->always_allocate_scope_count_++; heap_->always_allocate_scope_count_++;
} }
......
...@@ -3850,14 +3850,14 @@ class SlotCollectingVisitor final : public ObjectVisitor { ...@@ -3850,14 +3850,14 @@ class SlotCollectingVisitor final : public ObjectVisitor {
MaybeObjectSlot slot(int i) { return slots_[i]; } MaybeObjectSlot slot(int i) { return slots_[i]; }
#if V8_EXTERNAL_CODE_SPACE #if V8_EXTERNAL_CODE_SPACE
ObjectSlot code_slot(int i) { return code_slots_[i]; } CodeObjectSlot code_slot(int i) { return code_slots_[i]; }
int number_of_code_slots() { return static_cast<int>(code_slots_.size()); } int number_of_code_slots() { return static_cast<int>(code_slots_.size()); }
#endif #endif
private: private:
std::vector<MaybeObjectSlot> slots_; std::vector<MaybeObjectSlot> slots_;
#if V8_EXTERNAL_CODE_SPACE #if V8_EXTERNAL_CODE_SPACE
std::vector<ObjectSlot> code_slots_; std::vector<CodeObjectSlot> code_slots_;
#endif #endif
}; };
...@@ -4444,11 +4444,11 @@ void Heap::VerifyReadOnlyHeap() { ...@@ -4444,11 +4444,11 @@ void Heap::VerifyReadOnlyHeap() {
read_only_space_->Verify(isolate()); read_only_space_->Verify(isolate());
} }
class SlotVerifyingVisitor : public ObjectVisitor { class SlotVerifyingVisitor : public ObjectVisitorWithCageBases {
public: public:
SlotVerifyingVisitor(std::set<Address>* untyped, SlotVerifyingVisitor(Isolate* isolate, std::set<Address>* untyped,
std::set<std::pair<SlotType, Address>>* typed) std::set<std::pair<SlotType, Address>>* typed)
: untyped_(untyped), typed_(typed) {} : ObjectVisitorWithCageBases(isolate), untyped_(untyped), typed_(typed) {}
virtual bool ShouldHaveBeenRecorded(HeapObject host, MaybeObject target) = 0; virtual bool ShouldHaveBeenRecorded(HeapObject host, MaybeObject target) = 0;
...@@ -4456,7 +4456,8 @@ class SlotVerifyingVisitor : public ObjectVisitor { ...@@ -4456,7 +4456,8 @@ class SlotVerifyingVisitor : public ObjectVisitor {
ObjectSlot end) override { ObjectSlot end) override {
#ifdef DEBUG #ifdef DEBUG
for (ObjectSlot slot = start; slot < end; ++slot) { for (ObjectSlot slot = start; slot < end; ++slot) {
DCHECK(!MapWord::IsPacked((*slot).ptr()) || !HasWeakHeapObjectTag(*slot)); Object obj = slot.load(cage_base());
CHECK(!MapWord::IsPacked(obj.ptr()) || !HasWeakHeapObjectTag(obj));
} }
#endif // DEBUG #endif // DEBUG
VisitPointers(host, MaybeObjectSlot(start), MaybeObjectSlot(end)); VisitPointers(host, MaybeObjectSlot(start), MaybeObjectSlot(end));
...@@ -4465,7 +4466,7 @@ class SlotVerifyingVisitor : public ObjectVisitor { ...@@ -4465,7 +4466,7 @@ class SlotVerifyingVisitor : public ObjectVisitor {
void VisitPointers(HeapObject host, MaybeObjectSlot start, void VisitPointers(HeapObject host, MaybeObjectSlot start,
MaybeObjectSlot end) final { MaybeObjectSlot end) final {
for (MaybeObjectSlot slot = start; slot < end; ++slot) { for (MaybeObjectSlot slot = start; slot < end; ++slot) {
if (ShouldHaveBeenRecorded(host, *slot)) { if (ShouldHaveBeenRecorded(host, slot.load(cage_base()))) {
CHECK_GT(untyped_->count(slot.address()), 0); CHECK_GT(untyped_->count(slot.address()), 0);
} }
} }
...@@ -4473,11 +4474,8 @@ class SlotVerifyingVisitor : public ObjectVisitor { ...@@ -4473,11 +4474,8 @@ class SlotVerifyingVisitor : public ObjectVisitor {
void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override { void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL); CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// TODO(v8:11880): support external code space.
PtrComprCageBase code_cage_base =
GetPtrComprCageBaseFromOnHeapAddress(slot.address());
if (ShouldHaveBeenRecorded( if (ShouldHaveBeenRecorded(
host, MaybeObject::FromObject(slot.load(code_cage_base)))) { host, MaybeObject::FromObject(slot.load(code_cage_base())))) {
CHECK_GT(untyped_->count(slot.address()), 0); CHECK_GT(untyped_->count(slot.address()), 0);
} }
} }
...@@ -4493,7 +4491,7 @@ class SlotVerifyingVisitor : public ObjectVisitor { ...@@ -4493,7 +4491,7 @@ class SlotVerifyingVisitor : public ObjectVisitor {
} }
void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) override { void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) override {
Object target = rinfo->target_object(); Object target = rinfo->target_object_no_host(cage_base());
if (ShouldHaveBeenRecorded(host, MaybeObject::FromObject(target))) { if (ShouldHaveBeenRecorded(host, MaybeObject::FromObject(target))) {
CHECK( CHECK(
InTypedSet(FULL_EMBEDDED_OBJECT_SLOT, rinfo->pc()) || InTypedSet(FULL_EMBEDDED_OBJECT_SLOT, rinfo->pc()) ||
...@@ -4522,10 +4520,10 @@ class SlotVerifyingVisitor : public ObjectVisitor { ...@@ -4522,10 +4520,10 @@ class SlotVerifyingVisitor : public ObjectVisitor {
class OldToNewSlotVerifyingVisitor : public SlotVerifyingVisitor { class OldToNewSlotVerifyingVisitor : public SlotVerifyingVisitor {
public: public:
OldToNewSlotVerifyingVisitor(std::set<Address>* untyped, OldToNewSlotVerifyingVisitor(Isolate* isolate, std::set<Address>* untyped,
std::set<std::pair<SlotType, Address>>* typed, std::set<std::pair<SlotType, Address>>* typed,
EphemeronRememberedSet* ephemeron_remembered_set) EphemeronRememberedSet* ephemeron_remembered_set)
: SlotVerifyingVisitor(untyped, typed), : SlotVerifyingVisitor(isolate, untyped, typed),
ephemeron_remembered_set_(ephemeron_remembered_set) {} ephemeron_remembered_set_(ephemeron_remembered_set) {}
bool ShouldHaveBeenRecorded(HeapObject host, MaybeObject target) override { bool ShouldHaveBeenRecorded(HeapObject host, MaybeObject target) override {
...@@ -4605,7 +4603,8 @@ void Heap::VerifyRememberedSetFor(HeapObject object) { ...@@ -4605,7 +4603,8 @@ void Heap::VerifyRememberedSetFor(HeapObject object) {
std::set<std::pair<SlotType, Address>> typed_old_to_new; std::set<std::pair<SlotType, Address>> typed_old_to_new;
if (!InYoungGeneration(object)) { if (!InYoungGeneration(object)) {
CollectSlots<OLD_TO_NEW>(chunk, start, end, &old_to_new, &typed_old_to_new); CollectSlots<OLD_TO_NEW>(chunk, start, end, &old_to_new, &typed_old_to_new);
OldToNewSlotVerifyingVisitor visitor(&old_to_new, &typed_old_to_new, OldToNewSlotVerifyingVisitor visitor(isolate(), &old_to_new,
&typed_old_to_new,
&this->ephemeron_remembered_set_); &this->ephemeron_remembered_set_);
object.IterateBody(&visitor); object.IterateBody(&visitor);
} }
...@@ -6367,10 +6366,10 @@ class UnreachableObjectsFilter : public HeapObjectsFilter { ...@@ -6367,10 +6366,10 @@ class UnreachableObjectsFilter : public HeapObjectsFilter {
static constexpr intptr_t kLogicalChunkAlignmentMask = static constexpr intptr_t kLogicalChunkAlignmentMask =
kLogicalChunkAlignment - 1; kLogicalChunkAlignment - 1;
class MarkingVisitor : public ObjectVisitor, public RootVisitor { class MarkingVisitor : public ObjectVisitorWithCageBases, public RootVisitor {
public: public:
explicit MarkingVisitor(UnreachableObjectsFilter* filter) explicit MarkingVisitor(UnreachableObjectsFilter* filter)
: filter_(filter) {} : ObjectVisitorWithCageBases(filter->heap_), filter_(filter) {}
void VisitMapPointer(HeapObject object) override { void VisitMapPointer(HeapObject object) override {
MarkHeapObject(Map::unchecked_cast(object.map())); MarkHeapObject(Map::unchecked_cast(object.map()));
...@@ -6387,9 +6386,7 @@ class UnreachableObjectsFilter : public HeapObjectsFilter { ...@@ -6387,9 +6386,7 @@ class UnreachableObjectsFilter : public HeapObjectsFilter {
void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override { void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL); CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// TODO(v8:11880): support external code space. HeapObject code = HeapObject::unchecked_cast(slot.load(code_cage_base()));
PtrComprCageBase code_cage_base = GetPtrComprCageBase(host);
HeapObject code = HeapObject::unchecked_cast(slot.load(code_cage_base));
MarkHeapObject(code); MarkHeapObject(code);
} }
...@@ -6398,7 +6395,7 @@ class UnreachableObjectsFilter : public HeapObjectsFilter { ...@@ -6398,7 +6395,7 @@ class UnreachableObjectsFilter : public HeapObjectsFilter {
MarkHeapObject(target); MarkHeapObject(target);
} }
void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) final { void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) final {
MarkHeapObject(rinfo->target_object()); MarkHeapObject(rinfo->target_object_no_host(cage_base()));
} }
void VisitRootPointers(Root root, const char* description, void VisitRootPointers(Root root, const char* description,
...@@ -6427,9 +6424,8 @@ class UnreachableObjectsFilter : public HeapObjectsFilter { ...@@ -6427,9 +6424,8 @@ class UnreachableObjectsFilter : public HeapObjectsFilter {
template <typename TSlot> template <typename TSlot>
V8_INLINE void MarkPointersImpl(TSlot start, TSlot end) { V8_INLINE void MarkPointersImpl(TSlot start, TSlot end) {
// Treat weak references as strong. // Treat weak references as strong.
Isolate* isolate = filter_->heap_->isolate();
for (TSlot p = start; p < end; ++p) { for (TSlot p = start; p < end; ++p) {
typename TSlot::TObject object = p.load(isolate); typename TSlot::TObject object = p.load(cage_base());
HeapObject heap_object; HeapObject heap_object;
if (object.GetHeapObject(&heap_object)) { if (object.GetHeapObject(&heap_object)) {
MarkHeapObject(heap_object); MarkHeapObject(heap_object);
...@@ -6868,9 +6864,7 @@ void VerifyPointersVisitor::VisitPointers(HeapObject host, ...@@ -6868,9 +6864,7 @@ void VerifyPointersVisitor::VisitPointers(HeapObject host,
void VerifyPointersVisitor::VisitCodePointer(HeapObject host, void VerifyPointersVisitor::VisitCodePointer(HeapObject host,
CodeObjectSlot slot) { CodeObjectSlot slot) {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL); CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// TODO(v8:11880): support external code space. Object maybe_code = slot.load(code_cage_base());
PtrComprCageBase code_cage_base = GetPtrComprCageBase(host);
Object maybe_code = slot.load(code_cage_base);
HeapObject code; HeapObject code;
if (maybe_code.GetHeapObject(&code)) { if (maybe_code.GetHeapObject(&code)) {
VerifyCodeObjectImpl(code); VerifyCodeObjectImpl(code);
...@@ -6895,22 +6889,20 @@ void VerifyPointersVisitor::VisitRootPointers(Root root, ...@@ -6895,22 +6889,20 @@ void VerifyPointersVisitor::VisitRootPointers(Root root,
void VerifyPointersVisitor::VerifyHeapObjectImpl(HeapObject heap_object) { void VerifyPointersVisitor::VerifyHeapObjectImpl(HeapObject heap_object) {
CHECK(IsValidHeapObject(heap_, heap_object)); CHECK(IsValidHeapObject(heap_, heap_object));
CHECK(heap_object.map().IsMap()); CHECK(heap_object.map(cage_base()).IsMap());
} }
void VerifyPointersVisitor::VerifyCodeObjectImpl(HeapObject heap_object) { void VerifyPointersVisitor::VerifyCodeObjectImpl(HeapObject heap_object) {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL); CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
CHECK(IsValidCodeObject(heap_, heap_object)); CHECK(IsValidCodeObject(heap_, heap_object));
PtrComprCageBase cage_base(heap_->isolate()); CHECK(heap_object.map(cage_base()).IsMap());
CHECK(heap_object.map(cage_base).IsMap(cage_base)); CHECK(heap_object.map(cage_base()).instance_type() == CODE_TYPE);
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();
for (TSlot slot = start; slot < end; ++slot) { for (TSlot slot = start; slot < end; ++slot) {
typename TSlot::TObject object = slot.load(isolate); typename TSlot::TObject object = slot.load(cage_base());
HeapObject heap_object; HeapObject heap_object;
if (object.GetHeapObject(&heap_object)) { if (object.GetHeapObject(&heap_object)) {
VerifyHeapObjectImpl(heap_object); VerifyHeapObjectImpl(heap_object);
...@@ -6938,7 +6930,7 @@ void VerifyPointersVisitor::VisitCodeTarget(Code host, RelocInfo* rinfo) { ...@@ -6938,7 +6930,7 @@ void VerifyPointersVisitor::VisitCodeTarget(Code host, RelocInfo* rinfo) {
} }
void VerifyPointersVisitor::VisitEmbeddedPointer(Code host, RelocInfo* rinfo) { void VerifyPointersVisitor::VisitEmbeddedPointer(Code host, RelocInfo* rinfo) {
VerifyHeapObjectImpl(rinfo->target_object()); VerifyHeapObjectImpl(rinfo->target_object_no_host(cage_base()));
} }
void VerifySmisVisitor::VisitRootPointers(Root root, const char* description, void VerifySmisVisitor::VisitRootPointers(Root root, const char* description,
......
...@@ -2658,9 +2658,10 @@ class V8_NODISCARD CodePageMemoryModificationScope { ...@@ -2658,9 +2658,10 @@ class V8_NODISCARD CodePageMemoryModificationScope {
// point into the heap to a location that has a map pointer at its first word. // point into the heap to a location that has a map pointer at its first word.
// Caveat: Heap::Contains is an approximation because it can return true for // Caveat: Heap::Contains is an approximation because it can return true for
// objects in a heap space but above the allocation pointer. // objects in a heap space but above the allocation pointer.
class VerifyPointersVisitor : public ObjectVisitor, public RootVisitor { class VerifyPointersVisitor : public ObjectVisitorWithCageBases,
public RootVisitor {
public: public:
explicit VerifyPointersVisitor(Heap* heap) : heap_(heap) {} V8_INLINE explicit VerifyPointersVisitor(Heap* heap);
void VisitPointers(HeapObject host, ObjectSlot start, void VisitPointers(HeapObject host, ObjectSlot start,
ObjectSlot end) override; ObjectSlot end) override;
void VisitPointers(HeapObject host, MaybeObjectSlot start, void VisitPointers(HeapObject host, MaybeObjectSlot start,
......
This diff is collapsed.
...@@ -20,6 +20,15 @@ namespace internal { ...@@ -20,6 +20,15 @@ namespace internal {
// Visiting strong and weak pointers ========================================= // Visiting strong and weak pointers =========================================
// =========================================================================== // ===========================================================================
template <typename ConcreteVisitor, typename MarkingState>
void MarkingVisitorBase<ConcreteVisitor, MarkingState>::VisitMapPointer(
HeapObject host) {
// Note that we are skipping the recording the slot because map objects
// can't move, so this is safe (see ProcessStrongHeapObject for comparison)
MarkObject(host, HeapObject::cast(
host.map(ObjectVisitorWithCageBases::cage_base())));
}
template <typename ConcreteVisitor, typename MarkingState> template <typename ConcreteVisitor, typename MarkingState>
void MarkingVisitorBase<ConcreteVisitor, MarkingState>::MarkObject( void MarkingVisitorBase<ConcreteVisitor, MarkingState>::MarkObject(
HeapObject host, HeapObject object) { HeapObject host, HeapObject object) {
...@@ -76,7 +85,8 @@ MarkingVisitorBase<ConcreteVisitor, MarkingState>::VisitPointersImpl( ...@@ -76,7 +85,8 @@ MarkingVisitorBase<ConcreteVisitor, MarkingState>::VisitPointersImpl(
HeapObject host, TSlot start, TSlot end) { HeapObject host, TSlot start, TSlot end) {
using THeapObjectSlot = typename TSlot::THeapObjectSlot; using THeapObjectSlot = typename TSlot::THeapObjectSlot;
for (TSlot slot = start; slot < end; ++slot) { for (TSlot slot = start; slot < end; ++slot) {
typename TSlot::TObject object = slot.Relaxed_Load(); typename TSlot::TObject object =
slot.Relaxed_Load(ObjectVisitorWithCageBases::cage_base());
HeapObject heap_object; HeapObject heap_object;
if (object.GetHeapObjectIfStrong(&heap_object)) { if (object.GetHeapObjectIfStrong(&heap_object)) {
// If the reference changes concurrently from strong to weak, the write // If the reference changes concurrently from strong to weak, the write
...@@ -94,9 +104,8 @@ V8_INLINE void ...@@ -94,9 +104,8 @@ V8_INLINE void
MarkingVisitorBase<ConcreteVisitor, MarkingState>::VisitCodePointerImpl( MarkingVisitorBase<ConcreteVisitor, MarkingState>::VisitCodePointerImpl(
HeapObject host, CodeObjectSlot slot) { HeapObject host, CodeObjectSlot slot) {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL); CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// TODO(v8:11880): support external code space. Object object =
PtrComprCageBase code_cage_base = GetPtrComprCageBase(host); slot.Relaxed_Load(ObjectVisitorWithCageBases::code_cage_base());
Object object = slot.Relaxed_Load(code_cage_base);
HeapObject heap_object; HeapObject heap_object;
if (object.GetHeapObjectIfStrong(&heap_object)) { if (object.GetHeapObjectIfStrong(&heap_object)) {
// If the reference changes concurrently from strong to weak, the write // If the reference changes concurrently from strong to weak, the write
...@@ -110,7 +119,8 @@ template <typename ConcreteVisitor, typename MarkingState> ...@@ -110,7 +119,8 @@ template <typename ConcreteVisitor, typename MarkingState>
void MarkingVisitorBase<ConcreteVisitor, MarkingState>::VisitEmbeddedPointer( void MarkingVisitorBase<ConcreteVisitor, MarkingState>::VisitEmbeddedPointer(
Code host, RelocInfo* rinfo) { Code host, RelocInfo* rinfo) {
DCHECK(RelocInfo::IsEmbeddedObjectMode(rinfo->rmode())); DCHECK(RelocInfo::IsEmbeddedObjectMode(rinfo->rmode()));
HeapObject object = rinfo->target_object(); HeapObject object =
rinfo->target_object_no_host(ObjectVisitorWithCageBases::cage_base());
if (!concrete_visitor()->marking_state()->IsBlackOrGrey(object)) { if (!concrete_visitor()->marking_state()->IsBlackOrGrey(object)) {
if (host.IsWeakObject(object)) { if (host.IsWeakObject(object)) {
weak_objects_->weak_objects_in_code.Push(task_id_, weak_objects_->weak_objects_in_code.Push(task_id_,
......
...@@ -107,7 +107,8 @@ class MarkingVisitorBase : public HeapVisitor<int, ConcreteVisitor> { ...@@ -107,7 +107,8 @@ class MarkingVisitorBase : public HeapVisitor<int, ConcreteVisitor> {
unsigned mark_compact_epoch, unsigned mark_compact_epoch,
base::EnumSet<CodeFlushMode> code_flush_mode, base::EnumSet<CodeFlushMode> code_flush_mode,
bool is_embedder_tracing_enabled, bool is_forced_gc) bool is_embedder_tracing_enabled, bool is_forced_gc)
: local_marking_worklists_(local_marking_worklists), : HeapVisitor<int, ConcreteVisitor>(heap),
local_marking_worklists_(local_marking_worklists),
weak_objects_(weak_objects), weak_objects_(weak_objects),
heap_(heap), heap_(heap),
task_id_(task_id), task_id_(task_id),
...@@ -134,11 +135,7 @@ class MarkingVisitorBase : public HeapVisitor<int, ConcreteVisitor> { ...@@ -134,11 +135,7 @@ class MarkingVisitorBase : public HeapVisitor<int, ConcreteVisitor> {
V8_INLINE int VisitWeakCell(Map map, WeakCell object); V8_INLINE int VisitWeakCell(Map map, WeakCell object);
// ObjectVisitor overrides. // ObjectVisitor overrides.
void VisitMapPointer(HeapObject host) final { V8_INLINE void VisitMapPointer(HeapObject host) final;
// Note that we are skipping the recording the slot because map objects
// can't move, so this is safe (see ProcessStrongHeapObject for comparison)
MarkObject(host, HeapObject::cast(host.map()));
}
V8_INLINE void VisitPointer(HeapObject host, ObjectSlot p) final { V8_INLINE void VisitPointer(HeapObject host, ObjectSlot p) final {
VisitPointersImpl(host, p, p + 1); VisitPointersImpl(host, p, p + 1);
} }
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "src/objects/ordered-hash-table.h" #include "src/objects/ordered-hash-table.h"
#include "src/objects/synthetic-module-inl.h" #include "src/objects/synthetic-module-inl.h"
#include "src/objects/torque-defined-classes.h" #include "src/objects/torque-defined-classes.h"
#include "src/objects/visitors.h"
#if V8_ENABLE_WEBASSEMBLY #if V8_ENABLE_WEBASSEMBLY
#include "src/wasm/wasm-objects.h" #include "src/wasm/wasm-objects.h"
...@@ -27,6 +28,19 @@ ...@@ -27,6 +28,19 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
template <typename ResultType, typename ConcreteVisitor>
HeapVisitor<ResultType, ConcreteVisitor>::HeapVisitor(
PtrComprCageBase cage_base, PtrComprCageBase code_cage_base)
: ObjectVisitorWithCageBases(cage_base, code_cage_base) {}
template <typename ResultType, typename ConcreteVisitor>
HeapVisitor<ResultType, ConcreteVisitor>::HeapVisitor(Isolate* isolate)
: ObjectVisitorWithCageBases(isolate) {}
template <typename ResultType, typename ConcreteVisitor>
HeapVisitor<ResultType, ConcreteVisitor>::HeapVisitor(Heap* heap)
: ObjectVisitorWithCageBases(heap) {}
template <typename ResultType, typename ConcreteVisitor> template <typename ResultType, typename ConcreteVisitor>
template <typename T> template <typename T>
T HeapVisitor<ResultType, ConcreteVisitor>::Cast(HeapObject object) { T HeapVisitor<ResultType, ConcreteVisitor>::Cast(HeapObject object) {
...@@ -35,7 +49,7 @@ T HeapVisitor<ResultType, ConcreteVisitor>::Cast(HeapObject object) { ...@@ -35,7 +49,7 @@ T HeapVisitor<ResultType, ConcreteVisitor>::Cast(HeapObject object) {
template <typename ResultType, typename ConcreteVisitor> template <typename ResultType, typename ConcreteVisitor>
ResultType HeapVisitor<ResultType, ConcreteVisitor>::Visit(HeapObject object) { ResultType HeapVisitor<ResultType, ConcreteVisitor>::Visit(HeapObject object) {
return Visit(object.map(), object); return Visit(object.map(cage_base()), object);
} }
template <typename ResultType, typename ConcreteVisitor> template <typename ResultType, typename ConcreteVisitor>
...@@ -172,6 +186,10 @@ ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitFreeSpace( ...@@ -172,6 +186,10 @@ ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitFreeSpace(
return static_cast<ResultType>(object.size(kRelaxedLoad)); return static_cast<ResultType>(object.size(kRelaxedLoad));
} }
template <typename ConcreteVisitor>
NewSpaceVisitor<ConcreteVisitor>::NewSpaceVisitor(Isolate* isolate)
: HeapVisitor<int, ConcreteVisitor>(isolate) {}
template <typename ConcreteVisitor> template <typename ConcreteVisitor>
int NewSpaceVisitor<ConcreteVisitor>::VisitNativeContext(Map map, int NewSpaceVisitor<ConcreteVisitor>::VisitNativeContext(Map map,
NativeContext object) { NativeContext object) {
......
...@@ -78,8 +78,13 @@ TORQUE_VISITOR_ID_LIST(FORWARD_DECLARE) ...@@ -78,8 +78,13 @@ TORQUE_VISITOR_ID_LIST(FORWARD_DECLARE)
// ... // ...
// } // }
template <typename ResultType, typename ConcreteVisitor> template <typename ResultType, typename ConcreteVisitor>
class HeapVisitor : public ObjectVisitor { class HeapVisitor : public ObjectVisitorWithCageBases {
public: public:
inline HeapVisitor(PtrComprCageBase cage_base,
PtrComprCageBase code_cage_base);
inline explicit HeapVisitor(Isolate* isolate);
inline explicit HeapVisitor(Heap* heap);
V8_INLINE ResultType Visit(HeapObject object); V8_INLINE ResultType Visit(HeapObject object);
V8_INLINE ResultType Visit(Map map, HeapObject object); V8_INLINE ResultType Visit(Map map, HeapObject object);
// A callback for visiting the map pointer in the object header. // A callback for visiting the map pointer in the object header.
...@@ -115,6 +120,8 @@ class HeapVisitor : public ObjectVisitor { ...@@ -115,6 +120,8 @@ class HeapVisitor : public ObjectVisitor {
template <typename ConcreteVisitor> template <typename ConcreteVisitor>
class NewSpaceVisitor : public HeapVisitor<int, ConcreteVisitor> { class NewSpaceVisitor : public HeapVisitor<int, ConcreteVisitor> {
public: public:
V8_INLINE NewSpaceVisitor(Isolate* isolate);
V8_INLINE bool ShouldVisitMapPointer() { return false; } V8_INLINE bool ShouldVisitMapPointer() { return false; }
// Special cases for young generation. // Special cases for young generation.
......
...@@ -780,7 +780,8 @@ RootScavengeVisitor::RootScavengeVisitor(Scavenger* scavenger) ...@@ -780,7 +780,8 @@ RootScavengeVisitor::RootScavengeVisitor(Scavenger* scavenger)
: scavenger_(scavenger) {} : scavenger_(scavenger) {}
ScavengeVisitor::ScavengeVisitor(Scavenger* scavenger) ScavengeVisitor::ScavengeVisitor(Scavenger* scavenger)
: scavenger_(scavenger) {} : NewSpaceVisitor<ScavengeVisitor>(scavenger->heap()->isolate()),
scavenger_(scavenger) {}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -152,6 +152,7 @@ class HeapObject : public Object { ...@@ -152,6 +152,7 @@ class HeapObject : public Object {
// during marking GC. // during marking GC.
inline ObjectSlot RawField(int byte_offset) const; inline ObjectSlot RawField(int byte_offset) const;
inline MaybeObjectSlot RawMaybeWeakField(int byte_offset) const; inline MaybeObjectSlot RawMaybeWeakField(int byte_offset) const;
inline CodeObjectSlot RawCodeField(int byte_offset) const;
DECL_CAST(HeapObject) DECL_CAST(HeapObject)
......
...@@ -931,7 +931,7 @@ class CodeDataContainer::BodyDescriptor final : public BodyDescriptorBase { ...@@ -931,7 +931,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) {
v->VisitCodePointer(obj, obj.RawField(kCodeOffset)); v->VisitCodePointer(obj, obj.RawCodeField(kCodeOffset));
} }
} }
......
...@@ -648,6 +648,10 @@ MaybeObjectSlot HeapObject::RawMaybeWeakField(int byte_offset) const { ...@@ -648,6 +648,10 @@ MaybeObjectSlot HeapObject::RawMaybeWeakField(int byte_offset) const {
return MaybeObjectSlot(field_address(byte_offset)); return MaybeObjectSlot(field_address(byte_offset));
} }
CodeObjectSlot HeapObject::RawCodeField(int byte_offset) const {
return CodeObjectSlot(field_address(byte_offset));
}
MapWord MapWord::FromMap(const Map map) { MapWord MapWord::FromMap(const Map map) {
DCHECK(map.is_null() || !MapWord::IsPacked(map.ptr())); DCHECK(map.is_null() || !MapWord::IsPacked(map.ptr()));
#ifdef V8_MAP_PACKING #ifdef V8_MAP_PACKING
......
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_OBJECTS_VISITORS_INL_H_
#define V8_OBJECTS_VISITORS_INL_H_
#include "src/common/globals.h"
#include "src/execution/isolate.h"
#include "src/objects/visitors.h"
namespace v8 {
namespace internal {
ObjectVisitorWithCageBases::ObjectVisitorWithCageBases(
PtrComprCageBase cage_base, PtrComprCageBase code_cage_base)
#if V8_COMPRESS_POINTERS
: cage_base_(cage_base)
#ifdef V8_EXTERNAL_CODE_SPACE
,
code_cage_base_(code_cage_base)
#endif // V8_EXTERNAL_CODE_SPACE
#endif // V8_COMPRESS_POINTERS
{
}
ObjectVisitorWithCageBases::ObjectVisitorWithCageBases(Isolate* isolate)
#if V8_COMPRESS_POINTERS
: ObjectVisitorWithCageBases(PtrComprCageBase(isolate->cage_base()),
PtrComprCageBase(isolate->code_cage_base()))
#else
: ObjectVisitorWithCageBases(PtrComprCageBase(), PtrComprCageBase())
#endif // V8_COMPRESS_POINTERS
{
}
ObjectVisitorWithCageBases::ObjectVisitorWithCageBases(Heap* heap)
: ObjectVisitorWithCageBases(Isolate::FromHeap(heap)) {}
} // namespace internal
} // namespace v8
#endif // V8_OBJECTS_VISITORS_INL_H_
...@@ -174,6 +174,44 @@ class ObjectVisitor { ...@@ -174,6 +174,44 @@ class ObjectVisitor {
virtual void VisitMapPointer(HeapObject host) { UNREACHABLE(); } virtual void VisitMapPointer(HeapObject host) { UNREACHABLE(); }
}; };
// Helper version of ObjectVisitor that also takes care of caching base values
// of the main pointer compression cage and for the code cage.
class ObjectVisitorWithCageBases : public ObjectVisitor {
public:
inline ObjectVisitorWithCageBases(PtrComprCageBase cage_base,
PtrComprCageBase code_cage_base);
inline explicit ObjectVisitorWithCageBases(Isolate* isolate);
inline explicit ObjectVisitorWithCageBases(Heap* heap);
// The pointer compression cage base value used for decompression of all
// tagged values except references to Code objects.
PtrComprCageBase cage_base() const {
#if V8_COMPRESS_POINTERS
return cage_base_;
#else
return PtrComprCageBase{};
#endif // V8_COMPRESS_POINTERS
}
// The pointer compression cage base value used for decompression of
// references to Code objects.
PtrComprCageBase code_cage_base() const {
#if V8_EXTERNAL_CODE_SPACE
return code_cage_base_;
#else
return cage_base();
#endif // V8_EXTERNAL_CODE_SPACE
}
private:
#if V8_COMPRESS_POINTERS
const PtrComprCageBase cage_base_;
#ifdef V8_EXTERNAL_CODE_SPACE
const PtrComprCageBase code_cage_base_;
#endif // V8_EXTERNAL_CODE_SPACE
#endif // V8_COMPRESS_POINTERS
};
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
......
...@@ -718,11 +718,12 @@ int V8HeapExplorer::EstimateObjectsCount() { ...@@ -718,11 +718,12 @@ int V8HeapExplorer::EstimateObjectsCount() {
return objects_count; return objects_count;
} }
class IndexedReferencesExtractor : public ObjectVisitor { class IndexedReferencesExtractor : public ObjectVisitorWithCageBases {
public: public:
IndexedReferencesExtractor(V8HeapExplorer* generator, HeapObject parent_obj, IndexedReferencesExtractor(V8HeapExplorer* generator, HeapObject parent_obj,
HeapEntry* parent) HeapEntry* parent)
: generator_(generator), : ObjectVisitorWithCageBases(generator->isolate()),
generator_(generator),
parent_obj_(parent_obj), parent_obj_(parent_obj),
parent_start_(parent_obj_.RawMaybeWeakField(0)), parent_start_(parent_obj_.RawMaybeWeakField(0)),
parent_end_(parent_obj_.RawMaybeWeakField(parent_obj_.Size())), parent_end_(parent_obj_.RawMaybeWeakField(parent_obj_.Size())),
...@@ -733,10 +734,7 @@ class IndexedReferencesExtractor : public ObjectVisitor { ...@@ -733,10 +734,7 @@ class IndexedReferencesExtractor : public ObjectVisitor {
VisitPointers(host, MaybeObjectSlot(start), MaybeObjectSlot(end)); VisitPointers(host, MaybeObjectSlot(start), MaybeObjectSlot(end));
} }
void VisitMapPointer(HeapObject object) override { void VisitMapPointer(HeapObject object) override {
// TODO(v8:11880): support external code space (here object could be Code, VisitSlotImpl(cage_base(), object.map_slot());
// so the V8 heap cage_base must be used here).
PtrComprCageBase cage_base = GetPtrComprCageBase(object);
VisitSlotImpl(cage_base, object.map_slot());
} }
void VisitPointers(HeapObject host, MaybeObjectSlot start, void VisitPointers(HeapObject host, MaybeObjectSlot start,
MaybeObjectSlot end) override { MaybeObjectSlot end) override {
...@@ -744,17 +742,14 @@ class IndexedReferencesExtractor : public ObjectVisitor { ...@@ -744,17 +742,14 @@ class IndexedReferencesExtractor : public ObjectVisitor {
// all the slots must point inside the object. // all the slots must point inside the object.
CHECK_LE(parent_start_, start); CHECK_LE(parent_start_, start);
CHECK_LE(end, parent_end_); CHECK_LE(end, parent_end_);
PtrComprCageBase cage_base = GetPtrComprCageBase(host);
for (MaybeObjectSlot slot = start; slot < end; ++slot) { for (MaybeObjectSlot slot = start; slot < end; ++slot) {
VisitSlotImpl(cage_base, slot); VisitSlotImpl(cage_base(), slot);
} }
} }
void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override { void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL); CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// TODO(v8:11880): support external code space. VisitSlotImpl(code_cage_base(), slot);
PtrComprCageBase code_cage_base = GetPtrComprCageBase(host);
VisitSlotImpl(code_cage_base, slot);
} }
void VisitCodeTarget(Code host, RelocInfo* rinfo) override { void VisitCodeTarget(Code host, RelocInfo* rinfo) override {
...@@ -763,7 +758,7 @@ class IndexedReferencesExtractor : public ObjectVisitor { ...@@ -763,7 +758,7 @@ class IndexedReferencesExtractor : public ObjectVisitor {
} }
void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) override { void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) override {
HeapObject object = rinfo->target_object(); HeapObject object = rinfo->target_object_no_host(cage_base());
if (host.IsWeakObject(object)) { if (host.IsWeakObject(object)) {
generator_->SetWeakReference(parent_, next_index_++, object, {}); generator_->SetWeakReference(parent_, next_index_++, object, {});
} else { } else {
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "include/v8-profiler.h" #include "include/v8-profiler.h"
#include "src/base/platform/time.h" #include "src/base/platform/time.h"
#include "src/execution/isolate.h"
#include "src/objects/fixed-array.h" #include "src/objects/fixed-array.h"
#include "src/objects/hash-table.h" #include "src/objects/hash-table.h"
#include "src/objects/heap-object.h" #include "src/objects/heap-object.h"
...@@ -349,6 +350,8 @@ class V8_EXPORT_PRIVATE V8HeapExplorer : public HeapEntriesAllocator { ...@@ -349,6 +350,8 @@ class V8_EXPORT_PRIVATE V8HeapExplorer : public HeapEntriesAllocator {
V8HeapExplorer(const V8HeapExplorer&) = delete; V8HeapExplorer(const V8HeapExplorer&) = delete;
V8HeapExplorer& operator=(const V8HeapExplorer&) = delete; V8HeapExplorer& operator=(const V8HeapExplorer&) = delete;
V8_INLINE Isolate* isolate() { return Isolate::FromHeap(heap_); }
HeapEntry* AllocateEntry(HeapThing ptr) override; HeapEntry* AllocateEntry(HeapThing ptr) override;
HeapEntry* AllocateEntry(Smi smi) override; HeapEntry* AllocateEntry(Smi smi) override;
int EstimateObjectsCount(); int EstimateObjectsCount();
......
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