[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: Camillo Bruni <cbruni@chromium.org>
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/main@{#77088}
This commit is contained in:
Igor Sheludko 2021-09-27 14:07:55 +02:00 committed by V8 LUCI CQ
parent 14cc79ccf5
commit 3ac59282af
32 changed files with 275 additions and 157 deletions

View File

@ -3125,6 +3125,7 @@ v8_header_set("v8_internal_headers") {
"src/objects/transitions.h",
"src/objects/type-hints.h",
"src/objects/value-serializer.h",
"src/objects/visitors-inl.h",
"src/objects/visitors.h",
"src/parsing/expression-scope.h",
"src/parsing/func-name-inferrer.h",

View File

@ -101,7 +101,7 @@ HeapObject RelocInfo::target_object() {
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();
}

View File

@ -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_)) {
return HeapObject::cast(Object(DecompressTaggedAny(
isolate,
cage_base,
Assembler::target_compressed_address_at(pc_, constant_pool_))));
} else {
return target_object();

View File

@ -86,7 +86,7 @@ HeapObject RelocInfo::target_object() {
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();
}

View File

@ -95,7 +95,7 @@ HeapObject RelocInfo::target_object() {
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();
}

View File

@ -166,7 +166,7 @@ HeapObject RelocInfo::target_object() {
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();
}

View File

@ -145,7 +145,7 @@ HeapObject RelocInfo::target_object() {
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();
}

View File

@ -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_)) {
return HeapObject::cast(Object(DecompressTaggedAny(
isolate,
cage_base,
Assembler::target_compressed_address_at(pc_, constant_pool_))));
} else {
return target_object();

View File

@ -255,8 +255,9 @@ class RelocInfo {
V8_INLINE HeapObject target_object();
// In GC operations, we don't have a host_ pointer. Retrieving a target
// for COMPRESSED_EMBEDDED_OBJECT mode requires an isolate.
V8_INLINE HeapObject target_object_no_host(Isolate* isolate);
// for COMPRESSED_EMBEDDED_OBJECT mode requires a pointer compression cage
// base value.
V8_INLINE HeapObject target_object_no_host(PtrComprCageBase cage_base);
V8_INLINE Handle<HeapObject> target_object_handle(Assembler* origin);
V8_INLINE void set_target_object(

View File

@ -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_)) {
return HeapObject::cast(Object(DecompressTaggedAny(
isolate,
cage_base,
Assembler::target_compressed_address_at(pc_, constant_pool_))));
} else {
return target_object();

View File

@ -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_)) {
return HeapObject::cast(Object(DecompressTaggedAny(
isolate,
cage_base,
Assembler::target_compressed_address_at(pc_, constant_pool_))));
} else {
return target_object();

View File

@ -342,12 +342,12 @@ HeapObject RelocInfo::target_object() {
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_));
if (IsCompressedEmbeddedObject(rmode_)) {
Tagged_t compressed = ReadUnalignedValue<Tagged_t>(pc_);
DCHECK(!HAS_SMI_TAG(compressed));
Object obj(DecompressTaggedPointer(isolate, compressed));
Object obj(DecompressTaggedPointer(cage_base, compressed));
return HeapObject::cast(obj);
}
DCHECK(IsFullEmbeddedObject(rmode_) || IsDataEmbeddedObject(rmode_));

View File

@ -1076,6 +1076,8 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
return isolate_data()->cage_base();
}
Address code_cage_base() const { return cage_base(); }
// When pointer compression is on, the PtrComprCage used by this
// Isolate. Otherwise nullptr.
VirtualMemoryCage* GetPtrComprCage() {

View File

@ -13,6 +13,11 @@ namespace v8 {
namespace internal {
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 {
return isolate_->read_only_heap();
}

View File

@ -58,6 +58,7 @@ class V8_EXPORT_PRIVATE LocalIsolate final : private HiddenLocalFactory {
LocalHeap* heap() { return &heap_; }
inline Address cage_base() const;
inline Address code_cage_base() const;
inline ReadOnlyHeap* read_only_heap() const;
inline Object root(RootIndex index) const;
inline Handle<Object> root_handle(RootIndex index) const;

View File

@ -31,6 +31,7 @@
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/slots-inl.h"
#include "src/objects/transitions-inl.h"
#include "src/objects/visitors.h"
#include "src/utils/utils-inl.h"
#include "src/utils/utils.h"
@ -168,28 +169,28 @@ class ConcurrentMarkingVisitor final
private:
// Helper class for collecting in-object slot addresses and values.
class SlotSnapshottingVisitor final : public ObjectVisitor {
class SlotSnapshottingVisitor final : public ObjectVisitorWithCageBases {
public:
explicit SlotSnapshottingVisitor(SlotSnapshot* slot_snapshot)
: slot_snapshot_(slot_snapshot) {
explicit SlotSnapshottingVisitor(SlotSnapshot* slot_snapshot,
PtrComprCageBase cage_base,
PtrComprCageBase code_cage_base)
: ObjectVisitorWithCageBases(cage_base, code_cage_base),
slot_snapshot_(slot_snapshot) {
slot_snapshot_->clear();
}
void VisitPointers(HeapObject host, ObjectSlot start,
ObjectSlot end) override {
PtrComprCageBase cage_base = GetPtrComprCageBase(host);
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);
}
}
void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// TODO(v8:11880): support external code space.
PtrComprCageBase code_cage_base = GetPtrComprCageBase(host);
Object code = slot.Relaxed_Load(code_cage_base);
slot_snapshot_->add(slot, code);
Object code = slot.Relaxed_Load(code_cage_base());
slot_snapshot_->add(ObjectSlot(slot.address()), code);
}
void VisitPointers(HeapObject host, MaybeObjectSlot start,
@ -280,7 +281,8 @@ class ConcurrentMarkingVisitor final
template <typename T, typename TBodyDescriptor>
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());
TBodyDescriptor::IterateBody(map, object, size, &visitor);
return slot_snapshot_;

View File

@ -43,6 +43,7 @@
#include "src/objects/scope-info.h"
#include "src/objects/slots-inl.h"
#include "src/objects/struct-inl.h"
#include "src/objects/visitors-inl.h"
#include "src/profiler/heap-profiler.h"
#include "src/strings/string-hasher.h"
#include "src/utils/ostreams.h"
@ -769,6 +770,9 @@ bool Heap::HasDirtyJSFinalizationRegistries() {
return !dirty_js_finalization_registries_list().IsUndefined(isolate());
}
VerifyPointersVisitor::VerifyPointersVisitor(Heap* heap)
: ObjectVisitorWithCageBases(heap), heap_(heap) {}
AlwaysAllocateScope::AlwaysAllocateScope(Heap* heap) : heap_(heap) {
heap_->always_allocate_scope_count_++;
}

View File

@ -3850,14 +3850,14 @@ class SlotCollectingVisitor final : public ObjectVisitor {
MaybeObjectSlot slot(int i) { return slots_[i]; }
#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()); }
#endif
private:
std::vector<MaybeObjectSlot> slots_;
#if V8_EXTERNAL_CODE_SPACE
std::vector<ObjectSlot> code_slots_;
std::vector<CodeObjectSlot> code_slots_;
#endif
};
@ -4444,11 +4444,11 @@ void Heap::VerifyReadOnlyHeap() {
read_only_space_->Verify(isolate());
}
class SlotVerifyingVisitor : public ObjectVisitor {
class SlotVerifyingVisitor : public ObjectVisitorWithCageBases {
public:
SlotVerifyingVisitor(std::set<Address>* untyped,
SlotVerifyingVisitor(Isolate* isolate, std::set<Address>* untyped,
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;
@ -4456,7 +4456,8 @@ class SlotVerifyingVisitor : public ObjectVisitor {
ObjectSlot end) override {
#ifdef DEBUG
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
VisitPointers(host, MaybeObjectSlot(start), MaybeObjectSlot(end));
@ -4465,7 +4466,7 @@ class SlotVerifyingVisitor : public ObjectVisitor {
void VisitPointers(HeapObject host, MaybeObjectSlot start,
MaybeObjectSlot end) final {
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);
}
}
@ -4473,11 +4474,8 @@ class SlotVerifyingVisitor : public ObjectVisitor {
void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// TODO(v8:11880): support external code space.
PtrComprCageBase code_cage_base =
GetPtrComprCageBaseFromOnHeapAddress(slot.address());
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);
}
}
@ -4493,7 +4491,7 @@ class SlotVerifyingVisitor : public ObjectVisitor {
}
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))) {
CHECK(
InTypedSet(FULL_EMBEDDED_OBJECT_SLOT, rinfo->pc()) ||
@ -4522,10 +4520,10 @@ class SlotVerifyingVisitor : public ObjectVisitor {
class OldToNewSlotVerifyingVisitor : public SlotVerifyingVisitor {
public:
OldToNewSlotVerifyingVisitor(std::set<Address>* untyped,
OldToNewSlotVerifyingVisitor(Isolate* isolate, std::set<Address>* untyped,
std::set<std::pair<SlotType, Address>>* typed,
EphemeronRememberedSet* ephemeron_remembered_set)
: SlotVerifyingVisitor(untyped, typed),
: SlotVerifyingVisitor(isolate, untyped, typed),
ephemeron_remembered_set_(ephemeron_remembered_set) {}
bool ShouldHaveBeenRecorded(HeapObject host, MaybeObject target) override {
@ -4605,7 +4603,8 @@ void Heap::VerifyRememberedSetFor(HeapObject object) {
std::set<std::pair<SlotType, Address>> typed_old_to_new;
if (!InYoungGeneration(object)) {
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_);
object.IterateBody(&visitor);
}
@ -6367,10 +6366,10 @@ class UnreachableObjectsFilter : public HeapObjectsFilter {
static constexpr intptr_t kLogicalChunkAlignmentMask =
kLogicalChunkAlignment - 1;
class MarkingVisitor : public ObjectVisitor, public RootVisitor {
class MarkingVisitor : public ObjectVisitorWithCageBases, public RootVisitor {
public:
explicit MarkingVisitor(UnreachableObjectsFilter* filter)
: filter_(filter) {}
: ObjectVisitorWithCageBases(filter->heap_), filter_(filter) {}
void VisitMapPointer(HeapObject object) override {
MarkHeapObject(Map::unchecked_cast(object.map()));
@ -6387,9 +6386,7 @@ class UnreachableObjectsFilter : public HeapObjectsFilter {
void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// TODO(v8:11880): support external code space.
PtrComprCageBase code_cage_base = GetPtrComprCageBase(host);
HeapObject code = HeapObject::unchecked_cast(slot.load(code_cage_base));
HeapObject code = HeapObject::unchecked_cast(slot.load(code_cage_base()));
MarkHeapObject(code);
}
@ -6398,7 +6395,7 @@ class UnreachableObjectsFilter : public HeapObjectsFilter {
MarkHeapObject(target);
}
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,
@ -6427,9 +6424,8 @@ class UnreachableObjectsFilter : public HeapObjectsFilter {
template <typename TSlot>
V8_INLINE void MarkPointersImpl(TSlot start, TSlot end) {
// Treat weak references as strong.
Isolate* isolate = filter_->heap_->isolate();
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;
if (object.GetHeapObject(&heap_object)) {
MarkHeapObject(heap_object);
@ -6868,9 +6864,7 @@ void VerifyPointersVisitor::VisitPointers(HeapObject host,
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);
Object maybe_code = slot.load(code_cage_base());
HeapObject code;
if (maybe_code.GetHeapObject(&code)) {
VerifyCodeObjectImpl(code);
@ -6895,22 +6889,20 @@ void VerifyPointersVisitor::VisitRootPointers(Root root,
void VerifyPointersVisitor::VerifyHeapObjectImpl(HeapObject 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) {
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);
CHECK(heap_object.map(cage_base()).IsMap());
CHECK(heap_object.map(cage_base()).instance_type() == CODE_TYPE);
}
template <typename TSlot>
void VerifyPointersVisitor::VerifyPointersImpl(TSlot start, TSlot end) {
Isolate* isolate = heap_->isolate();
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;
if (object.GetHeapObject(&heap_object)) {
VerifyHeapObjectImpl(heap_object);
@ -6938,7 +6930,7 @@ void VerifyPointersVisitor::VisitCodeTarget(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,

View File

@ -2658,9 +2658,10 @@ class V8_NODISCARD CodePageMemoryModificationScope {
// 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
// objects in a heap space but above the allocation pointer.
class VerifyPointersVisitor : public ObjectVisitor, public RootVisitor {
class VerifyPointersVisitor : public ObjectVisitorWithCageBases,
public RootVisitor {
public:
explicit VerifyPointersVisitor(Heap* heap) : heap_(heap) {}
V8_INLINE explicit VerifyPointersVisitor(Heap* heap);
void VisitPointers(HeapObject host, ObjectSlot start,
ObjectSlot end) override;
void VisitPointers(HeapObject host, MaybeObjectSlot start,

View File

@ -52,6 +52,7 @@
#include "src/objects/slots-inl.h"
#include "src/objects/smi.h"
#include "src/objects/transitions-inl.h"
#include "src/objects/visitors.h"
#include "src/tasks/cancelable-task.h"
#include "src/tracing/tracing-category-observer.h"
#include "src/utils/utils-inl.h"
@ -75,12 +76,13 @@ STATIC_ASSERT(Heap::kMinObjectSizeInTaggedWords >= 2);
#ifdef VERIFY_HEAP
namespace {
class MarkingVerifier : public ObjectVisitor, public RootVisitor {
class MarkingVerifier : public ObjectVisitorWithCageBases, public RootVisitor {
public:
virtual void Run() = 0;
protected:
explicit MarkingVerifier(Heap* heap) : heap_(heap) {}
explicit MarkingVerifier(Heap* heap)
: ObjectVisitorWithCageBases(heap), heap_(heap) {}
virtual ConcurrentBitmap<AccessMode::NON_ATOMIC>* bitmap(
const MemoryChunk* chunk) = 0;
@ -235,10 +237,7 @@ class FullMarkingVerifier : public MarkingVerifier {
void VerifyCodePointer(CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// TODO(v8:11880): support external code space.
PtrComprCageBase code_cage_base =
GetPtrComprCageBaseFromOnHeapAddress(slot.address());
Object maybe_code = slot.load(code_cage_base);
Object maybe_code = slot.load(code_cage_base());
HeapObject code;
if (maybe_code.GetHeapObject(&code)) {
VerifyHeapObjectImpl(code);
@ -256,9 +255,9 @@ class FullMarkingVerifier : public MarkingVerifier {
void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) override {
DCHECK(RelocInfo::IsEmbeddedObjectMode(rinfo->rmode()));
if (!host.IsWeakObject(rinfo->target_object())) {
HeapObject object = rinfo->target_object();
VerifyHeapObjectImpl(object);
HeapObject target_object = rinfo->target_object_no_host(cage_base());
if (!host.IsWeakObject(target_object)) {
VerifyHeapObjectImpl(target_object);
}
}
@ -273,10 +272,8 @@ class FullMarkingVerifier : public MarkingVerifier {
template <typename TSlot>
V8_INLINE void VerifyPointersImpl(TSlot start, TSlot end) {
PtrComprCageBase cage_base =
GetPtrComprCageBaseFromOnHeapAddress(start.address());
for (TSlot slot = start; slot < end; ++slot) {
typename TSlot::TObject object = slot.load(cage_base);
typename TSlot::TObject object = slot.load(cage_base());
HeapObject heap_object;
if (object.GetHeapObjectIfStrong(&heap_object)) {
VerifyHeapObjectImpl(heap_object);
@ -287,7 +284,8 @@ class FullMarkingVerifier : public MarkingVerifier {
MarkCompactCollector::NonAtomicMarkingState* marking_state_;
};
class EvacuationVerifier : public ObjectVisitor, public RootVisitor {
class EvacuationVerifier : public ObjectVisitorWithCageBases,
public RootVisitor {
public:
virtual void Run() = 0;
@ -314,7 +312,8 @@ class EvacuationVerifier : public ObjectVisitor, public RootVisitor {
void VisitMapPointer(HeapObject object) override { VerifyMap(object.map()); }
protected:
explicit EvacuationVerifier(Heap* heap) : heap_(heap) {}
explicit EvacuationVerifier(Heap* heap)
: ObjectVisitorWithCageBases(heap), heap_(heap) {}
inline Heap* heap() { return heap_; }
@ -396,10 +395,8 @@ class FullEvacuationVerifier : public EvacuationVerifier {
template <typename TSlot>
void VerifyPointersImpl(TSlot start, TSlot end) {
PtrComprCageBase cage_base =
GetPtrComprCageBaseFromOnHeapAddress(start.address());
for (TSlot current = start; current < end; ++current) {
typename TSlot::TObject object = current.load(cage_base);
typename TSlot::TObject object = current.load(cage_base());
HeapObject heap_object;
if (object.GetHeapObjectIfStrong(&heap_object)) {
VerifyHeapObjectImpl(heap_object);
@ -415,10 +412,7 @@ class FullEvacuationVerifier : public EvacuationVerifier {
}
void VerifyCodePointer(CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// TODO(v8:11880): support external code space.
PtrComprCageBase code_cage_base =
GetPtrComprCageBaseFromOnHeapAddress(slot.address());
Object maybe_code = slot.load(code_cage_base);
Object maybe_code = slot.load(code_cage_base());
HeapObject code;
if (maybe_code.GetHeapObject(&code)) {
VerifyHeapObjectImpl(code);
@ -429,7 +423,7 @@ class FullEvacuationVerifier : public EvacuationVerifier {
VerifyHeapObjectImpl(target);
}
void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) override {
VerifyHeapObjectImpl(rinfo->target_object());
VerifyHeapObjectImpl(rinfo->target_object_no_host(cage_base()));
}
void VerifyRootPointers(FullObjectSlot start, FullObjectSlot end) override {
VerifyPointersImpl(start, end);
@ -1066,24 +1060,26 @@ class MarkCompactCollector::RootMarkingVisitor final : public RootVisitor {
// keep alive its embedded pointers (which would otherwise be dropped).
// - Prefix of the string table.
class MarkCompactCollector::CustomRootBodyMarkingVisitor final
: public ObjectVisitor {
: public ObjectVisitorWithCageBases {
public:
explicit CustomRootBodyMarkingVisitor(MarkCompactCollector* collector)
: collector_(collector) {}
: ObjectVisitorWithCageBases(collector->isolate()),
collector_(collector) {}
void VisitPointer(HeapObject host, ObjectSlot p) final {
MarkObject(host, *p);
MarkObject(host, p.load(cage_base()));
}
void VisitMapPointer(HeapObject host) final { MarkObject(host, host.map()); }
void VisitMapPointer(HeapObject host) final {
MarkObject(host, host.map(cage_base()));
}
void VisitPointers(HeapObject host, ObjectSlot start, ObjectSlot end) final {
PtrComprCageBase cage_base = GetPtrComprCageBase(host);
for (ObjectSlot p = start; p < end; ++p) {
// The map slot should be handled in VisitMapPointer.
DCHECK_NE(host.map_slot(), p);
DCHECK(!HasWeakHeapObjectTag(p.load(cage_base)));
MarkObject(host, p.load(cage_base));
DCHECK(!HasWeakHeapObjectTag(p.load(cage_base())));
MarkObject(host, p.load(cage_base()));
}
}
@ -1106,7 +1102,7 @@ class MarkCompactCollector::CustomRootBodyMarkingVisitor final
MarkObject(host, target);
}
void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) override {
MarkObject(host, rinfo->target_object());
MarkObject(host, rinfo->target_object_no_host(cage_base()));
}
private:
@ -1227,22 +1223,24 @@ class MarkCompactWeakObjectRetainer : public WeakObjectRetainer {
MarkCompactCollector::NonAtomicMarkingState* marking_state_;
};
class RecordMigratedSlotVisitor : public ObjectVisitor {
class RecordMigratedSlotVisitor : public ObjectVisitorWithCageBases {
public:
explicit RecordMigratedSlotVisitor(
MarkCompactCollector* collector,
EphemeronRememberedSet* ephemeron_remembered_set)
: collector_(collector),
: ObjectVisitorWithCageBases(collector->isolate()),
collector_(collector),
ephemeron_remembered_set_(ephemeron_remembered_set) {}
inline void VisitPointer(HeapObject host, ObjectSlot p) final {
DCHECK(!HasWeakHeapObjectTag(*p));
RecordMigratedSlot(host, MaybeObject::FromObject(*p), p.address());
DCHECK(!HasWeakHeapObjectTag(p.load(cage_base())));
RecordMigratedSlot(host, MaybeObject::FromObject(p.load(cage_base())),
p.address());
}
inline void VisitPointer(HeapObject host, MaybeObjectSlot p) final {
DCHECK(!MapWord::IsPacked(p.Relaxed_Load().ptr()));
RecordMigratedSlot(host, *p, p.address());
DCHECK(!MapWord::IsPacked(p.Relaxed_Load(cage_base()).ptr()));
RecordMigratedSlot(host, p.load(cage_base()), p.address());
}
inline void VisitPointers(HeapObject host, ObjectSlot start,
@ -1265,10 +1263,8 @@ class RecordMigratedSlotVisitor : public ObjectVisitor {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// This code is similar to the implementation of VisitPointer() modulo
// new kind of slot.
DCHECK(!HasWeakHeapObjectTag(*slot));
// TODO(v8:11880): support external code space.
PtrComprCageBase code_cage_base = GetPtrComprCageBase(host);
Object code = slot.load(code_cage_base);
DCHECK(!HasWeakHeapObjectTag(slot.load(code_cage_base())));
Object code = slot.load(code_cage_base());
RecordMigratedSlot(host, MaybeObject::FromObject(code), slot.address());
}
@ -1302,7 +1298,8 @@ class RecordMigratedSlotVisitor : public ObjectVisitor {
inline void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) override {
DCHECK_EQ(host, rinfo->host());
DCHECK(RelocInfo::IsEmbeddedObjectMode(rinfo->rmode()));
HeapObject object = HeapObject::cast(rinfo->target_object());
HeapObject object =
HeapObject::cast(rinfo->target_object_no_host(cage_base()));
GenerationalBarrierForCode(host, rinfo, object);
collector_->RecordRelocSlot(host, rinfo, object);
}
@ -2920,50 +2917,50 @@ static inline SlotCallbackResult UpdateStrongCodeSlot(
// Visitor for updating root pointers and to-space pointers.
// It does not expect to encounter pointers to dead objects.
class PointersUpdatingVisitor : public ObjectVisitor, public RootVisitor {
class PointersUpdatingVisitor : public ObjectVisitorWithCageBases,
public RootVisitor {
public:
explicit PointersUpdatingVisitor(Heap* heap) : cage_base_(heap->isolate()) {}
explicit PointersUpdatingVisitor(Heap* heap)
: ObjectVisitorWithCageBases(heap) {}
void VisitPointer(HeapObject host, ObjectSlot p) override {
UpdateStrongSlotInternal(cage_base_, p);
UpdateStrongSlotInternal(cage_base(), p);
}
void VisitPointer(HeapObject host, MaybeObjectSlot p) override {
UpdateSlotInternal(cage_base_, p);
UpdateSlotInternal(cage_base(), p);
}
void VisitPointers(HeapObject host, ObjectSlot start,
ObjectSlot end) override {
for (ObjectSlot p = start; p < end; ++p) {
UpdateStrongSlotInternal(cage_base_, p);
UpdateStrongSlotInternal(cage_base(), p);
}
}
void VisitPointers(HeapObject host, MaybeObjectSlot start,
MaybeObjectSlot end) final {
for (MaybeObjectSlot p = start; p < end; ++p) {
UpdateSlotInternal(cage_base_, p);
UpdateSlotInternal(cage_base(), p);
}
}
void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// TODO(v8:11880): support external code space.
PtrComprCageBase code_cage_base = cage_base_;
UpdateStrongCodeSlot<AccessMode::NON_ATOMIC>(host, cage_base_,
code_cage_base, slot);
UpdateStrongCodeSlot<AccessMode::NON_ATOMIC>(host, cage_base(),
code_cage_base(), slot);
}
void VisitRootPointer(Root root, const char* description,
FullObjectSlot p) override {
DCHECK(!MapWord::IsPacked(p.Relaxed_Load().ptr()));
UpdateRootSlotInternal(cage_base_, p);
UpdateRootSlotInternal(cage_base(), p);
}
void VisitRootPointers(Root root, const char* description,
FullObjectSlot start, FullObjectSlot end) override {
for (FullObjectSlot p = start; p < end; ++p) {
UpdateRootSlotInternal(cage_base_, p);
UpdateRootSlotInternal(cage_base(), p);
}
}
@ -2971,7 +2968,7 @@ class PointersUpdatingVisitor : public ObjectVisitor, public RootVisitor {
OffHeapObjectSlot start,
OffHeapObjectSlot end) override {
for (OffHeapObjectSlot p = start; p < end; ++p) {
UpdateRootSlotInternal(cage_base_, p);
UpdateRootSlotInternal(cage_base(), p);
}
}
@ -3010,8 +3007,6 @@ class PointersUpdatingVisitor : public ObjectVisitor, public RootVisitor {
PtrComprCageBase cage_base, MaybeObjectSlot slot) {
return UpdateSlot<AccessMode::NON_ATOMIC>(cage_base, slot);
}
PtrComprCageBase cage_base_;
};
static String UpdateReferenceInExternalStringTableEntry(Heap* heap,
@ -4456,10 +4451,8 @@ class YoungGenerationEvacuationVerifier : public EvacuationVerifier {
template <typename TSlot>
void VerifyPointersImpl(TSlot start, TSlot end) {
PtrComprCageBase cage_base =
GetPtrComprCageBaseFromOnHeapAddress(start.address());
for (TSlot current = start; current < end; ++current) {
typename TSlot::TObject object = current.load(cage_base);
typename TSlot::TObject object = current.load(cage_base());
HeapObject heap_object;
if (object.GetHeapObject(&heap_object)) {
VerifyHeapObjectImpl(heap_object);
@ -4475,10 +4468,7 @@ class YoungGenerationEvacuationVerifier : public EvacuationVerifier {
}
void VerifyCodePointer(CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// TODO(v8:11880): support external code space.
PtrComprCageBase code_cage_base =
GetPtrComprCageBaseFromOnHeapAddress(slot.address());
Code code = Code::unchecked_cast(slot.load(code_cage_base));
Code code = Code::unchecked_cast(slot.load(code_cage_base()));
VerifyHeapObjectImpl(code);
}
void VisitCodeTarget(Code host, RelocInfo* rinfo) override {
@ -4486,7 +4476,7 @@ class YoungGenerationEvacuationVerifier : public EvacuationVerifier {
VerifyHeapObjectImpl(target);
}
void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) override {
VerifyHeapObjectImpl(rinfo->target_object());
VerifyHeapObjectImpl(rinfo->target_object_no_host(cage_base()));
}
void VerifyRootPointers(FullObjectSlot start, FullObjectSlot end) override {
VerifyPointersImpl(start, end);
@ -4508,9 +4498,11 @@ class YoungGenerationMarkingVisitor final
: public NewSpaceVisitor<YoungGenerationMarkingVisitor> {
public:
YoungGenerationMarkingVisitor(
MinorMarkCompactCollector::MarkingState* marking_state,
Isolate* isolate, MinorMarkCompactCollector::MarkingState* marking_state,
MinorMarkCompactCollector::MarkingWorklist* global_worklist, int task_id)
: worklist_(global_worklist, task_id), marking_state_(marking_state) {}
: NewSpaceVisitor(isolate),
worklist_(global_worklist, task_id),
marking_state_(marking_state) {}
V8_INLINE void VisitPointers(HeapObject host, ObjectSlot start,
ObjectSlot end) final {
@ -4594,7 +4586,7 @@ MinorMarkCompactCollector::MinorMarkCompactCollector(Heap* heap)
: MarkCompactCollectorBase(heap),
worklist_(new MinorMarkCompactCollector::MarkingWorklist()),
main_marking_visitor_(new YoungGenerationMarkingVisitor(
marking_state(), worklist_, kMainMarker)),
heap->isolate(), marking_state(), worklist_, kMainMarker)),
page_parallel_job_semaphore_(0) {
static_assert(
kNumMarkers <= MinorMarkCompactCollector::MarkingWorklist::kMaxNumTasks,
@ -5007,7 +4999,7 @@ class YoungGenerationMarkingTask {
MinorMarkCompactCollector::MarkingWorklist* global_worklist, int task_id)
: marking_worklist_(global_worklist, task_id),
marking_state_(collector->marking_state()),
visitor_(marking_state_, global_worklist, task_id) {
visitor_(isolate, marking_state_, global_worklist, task_id) {
local_live_bytes_.reserve(isolate->heap()->new_space()->Capacity() /
Page::kPageSize);
}

View File

@ -20,6 +20,15 @@ namespace internal {
// 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>
void MarkingVisitorBase<ConcreteVisitor, MarkingState>::MarkObject(
HeapObject host, HeapObject object) {
@ -76,7 +85,8 @@ MarkingVisitorBase<ConcreteVisitor, MarkingState>::VisitPointersImpl(
HeapObject host, TSlot start, TSlot end) {
using THeapObjectSlot = typename TSlot::THeapObjectSlot;
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;
if (object.GetHeapObjectIfStrong(&heap_object)) {
// If the reference changes concurrently from strong to weak, the write
@ -94,9 +104,8 @@ V8_INLINE void
MarkingVisitorBase<ConcreteVisitor, MarkingState>::VisitCodePointerImpl(
HeapObject host, CodeObjectSlot slot) {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// TODO(v8:11880): support external code space.
PtrComprCageBase code_cage_base = GetPtrComprCageBase(host);
Object object = slot.Relaxed_Load(code_cage_base);
Object object =
slot.Relaxed_Load(ObjectVisitorWithCageBases::code_cage_base());
HeapObject heap_object;
if (object.GetHeapObjectIfStrong(&heap_object)) {
// If the reference changes concurrently from strong to weak, the write
@ -110,7 +119,8 @@ template <typename ConcreteVisitor, typename MarkingState>
void MarkingVisitorBase<ConcreteVisitor, MarkingState>::VisitEmbeddedPointer(
Code host, RelocInfo* rinfo) {
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 (host.IsWeakObject(object)) {
weak_objects_->weak_objects_in_code.Push(task_id_,

View File

@ -107,7 +107,8 @@ class MarkingVisitorBase : public HeapVisitor<int, ConcreteVisitor> {
unsigned mark_compact_epoch,
base::EnumSet<CodeFlushMode> code_flush_mode,
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),
heap_(heap),
task_id_(task_id),
@ -134,11 +135,7 @@ class MarkingVisitorBase : public HeapVisitor<int, ConcreteVisitor> {
V8_INLINE int VisitWeakCell(Map map, WeakCell object);
// ObjectVisitor overrides.
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 VisitMapPointer(HeapObject host) final;
V8_INLINE void VisitPointer(HeapObject host, ObjectSlot p) final {
VisitPointersImpl(host, p, p + 1);
}

View File

@ -19,6 +19,7 @@
#include "src/objects/ordered-hash-table.h"
#include "src/objects/synthetic-module-inl.h"
#include "src/objects/torque-defined-classes.h"
#include "src/objects/visitors.h"
#if V8_ENABLE_WEBASSEMBLY
#include "src/wasm/wasm-objects.h"
@ -27,6 +28,19 @@
namespace v8 {
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 T>
T HeapVisitor<ResultType, ConcreteVisitor>::Cast(HeapObject object) {
@ -35,7 +49,7 @@ T HeapVisitor<ResultType, ConcreteVisitor>::Cast(HeapObject object) {
template <typename ResultType, typename ConcreteVisitor>
ResultType HeapVisitor<ResultType, ConcreteVisitor>::Visit(HeapObject object) {
return Visit(object.map(), object);
return Visit(object.map(cage_base()), object);
}
template <typename ResultType, typename ConcreteVisitor>
@ -172,6 +186,10 @@ ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitFreeSpace(
return static_cast<ResultType>(object.size(kRelaxedLoad));
}
template <typename ConcreteVisitor>
NewSpaceVisitor<ConcreteVisitor>::NewSpaceVisitor(Isolate* isolate)
: HeapVisitor<int, ConcreteVisitor>(isolate) {}
template <typename ConcreteVisitor>
int NewSpaceVisitor<ConcreteVisitor>::VisitNativeContext(Map map,
NativeContext object) {

View File

@ -78,8 +78,13 @@ TORQUE_VISITOR_ID_LIST(FORWARD_DECLARE)
// ...
// }
template <typename ResultType, typename ConcreteVisitor>
class HeapVisitor : public ObjectVisitor {
class HeapVisitor : public ObjectVisitorWithCageBases {
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(Map map, HeapObject object);
// A callback for visiting the map pointer in the object header.
@ -115,6 +120,8 @@ class HeapVisitor : public ObjectVisitor {
template <typename ConcreteVisitor>
class NewSpaceVisitor : public HeapVisitor<int, ConcreteVisitor> {
public:
V8_INLINE NewSpaceVisitor(Isolate* isolate);
V8_INLINE bool ShouldVisitMapPointer() { return false; }
// Special cases for young generation.

View File

@ -780,7 +780,8 @@ RootScavengeVisitor::RootScavengeVisitor(Scavenger* scavenger)
: scavenger_(scavenger) {}
ScavengeVisitor::ScavengeVisitor(Scavenger* scavenger)
: scavenger_(scavenger) {}
: NewSpaceVisitor<ScavengeVisitor>(scavenger->heap()->isolate()),
scavenger_(scavenger) {}
} // namespace internal
} // namespace v8

View File

@ -152,6 +152,7 @@ class HeapObject : public Object {
// during marking GC.
inline ObjectSlot RawField(int byte_offset) const;
inline MaybeObjectSlot RawMaybeWeakField(int byte_offset) const;
inline CodeObjectSlot RawCodeField(int byte_offset) const;
DECL_CAST(HeapObject)

View File

@ -931,7 +931,7 @@ class CodeDataContainer::BodyDescriptor final : public BodyDescriptorBase {
CodeDataContainer::kPointerFieldsWeakEndOffset, v);
if (V8_EXTERNAL_CODE_SPACE_BOOL) {
v->VisitCodePointer(obj, obj.RawField(kCodeOffset));
v->VisitCodePointer(obj, obj.RawCodeField(kCodeOffset));
}
}

View File

@ -648,6 +648,10 @@ MaybeObjectSlot HeapObject::RawMaybeWeakField(int byte_offset) const {
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) {
DCHECK(map.is_null() || !MapWord::IsPacked(map.ptr()));
#ifdef V8_MAP_PACKING

View File

@ -0,0 +1,43 @@
// 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_

View File

@ -174,6 +174,44 @@ class ObjectVisitor {
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 v8

View File

@ -718,11 +718,12 @@ int V8HeapExplorer::EstimateObjectsCount() {
return objects_count;
}
class IndexedReferencesExtractor : public ObjectVisitor {
class IndexedReferencesExtractor : public ObjectVisitorWithCageBases {
public:
IndexedReferencesExtractor(V8HeapExplorer* generator, HeapObject parent_obj,
HeapEntry* parent)
: generator_(generator),
: ObjectVisitorWithCageBases(generator->isolate()),
generator_(generator),
parent_obj_(parent_obj),
parent_start_(parent_obj_.RawMaybeWeakField(0)),
parent_end_(parent_obj_.RawMaybeWeakField(parent_obj_.Size())),
@ -733,10 +734,7 @@ class IndexedReferencesExtractor : public ObjectVisitor {
VisitPointers(host, MaybeObjectSlot(start), MaybeObjectSlot(end));
}
void VisitMapPointer(HeapObject object) override {
// TODO(v8:11880): support external code space (here object could be Code,
// so the V8 heap cage_base must be used here).
PtrComprCageBase cage_base = GetPtrComprCageBase(object);
VisitSlotImpl(cage_base, object.map_slot());
VisitSlotImpl(cage_base(), object.map_slot());
}
void VisitPointers(HeapObject host, MaybeObjectSlot start,
MaybeObjectSlot end) override {
@ -744,17 +742,14 @@ class IndexedReferencesExtractor : public ObjectVisitor {
// all the slots must point inside the object.
CHECK_LE(parent_start_, start);
CHECK_LE(end, parent_end_);
PtrComprCageBase cage_base = GetPtrComprCageBase(host);
for (MaybeObjectSlot slot = start; slot < end; ++slot) {
VisitSlotImpl(cage_base, slot);
VisitSlotImpl(cage_base(), slot);
}
}
void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// TODO(v8:11880): support external code space.
PtrComprCageBase code_cage_base = GetPtrComprCageBase(host);
VisitSlotImpl(code_cage_base, slot);
VisitSlotImpl(code_cage_base(), slot);
}
void VisitCodeTarget(Code host, RelocInfo* rinfo) override {
@ -763,7 +758,7 @@ class IndexedReferencesExtractor : public ObjectVisitor {
}
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)) {
generator_->SetWeakReference(parent_, next_index_++, object, {});
} else {

View File

@ -13,6 +13,7 @@
#include "include/v8-profiler.h"
#include "src/base/platform/time.h"
#include "src/execution/isolate.h"
#include "src/objects/fixed-array.h"
#include "src/objects/hash-table.h"
#include "src/objects/heap-object.h"
@ -349,6 +350,8 @@ class V8_EXPORT_PRIVATE V8HeapExplorer : public HeapEntriesAllocator {
V8HeapExplorer(const V8HeapExplorer&) = delete;
V8HeapExplorer& operator=(const V8HeapExplorer&) = delete;
V8_INLINE Isolate* isolate() { return Isolate::FromHeap(heap_); }
HeapEntry* AllocateEntry(HeapThing ptr) override;
HeapEntry* AllocateEntry(Smi smi) override;
int EstimateObjectsCount();