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 7503116670 : Subclass& operator++() { // Prefix increment.
25 8785160654 : ptr_ += kSlotDataSize;
26 7503116670 : return *static_cast<Subclass*>(this);
27 : }
28 : Subclass operator++(int) { // Postfix increment.
29 : Subclass result = *static_cast<Subclass*>(this);
30 : ptr_ += kSlotDataSize;
31 : return result;
32 : }
33 : Subclass& operator--() { // Prefix decrement.
34 69059048 : 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 9667332979 : bool operator<(const SlotBase& other) const { return ptr_ < other.ptr_; }
44 13938284 : 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 7224918 : bool operator==(const SlotBase& other) const { return ptr_ == other.ptr_; }
48 6973440 : 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 21598105 : return static_cast<size_t>((ptr_ - other.ptr_) / kSlotDataSize);
52 : }
53 : Subclass operator-(int i) const { return Subclass(ptr_ - i * kSlotDataSize); }
54 875341246 : 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 119 : ptr_ += i * kSlotDataSize;
60 : return *static_cast<Subclass*>(this);
61 : }
62 5957981 : 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 1198 : void* ToVoidPtr() const { return reinterpret_cast<void*>(address()); }
69 :
70 11378918594 : Address address() const { return ptr_; }
71 : // For symmetry with Handle.
72 60182688190 : TData* location() const { return reinterpret_cast<TData*>(ptr_); }
73 :
74 : protected:
75 : STATIC_ASSERT(IsAligned(kSlotDataSize, kTaggedSize));
76 8930757658 : explicit SlotBase(Address ptr) : ptr_(ptr) {
77 : DCHECK(IsAligned(ptr, kTaggedSize));
78 1062982 : }
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 862863178 : explicit FullObjectSlot(Address ptr) : SlotBase(ptr) {}
102 : explicit FullObjectSlot(const Address* ptr)
103 67277686 : : SlotBase(reinterpret_cast<Address>(ptr)) {}
104 : inline explicit FullObjectSlot(Object* object);
105 : template <typename T>
106 96305 : explicit FullObjectSlot(SlotBase<T, TData, kSlotDataSize> slot)
107 96305 : : 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 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 : explicit FullMaybeObjectSlot(Address ptr) : SlotBase(ptr) {}
138 : explicit FullMaybeObjectSlot(Object* ptr)
139 450095 : : SlotBase(reinterpret_cast<Address>(ptr)) {}
140 : template <typename T>
141 20982274 : explicit FullMaybeObjectSlot(SlotBase<T, TData, kSlotDataSize> slot)
142 20982274 : : SlotBase(slot.address()) {}
143 :
144 : inline MaybeObject operator*() const;
145 : inline void store(MaybeObject value) const;
146 :
147 : inline MaybeObject Relaxed_Load() const;
148 : inline void Relaxed_Store(MaybeObject value) const;
149 : inline void Release_CompareAndSwap(MaybeObject old, MaybeObject target) const;
150 : };
151 :
152 : // A FullHeapObjectSlot instance describes a kSystemPointerSize-sized field
153 : // ("slot") holding a weak or strong pointer to a heap object (think:
154 : // HeapObjectReference).
155 : // Its address() is the address of the slot.
156 : // The slot's contents can be read and written using operator* and store().
157 : // In case it is known that that slot contains a strong heap object pointer,
158 : // ToHeapObject() can be used to retrieve that heap object.
159 : class FullHeapObjectSlot
160 : : public SlotBase<FullHeapObjectSlot, Address, kSystemPointerSize> {
161 : public:
162 : FullHeapObjectSlot() : SlotBase(kNullAddress) {}
163 : explicit FullHeapObjectSlot(Address ptr) : SlotBase(ptr) {}
164 0 : explicit FullHeapObjectSlot(Object* ptr)
165 0 : : SlotBase(reinterpret_cast<Address>(ptr)) {}
166 : template <typename T>
167 6798574330 : explicit FullHeapObjectSlot(SlotBase<T, TData, kSlotDataSize> slot)
168 6798574330 : : SlotBase(slot.address()) {}
169 :
170 : inline HeapObjectReference operator*() const;
171 : inline void store(HeapObjectReference value) const;
172 :
173 : inline HeapObject ToHeapObject() const;
174 :
175 : inline void StoreHeapObject(HeapObject value) const;
176 : };
177 :
178 : } // namespace internal
179 : } // namespace v8
180 :
181 : #endif // V8_OBJECTS_SLOTS_H_
|