1 /* 2 * Copyright (c) 2023 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 ECMASCRIPT_COMPILER_PGO_TYPE_PGO_TYPE_MANAGER_H 16 #define ECMASCRIPT_COMPILER_PGO_TYPE_PGO_TYPE_MANAGER_H 17 18 #include "ecmascript/compiler/aot_snapshot/aot_snapshot.h" 19 #include "ecmascript/compiler/pgo_type/pgo_type_location.h" 20 #include "ecmascript/pgo_profiler/types/pgo_profiler_type.h" 21 22 namespace panda::ecmascript::kungfu { 23 class PGOTypeManager { 24 public: PGOTypeManager(EcmaVM * vm)25 PGOTypeManager(EcmaVM *vm) 26 : thread_(vm->GetJSThread()), aotSnapshot_(vm) {} 27 ~PGOTypeManager() = default; 28 29 void Iterate(RootVisitor &v); 30 31 // common 32 uint32_t PUBLIC_API GetConstantPoolIDByMethodOffset(const uint32_t methodOffset) const; 33 34 JSTaggedValue PUBLIC_API GetConstantPoolByMethodOffset(const uint32_t methodOffset) const; 35 36 JSTaggedValue PUBLIC_API GetStringFromConstantPool(const uint32_t methodOffset, const uint16_t cpIdx) const; 37 GetJSThread()38 inline JSThread* GetJSThread() 39 { 40 return thread_; 41 } 42 SetCurCompilationFile(const JSPandaFile * jsPandaFile)43 void PUBLIC_API SetCurCompilationFile(const JSPandaFile *jsPandaFile) 44 { 45 curJSPandaFile_ = jsPandaFile; 46 } 47 48 // snapshot 49 void PUBLIC_API InitAOTSnapshot(uint32_t compileFilesCount); 50 GetAOTSnapshot()51 AOTSnapshot& GetAOTSnapshot() 52 { 53 return aotSnapshot_; 54 } 55 56 // array 57 void RecordConstantIndex(uint32_t bcAbsoluteOffset, uint32_t index); 58 59 // hclass 60 void RecordHClass(ProfileType rootType, ProfileType childType, JSTaggedType hclass, bool update = false); 61 int PUBLIC_API RecordAndGetHclassIndexForJIT(JSHClass* hclass); 62 uint32_t PUBLIC_API GetHClassIndexByProfileType(ProfileTyper type) const; 63 int PUBLIC_API GetHolderHIndexByPGOObjectInfoType(pgo::PGOObjectInfo type, bool isAot); 64 int PUBLIC_API GetReceiverHIndexByPGOObjectInfoType(pgo::PGOObjectInfo type, bool isAot); 65 66 JSTaggedValue PUBLIC_API QueryHClass(ProfileType rootType, ProfileType childType) ; 67 JSTaggedValue PUBLIC_API QueryHClassByIndexForJIT(uint32_t hclassIndex) ; 68 ElementsKind QueryElementKind(ProfileType rootType); 69 GetRootIdByLocation(const PGOTypeLocation & loc)70 inline ProfileType GetRootIdByLocation(const PGOTypeLocation &loc) 71 { 72 auto it = locToRootIdMap_.find(loc); 73 if (it != locToRootIdMap_.end()) { 74 return it->second; 75 } 76 return ProfileType::PROFILE_TYPE_NONE; 77 } 78 GetElementsKindByLocation(PGOTypeLocation loc)79 inline ElementsKind GetElementsKindByLocation(PGOTypeLocation loc) 80 { 81 auto it = locToElmsKindMap_.find(loc); 82 if (it != locToElmsKindMap_.end()) { 83 return it->second; 84 } 85 return ElementsKind::GENERIC; 86 } 87 RecordLocationToRootType(const PGOTypeLocation & loc,ProfileType rootType)88 inline void RecordLocationToRootType(const PGOTypeLocation &loc, ProfileType rootType) 89 { 90 locToRootIdMap_.emplace(loc, rootType); 91 } 92 RecordLocationToElementsKind(PGOTypeLocation loc,ElementsKind kind)93 inline void RecordLocationToElementsKind(PGOTypeLocation loc, ElementsKind kind) 94 { 95 locToElmsKindMap_.emplace(loc, kind); 96 } 97 98 struct ProtoTransType { ProtoTransTypeProtoTransType99 ProtoTransType(ProfileType ihcType, 100 ProfileType baseRootType, 101 ProfileType baseType, 102 ProfileType transIhcType, 103 ProfileType transPhcType) 104 : ihcType(ihcType), 105 baseRootType(baseRootType), 106 baseType(baseType), 107 transIhcType(transIhcType), 108 transPhcType(transPhcType) {} 109 110 ProfileType ihcType {}; 111 ProfileType baseRootType {}; 112 ProfileType baseType {}; 113 ProfileType transIhcType {}; 114 ProfileType transPhcType {}; 115 }; 116 RecordProtoTransType(const ProtoTransType & type)117 inline void RecordProtoTransType(const ProtoTransType &type) 118 { 119 protoTransTypes_.emplace_back(type); 120 } 121 FindAllTransPhcByBaseType(ProfileType baseRootType)122 std::vector<ProfileType> FindAllTransPhcByBaseType(ProfileType baseRootType) 123 { 124 std::vector<ProfileType> transPhcs; 125 for (auto &transType: protoTransTypes_) { 126 if (baseRootType == transType.baseRootType) { 127 transPhcs.emplace_back(transType.transPhcType); 128 } 129 } 130 return transPhcs; 131 } 132 ClearHCInfoLocal()133 inline void ClearHCInfoLocal() 134 { 135 hclassInfoLocal_.clear(); 136 pos_ = 0; 137 } 138 139 // symbol 140 std::optional<uint64_t> PUBLIC_API GetSymbolIdByProfileType(ProfileTypeTuple type) const; 141 DumpHClassData(std::ostream & os)142 void DumpHClassData(std::ostream& os) const 143 { 144 int i = 0; 145 for (const auto& root: hcData_) { 146 int j = 0; 147 os << "[" << i << "]" << std::endl; 148 os << "RootType: " << root.first << std::endl; 149 for (const auto& child: root.second) { 150 os << "[" << i << "]" << "[" << j << "]" << std::endl; 151 os << "ChildType: " << child.first << std::endl; 152 os << "HClass: " << JSTaggedValue(child.second) << std::endl; 153 j++; 154 } 155 i++; 156 } 157 } 158 159 void PUBLIC_API MergeRepresentationForProtoTransition(); 160 161 private: 162 // snapshot 163 void GenHClassInfo(); 164 void GenSymbolInfo(); 165 void GenArrayInfo(); 166 void GenConstantIndexInfo(); 167 void GenProtoTransitionInfo(); 168 169 bool IsNapiIhc(ProfileType rootType, ProfileType childType); 170 uint32_t GetSymbolCountFromHClassData(); 171 172 // opt to std::unordered_map 173 using TransIdToHClass = std::map<ProfileType, JSTaggedType>; 174 using RootIdToTransMap = std::map<ProfileType, TransIdToHClass>; 175 176 JSThread *thread_; 177 RootIdToTransMap hcData_; 178 CVector<uint32_t> constantIndexData_ {}; 179 CUnorderedMap<PGOTypeLocation, ProfileType, HashPGOTypeLocation> locToRootIdMap_ {}; 180 CUnorderedMap<PGOTypeLocation, ElementsKind, HashPGOTypeLocation> locToElmsKindMap_ {}; 181 CMap<ProfileTyper, uint32_t> profileTyperToHClassIndex_ {}; 182 CMap<ProfileTypeTuple, uint64_t> profileTypeToSymbolId_ {}; 183 std::vector<ProtoTransType> protoTransTypes_; 184 185 AOTSnapshot aotSnapshot_; 186 187 // Since there is only one PGOTypeManager instance during compilation, 188 // the currently compiled jspandafile needs to be set to satisfy multi-file compilation. 189 const JSPandaFile *curJSPandaFile_ {nullptr}; 190 Mutex mutex_; 191 CVector<JSTaggedValue> hclassInfoLocal_ {}; 192 // When the passmanager iterates each method, the curCP_ and curCPID_ should be updated, 193 // so that subsequent passes (type_infer, ts_hcr_lowering) can obtain the correct constpool. 194 JSTaggedValue curCP_ {JSTaggedValue::Hole()}; 195 int32_t curCPID_ {0}; 196 int32_t pos_ {0}; 197 }; 198 } // panda::ecmascript::kungfu 199 #endif // ECMASCRIPT_COMPILER_PGO_TYPE_PGO_TYPE_MANAGER_H 200