• 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 
16 #ifndef ECMASCRIPT_PGO_PROFILER_AP_FILE_PGO_METHOD_TYPE_SET_H
17 #define ECMASCRIPT_PGO_PROFILER_AP_FILE_PGO_METHOD_TYPE_SET_H
18 
19 #include <set>
20 
21 #include "ecmascript/pgo_profiler/ap_file/pgo_file_info.h"
22 #include "ecmascript/pgo_profiler/pgo_utils.h"
23 #include "ecmascript/pgo_profiler/types/pgo_profiler_type.h"
24 
25 namespace panda::ecmascript::pgo {
26 class PGOMethodTypeSet {
27 public:
28     static constexpr int METHOD_TYPE_INFO_INDEX = 4;
29     static constexpr int METHOD_TYPE_INFO_COUNT = 2;
30     static constexpr int METHOD_OFFSET_INDEX = 0;
31     static constexpr int METHOD_TYPE_INDEX = 1;
32     static constexpr uint32_t MAX_METHOD_TYPE_SIZE = 512 * 1024 * 1024;
33 
34     PGOMethodTypeSet() = default;
Clear()35     void Clear()
36     {
37         scalarOpTypeInfos_.clear();
38         rwScalarOpTypeInfos_.clear();
39         objDefOpTypeInfos_.clear();
40     }
41 
AddType(uint32_t offset,PGOSampleType type)42     void AddType(uint32_t offset, PGOSampleType type)
43     {
44         auto result = scalarOpTypeInfos_.find(ScalarOpTypeInfo(offset, type));
45         if (result != scalarOpTypeInfos_.end()) {
46             auto combineType = result->GetType().CombineType(type);
47             const_cast<ScalarOpTypeInfo &>(*result).SetType(combineType);
48         } else {
49             scalarOpTypeInfos_.emplace(offset, type);
50         }
51     }
52 
AddCallTargetType(uint32_t offset,PGOSampleType type)53     void AddCallTargetType(uint32_t offset, PGOSampleType type)
54     {
55         auto result = scalarOpTypeInfos_.find(ScalarOpTypeInfo(offset, type));
56         if (result != scalarOpTypeInfos_.end()) {
57             auto combineType = result->GetType().CombineCallTargetType(type);
58             const_cast<ScalarOpTypeInfo &>(*result).SetType(combineType);
59         } else {
60             scalarOpTypeInfos_.emplace(offset, type);
61         }
62     }
63 
AddObjectInfo(uint32_t offset,const PGOObjectInfo & info)64     void AddObjectInfo(uint32_t offset, const PGOObjectInfo &info)
65     {
66         auto result = rwScalarOpTypeInfos_.find(RWScalarOpTypeInfo(offset));
67         if (result != rwScalarOpTypeInfos_.end()) {
68             const_cast<RWScalarOpTypeInfo &>(*result).AddObjectInfo(info);
69         } else {
70             rwScalarOpTypeInfos_.emplace(offset, info);
71         }
72     }
73 
AddDefine(uint32_t offset,PGODefineOpType type)74     void AddDefine(uint32_t offset, PGODefineOpType type)
75     {
76         auto result = objDefOpTypeInfos_.find(ObjDefOpTypeInfo(offset, type));
77         if (result != objDefOpTypeInfos_.end()) {
78             if (type.GetProfileType().IsArrayLiteralType())  {
79                 const_cast<PGODefineOpTemplate<ProfileType> *>(&((*result).GetTypeRef()))
80                     ->SetElementsKind(type.GetElementsKind());
81             }
82             return;
83         }
84         objDefOpTypeInfos_.emplace(offset, type);
85     }
86 
87     template <typename Callback>
GetTypeInfo(Callback callback)88     void GetTypeInfo(Callback callback)
89     {
90         for (const auto &typeInfo : scalarOpTypeInfos_) {
91             const auto &type = typeInfo.GetTypeRef();
92             callback(typeInfo.GetOffset(), &type);
93         }
94         for (const auto &typeInfo : rwScalarOpTypeInfos_) {
95             const auto &type = typeInfo.GetTypeRef();
96             callback(typeInfo.GetOffset(), &type);
97         }
98         for (const auto &typeInfo : objDefOpTypeInfos_) {
99             const auto &type = typeInfo.GetTypeRef();
100             callback(typeInfo.GetOffset(), &type);
101         }
102     }
103 
104     void Merge(const PGOMethodTypeSet *info);
105     static void SkipFromBinary(void **buffer);
106 
107     bool ParseFromBinary(PGOContext &context, void **buffer);
108     bool ProcessToBinary(PGOContext &context, std::stringstream &stream) const;
109 
110     bool ParseFromText(const std::string &typeString);
111     void ProcessToText(std::string &text) const;
112 
113     void ProcessToJson(ProfileType::VariantVector &typeArray) const;
114 
115     NO_COPY_SEMANTIC(PGOMethodTypeSet);
116     NO_MOVE_SEMANTIC(PGOMethodTypeSet);
117 
118 private:
119     enum class InfoType : uint8_t {
120         NONE,
121         OP_TYPE,
122         DEFINE_CLASS_TYPE = 3,
123         USE_HCLASS_TYPE
124     };
125 
126     class TypeInfoHeader {
127     public:
TypeInfoHeader(InfoType type,uint32_t offset)128         TypeInfoHeader(InfoType type, uint32_t offset) : infoType_(type), offset_(offset) {}
TypeInfoHeader(uint32_t size,InfoType type,uint32_t offset)129         TypeInfoHeader(uint32_t size, InfoType type, uint32_t offset)
130             : size_(size), infoType_(type), offset_(offset) {}
131 
GetInfoType()132         InfoType GetInfoType()
133         {
134             return infoType_;
135         }
136 
Size()137         int32_t Size() const
138         {
139             return size_;
140         }
141 
GetOffset()142         uint32_t GetOffset() const
143         {
144             return offset_;
145         }
146 
147     protected:
148         uint32_t size_ {0};
149         InfoType infoType_ {InfoType::NONE};
150         uint32_t offset_ {0};
151     };
152 
153     template <typename RWOpType, typename ObjectInfoType>
154     class RWScalarOpTemplate : public TypeInfoHeader {
155     public:
RWScalarOpTemplate(uint32_t offset)156         explicit RWScalarOpTemplate(uint32_t offset) : TypeInfoHeader(InfoType::USE_HCLASS_TYPE, offset) {};
RWScalarOpTemplate(uint32_t offset,ObjectInfoType info)157         RWScalarOpTemplate(uint32_t offset, ObjectInfoType info)
158             : TypeInfoHeader(sizeof(RWScalarOpTemplate), InfoType::USE_HCLASS_TYPE, offset)
159         {
160             type_.AddObjectInfo(info);
161         }
162 
163         template <typename FromType>
ConvertFrom(PGOContext & context,const FromType & from)164         void ConvertFrom(PGOContext &context, const FromType &from)
165         {
166             size_ = sizeof(RWScalarOpTemplate);
167             type_.ConvertFrom(context, from.GetTypeRef());
168         }
169 
170         bool operator<(const RWScalarOpTemplate &right) const
171         {
172             return offset_ < right.offset_;
173         }
174 
GetCount()175         int32_t GetCount() const
176         {
177             return type_.GetCount();
178         }
179 
Merge(const RWScalarOpTemplate & type)180         void Merge(const RWScalarOpTemplate &type)
181         {
182             type_.Merge(type.type_);
183         }
184 
AddObjectInfo(const ObjectInfoType & info)185         void AddObjectInfo(const ObjectInfoType &info)
186         {
187             type_.AddObjectInfo(info);
188         }
189 
GetTypeRef()190         const RWOpType &GetTypeRef() const
191         {
192             return type_;
193         }
194 
ProcessToText(std::string & text)195         void ProcessToText(std::string &text) const
196         {
197             text += std::to_string(GetOffset());
198             text += DumpUtils::BLOCK_START;
199             text += DumpUtils::ARRAY_START + DumpUtils::SPACE;
200             bool isFirst = true;
201             for (uint32_t i = 0; i < type_.GetCount(); i++) {
202                 if (!isFirst) {
203                     text += DumpUtils::TYPE_SEPARATOR + DumpUtils::SPACE;
204                 }
205                 isFirst = false;
206                 text += type_.GetObjectInfo(i).GetInfoString();
207             }
208             text += (DumpUtils::SPACE + DumpUtils::ARRAY_END);
209         }
210 
ProcessToJson(ProfileType::MapVector & typeArray)211         void ProcessToJson(ProfileType::MapVector &typeArray) const
212         {
213             for (uint32_t i = 0; i < type_.GetCount(); i++) {
214                 std::vector<ProfileType::StringMap> sameOffsetTypeArray;
215                 type_.GetObjectInfo(i).GetInfoJson(sameOffsetTypeArray, std::to_string(GetOffset()));
216                 typeArray.push_back(sameOffsetTypeArray);
217             }
218         }
219 
220     private:
221         RWOpType type_;
222     };
223     using RWScalarOpTypeInfo = RWScalarOpTemplate<PGORWOpType, PGOObjectInfo>;
224     using RWScalarOpTypeInfoRef = RWScalarOpTemplate<PGORWOpTypeRef, PGOObjectInfoRef>;
225 
226     template <typename SampleType>
227     class ScalarOpTemplate : public TypeInfoHeader {
228     public:
ScalarOpTemplate(uint32_t offset,SampleType type)229         ScalarOpTemplate(uint32_t offset, SampleType type)
230             : TypeInfoHeader(sizeof(ScalarOpTemplate), InfoType::OP_TYPE, offset), type_(type) {}
231 
232         bool operator<(const ScalarOpTemplate &right) const
233         {
234             return offset_ < right.offset_;
235         }
236 
SetType(SampleType type)237         void SetType(SampleType type)
238         {
239             if (type_ != type) {
240                 type_ = type;
241             }
242         }
243 
Merge(const ScalarOpTemplate & typeInfo)244         void Merge(const ScalarOpTemplate &typeInfo)
245         {
246             SampleType combineType = GetType().CombineType(typeInfo.GetType());
247             SetType(combineType);
248         }
249 
GetType()250         SampleType GetType() const
251         {
252             return type_;
253         }
254 
GetTypeRef()255         const SampleType &GetTypeRef() const
256         {
257             return type_;
258         }
259 
260     protected:
ScalarOpTemplate(uint32_t size,InfoType infoType,uint32_t offset,SampleType type)261         ScalarOpTemplate(uint32_t size, InfoType infoType, uint32_t offset, SampleType type)
262             : TypeInfoHeader(size, infoType, offset), type_(type) {}
263 
264     private:
265         SampleType type_;
266     };
267     using ScalarOpTypeInfo = ScalarOpTemplate<PGOSampleType>;
268     using ScalarOpTypeInfoRef = ScalarOpTemplate<PGOSampleTypeRef>;
269 
270     template <typename PGODefineOpType>
271     class ObjDefOpTemplate : public TypeInfoHeader {
272     public:
ObjDefOpTemplate(uint32_t offset,PGODefineOpType type)273         ObjDefOpTemplate(uint32_t offset, PGODefineOpType type)
274             : TypeInfoHeader(sizeof(ObjDefOpTemplate), InfoType::DEFINE_CLASS_TYPE, offset), type_(type) {}
275 
276         bool operator<(const ObjDefOpTemplate &right) const
277         {
278             if (this->offset_ != right.GetOffset()) {
279                 return this->offset_ < right.GetOffset();
280             }
281             return this->GetType() < right.GetType();
282         }
283 
ProcessToText(std::string & text)284         void ProcessToText(std::string &text) const
285         {
286             text += std::to_string(this->GetOffset());
287             text += DumpUtils::BLOCK_START;
288             text += DumpUtils::ARRAY_START + DumpUtils::SPACE;
289             text += this->GetType().GetTypeString();
290             text += (DumpUtils::SPACE + DumpUtils::ARRAY_END);
291         }
292 
ProcessToJson(std::vector<ProfileType::StringMap> & sameOffsetTypeArray)293         void ProcessToJson(std::vector<ProfileType::StringMap> &sameOffsetTypeArray) const
294         {
295             this->GetType().GetTypeJson(sameOffsetTypeArray, std::to_string(this->GetOffset()));
296         }
297 
GetType()298         PGODefineOpType GetType() const
299         {
300             return type_;
301         }
302 
GetTypeRef()303         const PGODefineOpType &GetTypeRef() const
304         {
305             return type_;
306         }
307 
308     protected:
ObjDefOpTemplate(uint32_t size,InfoType infoType,uint32_t offset,PGODefineOpType type)309         ObjDefOpTemplate(
310             uint32_t size, InfoType infoType, uint32_t offset, PGODefineOpType type)
311             : TypeInfoHeader(size, infoType, offset), type_(type) {}
312     private:
313         PGODefineOpType type_;
314     };
315     using ObjDefOpTypeInfo = ObjDefOpTemplate<PGODefineOpType>;
316     using ObjDefOpTypeInfoRef = ObjDefOpTemplate<PGODefineOpTypeRef>;
317 
318     std::set<ScalarOpTypeInfo> scalarOpTypeInfos_;
319     std::set<RWScalarOpTypeInfo> rwScalarOpTypeInfos_;
320     std::set<ObjDefOpTypeInfo> objDefOpTypeInfos_;
321 };
322 } // namespace panda::ecmascript::pgo
323 #endif  // ECMASCRIPT_PGO_PROFILER_AP_FILE_PGO_METHOD_TYPE_SET_H
324