1 // Copyright 2019 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_TAGGED_FIELD_INL_H_
6 #define V8_OBJECTS_TAGGED_FIELD_INL_H_
7
8 #include "src/objects/tagged-field.h"
9
10 #include "src/common/ptr-compr-inl.h"
11
12 namespace v8 {
13 namespace internal {
14
15 // static
16 template <typename T, int kFieldOffset>
address(HeapObject host,int offset)17 Address TaggedField<T, kFieldOffset>::address(HeapObject host, int offset) {
18 return host.address() + kFieldOffset + offset;
19 }
20
21 // static
22 template <typename T, int kFieldOffset>
location(HeapObject host,int offset)23 Tagged_t* TaggedField<T, kFieldOffset>::location(HeapObject host, int offset) {
24 return reinterpret_cast<Tagged_t*>(address(host, offset));
25 }
26
27 // static
28 template <typename T, int kFieldOffset>
29 template <typename TOnHeapAddress>
tagged_to_full(TOnHeapAddress on_heap_addr,Tagged_t tagged_value)30 Address TaggedField<T, kFieldOffset>::tagged_to_full(
31 TOnHeapAddress on_heap_addr, Tagged_t tagged_value) {
32 #ifdef V8_COMPRESS_POINTERS
33 if (kIsSmi) {
34 return DecompressTaggedSigned(tagged_value);
35 } else if (kIsHeapObject) {
36 return DecompressTaggedPointer(on_heap_addr, tagged_value);
37 } else {
38 return DecompressTaggedAny(on_heap_addr, tagged_value);
39 }
40 #else
41 return tagged_value;
42 #endif
43 }
44
45 // static
46 template <typename T, int kFieldOffset>
full_to_tagged(Address value)47 Tagged_t TaggedField<T, kFieldOffset>::full_to_tagged(Address value) {
48 #ifdef V8_COMPRESS_POINTERS
49 return CompressTagged(value);
50 #else
51 return value;
52 #endif
53 }
54
55 // static
56 template <typename T, int kFieldOffset>
load(HeapObject host,int offset)57 T TaggedField<T, kFieldOffset>::load(HeapObject host, int offset) {
58 Tagged_t value = *location(host, offset);
59 DCHECK_NE(kFieldOffset + offset, HeapObject::kMapOffset);
60 return T(tagged_to_full(host.ptr(), value));
61 }
62
63 // static
64 template <typename T, int kFieldOffset>
load(PtrComprCageBase cage_base,HeapObject host,int offset)65 T TaggedField<T, kFieldOffset>::load(PtrComprCageBase cage_base,
66 HeapObject host, int offset) {
67 Tagged_t value = *location(host, offset);
68 DCHECK_NE(kFieldOffset + offset, HeapObject::kMapOffset);
69 return T(tagged_to_full(cage_base, value));
70 }
71
72 // static
73 template <typename T, int kFieldOffset>
store(HeapObject host,T value)74 void TaggedField<T, kFieldOffset>::store(HeapObject host, T value) {
75 #ifdef V8_ATOMIC_OBJECT_FIELD_WRITES
76 Relaxed_Store(host, value);
77 #else
78 Address ptr = value.ptr();
79 DCHECK_NE(kFieldOffset, HeapObject::kMapOffset);
80 *location(host) = full_to_tagged(ptr);
81 #endif
82 }
83
84 // static
85 template <typename T, int kFieldOffset>
store(HeapObject host,int offset,T value)86 void TaggedField<T, kFieldOffset>::store(HeapObject host, int offset, T value) {
87 #ifdef V8_ATOMIC_OBJECT_FIELD_WRITES
88 Relaxed_Store(host, offset, value);
89 #else
90 Address ptr = value.ptr();
91 DCHECK_NE(kFieldOffset + offset, HeapObject::kMapOffset);
92 *location(host, offset) = full_to_tagged(ptr);
93 #endif
94 }
95
96 // static
97 template <typename T, int kFieldOffset>
Relaxed_Load(HeapObject host,int offset)98 T TaggedField<T, kFieldOffset>::Relaxed_Load(HeapObject host, int offset) {
99 AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location(host, offset));
100 DCHECK_NE(kFieldOffset + offset, HeapObject::kMapOffset);
101 return T(tagged_to_full(host.ptr(), value));
102 }
103
104 // static
105 template <typename T, int kFieldOffset>
Relaxed_Load(PtrComprCageBase cage_base,HeapObject host,int offset)106 T TaggedField<T, kFieldOffset>::Relaxed_Load(PtrComprCageBase cage_base,
107 HeapObject host, int offset) {
108 AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location(host, offset));
109 DCHECK_NE(kFieldOffset + offset, HeapObject::kMapOffset);
110 return T(tagged_to_full(cage_base, value));
111 }
112
113 // static
114 template <typename T, int kFieldOffset>
Relaxed_Load_Map_Word(PtrComprCageBase cage_base,HeapObject host)115 T TaggedField<T, kFieldOffset>::Relaxed_Load_Map_Word(
116 PtrComprCageBase cage_base, HeapObject host) {
117 AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location(host, 0));
118 return T(tagged_to_full(cage_base, value));
119 }
120
121 // static
122 template <typename T, int kFieldOffset>
Relaxed_Store_Map_Word(HeapObject host,T value)123 void TaggedField<T, kFieldOffset>::Relaxed_Store_Map_Word(HeapObject host,
124 T value) {
125 AsAtomicTagged::Relaxed_Store(location(host), full_to_tagged(value.ptr()));
126 }
127
128 // static
129 template <typename T, int kFieldOffset>
Relaxed_Store(HeapObject host,T value)130 void TaggedField<T, kFieldOffset>::Relaxed_Store(HeapObject host, T value) {
131 Address ptr = value.ptr();
132 DCHECK_NE(kFieldOffset, HeapObject::kMapOffset);
133 AsAtomicTagged::Relaxed_Store(location(host), full_to_tagged(ptr));
134 }
135
136 // static
137 template <typename T, int kFieldOffset>
Relaxed_Store(HeapObject host,int offset,T value)138 void TaggedField<T, kFieldOffset>::Relaxed_Store(HeapObject host, int offset,
139 T value) {
140 Address ptr = value.ptr();
141 DCHECK_NE(kFieldOffset + offset, HeapObject::kMapOffset);
142 AsAtomicTagged::Relaxed_Store(location(host, offset), full_to_tagged(ptr));
143 }
144
145 // static
146 template <typename T, int kFieldOffset>
Acquire_Load(HeapObject host,int offset)147 T TaggedField<T, kFieldOffset>::Acquire_Load(HeapObject host, int offset) {
148 AtomicTagged_t value = AsAtomicTagged::Acquire_Load(location(host, offset));
149 DCHECK_NE(kFieldOffset + offset, HeapObject::kMapOffset);
150 return T(tagged_to_full(host.ptr(), value));
151 }
152
153 // static
154 template <typename T, int kFieldOffset>
Acquire_Load_No_Unpack(PtrComprCageBase cage_base,HeapObject host,int offset)155 T TaggedField<T, kFieldOffset>::Acquire_Load_No_Unpack(
156 PtrComprCageBase cage_base, HeapObject host, int offset) {
157 AtomicTagged_t value = AsAtomicTagged::Acquire_Load(location(host, offset));
158 return T(tagged_to_full(cage_base, value));
159 }
160
161 template <typename T, int kFieldOffset>
Acquire_Load(PtrComprCageBase cage_base,HeapObject host,int offset)162 T TaggedField<T, kFieldOffset>::Acquire_Load(PtrComprCageBase cage_base,
163 HeapObject host, int offset) {
164 AtomicTagged_t value = AsAtomicTagged::Acquire_Load(location(host, offset));
165 DCHECK_NE(kFieldOffset + offset, HeapObject::kMapOffset);
166 return T(tagged_to_full(cage_base, value));
167 }
168
169 // static
170 template <typename T, int kFieldOffset>
Release_Store(HeapObject host,T value)171 void TaggedField<T, kFieldOffset>::Release_Store(HeapObject host, T value) {
172 Address ptr = value.ptr();
173 DCHECK_NE(kFieldOffset, HeapObject::kMapOffset);
174 AsAtomicTagged::Release_Store(location(host), full_to_tagged(ptr));
175 }
176
177 // static
178 template <typename T, int kFieldOffset>
Release_Store_Map_Word(HeapObject host,T value)179 void TaggedField<T, kFieldOffset>::Release_Store_Map_Word(HeapObject host,
180 T value) {
181 Address ptr = value.ptr();
182 AsAtomicTagged::Release_Store(location(host), full_to_tagged(ptr));
183 }
184
185 // static
186 template <typename T, int kFieldOffset>
Release_Store(HeapObject host,int offset,T value)187 void TaggedField<T, kFieldOffset>::Release_Store(HeapObject host, int offset,
188 T value) {
189 Address ptr = value.ptr();
190 DCHECK_NE(kFieldOffset + offset, HeapObject::kMapOffset);
191 AsAtomicTagged::Release_Store(location(host, offset), full_to_tagged(ptr));
192 }
193
194 // static
195 template <typename T, int kFieldOffset>
Release_CompareAndSwap(HeapObject host,T old,T value)196 Tagged_t TaggedField<T, kFieldOffset>::Release_CompareAndSwap(HeapObject host,
197 T old, T value) {
198 Tagged_t old_value = full_to_tagged(old.ptr());
199 Tagged_t new_value = full_to_tagged(value.ptr());
200 Tagged_t result = AsAtomicTagged::Release_CompareAndSwap(
201 location(host), old_value, new_value);
202 return result;
203 }
204
205 // static
206 template <typename T, int kFieldOffset>
SeqCst_Load(HeapObject host,int offset)207 T TaggedField<T, kFieldOffset>::SeqCst_Load(HeapObject host, int offset) {
208 AtomicTagged_t value = AsAtomicTagged::SeqCst_Load(location(host, offset));
209 DCHECK_NE(kFieldOffset + offset, HeapObject::kMapOffset);
210 return T(tagged_to_full(host.ptr(), value));
211 }
212
213 // static
214 template <typename T, int kFieldOffset>
SeqCst_Load(PtrComprCageBase cage_base,HeapObject host,int offset)215 T TaggedField<T, kFieldOffset>::SeqCst_Load(PtrComprCageBase cage_base,
216 HeapObject host, int offset) {
217 AtomicTagged_t value = AsAtomicTagged::SeqCst_Load(location(host, offset));
218 DCHECK_NE(kFieldOffset + offset, HeapObject::kMapOffset);
219 return T(tagged_to_full(cage_base, value));
220 }
221
222 // static
223 template <typename T, int kFieldOffset>
SeqCst_Store(HeapObject host,T value)224 void TaggedField<T, kFieldOffset>::SeqCst_Store(HeapObject host, T value) {
225 Address ptr = value.ptr();
226 DCHECK_NE(kFieldOffset, HeapObject::kMapOffset);
227 AsAtomicTagged::SeqCst_Store(location(host), full_to_tagged(ptr));
228 }
229
230 // static
231 template <typename T, int kFieldOffset>
SeqCst_Store(HeapObject host,int offset,T value)232 void TaggedField<T, kFieldOffset>::SeqCst_Store(HeapObject host, int offset,
233 T value) {
234 Address ptr = value.ptr();
235 DCHECK_NE(kFieldOffset + offset, HeapObject::kMapOffset);
236 AsAtomicTagged::SeqCst_Store(location(host, offset), full_to_tagged(ptr));
237 }
238
239 // static
240 template <typename T, int kFieldOffset>
SeqCst_Swap(HeapObject host,int offset,T value)241 T TaggedField<T, kFieldOffset>::SeqCst_Swap(HeapObject host, int offset,
242 T value) {
243 Address ptr = value.ptr();
244 DCHECK_NE(kFieldOffset + offset, HeapObject::kMapOffset);
245 AtomicTagged_t old_value =
246 AsAtomicTagged::SeqCst_Swap(location(host, offset), full_to_tagged(ptr));
247 return T(tagged_to_full(host.ptr(), old_value));
248 }
249
250 // static
251 template <typename T, int kFieldOffset>
SeqCst_Swap(PtrComprCageBase cage_base,HeapObject host,int offset,T value)252 T TaggedField<T, kFieldOffset>::SeqCst_Swap(PtrComprCageBase cage_base,
253 HeapObject host, int offset,
254 T value) {
255 Address ptr = value.ptr();
256 DCHECK_NE(kFieldOffset + offset, HeapObject::kMapOffset);
257 AtomicTagged_t old_value =
258 AsAtomicTagged::SeqCst_Swap(location(host, offset), full_to_tagged(ptr));
259 return T(tagged_to_full(cage_base, old_value));
260 }
261
262 } // namespace internal
263 } // namespace v8
264
265 #endif // V8_OBJECTS_TAGGED_FIELD_INL_H_
266