• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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