• 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_CLASS_INL_H_
17 #define PANDA_RUNTIME_INCLUDE_CLASS_INL_H_
18 
19 #include "runtime/include/class.h"
20 #include "runtime/include/coretypes/tagged_value.h"
21 #include "runtime/include/object_accessor-inl.h"
22 
23 namespace panda {
24 
GetTypeSize(panda_file::Type type)25 inline uint32_t Class::GetTypeSize(panda_file::Type type)
26 {
27     switch (type.GetId()) {
28         case panda_file::Type::TypeId::U1:
29         case panda_file::Type::TypeId::I8:
30         case panda_file::Type::TypeId::U8:
31             return sizeof(uint8_t);
32         case panda_file::Type::TypeId::I16:
33         case panda_file::Type::TypeId::U16:
34             return sizeof(uint16_t);
35         case panda_file::Type::TypeId::I32:
36         case panda_file::Type::TypeId::U32:
37         case panda_file::Type::TypeId::F32:
38             return sizeof(uint32_t);
39         case panda_file::Type::TypeId::I64:
40         case panda_file::Type::TypeId::U64:
41         case panda_file::Type::TypeId::F64:
42             return sizeof(uint64_t);
43         case panda_file::Type::TypeId::TAGGED:
44             return coretypes::TaggedValue::TaggedTypeSize();
45         case panda_file::Type::TypeId::REFERENCE:
46             return ClassHelper::OBJECT_POINTER_SIZE;
47         default:
48             UNREACHABLE();
49     }
50 }
51 
GetComponentSize()52 inline uint32_t Class::GetComponentSize() const
53 {
54     if (component_type_ == nullptr) {
55         return 0;
56     }
57 
58     return GetTypeSize(component_type_->GetType());
59 }
60 
IsSubClassOf(const Class * klass)61 inline bool Class::IsSubClassOf(const Class *klass) const
62 {
63     const Class *current = this;
64 
65     do {
66         if (current == klass) {
67             return true;
68         }
69 
70         current = current->GetBase();
71     } while (current != nullptr);
72 
73     return false;
74 }
75 
IsAssignableFrom(const Class * klass)76 inline bool Class::IsAssignableFrom(const Class *klass) const
77 {
78     if (klass == this) {
79         return true;
80     }
81     if (IsObjectClass()) {
82         return !klass->IsPrimitive();
83     }
84     if (IsInterface()) {
85         return klass->Implements(this);
86     }
87     if (klass->IsArrayClass()) {
88         return IsArrayClass() && GetComponentType()->IsAssignableFrom(klass->GetComponentType());
89     }
90     return !klass->IsInterface() && klass->IsSubClassOf(this);
91 }
92 
Implements(const Class * klass)93 inline bool Class::Implements(const Class *klass) const
94 {
95     for (const auto &elem : itable_.Get()) {
96         if (elem.GetInterface() == klass) {
97             return true;
98         }
99     }
100 
101     return false;
102 }
103 
104 template <Class::FindFilter filter>
GetFields()105 inline Span<Field> Class::GetFields() const
106 {
107     switch (filter) {
108         case FindFilter::STATIC:
109             return GetStaticFields();
110         case FindFilter::INSTANCE:
111             return GetInstanceFields();
112         case FindFilter::ALL:
113             return GetFields();
114         default:
115             UNREACHABLE();
116     }
117 }
118 
119 template <Class::FindFilter filter, class Pred>
FindDeclaredField(Pred pred)120 inline Field *Class::FindDeclaredField(Pred pred) const
121 {
122     auto fields = GetFields<filter>();
123     auto it = std::find_if(fields.begin(), fields.end(), pred);
124     if (it != fields.end()) {
125         return &*it;
126     }
127     return nullptr;
128 }
129 
130 template <Class::FindFilter filter, class Pred>
FindField(Pred pred)131 inline Field *Class::FindField(Pred pred) const
132 {
133     auto *cls = this;
134     while (cls != nullptr) {
135         auto *field = cls->FindDeclaredField<filter>(pred);
136         if (field != nullptr) {
137             return field;
138         }
139 
140         cls = cls->GetBase();
141     }
142 
143     if (filter == FindFilter::STATIC || filter == FindFilter::ALL) {
144         auto *kls = this;
145         while (kls != nullptr) {
146             for (auto *iface : kls->GetInterfaces()) {
147                 auto *field = iface->FindField<filter>(pred);
148                 if (field != nullptr) {
149                     return field;
150                 }
151             }
152 
153             kls = kls->GetBase();
154         }
155     }
156 
157     return nullptr;
158 }
159 
160 template <Class::FindFilter filter>
GetMethods()161 inline Span<Method> Class::GetMethods() const
162 {
163     switch (filter) {
164         case FindFilter::STATIC:
165             return GetStaticMethods();
166         case FindFilter::INSTANCE:
167             return GetVirtualMethods();
168         case FindFilter::ALL:
169             return GetMethods();
170         case FindFilter::COPIED:
171             return GetCopiedMethods();
172         default:
173             UNREACHABLE();
174     }
175 }
176 
177 template <Class::FindFilter filter, class Pred>
FindDirectMethod(Pred pred)178 inline Method *Class::FindDirectMethod(Pred pred) const
179 {
180     auto methods = GetMethods<filter>();
181     auto it = std::find_if(methods.begin(), methods.end(), pred);
182     if (it != methods.end()) {
183         return &*it;
184     }
185     return nullptr;
186 }
187 
188 template <Class::FindFilter filter, class Pred>
FindClassMethod(Pred pred)189 inline Method *Class::FindClassMethod(Pred pred) const
190 {
191     auto *cls = this;
192     while (cls != nullptr) {
193         auto *method = cls->FindDirectMethod<filter>(pred);
194         if (method != nullptr) {
195             return method;
196         }
197 
198         cls = cls->GetBase();
199     }
200 
201     if (filter == FindFilter::ALL || filter == FindFilter::INSTANCE) {
202         return FindClassMethod<FindFilter::COPIED>(pred);
203     }
204 
205     return nullptr;
206 }
207 
208 template <Class::FindFilter filter, class Pred>
FindInterfaceMethod(Pred pred)209 inline Method *Class::FindInterfaceMethod(Pred pred) const
210 {
211     static_assert(filter != FindFilter::COPIED, "interfaces don't have copied methods");
212 
213     if (LIKELY(IsInterface())) {
214         auto *method = FindDirectMethod<filter>(pred);
215         if (method != nullptr) {
216             return method;
217         }
218     }
219 
220     if (filter == FindFilter::STATIC) {
221         return nullptr;
222     }
223 
224     for (const auto &entry : itable_.Get()) {
225         auto *iface = entry.GetInterface();
226         auto *method = iface->FindDirectMethod<FindFilter::INSTANCE>(pred);
227         if (method != nullptr) {
228             return method;
229         }
230     }
231 
232     if (LIKELY(IsInterface())) {
233         return GetBase()->FindDirectMethod<FindFilter::INSTANCE>(
234             [&pred](const Method &method) { return method.IsPublic() && pred(method); });
235     }
236 
237     return nullptr;
238 }
239 
240 template <class Pred>
FindInterfaceMethod(Pred pred)241 inline Method *Class::FindInterfaceMethod(Pred pred) const
242 {
243     return FindInterfaceMethod<FindFilter::ALL>(pred);
244 }
245 
246 template <class Pred>
FindVirtualInterfaceMethod(Pred pred)247 inline Method *Class::FindVirtualInterfaceMethod(Pred pred) const
248 {
249     return FindInterfaceMethod<FindFilter::INSTANCE>(pred);
250 }
251 
252 template <class Pred>
FindStaticInterfaceMethod(Pred pred)253 inline Method *Class::FindStaticInterfaceMethod(Pred pred) const
254 {
255     return FindInterfaceMethod<FindFilter::STATIC>(pred);
256 }
257 
258 template <class Pred>
FindInstanceField(Pred pred)259 inline Field *Class::FindInstanceField(Pred pred) const
260 {
261     return FindField<FindFilter::INSTANCE>(pred);
262 }
263 
264 template <class Pred>
FindStaticField(Pred pred)265 inline Field *Class::FindStaticField(Pred pred) const
266 {
267     return FindField<FindFilter::STATIC>(pred);
268 }
269 
270 template <class Pred>
FindField(Pred pred)271 inline Field *Class::FindField(Pred pred) const
272 {
273     return FindField<FindFilter::ALL>(pred);
274 }
275 
276 template <class Pred>
FindDeclaredField(Pred pred)277 inline Field *Class::FindDeclaredField(Pred pred) const
278 {
279     return FindDeclaredField<FindFilter::ALL>(pred);
280 }
281 
GetInstanceFieldByName(const uint8_t * mutf8_name)282 inline Field *Class::GetInstanceFieldByName(const uint8_t *mutf8_name) const
283 {
284     panda_file::File::StringData sd = {static_cast<uint32_t>(panda::utf::MUtf8ToUtf16Size(mutf8_name)), mutf8_name};
285     return FindInstanceField([sd](const Field &field) { return field.GetName() == sd; });
286 }
287 
GetStaticFieldByName(const uint8_t * mutf8_name)288 inline Field *Class::GetStaticFieldByName(const uint8_t *mutf8_name) const
289 {
290     panda_file::File::StringData sd = {static_cast<uint32_t>(panda::utf::MUtf8ToUtf16Size(mutf8_name)), mutf8_name};
291     return FindStaticField([sd](const Field &field) { return field.GetName() == sd; });
292 }
293 
GetDeclaredFieldByName(const uint8_t * mutf8_name)294 inline Field *Class::GetDeclaredFieldByName(const uint8_t *mutf8_name) const
295 {
296     panda_file::File::StringData sd = {static_cast<uint32_t>(panda::utf::MUtf8ToUtf16Size(mutf8_name)), mutf8_name};
297     return FindDeclaredField([sd](const Field &field) { return field.GetName() == sd; });
298 }
299 
300 template <class Pred>
FindVirtualClassMethod(Pred pred)301 inline Method *Class::FindVirtualClassMethod(Pred pred) const
302 {
303     return FindClassMethod<FindFilter::INSTANCE>(pred);
304 }
305 
306 template <class Pred>
FindStaticClassMethod(Pred pred)307 inline Method *Class::FindStaticClassMethod(Pred pred) const
308 {
309     return FindClassMethod<FindFilter::STATIC>(pred);
310 }
311 
312 template <class Pred>
FindClassMethod(Pred pred)313 inline Method *Class::FindClassMethod(Pred pred) const
314 {
315     return FindClassMethod<FindFilter::ALL>(pred);
316 }
317 
GetDirectMethod(const uint8_t * mutf8_name,const Method::Proto & proto)318 inline Method *Class::GetDirectMethod(const uint8_t *mutf8_name, const Method::Proto &proto) const
319 {
320     panda_file::File::StringData sd = {static_cast<uint32_t>(panda::utf::MUtf8ToUtf16Size(mutf8_name)), mutf8_name};
321     return FindDirectMethod<FindFilter::ALL>(
322         [sd, proto](const Method &method) { return method.GetName() == sd && method.GetProto() == proto; });
323 }
324 
GetClassMethod(const uint8_t * mutf8_name,const Method::Proto & proto)325 inline Method *Class::GetClassMethod(const uint8_t *mutf8_name, const Method::Proto &proto) const
326 {
327     panda_file::File::StringData sd = {static_cast<uint32_t>(panda::utf::MUtf8ToUtf16Size(mutf8_name)), mutf8_name};
328     return FindClassMethod(
329         [sd, proto](const Method &method) { return method.GetName() == sd && method.GetProto() == proto; });
330 }
331 
GetInterfaceMethod(const uint8_t * mutf8_name,const Method::Proto & proto)332 inline Method *Class::GetInterfaceMethod(const uint8_t *mutf8_name, const Method::Proto &proto) const
333 {
334     panda_file::File::StringData sd = {static_cast<uint32_t>(panda::utf::MUtf8ToUtf16Size(mutf8_name)), mutf8_name};
335     return FindInterfaceMethod(
336         [sd, proto](const Method &method) { return method.GetName() == sd && method.GetProto() == proto; });
337 }
338 
GetDirectMethod(const uint8_t * mutf8_name)339 inline Method *Class::GetDirectMethod(const uint8_t *mutf8_name) const
340 {
341     panda_file::File::StringData sd = {static_cast<uint32_t>(panda::utf::MUtf8ToUtf16Size(mutf8_name)), mutf8_name};
342     return FindDirectMethod<FindFilter::ALL>([sd](const Method &method) { return method.GetName() == sd; });
343 }
344 
GetClassMethod(const uint8_t * mutf8_name)345 inline Method *Class::GetClassMethod(const uint8_t *mutf8_name) const
346 {
347     panda_file::File::StringData sd = {static_cast<uint32_t>(panda::utf::MUtf8ToUtf16Size(mutf8_name)), mutf8_name};
348     return FindClassMethod([sd](const Method &method) { return method.GetName() == sd; });
349 }
350 
ResolveVirtualMethod(const Method * method)351 inline Method *Class::ResolveVirtualMethod(const Method *method) const
352 {
353     Method *resolved = nullptr;
354 
355     ASSERT(!IsInterface());
356 
357     if (method->GetClass()->IsInterface() && !method->IsDefaultInterfaceMethod()) {
358         // find method in imtable
359         auto imtable_size = GetIMTSize();
360         if (LIKELY(imtable_size != 0)) {
361             auto imtable = GetIMT();
362             auto method_id = GetIMTableIndex(method->GetFileId().GetOffset());
363             resolved = imtable[method_id];
364             if (resolved != nullptr) {
365                 return resolved;
366             }
367         }
368 
369         // find method in itable
370         auto *iface = method->GetClass();
371         auto itable = GetITable();
372         for (size_t i = 0; i < itable.Size(); i++) {
373             auto &entry = itable[i];
374             if (entry.GetInterface() != iface) {
375                 continue;
376             }
377 
378             resolved = entry.GetMethods()[method->GetVTableIndex()];
379         }
380     } else {
381         // find method in vtable
382         auto vtable = GetVTable();
383         ASSERT(method->GetVTableIndex() < vtable.size());
384         resolved = vtable[method->GetVTableIndex()];
385     }
386 
387     return resolved;
388 }
389 
390 // CODECHECK-NOLINTNEXTLINE(C_RULE_ID_COMMENT_LOCATION)
391 template <class T, bool is_volatile /* = false */>
GetFieldPrimitive(size_t offset)392 inline T Class::GetFieldPrimitive(size_t offset) const
393 {
394     ASSERT(IsInitializing() || IsInitialized());
395     return ObjectAccessor::GetPrimitive<T, is_volatile>(this, offset);
396 }
397 
398 // CODECHECK-NOLINTNEXTLINE(C_RULE_ID_COMMENT_LOCATION)
399 template <class T, bool is_volatile /* = false */>
SetFieldPrimitive(size_t offset,T value)400 inline void Class::SetFieldPrimitive(size_t offset, T value)
401 {
402     ObjectAccessor::SetPrimitive<T, is_volatile>(this, offset, value);
403 }
404 
405 // CODECHECK-NOLINTNEXTLINE(C_RULE_ID_HORIZON_SPACE, C_RULE_ID_COMMENT_LOCATION)
406 template <bool is_volatile /* = false */, bool need_read_barrier /* = true */>
GetFieldObject(size_t offset)407 inline ObjectHeader *Class::GetFieldObject(size_t offset) const
408 {
409     ASSERT(IsInitializing() || IsInitialized());
410     return ObjectAccessor::GetObject<is_volatile, need_read_barrier>(this, offset);
411 }
412 
413 // CODECHECK-NOLINTNEXTLINE(C_RULE_ID_HORIZON_SPACE, C_RULE_ID_COMMENT_LOCATION)
414 template <bool is_volatile /* = false */, bool need_write_barrier /* = true */>
SetFieldObject(size_t offset,ObjectHeader * value)415 inline void Class::SetFieldObject(size_t offset, ObjectHeader *value)
416 {
417     auto object = GetManagedObject();
418     auto new_offset = offset + (ToUintPtr(this) - ToUintPtr(object));
419     ObjectAccessor::SetObject<is_volatile, need_write_barrier>(object, new_offset, value);
420 }
421 
422 template <class T>
GetFieldPrimitive(const Field & field)423 inline T Class::GetFieldPrimitive(const Field &field) const
424 {
425     return ObjectAccessor::GetFieldPrimitive<T>(this, field);
426 }
427 
428 template <class T>
SetFieldPrimitive(const Field & field,T value)429 inline void Class::SetFieldPrimitive(const Field &field, T value)
430 {
431     ObjectAccessor::SetFieldPrimitive(this, field, value);
432 }
433 
434 // CODECHECK-NOLINTNEXTLINE(C_RULE_ID_COMMENT_LOCATION)
435 template <bool need_read_barrier /* = true */>
GetFieldObject(const Field & field)436 inline ObjectHeader *Class::GetFieldObject(const Field &field) const
437 {
438     return ObjectAccessor::GetFieldObject<need_read_barrier>(this, field);
439 }
440 
441 // CODECHECK-NOLINTNEXTLINE(C_RULE_ID_COMMENT_LOCATION)
442 template <bool need_write_barrier /* = true */>
SetFieldObject(const Field & field,ObjectHeader * value)443 inline void Class::SetFieldObject(const Field &field, ObjectHeader *value)
444 {
445     auto object = GetManagedObject();
446     auto offset = field.GetOffset() + (ToUintPtr(this) - ToUintPtr(object));
447     if (UNLIKELY(field.IsVolatile())) {
448         ObjectAccessor::SetObject<true, need_write_barrier>(object, offset, value);
449     } else {
450         ObjectAccessor::SetObject<false, need_write_barrier>(object, offset, value);
451     }
452 }
453 
454 // CODECHECK-NOLINTNEXTLINE(C_RULE_ID_COMMENT_LOCATION)
455 template <bool need_read_barrier /* = true */>
GetFieldObject(ManagedThread * thread,const Field & field)456 inline ObjectHeader *Class::GetFieldObject(ManagedThread *thread, const Field &field) const
457 {
458     return ObjectAccessor::GetFieldObject<need_read_barrier>(thread, this, field);
459 }
460 
461 // CODECHECK-NOLINTNEXTLINE(C_RULE_ID_COMMENT_LOCATION)
462 template <bool need_write_barrier /* = true */>
SetFieldObject(ManagedThread * thread,const Field & field,ObjectHeader * value)463 inline void Class::SetFieldObject(ManagedThread *thread, const Field &field, ObjectHeader *value)
464 {
465     auto object = GetManagedObject();
466     auto offset = field.GetOffset() + (ToUintPtr(this) - ToUintPtr(object));
467     if (UNLIKELY(field.IsVolatile())) {
468         ObjectAccessor::SetObject<true, need_write_barrier>(thread, object, offset, value);
469     } else {
470         ObjectAccessor::SetObject<false, need_write_barrier>(thread, object, offset, value);
471     }
472 }
473 
474 template <class T>
GetFieldPrimitive(size_t offset,std::memory_order memory_order)475 inline T Class::GetFieldPrimitive(size_t offset, std::memory_order memory_order) const
476 {
477     return ObjectAccessor::GetFieldPrimitive<T>(this, offset, memory_order);
478 }
479 
480 template <class T>
SetFieldPrimitive(size_t offset,T value,std::memory_order memory_order)481 inline void Class::SetFieldPrimitive(size_t offset, T value, std::memory_order memory_order)
482 {
483     ObjectAccessor::SetFieldPrimitive(this, offset, value, memory_order);
484 }
485 
486 // CODECHECK-NOLINTNEXTLINE(C_RULE_ID_HORIZON_SPACE, C_RULE_ID_COMMENT_LOCATION)
487 template <bool need_read_barrier /* = true */>
GetFieldObject(size_t offset,std::memory_order memory_order)488 inline ObjectHeader *Class::GetFieldObject(size_t offset, std::memory_order memory_order) const
489 {
490     return ObjectAccessor::GetFieldObject<need_read_barrier>(this, offset, memory_order);
491 }
492 
493 // CODECHECK-NOLINTNEXTLINE(C_RULE_ID_HORIZON_SPACE, C_RULE_ID_COMMENT_LOCATION)
494 template <bool need_write_barrier /* = true */>
SetFieldObject(size_t offset,ObjectHeader * value,std::memory_order memory_order)495 inline void Class::SetFieldObject(size_t offset, ObjectHeader *value, std::memory_order memory_order)
496 {
497     ObjectAccessor::SetFieldObject<need_write_barrier>(this, offset, value, memory_order);
498 }
499 
500 template <typename T>
CompareAndSetFieldPrimitive(size_t offset,T old_value,T new_value,std::memory_order memory_order,bool strong)501 inline bool Class::CompareAndSetFieldPrimitive(size_t offset, T old_value, T new_value, std::memory_order memory_order,
502                                                bool strong)
503 {
504     return ObjectAccessor::CompareAndSetFieldPrimitive(this, offset, old_value, new_value, memory_order, strong).first;
505 }
506 
507 // CODECHECK-NOLINTNEXTLINE(C_RULE_ID_HORIZON_SPACE, C_RULE_ID_COMMENT_LOCATION)
508 template <bool need_write_barrier /* = true */>
CompareAndSetFieldObject(size_t offset,ObjectHeader * old_value,ObjectHeader * new_value,std::memory_order memory_order,bool strong)509 inline bool Class::CompareAndSetFieldObject(size_t offset, ObjectHeader *old_value, ObjectHeader *new_value,
510                                             std::memory_order memory_order, bool strong)
511 {
512     return ObjectAccessor::CompareAndSetFieldObject<need_write_barrier>(this, offset, old_value, new_value,
513                                                                         memory_order, strong)
514         .first;
515 }
516 
517 template <typename T>
CompareAndExchangeFieldPrimitive(size_t offset,T old_value,T new_value,std::memory_order memory_order,bool strong)518 inline T Class::CompareAndExchangeFieldPrimitive(size_t offset, T old_value, T new_value,
519                                                  std::memory_order memory_order, bool strong)
520 {
521     return ObjectAccessor::CompareAndSetFieldPrimitive(this, offset, old_value, new_value, memory_order, strong).second;
522 }
523 
524 // CODECHECK-NOLINTNEXTLINE(C_RULE_ID_HORIZON_SPACE, C_RULE_ID_COMMENT_LOCATION)
525 template <bool need_write_barrier /* = true */>
CompareAndExchangeFieldObject(size_t offset,ObjectHeader * old_value,ObjectHeader * new_value,std::memory_order memory_order,bool strong)526 inline ObjectHeader *Class::CompareAndExchangeFieldObject(size_t offset, ObjectHeader *old_value,
527                                                           ObjectHeader *new_value, std::memory_order memory_order,
528                                                           bool strong)
529 {
530     return ObjectAccessor::CompareAndSetFieldObject<need_write_barrier>(this, offset, old_value, new_value,
531                                                                         memory_order, strong)
532         .second;
533 }
534 
535 template <typename T>
GetAndSetFieldPrimitive(size_t offset,T value,std::memory_order memory_order)536 inline T Class::GetAndSetFieldPrimitive(size_t offset, T value, std::memory_order memory_order)
537 {
538     return ObjectAccessor::GetAndSetFieldPrimitive(this, offset, value, memory_order);
539 }
540 
541 // CODECHECK-NOLINTNEXTLINE(C_RULE_ID_HORIZON_SPACE, C_RULE_ID_COMMENT_LOCATION)
542 template <bool need_write_barrier /* = true */>
GetAndSetFieldObject(size_t offset,ObjectHeader * value,std::memory_order memory_order)543 inline ObjectHeader *Class::GetAndSetFieldObject(size_t offset, ObjectHeader *value, std::memory_order memory_order)
544 {
545     return ObjectAccessor::GetAndSetFieldObject<need_write_barrier>(this, offset, value, memory_order);
546 }
547 
548 template <typename T>
GetAndAddFieldPrimitive(size_t offset,T value,std::memory_order memory_order)549 inline T Class::GetAndAddFieldPrimitive(size_t offset, T value, std::memory_order memory_order)
550 {
551     return ObjectAccessor::GetAndAddFieldPrimitive(this, offset, value, memory_order);
552 }
553 
554 template <typename T>
GetAndBitwiseOrFieldPrimitive(size_t offset,T value,std::memory_order memory_order)555 inline T Class::GetAndBitwiseOrFieldPrimitive(size_t offset, T value, std::memory_order memory_order)
556 {
557     return ObjectAccessor::GetAndBitwiseOrFieldPrimitive(this, offset, value, memory_order);
558 }
559 
560 template <typename T>
GetAndBitwiseAndFieldPrimitive(size_t offset,T value,std::memory_order memory_order)561 inline T Class::GetAndBitwiseAndFieldPrimitive(size_t offset, T value, std::memory_order memory_order)
562 {
563     return ObjectAccessor::GetAndBitwiseAndFieldPrimitive(this, offset, value, memory_order);
564 }
565 
566 template <typename T>
GetAndBitwiseXorFieldPrimitive(size_t offset,T value,std::memory_order memory_order)567 inline T Class::GetAndBitwiseXorFieldPrimitive(size_t offset, T value, std::memory_order memory_order)
568 {
569     return ObjectAccessor::GetAndBitwiseXorFieldPrimitive(this, offset, value, memory_order);
570 }
571 
572 }  // namespace panda
573 
574 #endif  // PANDA_RUNTIME_INCLUDE_CLASS_INL_H_
575