• 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 #include "ecmascript/pgo_profiler/ap_file/pgo_method_type_set.h"
17 #include "ecmascript/pgo_profiler/ap_file/pgo_file_info.h"
18 
19 namespace panda::ecmascript::pgo {
20 using StringHelper = base::StringHelper;
Merge(const PGOMethodTypeSet * info)21 void PGOMethodTypeSet::Merge(const PGOMethodTypeSet *info)
22 {
23     for (const auto &fromType : info->scalarOpTypeInfos_) {
24         auto iter = scalarOpTypeInfos_.find(fromType);
25         if (iter != scalarOpTypeInfos_.end()) {
26             const_cast<ScalarOpTypeInfo &>(*iter).Merge(fromType);
27         } else {
28             scalarOpTypeInfos_.emplace(fromType);
29         }
30     }
31     for (const auto &fromType : info->rwScalarOpTypeInfos_) {
32         auto iter = rwScalarOpTypeInfos_.find(fromType);
33         if (iter != rwScalarOpTypeInfos_.end()) {
34             const_cast<RWScalarOpTypeInfo &>(*iter).Merge(fromType);
35         } else {
36             rwScalarOpTypeInfos_.emplace(fromType);
37         }
38     }
39     for (const auto &fromType : info->objDefOpTypeInfos_) {
40         AddDefine(fromType.GetOffset(), fromType.GetType());
41     }
42 }
43 
SkipFromBinary(void ** buffer)44 void PGOMethodTypeSet::SkipFromBinary(void **buffer)
45 {
46     uint32_t size = base::ReadBuffer<uint32_t>(buffer, sizeof(uint32_t));
47     for (uint32_t i = 0; i < size; i++) {
48         base::ReadBufferInSize<ScalarOpTypeInfo>(buffer);
49     }
50 }
51 
ParseFromBinary(PGOContext & context,void ** buffer)52 bool PGOMethodTypeSet::ParseFromBinary(PGOContext &context, void **buffer)
53 {
54     PGOProfilerHeader *const header = context.GetHeader();
55     ASSERT(header != nullptr);
56     uint32_t size = base::ReadBuffer<uint32_t>(buffer, sizeof(uint32_t));
57     if (size > MAX_METHOD_TYPE_SIZE) {
58         return false;
59     }
60     for (uint32_t i = 0; i < size; i++) {
61         auto typeInfo = base::ReadBufferInSize<TypeInfoHeader>(buffer);
62         if (typeInfo->GetInfoType() == InfoType::OP_TYPE) {
63             auto *scalerInfo = reinterpret_cast<ScalarOpTypeInfoRef *>(typeInfo);
64             scalarOpTypeInfos_.emplace(scalerInfo->GetOffset(),
65                                        PGOSampleType::ConvertFrom(context, scalerInfo->GetType()));
66         } else if (typeInfo->GetInfoType() == InfoType::DEFINE_CLASS_TYPE) {
67             auto *defineInfo = reinterpret_cast<ObjDefOpTypeInfoRef *>(typeInfo);
68             PGODefineOpType type;
69             type.ConvertFrom(context, defineInfo->GetType());
70             ObjDefOpTypeInfo info(defineInfo->GetOffset(), type);
71             objDefOpTypeInfos_.emplace(info);
72         } else if (header->SupportUseHClassType() && typeInfo->GetInfoType() == InfoType::USE_HCLASS_TYPE) {
73             auto *opTypeInfo = reinterpret_cast<RWScalarOpTypeInfoRef *>(typeInfo);
74             RWScalarOpTypeInfo info(opTypeInfo->GetOffset());
75             info.ConvertFrom(context, *opTypeInfo);
76             for (int j = 0; j < info.GetCount(); j++) {
77                 if (info.GetTypeRef().GetObjectInfo(j).GetProtoChainMarker() == ProtoChainMarker::EXSIT) {
78                     auto protoChainRef = base::ReadBufferInSize<PGOProtoChainRef>(buffer);
79                     auto protoChain = PGOProtoChain::ConvertFrom(context, protoChainRef);
80                     const_cast<PGOObjectInfo &>(info.GetTypeRef().GetObjectInfo(j)).SetProtoChain(protoChain);
81                 }
82             }
83             rwScalarOpTypeInfos_.emplace(info);
84         }
85     }
86     return true;
87 }
88 
ProcessToBinary(PGOContext & context,std::stringstream & stream) const89 bool PGOMethodTypeSet::ProcessToBinary(PGOContext &context, std::stringstream &stream) const
90 {
91     uint32_t number = 0;
92     std::stringstream methodStream;
93     for (auto &typeInfo : scalarOpTypeInfos_) {
94         if (!typeInfo.GetType().IsNone()) {
95             PGOSampleTypeRef sampleTypeRef = PGOSampleTypeRef::ConvertFrom(context, typeInfo.GetType());
96             ScalarOpTypeInfoRef infoRef(typeInfo.GetOffset(), sampleTypeRef);
97             methodStream.write(reinterpret_cast<char *>(&infoRef), infoRef.Size());
98             number++;
99         }
100     }
101     for (auto &typeInfo : rwScalarOpTypeInfos_) {
102         if (typeInfo.GetCount() != 0) {
103             RWScalarOpTypeInfoRef infoRef(typeInfo.GetOffset());
104             infoRef.ConvertFrom(context, typeInfo);
105             methodStream.write(reinterpret_cast<char *>(&infoRef), infoRef.Size());
106             for (int i = 0; i < typeInfo.GetCount(); i++) {
107                 if (typeInfo.GetTypeRef().GetObjectInfo(i).GetProtoChainMarker() == ProtoChainMarker::EXSIT) {
108                     auto protoChain = typeInfo.GetTypeRef().GetObjectInfo(i).GetProtoChain();
109                     auto protoChainRef = PGOProtoChainRef::ConvertFrom(context, protoChain);
110                     methodStream.write(reinterpret_cast<char *>(protoChainRef), protoChainRef->Size());
111                     PGOProtoChainRef::DeleteProtoChain(protoChainRef);
112                 }
113             }
114             number++;
115         }
116     }
117 
118     for (const auto &typeInfo : objDefOpTypeInfos_) {
119         PGODefineOpTypeRef typeRef;
120         typeRef.ConvertFrom(context, typeInfo.GetType());
121         ObjDefOpTypeInfoRef infoRef(typeInfo.GetOffset(), typeRef);
122         methodStream.write(reinterpret_cast<char *>(&infoRef), infoRef.Size());
123         number++;
124     }
125 
126     stream.write(reinterpret_cast<char *>(&number), sizeof(uint32_t));
127     if (number > 0) {
128         stream << methodStream.rdbuf();
129         return true;
130     }
131     return false;
132 }
133 
ParseFromText(const std::string & typeString)134 bool PGOMethodTypeSet::ParseFromText(const std::string &typeString)
135 {
136     std::vector<std::string> typeInfoVector = StringHelper::SplitString(typeString, DumpUtils::TYPE_SEPARATOR);
137     if (typeInfoVector.size() > 0) {
138         for (const auto &iter : typeInfoVector) {
139             std::vector<std::string> typeStrings = StringHelper::SplitString(iter, DumpUtils::BLOCK_START);
140             if (typeStrings.size() < METHOD_TYPE_INFO_COUNT) {
141                 return false;
142             }
143 
144             uint32_t offset = 0;
145             if (!StringHelper::StrToUInt32(typeStrings[METHOD_OFFSET_INDEX].c_str(), &offset)) {
146                 return false;
147             }
148             uint32_t type = 0;
149             if (!StringHelper::StrToUInt32(typeStrings[METHOD_TYPE_INDEX].c_str(), &type)) {
150                 return false;
151             }
152             scalarOpTypeInfos_.emplace(offset, PGOSampleType(type));
153         }
154     }
155     return true;
156 }
157 
ProcessToText(std::string & text) const158 void PGOMethodTypeSet::ProcessToText(std::string &text) const
159 {
160     bool isFirst = true;
161     for (auto typeInfoIter : scalarOpTypeInfos_) {
162         if (typeInfoIter.GetType().IsNone()) {
163             continue;
164         }
165         if (isFirst) {
166             text += DumpUtils::ARRAY_START + DumpUtils::SPACE;
167             isFirst = false;
168         } else {
169             text += DumpUtils::TYPE_SEPARATOR + DumpUtils::SPACE;
170         }
171         text += std::to_string(typeInfoIter.GetOffset());
172         text += DumpUtils::BLOCK_START;
173         text += typeInfoIter.GetType().GetTypeString();
174     }
175     for (auto rwScalarOpTypeInfoIter : rwScalarOpTypeInfos_) {
176         if (rwScalarOpTypeInfoIter.GetCount() == 0) {
177             continue;
178         }
179         if (isFirst) {
180             text += DumpUtils::ARRAY_START + DumpUtils::SPACE;
181             isFirst = false;
182         } else {
183             text += DumpUtils::TYPE_SEPARATOR + DumpUtils::SPACE;
184         }
185         rwScalarOpTypeInfoIter.ProcessToText(text);
186     }
187     for (const auto &defTypeInfoIter : objDefOpTypeInfos_) {
188         if (isFirst) {
189             text += DumpUtils::ARRAY_START + DumpUtils::SPACE;
190             isFirst = false;
191         } else {
192             text += DumpUtils::TYPE_SEPARATOR + DumpUtils::SPACE;
193         }
194         defTypeInfoIter.ProcessToText(text);
195     }
196     if (!isFirst) {
197         text += (DumpUtils::SPACE + DumpUtils::ARRAY_END);
198     }
199 }
200 
ProcessToJson(ProfileType::VariantVector & typeArray) const201 void PGOMethodTypeSet::ProcessToJson(ProfileType::VariantVector &typeArray) const
202 {
203     for (auto typeInfoIter : scalarOpTypeInfos_) {
204         if (typeInfoIter.GetType().IsNone()) {
205             continue;
206         }
207         ProfileType::StringMap type;
208         type.insert(std::make_pair(DumpJsonUtils::TYPE_OFFSET, std::to_string(typeInfoIter.GetOffset())));
209         typeInfoIter.GetType().GetTypeJson(type);
210         typeArray.push_back(type);
211     }
212     for (auto rwScalarOpTypeInfoIter : rwScalarOpTypeInfos_) {
213         if (rwScalarOpTypeInfoIter.GetCount() == 0) {
214             continue;
215         }
216         ProfileType::MapVector sameOffsetTypeArray;
217         rwScalarOpTypeInfoIter.ProcessToJson(sameOffsetTypeArray);
218         typeArray.push_back(sameOffsetTypeArray);
219     }
220     for (const auto &defTypeInfoIter : objDefOpTypeInfos_) {
221         std::vector<ProfileType::StringMap> sameOffsetTypeArray;
222         defTypeInfoIter.ProcessToJson(sameOffsetTypeArray);
223         typeArray.push_back(sameOffsetTypeArray);
224     }
225 }
226 } // namespace panda::ecmascript::pgo
227