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