1 /** 2 * Copyright (c) 2021-2022 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 #ifndef PANDA_RUNTIME_CORETYPES_CLASS_H_ 16 #define PANDA_RUNTIME_CORETYPES_CLASS_H_ 17 18 #include <cstddef> 19 #include <cstdint> 20 #include <cstring> 21 22 #include "libpandabase/utils/utf.h" 23 #include "runtime/include/class.h" 24 #include "runtime/include/object_header.h" 25 26 namespace panda::coretypes { 27 28 class Class : public ObjectHeader { 29 public: Class(const uint8_t * descriptor,uint32_t vtable_size,uint32_t imt_size,uint32_t klass_size)30 Class(const uint8_t *descriptor, uint32_t vtable_size, uint32_t imt_size, uint32_t klass_size) 31 : ObjectHeader(), klass_(descriptor, panda_file::SourceLang::PANDA_ASSEMBLY, vtable_size, imt_size, klass_size) 32 { 33 } 34 35 // We shouldn't init header_ here - because it has been memset(0) in object allocation, 36 // otherwise it may cause data race while visiting object's class concurrently in gc. InitClass(const uint8_t * descriptor,uint32_t vtable_size,uint32_t imt_size,uint32_t klass_size)37 void InitClass(const uint8_t *descriptor, uint32_t vtable_size, uint32_t imt_size, uint32_t klass_size) 38 { 39 new (&klass_) 40 panda::Class(descriptor, panda_file::SourceLang::PANDA_ASSEMBLY, vtable_size, imt_size, klass_size); 41 } 42 GetRuntimeClass()43 panda::Class *GetRuntimeClass() 44 { 45 return &klass_; 46 } 47 GetRuntimeClass()48 const panda::Class *GetRuntimeClass() const 49 { 50 return &klass_; 51 } 52 53 template <class T> GetFieldPrimitive(const Field & field)54 T GetFieldPrimitive(const Field &field) const 55 { 56 return klass_.GetFieldPrimitive<T>(field); 57 } 58 59 template <class T> SetFieldPrimitive(const Field & field,T value)60 void SetFieldPrimitive(const Field &field, T value) 61 { 62 klass_.SetFieldPrimitive(field, value); 63 } 64 65 template <bool need_read_barrier = true> GetFieldObject(const Field & field)66 ObjectHeader *GetFieldObject(const Field &field) const 67 { 68 return klass_.GetFieldObject<need_read_barrier>(field); 69 } 70 71 template <bool need_write_barrier = true> SetFieldObject(const Field & field,ObjectHeader * value)72 void SetFieldObject(const Field &field, ObjectHeader *value) 73 { 74 klass_.SetFieldObject<need_write_barrier>(field, value); 75 } 76 GetSize(uint32_t klass_size)77 static size_t GetSize(uint32_t klass_size) 78 { 79 return GetRuntimeClassOffset() + klass_size; 80 } 81 GetRuntimeClassOffset()82 static constexpr size_t GetRuntimeClassOffset() 83 { 84 return MEMBER_OFFSET(Class, klass_); 85 } 86 FromRuntimeClass(panda::Class * klass)87 static Class *FromRuntimeClass(panda::Class *klass) 88 { 89 return reinterpret_cast<Class *>(reinterpret_cast<uintptr_t>(klass) - GetRuntimeClassOffset()); 90 } 91 92 private: 93 panda::Class klass_; 94 }; 95 96 // Klass field has variable size so it must be last 97 static_assert(Class::GetRuntimeClassOffset() + sizeof(panda::Class) == sizeof(Class)); 98 99 } // namespace panda::coretypes 100 101 #endif // PANDA_RUNTIME_CORETYPES_CLASS_H_ 102