[ptr-compr] Rename XxxSlot classes to FullXxxSlot
and 1) make them represent kSystemPointerSize-sized off-heap slots, 2) reintroduce XxxSlots as an on-heap kTaggedSize-sized slots (for now they are just aliases to respective FullXxxSlots). Bug: v8:8518 Change-Id: I8a9177562308bd9420b1eebca959cc52ceaa628e Reviewed-on: https://chromium-review.googlesource.com/c/1363144 Commit-Queue: Igor Sheludko <ishell@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Cr-Commit-Position: refs/heads/master@{#58056}
This commit is contained in:
parent
16afa0a226
commit
32a79b2b30
@ -17,7 +17,6 @@ class JSGlobalObject;
|
||||
class JSGlobalProxy;
|
||||
class MicrotaskQueue;
|
||||
class NativeContext;
|
||||
class ObjectSlot;
|
||||
class RegExpMatchInfo;
|
||||
|
||||
enum ContextLookupFlags {
|
||||
|
@ -574,7 +574,9 @@ class NewSpace;
|
||||
class NewLargeObjectSpace;
|
||||
class NumberDictionary;
|
||||
class Object;
|
||||
class ObjectSlot;
|
||||
class FullObjectSlot;
|
||||
class FullMaybeObjectSlot;
|
||||
class FullHeapObjectSlot;
|
||||
class OldSpace;
|
||||
class ParameterCount;
|
||||
class ReadOnlySpace;
|
||||
@ -591,6 +593,41 @@ class Struct;
|
||||
class Symbol;
|
||||
class Variable;
|
||||
|
||||
enum class SlotLocation { kOnHeap, kOffHeap };
|
||||
|
||||
template <SlotLocation slot_location>
|
||||
struct SlotTraits;
|
||||
|
||||
// Off-heap slots are always full-pointer slots.
|
||||
template <>
|
||||
struct SlotTraits<SlotLocation::kOffHeap> {
|
||||
using TObjectSlot = FullObjectSlot;
|
||||
using TMaybeObjectSlot = FullMaybeObjectSlot;
|
||||
using THeapObjectSlot = FullHeapObjectSlot;
|
||||
};
|
||||
|
||||
// On-heap slots are either full-pointer slots or compressed slots depending
|
||||
// on whether the pointer compression is enabled or not.
|
||||
template <>
|
||||
struct SlotTraits<SlotLocation::kOnHeap> {
|
||||
using TObjectSlot = FullObjectSlot;
|
||||
using TMaybeObjectSlot = FullMaybeObjectSlot;
|
||||
using THeapObjectSlot = FullHeapObjectSlot;
|
||||
};
|
||||
|
||||
// An ObjectSlot instance describes a kTaggedSize-sized on-heap field ("slot")
|
||||
// holding ObjectPtr value (smi or strong heap object).
|
||||
using ObjectSlot = SlotTraits<SlotLocation::kOnHeap>::TObjectSlot;
|
||||
|
||||
// A MaybeObjectSlot instance describes a kTaggedSize-sized on-heap field
|
||||
// ("slot") holding MaybeObject (smi or weak heap object or strong heap object).
|
||||
using MaybeObjectSlot = SlotTraits<SlotLocation::kOnHeap>::TMaybeObjectSlot;
|
||||
|
||||
// A HeapObjectSlot instance describes a kTaggedSize-sized field ("slot")
|
||||
// holding a weak or strong pointer to a heap object (think:
|
||||
// HeapObjectReference).
|
||||
using HeapObjectSlot = SlotTraits<SlotLocation::kOnHeap>::THeapObjectSlot;
|
||||
|
||||
typedef bool (*WeakSlotCallback)(ObjectSlot pointer);
|
||||
|
||||
typedef bool (*WeakSlotCallbackWithHeap)(Heap* heap, ObjectSlot pointer);
|
||||
|
@ -61,9 +61,7 @@ class SlotSnapshot {
|
||||
Object* value(int i) const { return snapshot_[i].second; }
|
||||
void clear() { number_of_slots_ = 0; }
|
||||
void add(ObjectSlot slot, Object* value) {
|
||||
snapshot_[number_of_slots_].first = slot;
|
||||
snapshot_[number_of_slots_].second = value;
|
||||
++number_of_slots_;
|
||||
snapshot_[number_of_slots_++] = {slot, value};
|
||||
}
|
||||
|
||||
private:
|
||||
@ -158,7 +156,7 @@ class ConcurrentMarkingVisitor final
|
||||
// barrier will treat the weak reference as strong, so we won't miss the
|
||||
// weak reference.
|
||||
ProcessStrongHeapObject(host, ObjectSlot(slot), heap_object);
|
||||
} else if (TSlot::kCanBeWeek &&
|
||||
} else if (TSlot::kCanBeWeak &&
|
||||
object.GetHeapObjectIfWeak(&heap_object)) {
|
||||
ProcessWeakHeapObject(host, HeapObjectSlot(slot), heap_object);
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define V8_HEAP_HEAP_WRITE_BARRIER_H_
|
||||
|
||||
#include "include/v8-internal.h"
|
||||
#include "src/globals.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
@ -16,9 +17,7 @@ class Heap;
|
||||
class HeapObject;
|
||||
class HeapObjectPtr;
|
||||
class MaybeObject;
|
||||
class MaybeObjectSlot;
|
||||
class Object;
|
||||
class ObjectSlot;
|
||||
class RelocInfo;
|
||||
|
||||
// Note: In general it is preferred to use the macros defined in
|
||||
|
@ -213,7 +213,7 @@ void MarkingVisitor<fixed_array_mode, retaining_path_mode,
|
||||
if (object.GetHeapObjectIfStrong(&target_object)) {
|
||||
collector_->RecordSlot(host, HeapObjectSlot(slot), target_object);
|
||||
MarkObject(host, target_object);
|
||||
} else if (TSlot::kCanBeWeek && object.GetHeapObjectIfWeak(&target_object)) {
|
||||
} else if (TSlot::kCanBeWeak && object.GetHeapObjectIfWeak(&target_object)) {
|
||||
if (marking_state()->IsBlackOrGrey(target_object)) {
|
||||
// Weak references with live values are directly processed here to reduce
|
||||
// the processing time of weak cells during the main GC pause.
|
||||
|
@ -272,7 +272,6 @@ class KeyAccumulator;
|
||||
class LayoutDescriptor;
|
||||
class LookupIterator;
|
||||
class FieldType;
|
||||
class MaybeObjectSlot;
|
||||
class Module;
|
||||
class ModuleInfoEntry;
|
||||
class ObjectHashTable;
|
||||
|
@ -18,7 +18,6 @@ template <typename T>
|
||||
class Handle;
|
||||
|
||||
class Isolate;
|
||||
class MaybeObjectSlot;
|
||||
|
||||
// An EnumCache is a pair used to hold keys and indices caches.
|
||||
class EnumCache : public Tuple2 {
|
||||
|
@ -74,7 +74,7 @@ Object* FixedArrayBase::unchecked_synchronized_length() const {
|
||||
ACCESSORS(FixedTypedArrayBase, base_pointer, Object, kBasePointerOffset)
|
||||
|
||||
ObjectSlot FixedArray::GetFirstElementAddress() {
|
||||
return ObjectSlot(FIELD_ADDR(this, OffsetOfElementAt(0)));
|
||||
return RawField(OffsetOfElementAt(0));
|
||||
}
|
||||
|
||||
bool FixedArray::ContainsOnlySmisOrHoles() {
|
||||
|
@ -136,7 +136,7 @@ class ObjectPtr {
|
||||
};
|
||||
|
||||
private:
|
||||
friend class ObjectSlot;
|
||||
friend class FullObjectSlot;
|
||||
Address ptr_;
|
||||
};
|
||||
|
||||
|
@ -156,9 +156,9 @@ template <class Derived>
|
||||
void SmallOrderedHashTable<Derived>::SetDataEntry(int entry, int relative_index,
|
||||
Object* value) {
|
||||
DCHECK_NE(kNotFound, entry);
|
||||
Address entry_offset = GetDataEntryOffset(entry, relative_index);
|
||||
int entry_offset = GetDataEntryOffset(entry, relative_index);
|
||||
RELAXED_WRITE_FIELD(this, entry_offset, value);
|
||||
WRITE_BARRIER(this, static_cast<int>(entry_offset), value);
|
||||
WRITE_BARRIER(this, entry_offset, value);
|
||||
}
|
||||
|
||||
template <class Derived, class TableType>
|
||||
|
@ -16,80 +16,108 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
ObjectSlot::ObjectSlot(ObjectPtr* object)
|
||||
//
|
||||
// FullObjectSlot implementation.
|
||||
//
|
||||
|
||||
FullObjectSlot::FullObjectSlot(ObjectPtr* object)
|
||||
: SlotBase(reinterpret_cast<Address>(&object->ptr_)) {}
|
||||
|
||||
ObjectPtr ObjectSlot::load() const { return ObjectPtr(*location()); }
|
||||
|
||||
void ObjectSlot::store(Object* value) const { *location() = value->ptr(); }
|
||||
|
||||
ObjectPtr ObjectSlot::Acquire_Load() const {
|
||||
return ObjectPtr(AsAtomicTagged::Acquire_Load(location()));
|
||||
bool FullObjectSlot::contains_value(Address raw_value) const {
|
||||
return *location() == raw_value;
|
||||
}
|
||||
|
||||
Object* ObjectSlot::Acquire_Load1() const {
|
||||
return reinterpret_cast<Object*>(AsAtomicTagged::Acquire_Load(location()));
|
||||
Object* FullObjectSlot::operator*() const {
|
||||
return reinterpret_cast<Object*>(*location());
|
||||
}
|
||||
|
||||
ObjectPtr ObjectSlot::Relaxed_Load() const {
|
||||
return ObjectPtr(AsAtomicTagged::Relaxed_Load(location()));
|
||||
ObjectPtr FullObjectSlot::load() const { return ObjectPtr(*location()); }
|
||||
|
||||
void FullObjectSlot::store(Object* value) const { *location() = value->ptr(); }
|
||||
void FullObjectSlot::store(ObjectPtr value) const { *location() = value.ptr(); }
|
||||
|
||||
ObjectPtr FullObjectSlot::Acquire_Load() const {
|
||||
return ObjectPtr(base::AsAtomicPointer::Acquire_Load(location()));
|
||||
}
|
||||
|
||||
void ObjectSlot::Relaxed_Store(ObjectPtr value) const {
|
||||
AsAtomicTagged::Relaxed_Store(location(), value->ptr());
|
||||
Object* FullObjectSlot::Acquire_Load1() const {
|
||||
return reinterpret_cast<Object*>(
|
||||
base::AsAtomicPointer::Acquire_Load(location()));
|
||||
}
|
||||
|
||||
void ObjectSlot::Relaxed_Store1(Object* value) const {
|
||||
AsAtomicTagged::Relaxed_Store(location(), value->ptr());
|
||||
ObjectPtr FullObjectSlot::Relaxed_Load() const {
|
||||
return ObjectPtr(base::AsAtomicPointer::Relaxed_Load(location()));
|
||||
}
|
||||
|
||||
void ObjectSlot::Release_Store1(Object* value) const {
|
||||
AsAtomicTagged::Release_Store(location(), value->ptr());
|
||||
void FullObjectSlot::Relaxed_Store(ObjectPtr value) const {
|
||||
base::AsAtomicPointer::Relaxed_Store(location(), value->ptr());
|
||||
}
|
||||
|
||||
void ObjectSlot::Release_Store(ObjectPtr value) const {
|
||||
AsAtomicTagged::Release_Store(location(), value->ptr());
|
||||
void FullObjectSlot::Relaxed_Store1(Object* value) const {
|
||||
base::AsAtomicPointer::Relaxed_Store(location(), value->ptr());
|
||||
}
|
||||
|
||||
ObjectPtr ObjectSlot::Release_CompareAndSwap(ObjectPtr old,
|
||||
ObjectPtr target) const {
|
||||
Address result = AsAtomicTagged::Release_CompareAndSwap(
|
||||
void FullObjectSlot::Release_Store1(Object* value) const {
|
||||
base::AsAtomicPointer::Release_Store(location(), value->ptr());
|
||||
}
|
||||
|
||||
void FullObjectSlot::Release_Store(ObjectPtr value) const {
|
||||
base::AsAtomicPointer::Release_Store(location(), value->ptr());
|
||||
}
|
||||
|
||||
ObjectPtr FullObjectSlot::Release_CompareAndSwap(ObjectPtr old,
|
||||
ObjectPtr target) const {
|
||||
Address result = base::AsAtomicPointer::Release_CompareAndSwap(
|
||||
location(), old->ptr(), target->ptr());
|
||||
return ObjectPtr(result);
|
||||
}
|
||||
|
||||
MaybeObject MaybeObjectSlot::operator*() const {
|
||||
//
|
||||
// FullMaybeObjectSlot implementation.
|
||||
//
|
||||
|
||||
MaybeObject FullMaybeObjectSlot::operator*() const {
|
||||
return MaybeObject(*location());
|
||||
}
|
||||
|
||||
MaybeObject MaybeObjectSlot::load() const { return MaybeObject(*location()); }
|
||||
MaybeObject FullMaybeObjectSlot::load() const {
|
||||
return MaybeObject(*location());
|
||||
}
|
||||
|
||||
void MaybeObjectSlot::store(MaybeObject value) const {
|
||||
void FullMaybeObjectSlot::store(MaybeObject value) const {
|
||||
*location() = value.ptr();
|
||||
}
|
||||
|
||||
MaybeObject MaybeObjectSlot::Relaxed_Load() const {
|
||||
MaybeObject FullMaybeObjectSlot::Relaxed_Load() const {
|
||||
return MaybeObject(AsAtomicTagged::Relaxed_Load(location()));
|
||||
}
|
||||
|
||||
void MaybeObjectSlot::Relaxed_Store(MaybeObject value) const {
|
||||
void FullMaybeObjectSlot::Relaxed_Store(MaybeObject value) const {
|
||||
AsAtomicTagged::Relaxed_Store(location(), value->ptr());
|
||||
}
|
||||
|
||||
void MaybeObjectSlot::Release_CompareAndSwap(MaybeObject old,
|
||||
MaybeObject target) const {
|
||||
void FullMaybeObjectSlot::Release_CompareAndSwap(MaybeObject old,
|
||||
MaybeObject target) const {
|
||||
AsAtomicTagged::Release_CompareAndSwap(location(), old.ptr(), target.ptr());
|
||||
}
|
||||
|
||||
HeapObjectReference HeapObjectSlot::operator*() const {
|
||||
//
|
||||
// FullHeapObjectSlot implementation.
|
||||
//
|
||||
|
||||
HeapObjectReference FullHeapObjectSlot::operator*() const {
|
||||
return HeapObjectReference(*location());
|
||||
}
|
||||
|
||||
void HeapObjectSlot::store(HeapObjectReference value) const {
|
||||
void FullHeapObjectSlot::store(HeapObjectReference value) const {
|
||||
*location() = value.ptr();
|
||||
}
|
||||
|
||||
inline void MemsetPointer(ObjectSlot start, Object* value, size_t counter) {
|
||||
//
|
||||
// Utils.
|
||||
//
|
||||
|
||||
inline void MemsetPointer(FullObjectSlot start, Object* value, size_t counter) {
|
||||
MemsetPointer(start.location(), reinterpret_cast<Address>(value), counter);
|
||||
}
|
||||
|
||||
|
@ -84,32 +84,39 @@ class SlotBase {
|
||||
Address ptr_;
|
||||
};
|
||||
|
||||
// An ObjectSlot instance describes a kTaggedSize-sized field ("slot") holding
|
||||
// a tagged pointer (smi or strong heap object).
|
||||
// An FullObjectSlot instance describes a kSystemPointerSize-sized field
|
||||
// ("slot") holding a tagged pointer (smi or strong heap object).
|
||||
// Its address() is the address of the slot.
|
||||
// The slot's contents can be read and written using operator* and store().
|
||||
class ObjectSlot : public SlotBase<ObjectSlot, Tagged_t, kTaggedSize> {
|
||||
class FullObjectSlot
|
||||
: public SlotBase<FullObjectSlot, Address, kSystemPointerSize> {
|
||||
public:
|
||||
using TObject = ObjectPtr;
|
||||
using THeapObjectSlot = FullHeapObjectSlot;
|
||||
|
||||
// Tagged value stored in this slot is guaranteed to never be a weak pointer.
|
||||
static constexpr bool kCanBeWeek = false;
|
||||
static constexpr bool kCanBeWeak = false;
|
||||
|
||||
ObjectSlot() : SlotBase(kNullAddress) {}
|
||||
explicit ObjectSlot(Address ptr) : SlotBase(ptr) {}
|
||||
explicit ObjectSlot(Address* ptr)
|
||||
FullObjectSlot() : SlotBase(kNullAddress) {}
|
||||
explicit FullObjectSlot(Address ptr) : SlotBase(ptr) {}
|
||||
explicit FullObjectSlot(Address* ptr)
|
||||
: SlotBase(reinterpret_cast<Address>(ptr)) {}
|
||||
inline explicit ObjectSlot(ObjectPtr* object);
|
||||
explicit ObjectSlot(Object const* const* ptr)
|
||||
inline explicit FullObjectSlot(ObjectPtr* object);
|
||||
explicit FullObjectSlot(Object const* const* ptr)
|
||||
: SlotBase(reinterpret_cast<Address>(ptr)) {}
|
||||
template <typename T>
|
||||
explicit ObjectSlot(SlotBase<T, TData, kSlotDataSize> slot)
|
||||
explicit FullObjectSlot(SlotBase<T, TData, kSlotDataSize> slot)
|
||||
: SlotBase(slot.address()) {}
|
||||
|
||||
Object* operator*() const { return *reinterpret_cast<Object**>(address()); }
|
||||
// Compares memory representation of a value stored in the slot with given
|
||||
// raw value.
|
||||
inline bool contains_value(Address raw_value) const;
|
||||
|
||||
inline Object* operator*() const;
|
||||
// TODO(3770): drop this in favor of operator* once migration is complete.
|
||||
inline ObjectPtr load() const;
|
||||
inline void store(Object* value) const;
|
||||
inline void store(ObjectPtr value) const;
|
||||
|
||||
inline ObjectPtr Acquire_Load() const;
|
||||
inline ObjectPtr Relaxed_Load() const;
|
||||
@ -125,23 +132,29 @@ class ObjectSlot : public SlotBase<ObjectSlot, Tagged_t, kTaggedSize> {
|
||||
inline void Release_Store1(Object* value) const;
|
||||
};
|
||||
|
||||
// A MaybeObjectSlot instance describes a kTaggedSize-sized field ("slot")
|
||||
// holding a possibly-weak tagged pointer (think: MaybeObject).
|
||||
// A FullMaybeObjectSlot instance describes a kSystemPointerSize-sized field
|
||||
// ("slot") holding a possibly-weak tagged pointer (think: MaybeObject).
|
||||
// Its address() is the address of the slot.
|
||||
// The slot's contents can be read and written using operator* and store().
|
||||
class MaybeObjectSlot
|
||||
: public SlotBase<MaybeObjectSlot, Tagged_t, kTaggedSize> {
|
||||
class FullMaybeObjectSlot
|
||||
: public SlotBase<FullMaybeObjectSlot, Address, kSystemPointerSize> {
|
||||
public:
|
||||
using TObject = MaybeObject;
|
||||
using THeapObjectSlot = FullHeapObjectSlot;
|
||||
|
||||
// Tagged value stored in this slot can be a weak pointer.
|
||||
static constexpr bool kCanBeWeek = true;
|
||||
static constexpr bool kCanBeWeak = true;
|
||||
|
||||
explicit MaybeObjectSlot(Address ptr) : SlotBase(ptr) {}
|
||||
explicit MaybeObjectSlot(Object** ptr)
|
||||
FullMaybeObjectSlot() : SlotBase(kNullAddress) {}
|
||||
explicit FullMaybeObjectSlot(Address ptr) : SlotBase(ptr) {}
|
||||
explicit FullMaybeObjectSlot(ObjectPtr* ptr)
|
||||
: SlotBase(reinterpret_cast<Address>(ptr)) {}
|
||||
explicit FullMaybeObjectSlot(Object** ptr)
|
||||
: SlotBase(reinterpret_cast<Address>(ptr)) {}
|
||||
explicit FullMaybeObjectSlot(HeapObject** ptr)
|
||||
: SlotBase(reinterpret_cast<Address>(ptr)) {}
|
||||
template <typename T>
|
||||
explicit MaybeObjectSlot(SlotBase<T, TData, kSlotDataSize> slot)
|
||||
explicit FullMaybeObjectSlot(SlotBase<T, TData, kSlotDataSize> slot)
|
||||
: SlotBase(slot.address()) {}
|
||||
|
||||
inline MaybeObject operator*() const;
|
||||
@ -154,19 +167,20 @@ class MaybeObjectSlot
|
||||
inline void Release_CompareAndSwap(MaybeObject old, MaybeObject target) const;
|
||||
};
|
||||
|
||||
// A HeapObjectSlot instance describes a kTaggedSize-sized field ("slot")
|
||||
// holding a weak or strong pointer to a heap object (think:
|
||||
// A FullHeapObjectSlot instance describes a kSystemPointerSize-sized field
|
||||
// ("slot") holding a weak or strong pointer to a heap object (think:
|
||||
// HeapObjectReference).
|
||||
// Its address() is the address of the slot.
|
||||
// The slot's contents can be read and written using operator* and store().
|
||||
// In case it is known that that slot contains a strong heap object pointer,
|
||||
// ToHeapObject() can be used to retrieve that heap object.
|
||||
class HeapObjectSlot : public SlotBase<HeapObjectSlot, Tagged_t, kTaggedSize> {
|
||||
class FullHeapObjectSlot
|
||||
: public SlotBase<HeapObjectSlot, Address, kSystemPointerSize> {
|
||||
public:
|
||||
HeapObjectSlot() : SlotBase(kNullAddress) {}
|
||||
explicit HeapObjectSlot(Address ptr) : SlotBase(ptr) {}
|
||||
FullHeapObjectSlot() : SlotBase(kNullAddress) {}
|
||||
explicit FullHeapObjectSlot(Address ptr) : SlotBase(ptr) {}
|
||||
template <typename T>
|
||||
explicit HeapObjectSlot(SlotBase<T, TData, kSlotDataSize> slot)
|
||||
explicit FullHeapObjectSlot(SlotBase<T, TData, kSlotDataSize> slot)
|
||||
: SlotBase(slot.address()) {}
|
||||
|
||||
inline HeapObjectReference operator*() const;
|
||||
|
Loading…
Reference in New Issue
Block a user