1 /* 2 * Copyright (c) 2022 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_PROFILE_DECODER_H 17 #define ECMASCRIPT_PGO_PROFILE_DECODER_H 18 19 #include "ecmascript/jspandafile/method_literal.h" 20 #include "ecmascript/log.h" 21 #include "ecmascript/log_wrapper.h" 22 #include "ecmascript/pgo_profiler/pgo_profiler_info.h" 23 #include "ecmascript/pgo_profiler/pgo_profiler_type.h" 24 #include "ecmascript/platform/map.h" 25 26 namespace panda::ecmascript { 27 class PGOProfilerDecoder { 28 public: 29 PGOProfilerDecoder() = default; PGOProfilerDecoder(const std::string & inPath,uint32_t hotnessThreshold)30 PGOProfilerDecoder(const std::string &inPath, uint32_t hotnessThreshold) 31 : inPath_(inPath), hotnessThreshold_(hotnessThreshold) {} 32 ~PGOProfilerDecoder()33 virtual ~PGOProfilerDecoder() 34 { 35 Clear(); 36 }; 37 38 NO_COPY_SEMANTIC(PGOProfilerDecoder); 39 NO_MOVE_SEMANTIC(PGOProfilerDecoder); 40 41 bool PUBLIC_API Match(const CString &recordName, PGOMethodId methodId); 42 43 bool PUBLIC_API LoadAndVerify(uint32_t checksum); 44 bool PUBLIC_API LoadFull(); 45 void PUBLIC_API Clear(); 46 47 bool PUBLIC_API SaveAPTextFile(const std::string &outPath); 48 49 void Merge(const PGOProfilerDecoder &decoder); 50 51 bool InitMergeData(); 52 GetInPath()53 const std::string& GetInPath() const 54 { 55 return inPath_; 56 } 57 GetHotnessThreshold()58 uint32_t GetHotnessThreshold() const 59 { 60 return hotnessThreshold_; 61 } 62 63 template <typename Callback> Update(Callback callback)64 void Update(Callback callback) 65 { 66 if (!isLoaded_ || !isVerifySuccess_) { 67 return; 68 } 69 recordSimpleInfos_->Update(callback); 70 } 71 72 template <typename Callback> Update(const CString & recordName,Callback callback)73 void Update(const CString &recordName, Callback callback) 74 { 75 if (!isLoaded_ || !isVerifySuccess_) { 76 return; 77 } 78 recordSimpleInfos_->Update(recordName, callback); 79 } 80 81 template <typename Callback> GetTypeInfo(const JSPandaFile * jsPandaFile,const CString & recordName,const MethodLiteral * methodLiteral,Callback callback)82 void GetTypeInfo(const JSPandaFile *jsPandaFile, const CString &recordName, const MethodLiteral *methodLiteral, 83 Callback callback) 84 { 85 if (!isLoaded_ || !isVerifySuccess_) { 86 return; 87 } 88 const auto *methodName = MethodLiteral::GetMethodName(jsPandaFile, methodLiteral->GetMethodId()); 89 if (IsMethodMatchEnabled()) { 90 auto checksum = 91 PGOMethodInfo::CalcChecksum(methodName, methodLiteral->GetBytecodeArray(), 92 MethodLiteral::GetCodeSize(jsPandaFile, methodLiteral->GetMethodId())); 93 94 return recordSimpleInfos_->GetTypeInfo(recordName, methodName, checksum, callback); 95 } 96 recordSimpleInfos_->GetTypeInfo(recordName, methodName, callback); 97 } 98 MatchAndMarkMethod(const CString & recordName,const char * methodName,EntityId methodId)99 void MatchAndMarkMethod(const CString &recordName, const char *methodName, EntityId methodId) 100 { 101 if (!isLoaded_ || !isVerifySuccess_) { 102 return; 103 } 104 recordSimpleInfos_->MatchAndMarkMethod(recordName, methodName, methodId); 105 } 106 107 void GetMismatchResult(uint32_t &totalMethodCount, uint32_t &mismatchMethodCount, 108 std::set<std::pair<std::string, CString>> &mismatchMethodSet) const; 109 IsMethodMatchEnabled()110 bool IsMethodMatchEnabled() const 111 { 112 return header_->SupportMethodChecksum(); 113 } 114 115 bool GetHClassLayoutDesc(PGOSampleType classType, PGOHClassLayoutDesc **desc) const; 116 IsLoaded()117 bool IsLoaded() const 118 { 119 return isLoaded_; 120 } 121 GetRecordDetailInfos()122 PGORecordDetailInfos &GetRecordDetailInfos() const 123 { 124 return *recordDetailInfos_; 125 } 126 GetRecordDetailInfosPtr()127 std::shared_ptr<PGORecordDetailInfos> GetRecordDetailInfosPtr() const 128 { 129 return recordDetailInfos_; 130 } 131 GetRecordSimpleInfos()132 PGORecordSimpleInfos &GetRecordSimpleInfos() const 133 { 134 return *recordSimpleInfos_; 135 } 136 GetPandaFileInfos()137 const PGOPandaFileInfos &GetPandaFileInfos() const 138 { 139 return pandaFileInfos_; 140 } 141 142 private: 143 bool Load(); 144 bool Verify(uint32_t checksum); 145 146 bool LoadAPBinaryFile(int prot = PAGE_PROT_READ); 147 void UnLoadAPBinaryFile(); 148 149 bool isLoaded_ {false}; 150 bool isVerifySuccess_ {false}; 151 std::string inPath_; 152 uint32_t hotnessThreshold_ {0}; 153 PGOProfilerHeader *header_ {nullptr}; 154 PGOPandaFileInfos pandaFileInfos_; 155 std::shared_ptr<PGORecordDetailInfos> recordDetailInfos_; 156 std::unique_ptr<PGORecordSimpleInfos> recordSimpleInfos_; 157 MemMap fileMapAddr_; 158 }; 159 } // namespace panda::ecmascript 160 #endif // ECMASCRIPT_PGO_PROFILE_DECODER_H 161