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 uint32_t GetMaxPropsNum(uint32_t literalLength) const; 66 void SetMaxPropsNum(uint32_t literalLength, uint32_t maxPropsNum) const; 67 68 JSTaggedValue PUBLIC_API QueryHClass(ProfileType rootType, ProfileType childType) ; 69 JSTaggedValue PUBLIC_API QueryHClassByIndexForJIT(uint32_t hclassIndex) ; 70 ElementsKind QueryElementKind(ProfileType rootType); 71 GetRootIdByLocation(const PGOTypeLocation & loc)72 inline ProfileType GetRootIdByLocation(const PGOTypeLocation &loc) 73 { 74 auto it = locToRootIdMap_.find(loc); 75 if (it != locToRootIdMap_.end()) { 76 return it->second; 77 } 78 return ProfileType::PROFILE_TYPE_NONE; 79 } 80 GetElementsKindByLocation(PGOTypeLocation loc)81 inline ElementsKind GetElementsKindByLocation(PGOTypeLocation loc) 82 { 83 auto it = locToElmsKindMap_.find(loc); 84 if (it != locToElmsKindMap_.end()) { 85 return it->second; 86 } 87 return ElementsKind::GENERIC; 88 } 89 RecordLocationToRootType(const PGOTypeLocation & loc,ProfileType rootType)90 inline void RecordLocationToRootType(const PGOTypeLocation &loc, ProfileType rootType) 91 { 92 locToRootIdMap_.emplace(loc, rootType); 93 } 94 RecordLocationToElementsKind(PGOTypeLocation loc,ElementsKind kind)95 inline void RecordLocationToElementsKind(PGOTypeLocation loc, ElementsKind kind) 96 { 97 locToElmsKindMap_.emplace(loc, kind); 98 } 99 100 struct ProtoTransType { ProtoTransTypeProtoTransType101 ProtoTransType(ProfileType ihcType, 102 ProfileType baseRootType, 103 ProfileType baseType, 104 ProfileType transIhcType, 105 ProfileType transPhcType) 106 : ihcType(ihcType), 107 baseRootType(baseRootType), 108 baseType(baseType), 109 transIhcType(transIhcType), 110 transPhcType(transPhcType) {} 111 112 ProfileType ihcType {}; 113 ProfileType baseRootType {}; 114 ProfileType baseType {}; 115 ProfileType transIhcType {}; 116 ProfileType transPhcType {}; 117 }; 118 RecordProtoTransType(const ProtoTransType & type)119 inline void RecordProtoTransType(const ProtoTransType &type) 120 { 121 protoTransTypes_.emplace_back(type); 122 } 123 FindAllTransPhcByBaseType(ProfileType baseRootType)124 std::vector<ProfileType> FindAllTransPhcByBaseType(ProfileType baseRootType) 125 { 126 std::vector<ProfileType> transPhcs; 127 for (auto &transType: protoTransTypes_) { 128 if (baseRootType == transType.baseRootType) { 129 transPhcs.emplace_back(transType.transPhcType); 130 } 131 } 132 return transPhcs; 133 } 134 ClearHCInfoLocal()135 inline void ClearHCInfoLocal() 136 { 137 hclassInfoLocal_.clear(); 138 pos_ = 0; 139 } 140 141 // symbol 142 std::optional<uint64_t> PUBLIC_API GetSymbolIdByProfileType(ProfileTypeTuple type) const; 143 DumpHClassData(std::ostream & os)144 void DumpHClassData(std::ostream& os) const 145 { 146 int i = 0; 147 for (const auto& root: hcData_) { 148 int j = 0; 149 os << "[" << i << "]" << std::endl; 150 os << "RootType: " << root.first << std::endl; 151 for (const auto& child: root.second) { 152 os << "[" << i << "]" << "[" << j << "]" << std::endl; 153 os << "ChildType: " << child.first << std::endl; 154 os << "HClass: " << JSTaggedValue(child.second) << std::endl; 155 j++; 156 } 157 i++; 158 } 159 } 160 161 void PUBLIC_API MergeRepresentationForProtoTransition(); 162 163 private: 164 // snapshot 165 void GenHClassInfo(); 166 void GenSymbolInfo(); 167 void GenArrayInfo(); 168 void GenConstantIndexInfo(); 169 void GenProtoTransitionInfo(); 170 171 bool IsNapiIhc(ProfileType rootType, ProfileType childType); 172 uint32_t GetSymbolCountFromHClassData(); 173 174 // opt to std::unordered_map 175 using TransIdToHClass = std::map<ProfileType, JSTaggedType>; 176 using RootIdToTransMap = std::map<ProfileType, TransIdToHClass>; 177 178 JSThread *thread_; 179 RootIdToTransMap hcData_; 180 CVector<uint32_t> constantIndexData_ {}; 181 CUnorderedMap<PGOTypeLocation, ProfileType, HashPGOTypeLocation> locToRootIdMap_ {}; 182 CUnorderedMap<PGOTypeLocation, ElementsKind, HashPGOTypeLocation> locToElmsKindMap_ {}; 183 CMap<ProfileTyper, uint32_t> profileTyperToHClassIndex_ {}; 184 CMap<ProfileTypeTuple, uint64_t> profileTypeToSymbolId_ {}; 185 std::vector<ProtoTransType> protoTransTypes_; 186 187 AOTSnapshot aotSnapshot_; 188 189 // Since there is only one PGOTypeManager instance during compilation, 190 // the currently compiled jspandafile needs to be set to satisfy multi-file compilation. 191 const JSPandaFile *curJSPandaFile_ {nullptr}; 192 Mutex mutex_; 193 CVector<JSTaggedValue> hclassInfoLocal_ {}; 194 // When the passmanager iterates each method, the curCP_ and curCPID_ should be updated, 195 // so that subsequent passes (type_infer, ts_hcr_lowering) can obtain the correct constpool. 196 JSTaggedValue curCP_ {JSTaggedValue::Hole()}; 197 int32_t curCPID_ {0}; 198 int32_t pos_ {0}; 199 mutable std::unordered_map<uint32_t, uint32_t> maxPropsNum_ {}; 200 }; 201 } // panda::ecmascript::kungfu 202 #endif // ECMASCRIPT_COMPILER_PGO_TYPE_PGO_TYPE_MANAGER_H 203