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 return T(tagged_to_full(host.ptr(), value));
60 }
61
62 // static
63 template <typename T, int kFieldOffset>
load(IsolateRoot isolate,HeapObject host,int offset)64 T TaggedField<T, kFieldOffset>::load(IsolateRoot isolate, HeapObject host,
65 int offset) {
66 Tagged_t value = *location(host, offset);
67 return T(tagged_to_full(isolate, value));
68 }
69
70 // static
71 template <typename T, int kFieldOffset>
store(HeapObject host,T value)72 void TaggedField<T, kFieldOffset>::store(HeapObject host, T value) {
73 #ifdef V8_ATOMIC_OBJECT_FIELD_WRITES
74 Relaxed_Store(host, value);
75 #else
76 *location(host) = full_to_tagged(value.ptr());
77 #endif
78 }
79
80 // static
81 template <typename T, int kFieldOffset>
store(HeapObject host,int offset,T value)82 void TaggedField<T, kFieldOffset>::store(HeapObject host, int offset, T value) {
83 #ifdef V8_ATOMIC_OBJECT_FIELD_WRITES
84 Relaxed_Store(host, offset, value);
85 #else
86 *location(host, offset) = full_to_tagged(value.ptr());
87 #endif
88 }
89
90 // static
91 template <typename T, int kFieldOffset>
Relaxed_Load(HeapObject host,int offset)92 T TaggedField<T, kFieldOffset>::Relaxed_Load(HeapObject host, int offset) {
93 AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location(host, offset));
94 return T(tagged_to_full(host.ptr(), value));
95 }
96
97 // static
98 template <typename T, int kFieldOffset>
Relaxed_Load(IsolateRoot isolate,HeapObject host,int offset)99 T TaggedField<T, kFieldOffset>::Relaxed_Load(IsolateRoot isolate,
100 HeapObject host, int offset) {
101 AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location(host, offset));
102 return T(tagged_to_full(isolate, value));
103 }
104
105 // static
106 template <typename T, int kFieldOffset>
Relaxed_Store(HeapObject host,T value)107 void TaggedField<T, kFieldOffset>::Relaxed_Store(HeapObject host, T value) {
108 AsAtomicTagged::Relaxed_Store(location(host), full_to_tagged(value.ptr()));
109 }
110
111 // static
112 template <typename T, int kFieldOffset>
Relaxed_Store(HeapObject host,int offset,T value)113 void TaggedField<T, kFieldOffset>::Relaxed_Store(HeapObject host, int offset,
114 T value) {
115 AsAtomicTagged::Relaxed_Store(location(host, offset),
116 full_to_tagged(value.ptr()));
117 }
118
119 // static
120 template <typename T, int kFieldOffset>
Acquire_Load(HeapObject host,int offset)121 T TaggedField<T, kFieldOffset>::Acquire_Load(HeapObject host, int offset) {
122 AtomicTagged_t value = AsAtomicTagged::Acquire_Load(location(host, offset));
123 return T(tagged_to_full(host.ptr(), value));
124 }
125
126 // static
127 template <typename T, int kFieldOffset>
Acquire_Load(IsolateRoot isolate,HeapObject host,int offset)128 T TaggedField<T, kFieldOffset>::Acquire_Load(IsolateRoot isolate,
129 HeapObject host, int offset) {
130 AtomicTagged_t value = AsAtomicTagged::Acquire_Load(location(host, offset));
131 return T(tagged_to_full(isolate, value));
132 }
133
134 // static
135 template <typename T, int kFieldOffset>
Release_Store(HeapObject host,T value)136 void TaggedField<T, kFieldOffset>::Release_Store(HeapObject host, T value) {
137 AsAtomicTagged::Release_Store(location(host), full_to_tagged(value.ptr()));
138 }
139
140 // static
141 template <typename T, int kFieldOffset>
Release_Store(HeapObject host,int offset,T value)142 void TaggedField<T, kFieldOffset>::Release_Store(HeapObject host, int offset,
143 T value) {
144 AsAtomicTagged::Release_Store(location(host, offset),
145 full_to_tagged(value.ptr()));
146 }
147
148 // static
149 template <typename T, int kFieldOffset>
Release_CompareAndSwap(HeapObject host,T old,T value)150 Tagged_t TaggedField<T, kFieldOffset>::Release_CompareAndSwap(HeapObject host,
151 T old, T value) {
152 Tagged_t old_value = full_to_tagged(old.ptr());
153 Tagged_t new_value = full_to_tagged(value.ptr());
154 Tagged_t result = AsAtomicTagged::Release_CompareAndSwap(
155 location(host), old_value, new_value);
156 return result;
157 }
158
159 } // namespace internal
160 } // namespace v8
161
162 #endif // V8_OBJECTS_TAGGED_FIELD_INL_H_
163