Line data Source code
1 : // Copyright 2018 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_OBJECTS_SLOTS_H_
6 : #define V8_OBJECTS_SLOTS_H_
7 :
8 : #include "src/globals.h"
9 :
10 : namespace v8 {
11 : namespace internal {
12 :
13 : class Object;
14 :
15 : template <typename Subclass, typename Data, size_t SlotDataSize>
16 : class SlotBase {
17 : public:
18 : using TData = Data;
19 :
20 : // TODO(ishell): This should eventually become just sizeof(TData) once
21 : // pointer compression is implemented.
22 : static constexpr size_t kSlotDataSize = SlotDataSize;
23 :
24 7515892835 : Subclass& operator++() { // Prefix increment.
25 9242340983 : ptr_ += kSlotDataSize;
26 7515892835 : return *static_cast<Subclass*>(this);
27 : }
28 : Subclass operator++(int) { // Postfix increment.
29 : Subclass result = *static_cast<Subclass*>(this);
30 2291121 : ptr_ += kSlotDataSize;
31 : return result;
32 : }
33 : Subclass& operator--() { // Prefix decrement.
34 63395105 : ptr_ -= kSlotDataSize;
35 : return *static_cast<Subclass*>(this);
36 : }
37 : Subclass operator--(int) { // Postfix decrement.
38 : Subclass result = *static_cast<Subclass*>(this);
39 : ptr_ -= kSlotDataSize;
40 : return result;
41 : }
42 :
43 13203952709 : bool operator<(const SlotBase& other) const { return ptr_ < other.ptr_; }
44 13304222 : bool operator<=(const SlotBase& other) const { return ptr_ <= other.ptr_; }
45 : bool operator>(const SlotBase& other) const { return ptr_ > other.ptr_; }
46 : bool operator>=(const SlotBase& other) const { return ptr_ >= other.ptr_; }
47 906474552 : bool operator==(const SlotBase& other) const { return ptr_ == other.ptr_; }
48 499228 : bool operator!=(const SlotBase& other) const { return ptr_ != other.ptr_; }
49 : size_t operator-(const SlotBase& other) const {
50 : DCHECK_GE(ptr_, other.ptr_);
51 22503970 : return static_cast<size_t>((ptr_ - other.ptr_) / kSlotDataSize);
52 : }
53 : Subclass operator-(int i) const { return Subclass(ptr_ - i * kSlotDataSize); }
54 2889544336 : Subclass operator+(int i) const { return Subclass(ptr_ + i * kSlotDataSize); }
55 : friend Subclass operator+(int i, const Subclass& slot) {
56 : return Subclass(slot.ptr_ + i * kSlotDataSize);
57 : }
58 : Subclass& operator+=(int i) {
59 478504506 : ptr_ += i * kSlotDataSize;
60 : return *static_cast<Subclass*>(this);
61 : }
62 1427845 : Subclass operator-(int i) { return Subclass(ptr_ - i * kSlotDataSize); }
63 : Subclass& operator-=(int i) {
64 : ptr_ -= i * kSlotDataSize;
65 : return *static_cast<Subclass*>(this);
66 : }
67 :
68 480730477 : void* ToVoidPtr() const { return reinterpret_cast<void*>(address()); }
69 :
70 10988864184 : Address address() const { return ptr_; }
71 : // For symmetry with Handle.
72 64400250922 : TData* location() const { return reinterpret_cast<TData*>(ptr_); }
73 :
74 : protected:
75 : STATIC_ASSERT(IsAligned(kSlotDataSize, kTaggedSize));
76 10252546941 : explicit SlotBase(Address ptr) : ptr_(ptr) {
77 : DCHECK(IsAligned(ptr, kTaggedSize));
78 56293515 : }
79 :
80 : private:
81 : // This field usually describes an on-heap address (a slot within an object),
82 : // so its type should not be a pointer to another C++ wrapper class.
83 : // Type safety is provided by well-defined conversion operations.
84 : Address ptr_;
85 : };
86 :
87 : // An FullObjectSlot instance describes a kSystemPointerSize-sized field
88 : // ("slot") holding a tagged pointer (smi or strong heap object).
89 : // Its address() is the address of the slot.
90 : // The slot's contents can be read and written using operator* and store().
91 : class FullObjectSlot
92 : : public SlotBase<FullObjectSlot, Address, kSystemPointerSize> {
93 : public:
94 : using TObject = Object;
95 : using THeapObjectSlot = FullHeapObjectSlot;
96 :
97 : // Tagged value stored in this slot is guaranteed to never be a weak pointer.
98 : static constexpr bool kCanBeWeak = false;
99 :
100 : FullObjectSlot() : SlotBase(kNullAddress) {}
101 872562708 : explicit FullObjectSlot(Address ptr) : SlotBase(ptr) {}
102 56 : explicit FullObjectSlot(const Address* ptr)
103 67364329 : : SlotBase(reinterpret_cast<Address>(ptr)) {}
104 : inline explicit FullObjectSlot(Object* object);
105 : template <typename T>
106 : explicit FullObjectSlot(SlotBase<T, TData, kSlotDataSize> slot)
107 : : SlotBase(slot.address()) {}
108 :
109 : // Compares memory representation of a value stored in the slot with given
110 : // raw value.
111 : inline bool contains_value(Address raw_value) const;
112 :
113 : inline const Object operator*() const;
114 : inline void store(Object value) const;
115 :
116 : inline Object Acquire_Load() const;
117 : inline Object Relaxed_Load() const;
118 : inline void Relaxed_Store(Object value) const;
119 : inline void Release_Store(Object value) const;
120 : inline Object Release_CompareAndSwap(Object old, Object target) const;
121 : };
122 :
123 : // A FullMaybeObjectSlot instance describes a kSystemPointerSize-sized field
124 : // ("slot") holding a possibly-weak tagged pointer (think: MaybeObject).
125 : // Its address() is the address of the slot.
126 : // The slot's contents can be read and written using operator* and store().
127 : class FullMaybeObjectSlot
128 : : public SlotBase<FullMaybeObjectSlot, Address, kSystemPointerSize> {
129 : public:
130 : using TObject = MaybeObject;
131 : using THeapObjectSlot = FullHeapObjectSlot;
132 :
133 : // Tagged value stored in this slot can be a weak pointer.
134 : static constexpr bool kCanBeWeak = true;
135 :
136 : FullMaybeObjectSlot() : SlotBase(kNullAddress) {}
137 8736 : explicit FullMaybeObjectSlot(Address ptr) : SlotBase(ptr) {}
138 : explicit FullMaybeObjectSlot(Object* ptr)
139 463010 : : SlotBase(reinterpret_cast<Address>(ptr)) {}
140 : explicit FullMaybeObjectSlot(MaybeObject* ptr)
141 171573932 : : SlotBase(reinterpret_cast<Address>(ptr)) {}
142 : template <typename T>
143 20248796 : explicit FullMaybeObjectSlot(SlotBase<T, TData, kSlotDataSize> slot)
144 20248796 : : SlotBase(slot.address()) {}
145 :
146 : inline const MaybeObject operator*() const;
147 : inline void store(MaybeObject value) const;
148 :
149 : inline MaybeObject Relaxed_Load() const;
150 : inline void Relaxed_Store(MaybeObject value) const;
151 : inline void Release_CompareAndSwap(MaybeObject old, MaybeObject target) const;
152 : };
153 :
154 : // A FullHeapObjectSlot instance describes a kSystemPointerSize-sized field
155 : // ("slot") holding a weak or strong pointer to a heap object (think:
156 : // HeapObjectReference).
157 : // Its address() is the address of the slot.
158 : // The slot's contents can be read and written using operator* and store().
159 : // In case it is known that that slot contains a strong heap object pointer,
160 : // ToHeapObject() can be used to retrieve that heap object.
161 : class FullHeapObjectSlot
162 : : public SlotBase<FullHeapObjectSlot, Address, kSystemPointerSize> {
163 : public:
164 : FullHeapObjectSlot() : SlotBase(kNullAddress) {}
165 : explicit FullHeapObjectSlot(Address ptr) : SlotBase(ptr) {}
166 0 : explicit FullHeapObjectSlot(Object* ptr)
167 0 : : SlotBase(reinterpret_cast<Address>(ptr)) {}
168 : template <typename T>
169 6746852305 : explicit FullHeapObjectSlot(SlotBase<T, TData, kSlotDataSize> slot)
170 6746852305 : : SlotBase(slot.address()) {}
171 :
172 : inline const HeapObjectReference operator*() const;
173 : inline void store(HeapObjectReference value) const;
174 :
175 : inline HeapObject ToHeapObject() const;
176 :
177 : inline void StoreHeapObject(HeapObject value) const;
178 : };
179 :
180 : } // namespace internal
181 : } // namespace v8
182 :
183 : #endif // V8_OBJECTS_SLOTS_H_
|