• 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 PANDA_RUNTIME_INCLUDE_OBJECT_ACCESSOR_H_
17 #define PANDA_RUNTIME_INCLUDE_OBJECT_ACCESSOR_H_
18 
19 #include <cstddef>
20 
21 #include "runtime/mem/gc/gc_barrier_set.h"
22 
23 namespace panda {
24 
25 class ObjectHeader;
26 class Field;
27 class ManagedThread;
28 
29 class ObjectAccessor {
30 public:
31     template <class T, bool is_volatile = false>
GetPrimitive(const void * obj,size_t offset)32     static T GetPrimitive(const void *obj, size_t offset)
33     {
34         return Get<T, is_volatile>(obj, offset);
35     }
36 
37     template <class T, bool is_volatile = false>
SetPrimitive(void * obj,size_t offset,T value)38     static void SetPrimitive(void *obj, size_t offset, T value)
39     {
40         Set<T, is_volatile>(obj, offset, value);
41     }
42 
43     template <bool is_volatile = false, bool need_read_barrier = true, bool is_dyn = false>
44     static ObjectHeader *GetObject(const void *obj, size_t offset);
45 
46     template <bool is_volatile = false, bool need_write_barrier = true, bool is_dyn = false>
47     static void SetObject(void *obj, size_t offset, ObjectHeader *value);
48 
49     template <class T>
50     static T GetFieldPrimitive(const void *obj, const Field &field);
51 
52     template <class T>
53     static void SetFieldPrimitive(void *obj, const Field &field, T value);
54 
55     template <bool need_read_barrier = true, bool is_dyn = false>
56     static ObjectHeader *GetFieldObject(const void *obj, const Field &field);
57 
58     template <bool need_write_barrier = true, bool is_dyn = false>
59     static void SetFieldObject(void *obj, const Field &field, ObjectHeader *value);
60 
61     // Pass thread parameter to speed up interpreter
62     template <bool is_volatile = false, bool need_read_barrier = true, bool is_dyn = false>
63     static ObjectHeader *GetObject(const ManagedThread *thread, const void *obj, size_t offset);
64 
65     template <bool is_volatile = false, bool need_write_barrier = true, bool is_dyn = false>
66     static void SetObject(const ManagedThread *thread, void *obj, size_t offset, ObjectHeader *value);
67 
68     template <bool need_read_barrier = true, bool is_dyn = false>
69     static ObjectHeader *GetFieldObject(ManagedThread *thread, const void *obj, const Field &field);
70 
71     template <bool need_write_barrier = true, bool is_dyn = false>
72     static void SetFieldObject(ManagedThread *thread, void *obj, const Field &field, ObjectHeader *value);
73 
74     template <class T>
75     static T GetFieldPrimitive(const void *obj, size_t offset, std::memory_order memory_order);
76 
77     template <class T>
78     static void SetFieldPrimitive(void *obj, size_t offset, T value, std::memory_order memory_order);
79 
80     template <bool need_read_barrier = true, bool is_dyn = false>
81     static ObjectHeader *GetFieldObject(const void *obj, int offset, std::memory_order memory_order);
82 
83     template <bool need_write_barrier = true, bool is_dyn = false>
84     static void SetFieldObject(void *obj, size_t offset, ObjectHeader *value, std::memory_order memory_order);
85 
86     template <typename T>
87     static std::pair<bool, T> CompareAndSetFieldPrimitive(void *obj, size_t offset, T old_value, T new_value,
88                                                           std::memory_order memory_order, bool strong);
89 
90     template <bool need_write_barrier = true, bool is_dyn = false>
91     static std::pair<bool, ObjectHeader *> CompareAndSetFieldObject(void *obj, size_t offset, ObjectHeader *old_value,
92                                                                     ObjectHeader *new_value,
93                                                                     std::memory_order memory_order, bool strong);
94 
95     template <typename T>
96     static T GetAndSetFieldPrimitive(void *obj, size_t offset, T value, std::memory_order memory_order);
97 
98     template <bool need_write_barrier = true, bool is_dyn = false>
99     static ObjectHeader *GetAndSetFieldObject(void *obj, size_t offset, ObjectHeader *value,
100                                               std::memory_order memory_order);
101 
102     template <typename T>
103     static T GetAndAddFieldPrimitive(void *obj, size_t offset, T value, std::memory_order memory_order);
104 
105     template <typename T>
106     static T GetAndBitwiseOrFieldPrimitive(void *obj, size_t offset, T value, std::memory_order memory_order);
107 
108     template <typename T>
109     static T GetAndBitwiseAndFieldPrimitive(void *obj, size_t offset, T value, std::memory_order memory_order);
110 
111     template <typename T>
112     static T GetAndBitwiseXorFieldPrimitive(void *obj, size_t offset, T value, std::memory_order memory_order);
113 
114     template <class T>
SetDynPrimitive(void * obj,size_t offset,T value)115     static inline void SetDynPrimitive(void *obj, size_t offset, T value)
116     {
117         auto *addr = reinterpret_cast<T *>(ToUintPtr(obj) + offset);
118         ASSERT(IsInObjectsAddressSpace(ToUintPtr(addr)));
119         *addr = value;
120     }
121 
122     template <bool need_write_barrier = true>
123     static inline void SetDynObject(const ManagedThread *thread, void *obj, size_t offset, ObjectHeader *value);
124 
125     template <class T>
GetDynValue(const void * obj,size_t offset)126     static inline T GetDynValue(const void *obj, size_t offset)
127     {
128         auto *addr = reinterpret_cast<T *>(ToUintPtr(obj) + offset);
129         ASSERT(IsInObjectsAddressSpace(ToUintPtr(addr)));
130         return *addr;
131     }
132 
133 private:
134     template <class T, bool is_volatile>
Get(const void * obj,size_t offset)135     static T Get(const void *obj, size_t offset)
136     {
137         auto *addr = reinterpret_cast<T *>(reinterpret_cast<uintptr_t>(obj) + offset);
138         ASSERT(IsInObjectsAddressSpace(ToUintPtr(addr)));
139         if (is_volatile) {
140             return reinterpret_cast<const std::atomic<T> *>(addr)->load(std::memory_order_seq_cst);
141         }
142         return reinterpret_cast<const std::atomic<T> *>(addr)->load(std::memory_order_relaxed);
143     }
144 
145     template <class T, bool is_volatile>
Set(void * obj,size_t offset,T value)146     static void Set(void *obj, size_t offset, T value)
147     {
148         auto *addr = reinterpret_cast<T *>(reinterpret_cast<uintptr_t>(obj) + offset);
149         ASSERT(IsInObjectsAddressSpace(ToUintPtr(addr)));
150         if (is_volatile) {
151             return reinterpret_cast<std::atomic<T> *>(addr)->store(value, std::memory_order_seq_cst);
152         }
153         return reinterpret_cast<std::atomic<T> *>(addr)->store(value, std::memory_order_relaxed);
154     }
155 
156     template <class T>
Get(const void * obj,size_t offset,std::memory_order memory_order)157     static T Get(const void *obj, size_t offset, std::memory_order memory_order)
158     {
159         auto *addr = reinterpret_cast<T *>(reinterpret_cast<uintptr_t>(obj) + offset);
160         ASSERT(IsInObjectsAddressSpace(ToUintPtr(addr)));
161         return reinterpret_cast<const std::atomic<T> *>(addr)->load(memory_order);
162     }
163 
164     template <class T>
Set(void * obj,size_t offset,T value,std::memory_order memory_order)165     static void Set(void *obj, size_t offset, T value, std::memory_order memory_order)
166     {
167         auto *addr = reinterpret_cast<T *>(reinterpret_cast<uintptr_t>(obj) + offset);
168         ASSERT(IsInObjectsAddressSpace(ToUintPtr(addr)));
169         return reinterpret_cast<std::atomic<T> *>(addr)->store(value, memory_order);
170     }
171 
172     static mem::GCBarrierSet *GetBarrierSet();
173 
174     static mem::GCBarrierSet *GetBarrierSet(const ManagedThread *thread);
175 
176     static mem::BarrierType GetPreBarrierType(const ManagedThread *thread);
177 
178     static mem::BarrierType GetPostBarrierType(const ManagedThread *thread);
179 };
180 
181 }  // namespace panda
182 
183 #endif  // PANDA_RUNTIME_INCLUDE_OBJECT_ACCESSOR_H_
184