• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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