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