• 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                 const_cast<PGODefineOpTemplate<ProfileType> *>(&((*result).GetTypeRef()))
82                     ->SetSpaceFlag(type.GetSpaceFlag());
83             }
84             return;
85         }
86         objDefOpTypeInfos_.emplace(offset, type);
87     }
88 
89     template <typename Callback>
GetTypeInfo(Callback callback)90     void GetTypeInfo(Callback callback)
91     {
92         for (const auto &typeInfo : scalarOpTypeInfos_) {
93             const auto &type = typeInfo.GetTypeRef();
94             callback(typeInfo.GetOffset(), &type);
95         }
96         for (const auto &typeInfo : rwScalarOpTypeInfos_) {
97             const auto &type = typeInfo.GetTypeRef();
98             callback(typeInfo.GetOffset(), &type);
99         }
100         for (const auto &typeInfo : objDefOpTypeInfos_) {
101             const auto &type = typeInfo.GetTypeRef();
102             callback(typeInfo.GetOffset(), &type);
103         }
104     }
105 
106     void Merge(const PGOMethodTypeSet *info);
107     static void SkipFromBinary(void **buffer);
108 
109     bool ParseFromBinary(PGOContext& context, void** addr, size_t bufferSize);
110     bool ProcessToBinary(PGOContext &context, std::stringstream &stream) const;
111 
112     bool ParseFromText(const std::string &typeString);
113     void ProcessToText(std::string &text) const;
114 
115     void ProcessToJson(ProfileType::VariantVector &typeArray) const;
116 
117     NO_COPY_SEMANTIC(PGOMethodTypeSet);
118     NO_MOVE_SEMANTIC(PGOMethodTypeSet);
119 
120 private:
121     enum class InfoType : uint8_t {
122         NONE,
123         OP_TYPE,
124         DEFINE_CLASS_TYPE = 3,
125         USE_HCLASS_TYPE
126     };
127 
128     class TypeInfoHeader {
129     public:
TypeInfoHeader(InfoType type,uint32_t offset)130         TypeInfoHeader(InfoType type, uint32_t offset) : infoType_(type), offset_(offset) {}
TypeInfoHeader(uint32_t size,InfoType type,uint32_t offset)131         TypeInfoHeader(uint32_t size, InfoType type, uint32_t offset)
132             : size_(size), infoType_(type), offset_(offset) {}
133 
GetInfoType()134         InfoType GetInfoType()
135         {
136             return infoType_;
137         }
138 
Size()139         int32_t Size() const
140         {
141             return size_;
142         }
143 
GetOffset()144         uint32_t GetOffset() const
145         {
146             return offset_;
147         }
148 
149     protected:
150         uint32_t size_ {0};
151         InfoType infoType_ {InfoType::NONE};
152         uint32_t offset_ {0};
153     };
154 
155     template <typename RWOpType, typename ObjectInfoType>
156     class RWScalarOpTemplate : public TypeInfoHeader {
157     public:
RWScalarOpTemplate(uint32_t offset)158         explicit RWScalarOpTemplate(uint32_t offset) : TypeInfoHeader(InfoType::USE_HCLASS_TYPE, offset) {};
RWScalarOpTemplate(uint32_t offset,ObjectInfoType info)159         RWScalarOpTemplate(uint32_t offset, ObjectInfoType info)
160             : TypeInfoHeader(sizeof(RWScalarOpTemplate), InfoType::USE_HCLASS_TYPE, offset)
161         {
162             type_.AddObjectInfo(info);
163         }
164 
165         template <typename FromType>
ConvertFrom(PGOContext & context,const FromType & from)166         void ConvertFrom(PGOContext &context, const FromType &from)
167         {
168             size_ = sizeof(RWScalarOpTemplate);
169             type_.ConvertFrom(context, from.GetTypeRef());
170         }
171 
172         bool operator<(const RWScalarOpTemplate &right) const
173         {
174             return offset_ < right.offset_;
175         }
176 
GetCount()177         int32_t GetCount() const
178         {
179             return type_.GetCount();
180         }
181 
Merge(const RWScalarOpTemplate & type)182         void Merge(const RWScalarOpTemplate &type)
183         {
184             type_.Merge(type.type_);
185         }
186 
AddObjectInfo(const ObjectInfoType & info)187         void AddObjectInfo(const ObjectInfoType &info)
188         {
189             type_.AddObjectInfo(info);
190         }
191 
GetTypeRef()192         const RWOpType &GetTypeRef() const
193         {
194             return type_;
195         }
196 
ProcessToText(std::string & text)197         void ProcessToText(std::string &text) const
198         {
199             text += std::to_string(GetOffset());
200             text += DumpUtils::BLOCK_START;
201             text += DumpUtils::ARRAY_START + DumpUtils::NEW_LINE;
202             bool isFirst = true;
203             for (uint32_t i = 0; i < type_.GetCount(); i++) {
204                 if (!isFirst) {
205                     text += DumpUtils::SPACE + DumpUtils::BLOCK_SEPARATOR + DumpUtils::NEW_LINE;
206                 }
207                 isFirst = false;
208                 text += type_.GetObjectInfo(i).GetInfoString();
209             }
210             text += DumpUtils::NEW_LINE + DumpUtils::ALIGN + DumpUtils::ALIGN + DumpUtils::ARRAY_END;
211         }
212 
ProcessToJson(ProfileType::MapVector & typeArray)213         void ProcessToJson(ProfileType::MapVector &typeArray) const
214         {
215             for (uint32_t i = 0; i < type_.GetCount(); i++) {
216                 std::vector<ProfileType::StringMap> sameOffsetTypeArray;
217                 type_.GetObjectInfo(i).GetInfoJson(sameOffsetTypeArray, std::to_string(GetOffset()));
218                 typeArray.push_back(sameOffsetTypeArray);
219             }
220         }
221 
222     private:
223         RWOpType type_;
224     };
225     using RWScalarOpTypeInfo = RWScalarOpTemplate<PGORWOpType, PGOObjectInfo>;
226     using RWScalarOpTypeInfoRef = RWScalarOpTemplate<PGORWOpTypeRef, PGOObjectInfoRef>;
227 
228     template <typename SampleType>
229     class ScalarOpTemplate : public TypeInfoHeader {
230     public:
ScalarOpTemplate(uint32_t offset,SampleType type)231         ScalarOpTemplate(uint32_t offset, SampleType type)
232             : TypeInfoHeader(sizeof(ScalarOpTemplate), InfoType::OP_TYPE, offset), type_(type) {}
233 
234         bool operator<(const ScalarOpTemplate &right) const
235         {
236             return offset_ < right.offset_;
237         }
238 
SetType(SampleType type)239         void SetType(SampleType type)
240         {
241             if (type_ != type) {
242                 type_ = type;
243             }
244         }
245 
Merge(const ScalarOpTemplate & typeInfo)246         void Merge(const ScalarOpTemplate &typeInfo)
247         {
248             SampleType combineType = GetType().CombineType(typeInfo.GetType());
249             SetType(combineType);
250         }
251 
GetType()252         SampleType GetType() const
253         {
254             return type_;
255         }
256 
GetTypeRef()257         const SampleType &GetTypeRef() const
258         {
259             return type_;
260         }
261 
262     protected:
ScalarOpTemplate(uint32_t size,InfoType infoType,uint32_t offset,SampleType type)263         ScalarOpTemplate(uint32_t size, InfoType infoType, uint32_t offset, SampleType type)
264             : TypeInfoHeader(size, infoType, offset), type_(type) {}
265 
266     private:
267         SampleType type_;
268     };
269     using ScalarOpTypeInfo = ScalarOpTemplate<PGOSampleType>;
270     using ScalarOpTypeInfoRef = ScalarOpTemplate<PGOSampleTypeRef>;
271 
272     template <typename PGODefineOpType>
273     class ObjDefOpTemplate : public TypeInfoHeader {
274     public:
ObjDefOpTemplate(uint32_t offset,PGODefineOpType type)275         ObjDefOpTemplate(uint32_t offset, PGODefineOpType type)
276             : TypeInfoHeader(sizeof(ObjDefOpTemplate), InfoType::DEFINE_CLASS_TYPE, offset), type_(type) {}
277 
278         bool operator<(const ObjDefOpTemplate &right) const
279         {
280             if (this->offset_ != right.GetOffset()) {
281                 return this->offset_ < right.GetOffset();
282             }
283             return this->GetType() < right.GetType();
284         }
285 
ProcessToText(std::string & text)286         void ProcessToText(std::string &text) const
287         {
288             text += std::to_string(this->GetOffset());
289             text += DumpUtils::BLOCK_START;
290             text += DumpUtils::ARRAY_START + DumpUtils::NEW_LINE;
291             text += this->GetType().GetTypeString();
292             text += DumpUtils::NEW_LINE + DumpUtils::ALIGN + DumpUtils::ALIGN + DumpUtils::ARRAY_END;
293         }
294 
ProcessToJson(std::vector<ProfileType::StringMap> & sameOffsetTypeArray)295         void ProcessToJson(std::vector<ProfileType::StringMap> &sameOffsetTypeArray) const
296         {
297             this->GetType().GetTypeJson(sameOffsetTypeArray, std::to_string(this->GetOffset()));
298         }
299 
GetType()300         PGODefineOpType GetType() const
301         {
302             return type_;
303         }
304 
GetTypeRef()305         const PGODefineOpType &GetTypeRef() const
306         {
307             return type_;
308         }
309 
310     protected:
ObjDefOpTemplate(uint32_t size,InfoType infoType,uint32_t offset,PGODefineOpType type)311         ObjDefOpTemplate(
312             uint32_t size, InfoType infoType, uint32_t offset, PGODefineOpType type)
313             : TypeInfoHeader(size, infoType, offset), type_(type) {}
314     private:
315         PGODefineOpType type_;
316     };
317 
318     bool ParseProtoChainsFromBinary(
319         PGOContext& context, RWScalarOpTypeInfo& info, void** addr, void* buffer, size_t bufferSize);
320 
321     using ObjDefOpTypeInfo = ObjDefOpTemplate<PGODefineOpType>;
322     using ObjDefOpTypeInfoRef = ObjDefOpTemplate<PGODefineOpTypeRef>;
323 
324     std::set<ScalarOpTypeInfo> scalarOpTypeInfos_;
325     std::set<RWScalarOpTypeInfo> rwScalarOpTypeInfos_;
326     std::set<ObjDefOpTypeInfo> objDefOpTypeInfos_;
327 };
328 } // namespace panda::ecmascript::pgo
329 #endif  // ECMASCRIPT_PGO_PROFILER_AP_FILE_PGO_METHOD_TYPE_SET_H
330