• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (c) 2025 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 COMMON_INTERFACES_OBJECTS_CLASS_MANAGER_H
17 #define COMMON_INTERFACES_OBJECTS_CLASS_MANAGER_H
18 
19 #include "objects/utils/field_macro.h"
20 #include "objects/base_class.h"
21 #include "objects/base_object.h"
22 #include "heap/heap_visitor.h"
23 #include <array>
24 #include <atomic>
25 #include <functional>
26 
27 // step 1. Allocate CompositeBaseClass instance in 1.0. The BaseObject of it is taggedobject in 1.0. It will be this:
28 // +------------------------------------------------+
29 // | CompositeBaseClass                             |
30 // +================================================+
31 // | BaseObject                                     |
32 // | +--------------------------------------------+ |
33 // | | BaseStateWord state_                       | |
34 // | | +------------------------+---------------+ | |
35 // | | | classAddress = corresponding hclass    | | | ----> CompositeBaseClassHClass
36 // | | | language_ = dynamic                    | | |       (an hclass to represent this created in 1.0, )
37 // | | +------------------------+---------------+ | |
38 // +------------------------------------------------+
39 // | padding (uint64_t, optional via ARK_HYBRID)    |
40 // +------------------------------------------------+
41 // | BaseClass class_                               |
42 // | +--------------------------+-----------------+ |
43 // | | uint64_t header_         | (unused)        | |
44 // | +--------------------------+-----------------+ |
45 // | | uint64_t bitfield_     = 0x01 (LINE_STRING)| |
46 // | +--------------------------------------------+ |
47 // +------------------------------------------------+
48 // | ... padding up to SIZE = 1408 bytes            |
49 // +------------------------------------------------+
50 //
51 //
52 // step 2. In 1.0 runtime. The BaseClass(used as hclass) part will be filled as hclass need
53 // +------------------------------------------------+
54 // | CompositeBaseClass                             |
55 // +================================================+
56 // | BaseObject                                     |
57 // | +--------------------------------------------+ |
58 // | | BaseStateWord state_                       | |
59 // | | +------------------------+---------------+ | |
60 // | | | classAddress = corresponding hclass    | | | ----> CompositeBaseClassHClass
61 // | | | language_ = dynamic                    | | |       (an hclass to represent this created in 1.0, )
62 // | | +------------------------+---------------+ | |
63 // +------------------------------------------------+
64 // | padding (uint64_t, optional via ARK_HYBRID)    |
65 // +------------------------------------------------+
66 // | BaseClass class_                               |
67 // | +--------------------------+-----------------+ |
68 // | | uint64_t header_ | hclass of hclass in 1.0 | | ----> point to the hclass of hclass in 1.0.
69 // | +--------------------------+-----------------+ |
70 // | | uint64_t bitfield_  = 0x01 (LINE_STRING)   | | ----> other bitfield is also filled as 1.0 need.
71 // | +--------------------------------------------+ |
72 // +------------------------------------------------+
73 // | ... padding up to SIZE = 1408 bytes            |
74 // +------------------------------------------------+
75 //
76 //
77 // (optional)step 3. In 1.2 runtime. The whole will be filled as 1.2 need,and the BaseObject part will be changed.
78 // Then CompositeBaseClass can be used as 1.2 class.
79 // +------------------------------------------------+
80 // | CompositeBaseClass                             |
81 // +================================================+
82 // | BaseObject                                     |
83 // | +--------------------------------------------+ |
84 // | | BaseStateWord state_                       | |
85 // | | +------------------------+---------------+ | |
86 // | | | classAddress =  ClassClass in 1.2      | | | ----> ClassClass in 1.2
87 // | | | language_ = static                     | | | ----> Change to static
88 // | | +------------------------+---------------+ | |
89 // +------------------------------------------------+
90 // | padding (uint64_t, optional via ARK_HYBRID)    | ----> used as 1.2 stateWord
91 // +------------------------------------------------+
92 // | BaseClass class_                               |
93 // | +--------------------------+-----------------+ |
94 // | | uint64_t header_ | hclass of hclass in 1.0 | | ----> point to the hclass of hclass in 1.0.
95 // | +--------------------------+-----------------+ |
96 // | | uint64_t bitfield_  = 0x01 (LINE_STRING)   | | ----> other bitfield is also filled as 1.0 need.
97 // | +--------------------------------------------+ |
98 // +------------------------------------------------+
99 // | ... padding up to SIZE = 1408 bytes            | ----> initialized as 1.2 class field.
100 // +------------------------------------------------+
101 //
102 //
103 namespace common {
104 class CompositeBaseClass : public BaseObject {
105 public:
106     CompositeBaseClass() = delete;
107     NO_MOVE_SEMANTIC_CC(CompositeBaseClass);
108     NO_COPY_SEMANTIC_CC(CompositeBaseClass);
109 #ifdef ARK_HYBRID
110     [[maybe_unused]] uint64_t padding_;
111     static constexpr size_t SIZE = 1416; // Note: should be same with 1.2 string Class size
112 #else
113     static constexpr size_t SIZE = 88; // Note: At least same with JSHClass::SIZE
114 #endif
115     BaseClass class_;
116     // These fields are primitive or pointer to root, skip it.
117     static constexpr size_t VISIT_BEGIN = sizeof(BaseObject) + sizeof(BaseClass);
118     static constexpr size_t VISIT_END = SIZE;
119 };
120 
121 class BaseClassRoots final {
122 public:
123     using CompositeBaseClassAllocator = const std::function<CompositeBaseClass *()>;
124     BaseClassRoots() = default;
125     ~BaseClassRoots() = default;
126 
127     NO_COPY_SEMANTIC_CC(BaseClassRoots);
128     NO_MOVE_SEMANTIC_CC(BaseClassRoots);
129 
130     enum ClassIndex {
131         LINE_STRING_CLASS = 0,
132         SLICED_STRING_CLASS = 1,
133         TREE_STRING_CLASS = 2,
134         CLASS_COUNT = 3,
135     };
136 
137     BaseClass *GetBaseClass(CommonType type) const;
138 
139     void IterateCompositeBaseClass(const RefFieldVisitor &visitorFunc);
140 
141     void InitializeCompositeBaseClass(CompositeBaseClassAllocator &allocator);
142 
Init()143     void Init() {};
144 
Fini()145     void Fini()
146     {
147         initialized_ = false;
148         compositeBaseClasses_ = {};
149         baseClasses_ = {};
150     }
151 
152 private:
153     constexpr static size_t ObjectTypeCount = static_cast<size_t>(CommonType::LAST_OBJECT_TYPE) + 1;
154     constexpr static std::array<ClassIndex, ObjectTypeCount> TypeToIndex = [] {
155         std::array<ClassIndex, ObjectTypeCount> res{};
156         res[static_cast<size_t>(CommonType::LINE_STRING)] = LINE_STRING_CLASS;
157         res[static_cast<size_t>(CommonType::SLICED_STRING)] = SLICED_STRING_CLASS;
158         res[static_cast<size_t>(CommonType::TREE_STRING)] = TREE_STRING_CLASS;
159         return res;
160     }();
161     void CreateCompositeBaseClass(CommonType type, CompositeBaseClassAllocator &allocator);
162     std::array<CompositeBaseClass *, CLASS_COUNT> compositeBaseClasses_{};
163     std::array<BaseClass *, CLASS_COUNT> baseClasses_{};
164     std::atomic_bool initialized_ = false;
165 };
166 } // namespace panda
167 #endif //COMMON_INTERFACES_OBJECTS_CLASS_MANAGER_H