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