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") {
"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",
......
......@@ -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();
}
......
......@@ -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();
......
......@@ -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();
}
......
......@@ -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();
}
......
......@@ -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();
}
......
......@@ -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();
}
......
......@@ -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();
......
......@@ -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(
......
......@@ -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();
......
......@@ -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();
......
......@@ -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_));
......
......@@ -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() {
......
......@@ -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();
}
......
......@@ -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;
......
......@@ -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_;
......
......@@ -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_++;
}
......
......@@ -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,
......
......@@ -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,
......
This diff is collapsed.
......@@ -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_,
......
......@@ -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);
}
......
......@@ -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) {
......
......@@ -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.
......
......@@ -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
......@@ -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)
......
......@@ -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));
}
}
......
......@@ -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
......
// 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 {
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
......
......@@ -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 {
......
......@@ -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();
......
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