1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef ECMASCRIPT_MEM_BARRIERS_GET_INL_H
17 #define ECMASCRIPT_MEM_BARRIERS_GET_INL_H
18
19 #include "ecmascript/js_tagged_value.h"
20 #include "ecmascript/js_thread.h"
21 #include "ecmascript/mem/barriers.h"
22
23 namespace panda::ecmascript {
ReadBarrier(const JSThread * thread,const void * obj,size_t offset,const JSTaggedValue & value)24 static ARK_INLINE JSTaggedType ReadBarrier(const JSThread *thread, const void *obj, size_t offset,
25 const JSTaggedValue &value)
26 {
27 if (value.IsHeapObject()) {
28 #ifdef ENABLE_CMC_RB_DFX
29 JSTaggedValue valueRB(reinterpret_cast<JSTaggedType>(
30 common::BaseRuntime::ReadBarrier(const_cast<void*>(obj), (void*) (ToUintPtr(obj) + offset))));
31 valueRB.RemoveReadBarrierDFXTag();
32 return valueRB.GetRawData();
33 #else
34 return reinterpret_cast<JSTaggedType>(
35 common::BaseRuntime::ReadBarrier(const_cast<void *>(obj), (void *)(ToUintPtr(obj) + offset)));
36 #endif
37 }
38 return value.GetRawData();
39 }
40
ReadBarrier(const JSThread * thread,uintptr_t slotAddress,const JSTaggedValue & value)41 static ARK_INLINE JSTaggedType ReadBarrier(const JSThread *thread, uintptr_t slotAddress, const JSTaggedValue &value)
42 {
43 if (value.IsHeapObject()) {
44 #ifdef ENABLE_CMC_RB_DFX
45 JSTaggedValue valueRB(
46 reinterpret_cast<JSTaggedType>(common::BaseRuntime::ReadBarrier((void *)slotAddress)));
47 valueRB.RemoveReadBarrierDFXTag();
48 return valueRB.GetRawData();
49 #else
50 return reinterpret_cast<JSTaggedType>(common::BaseRuntime::ReadBarrier((void*)slotAddress));
51 #endif
52 }
53 return value.GetRawData();
54 }
55
AtomicReadBarrier(const JSThread * thread,const void * obj,size_t offset,const JSTaggedValue & value)56 static ARK_INLINE JSTaggedType AtomicReadBarrier(const JSThread *thread, const void *obj, size_t offset,
57 const JSTaggedValue &value)
58 {
59 if (value.IsHeapObject()) {
60 #ifdef ENABLE_CMC_RB_DFX
61 JSTaggedValue value(reinterpret_cast<JSTaggedType>(common::BaseRuntime::AtomicReadBarrier(
62 const_cast<void*>(obj), (void*) (ToUintPtr(obj) + offset), std::memory_order_acquire)));
63 value.RemoveReadBarrierDFXTag();
64 return value.GetRawData();
65 #else
66 return reinterpret_cast<JSTaggedType>(common::BaseRuntime::AtomicReadBarrier(
67 const_cast<void *>(obj), (void *)(ToUintPtr(obj) + offset), std::memory_order_acquire));
68 #endif
69 }
70 return value.GetRawData();
71 }
72
ReadBarrierForObject(const JSThread * thread,uintptr_t slotAddress)73 inline ARK_INLINE JSTaggedType Barriers::ReadBarrierForObject(const JSThread *thread, uintptr_t slotAddress)
74 {
75 #ifdef ENABLE_CMC_RB_DFX
76 JSTaggedValue valueRB(
77 reinterpret_cast<JSTaggedType>(common::BaseRuntime::ReadBarrier((void *)slotAddress)));
78 valueRB.RemoveReadBarrierDFXTag();
79 return valueRB.GetRawData();
80 #else
81 return reinterpret_cast<JSTaggedType>(common::BaseRuntime::ReadBarrier((void*)slotAddress));
82 #endif
83 }
84
GetTaggedValue(const JSThread * thread,const void * obj,size_t offset)85 inline ARK_INLINE JSTaggedType Barriers::GetTaggedValue(const JSThread *thread, const void *obj, size_t offset)
86 {
87 JSTaggedValue value = *reinterpret_cast<JSTaggedValue *>(ToUintPtr(obj) + offset);
88 ASSERT(thread != nullptr);
89 if (UNLIKELY(thread->NeedReadBarrier())) {
90 return ReadBarrier(thread, obj, offset, value);
91 }
92 return value.GetRawData();
93 }
94
GetTaggedValue(const JSThread * thread,uintptr_t slotAddress)95 inline ARK_INLINE JSTaggedType Barriers::GetTaggedValue(const JSThread *thread, uintptr_t slotAddress)
96 {
97 JSTaggedValue value = *reinterpret_cast<JSTaggedValue *>(slotAddress);
98 ASSERT(thread != nullptr);
99 if (UNLIKELY(thread->NeedReadBarrier())) {
100 return ReadBarrier(thread, slotAddress, value);
101 }
102 return value.GetRawData();
103 }
104
GetTaggedValueAtomic(const JSThread * thread,const void * obj,size_t offset)105 inline ARK_INLINE JSTaggedType Barriers::GetTaggedValueAtomic(const JSThread *thread, const void *obj, size_t offset)
106 {
107 JSTaggedValue value = reinterpret_cast<volatile std::atomic<JSTaggedValue> *>(ToUintPtr(obj) +
108 offset)->load(std::memory_order_acquire);
109 ASSERT(thread != nullptr);
110 if (UNLIKELY(thread->NeedReadBarrier())) {
111 return AtomicReadBarrier(thread, obj, offset, value);
112 }
113 return value.GetRawData();
114 }
115
116 template <RBMode mode>
GetTaggedValue(const JSThread * thread,const void * obj,size_t offset)117 inline ARK_INLINE JSTaggedType Barriers::GetTaggedValue(const JSThread *thread, const void *obj, size_t offset)
118 {
119 JSTaggedValue value = *reinterpret_cast<JSTaggedValue *>(ToUintPtr(obj) + offset);
120 if constexpr (mode == RBMode::DEFAULT_RB) {
121 ASSERT(thread != nullptr);
122 if (UNLIKELY(thread->NeedReadBarrier())) {
123 return ReadBarrier(thread, obj, offset, value);
124 }
125 } else if constexpr (mode == RBMode::FAST_CMC_RB) {
126 return ReadBarrier(thread, obj, offset, value);
127 }
128
129 return value.GetRawData();
130 }
131
132 template <RBMode mode>
GetTaggedValue(const JSThread * thread,uintptr_t slotAddress)133 inline ARK_INLINE JSTaggedType Barriers::GetTaggedValue(const JSThread *thread, uintptr_t slotAddress)
134 {
135 JSTaggedValue value = *reinterpret_cast<JSTaggedValue *>(slotAddress);
136 if constexpr (mode == RBMode::DEFAULT_RB) {
137 ASSERT(thread != nullptr);
138 if (UNLIKELY(thread->NeedReadBarrier())) {
139 return ReadBarrier(thread, slotAddress, value);
140 }
141 } else if constexpr (mode == RBMode::FAST_CMC_RB) {
142 return ReadBarrier(thread, slotAddress, value);
143 }
144
145 return value.GetRawData();
146 }
147
148 template <RBMode mode>
GetTaggedValueAtomic(const JSThread * thread,const void * obj,size_t offset)149 inline ARK_INLINE JSTaggedType Barriers::GetTaggedValueAtomic(const JSThread *thread, const void *obj, size_t offset)
150 {
151 JSTaggedValue value = reinterpret_cast<volatile std::atomic<JSTaggedValue> *>(ToUintPtr(obj) +
152 offset)->load(std::memory_order_acquire);
153 if constexpr (mode == RBMode::DEFAULT_RB) {
154 ASSERT(thread != nullptr);
155 if (UNLIKELY(thread->NeedReadBarrier())) {
156 return AtomicReadBarrier(thread, obj, offset, value);
157 }
158 } else if constexpr (mode == RBMode::FAST_CMC_RB) {
159 return AtomicReadBarrier(thread, obj, offset, value);
160 }
161
162 return value.GetRawData();
163 }
164
GetTaggedObject(const JSThread * thread,const void * obj,size_t offset)165 inline ARK_INLINE TaggedObject* Barriers::GetTaggedObject(const JSThread *thread, const void* obj, size_t offset)
166 {
167 return JSTaggedValue(GetTaggedValue(thread, obj, offset)).GetTaggedObject();
168 }
169
170 template <RBMode mode>
GetTaggedObject(const JSThread * thread,const void * obj,size_t offset)171 inline ARK_INLINE TaggedObject* Barriers::GetTaggedObject(const JSThread *thread, const void *obj, size_t offset)
172 {
173 return JSTaggedValue(GetTaggedValue<mode>(thread, obj, offset)).GetTaggedObject();
174 }
175
UpdateSlot(const JSThread * thread,void * obj,size_t offset)176 inline ARK_INLINE JSTaggedType Barriers::UpdateSlot(const JSThread *thread, void *obj, size_t offset)
177 {
178 JSTaggedType value = GetTaggedValue(thread, obj, offset);
179 *reinterpret_cast<JSTaggedType *>(ToUintPtr(obj) + offset) = value;
180 return value;
181 }
182 } // namespace panda::ecmascript
183
184 #endif // ECMASCRIPT_MEM_BARRIERS_GET_INL_H
185