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