• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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_H
17 #define ECMASCRIPT_MEM_BARRIERS_H
18 
19 #include "ecmascript/common.h"
20 #include "ecmascript/js_tagged_value.h"
21 #include "ecmascript/mem/mark_word.h"
22 #include "ecmascript/mem/mem_common.h"
23 #include "common_interfaces/base_runtime.h"
24 #include "common_interfaces/thread/mutator_base.h"
25 
26 namespace panda::ecmascript {
27 class Region;
28 
29 enum class WriteBarrierType : size_t { NORMAL, DESERIALIZE, AOT_DESERIALIZE };
30 
31 class Barriers {
32 public:
33     template<class T>
SetPrimitive(void * obj,size_t offset,T value)34     static inline void SetPrimitive(void *obj, size_t offset, T value)
35     {
36         auto *addr = reinterpret_cast<T *>(ToUintPtr(obj) + offset);
37         // NOLINTNEXTLINE(clang-analyzer-core.NullDereference)
38         *addr = value;
39     }
40 
41 #ifdef ARK_USE_SATB_BARRIER
42     template<>
SetPrimitive(void * obj,size_t offset,JSTaggedType value)43     inline void SetPrimitive(void *obj, size_t offset, JSTaggedType value)
44     {
45         // NOT USE IN Concrruent Enum Barrier
46         CMCWriteBarrier(nullptr, obj, offset, JSTaggedValue::Hole().GetRawData());
47         auto *addr = reinterpret_cast<JSTaggedType *>(ToUintPtr(obj) + offset);
48         // NOLINTNEXTLINE(clang-analyzer-core.NullDereference)
49         *addr = value;
50         // thread not be used, and satb barrier don't need newvalue.
51     }
52 #endif
53 
54     template<class T>
AtomicSetPrimitive(volatile void * obj,size_t offset,T oldValue,T value)55     static inline T AtomicSetPrimitive(volatile void *obj, size_t offset, T oldValue, T value)
56     {
57         volatile auto atomicField = reinterpret_cast<volatile std::atomic<T> *>(ToUintPtr(obj) + offset);
58         std::atomic_compare_exchange_strong_explicit(atomicField, &oldValue, value, std::memory_order_release,
59                                                      std::memory_order_relaxed);
60         return oldValue;
61     }
62 
63     template<bool needWriteBarrier = true>
64     static void SetObject(const JSThread *thread, void *obj, size_t offset, JSTaggedType value);
65 
66     // dstAddr/srcAddr is the address will be copied to/from.
67     // It can be a derived pointer point to the middle of an object.
68     //
69     // Note: dstObj is the object address for dstAddr, it must point to the head of an object.
70     template <bool needWriteBarrier, bool maybeOverlap>
71     static void CopyObject(const JSThread *thread, const TaggedObject *dstObj, JSTaggedValue *dstAddr,
72                            const JSTaggedValue *srcAddr, size_t count);
73 
74     // dstAddr/srcAddr is the address will be copied to/from.
75     // It can be a derived pointer point to the middle of an object.
76     //
77     // Note: dstObj is the object address for dstAddr, it must point to the head of an object.
78     template<bool needReadBarrier, bool maybeOverlap>
79     static void CopyObjectPrimitive(const JSThread *thread, JSTaggedValue* dst, const JSTaggedValue* src,
80         size_t count);
81     static void SynchronizedSetObject(const JSThread *thread, void *obj, size_t offset, JSTaggedType value,
82                                       bool isPrimitive = false);
83 
84     template<class T>
GetPrimitive(const void * obj,size_t offset)85     static inline T GetPrimitive(const void *obj, size_t offset)
86     {
87         auto *addr = reinterpret_cast<T *>(ToUintPtr(obj) + offset);
88         return *addr;
89     }
90 
91     static JSTaggedType ReadBarrierForObject(const JSThread *thread, uintptr_t value);
92 
93     static TaggedObject* GetTaggedObject(const JSThread *thread, const void* obj, size_t offset);
94     static JSTaggedType GetTaggedValue(const JSThread *thread, const void *obj, size_t offset);
95     static JSTaggedType GetTaggedValue(const JSThread *thread, uintptr_t slotAddress);
96     static JSTaggedType GetTaggedValueAtomic(const JSThread *thread, const void *obj, size_t offset);
97     static JSTaggedType UpdateSlot(const JSThread *thread, void *obj, size_t offset);
98 
99     template <RBMode mode = RBMode::DEFAULT_RB>
100     static TaggedObject *GetTaggedObject(const JSThread *thread, const void *obj, size_t offset);
101 
102     template <RBMode mode>
103     static JSTaggedType GetTaggedValue(const JSThread *thread, const void *obj, size_t offset);
104 
105     template <RBMode mode>
106     static JSTaggedType GetTaggedValue(const JSThread *thread, uintptr_t slotAddress);
107 
108     template <RBMode mode>
109     static JSTaggedType GetTaggedValueAtomic(const JSThread *thread, const void *obj, size_t offset);
110 
111     static void PUBLIC_API Update(const JSThread *thread, uintptr_t slotAddr, Region *objectRegion,
112                                   TaggedObject *value, Region *valueRegion,
113                                   WriteBarrierType writeType = WriteBarrierType::NORMAL);
114 
115     static void PUBLIC_API UpdateShared(const JSThread *thread, uintptr_t slotAddr, Region *objectRegion,
116                                         TaggedObject *value, Region *valueRegion);
117     static void PUBLIC_API CMCWriteBarrier(const JSThread *thread, void *obj, size_t offset, JSTaggedType value);
118     static void PUBLIC_API CMCArrayCopyWriteBarrier(const JSThread *thread, const TaggedObject *dstObj,
119                                                         void* src, void* dst, size_t count);
120     static bool ShouldProcessSATB(common::GCPhase gcPhase);
121     static bool ShouldGetGCReason(common::GCPhase gcPhase);
122     static bool ShouldUpdateRememberSet(common::GCPhase gcPhase);
123 
124     static void CMCArrayCopyReadBarrierForward(const JSThread *thread, JSTaggedValue* dst, const JSTaggedValue* src,
125                                                size_t count);
126     static void CMCArrayCopyReadBarrierBackward(const JSThread *thread, JSTaggedValue* dst, const JSTaggedValue* src,
127                                                 size_t count);
128 };
129 }  // namespace panda::ecmascript
130 
131 #endif  // ECMASCRIPT_MEM_BARRIERS_H
132