14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#ifndef ECMASCRIPT_PGO_PROFILE_DECODER_H 174514f5e3Sopenharmony_ci#define ECMASCRIPT_PGO_PROFILE_DECODER_H 184514f5e3Sopenharmony_ci 194514f5e3Sopenharmony_ci#include "ecmascript/jspandafile/method_literal.h" 204514f5e3Sopenharmony_ci#include "ecmascript/log.h" 214514f5e3Sopenharmony_ci#include "ecmascript/log_wrapper.h" 224514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/pgo_profiler_info.h" 234514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/pgo_utils.h" 244514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/types/pgo_profiler_type.h" 254514f5e3Sopenharmony_ci#include "ecmascript/platform/map.h" 264514f5e3Sopenharmony_ci 274514f5e3Sopenharmony_cinamespace panda::ecmascript::pgo { 284514f5e3Sopenharmony_ciclass PGOProfilerDecoder { 294514f5e3Sopenharmony_cipublic: 304514f5e3Sopenharmony_ci PGOProfilerDecoder() = default; 314514f5e3Sopenharmony_ci PGOProfilerDecoder(const std::string &inPath, uint32_t hotnessThreshold) 324514f5e3Sopenharmony_ci : inPath_(inPath), hotnessThreshold_(hotnessThreshold) {} 334514f5e3Sopenharmony_ci 344514f5e3Sopenharmony_ci virtual ~PGOProfilerDecoder() 354514f5e3Sopenharmony_ci { 364514f5e3Sopenharmony_ci Clear(); 374514f5e3Sopenharmony_ci }; 384514f5e3Sopenharmony_ci 394514f5e3Sopenharmony_ci NO_COPY_SEMANTIC(PGOProfilerDecoder); 404514f5e3Sopenharmony_ci NO_MOVE_SEMANTIC(PGOProfilerDecoder); 414514f5e3Sopenharmony_ci 424514f5e3Sopenharmony_ci bool PUBLIC_API Match(const JSPandaFile *jsPandaFile, const CString &recordName, PGOMethodId methodId); 434514f5e3Sopenharmony_ci 444514f5e3Sopenharmony_ci bool PUBLIC_API LoadAndVerify(uint32_t checksum, 454514f5e3Sopenharmony_ci const std::shared_ptr<PGOAbcFilePool> &externalAbcFilePool = nullptr); 464514f5e3Sopenharmony_ci bool PUBLIC_API LoadFull(const std::shared_ptr<PGOAbcFilePool> &externalAbcFilePool = nullptr); 474514f5e3Sopenharmony_ci void PUBLIC_API Clear(); 484514f5e3Sopenharmony_ci 494514f5e3Sopenharmony_ci bool PUBLIC_API SaveAPTextFile(const std::string &outPath); 504514f5e3Sopenharmony_ci 514514f5e3Sopenharmony_ci void Merge(const PGOProfilerDecoder &decoder); 524514f5e3Sopenharmony_ci 534514f5e3Sopenharmony_ci std::shared_ptr<PGOAbcFilePool> GetAbcFilePool() const 544514f5e3Sopenharmony_ci { 554514f5e3Sopenharmony_ci return abcFilePool_; 564514f5e3Sopenharmony_ci } 574514f5e3Sopenharmony_ci 584514f5e3Sopenharmony_ci bool InitMergeData(); 594514f5e3Sopenharmony_ci 604514f5e3Sopenharmony_ci void SetInPath(const std::string &inPath) 614514f5e3Sopenharmony_ci { 624514f5e3Sopenharmony_ci LOG_COMPILER(INFO) << "Set Profiler paths: " << inPath; 634514f5e3Sopenharmony_ci inPath_ = inPath; 644514f5e3Sopenharmony_ci } 654514f5e3Sopenharmony_ci 664514f5e3Sopenharmony_ci const std::string& GetInPath() const 674514f5e3Sopenharmony_ci { 684514f5e3Sopenharmony_ci return inPath_; 694514f5e3Sopenharmony_ci } 704514f5e3Sopenharmony_ci 714514f5e3Sopenharmony_ci void SetHotnessThreshold(uint32_t hotnessThreshold) 724514f5e3Sopenharmony_ci { 734514f5e3Sopenharmony_ci hotnessThreshold_ = hotnessThreshold; 744514f5e3Sopenharmony_ci } 754514f5e3Sopenharmony_ci 764514f5e3Sopenharmony_ci uint32_t GetHotnessThreshold() const 774514f5e3Sopenharmony_ci { 784514f5e3Sopenharmony_ci return hotnessThreshold_; 794514f5e3Sopenharmony_ci } 804514f5e3Sopenharmony_ci 814514f5e3Sopenharmony_ci template <typename Callback> 824514f5e3Sopenharmony_ci void Update(const JSPandaFile *jsPandaFile, Callback callback) 834514f5e3Sopenharmony_ci { 844514f5e3Sopenharmony_ci if (!isLoaded_ || !isVerifySuccess_) { 854514f5e3Sopenharmony_ci return; 864514f5e3Sopenharmony_ci } 874514f5e3Sopenharmony_ci recordSimpleInfos_->Update(GetNormalizedFileDesc(jsPandaFile), callback); 884514f5e3Sopenharmony_ci } 894514f5e3Sopenharmony_ci 904514f5e3Sopenharmony_ci template <typename Callback> 914514f5e3Sopenharmony_ci void Update(const JSPandaFile *jsPandaFile, const CString &recordName, Callback callback) 924514f5e3Sopenharmony_ci { 934514f5e3Sopenharmony_ci if (!isLoaded_ || !isVerifySuccess_) { 944514f5e3Sopenharmony_ci return; 954514f5e3Sopenharmony_ci } 964514f5e3Sopenharmony_ci recordSimpleInfos_->Update(GetNormalizedFileDesc(jsPandaFile), recordName, callback); 974514f5e3Sopenharmony_ci } 984514f5e3Sopenharmony_ci 994514f5e3Sopenharmony_ci template <typename Callback> 1004514f5e3Sopenharmony_ci void GetTypeInfo(const JSPandaFile *jsPandaFile, const CString &recordName, const MethodLiteral *methodLiteral, 1014514f5e3Sopenharmony_ci Callback callback) const 1024514f5e3Sopenharmony_ci { 1034514f5e3Sopenharmony_ci if (!isLoaded_ || !isVerifySuccess_ || methodLiteral == nullptr) { 1044514f5e3Sopenharmony_ci return; 1054514f5e3Sopenharmony_ci } 1064514f5e3Sopenharmony_ci const auto *methodName = MethodLiteral::GetMethodName(jsPandaFile, methodLiteral->GetMethodId()); 1074514f5e3Sopenharmony_ci if (IsMethodMatchEnabled()) { 1084514f5e3Sopenharmony_ci auto checksum = 1094514f5e3Sopenharmony_ci PGOMethodInfo::CalcChecksum(methodName, methodLiteral->GetBytecodeArray(), 1104514f5e3Sopenharmony_ci MethodLiteral::GetCodeSize(jsPandaFile, methodLiteral->GetMethodId())); 1114514f5e3Sopenharmony_ci 1124514f5e3Sopenharmony_ci return recordSimpleInfos_->GetTypeInfo(GetNormalizedFileDesc(jsPandaFile), recordName, methodName, checksum, 1134514f5e3Sopenharmony_ci callback); 1144514f5e3Sopenharmony_ci } 1154514f5e3Sopenharmony_ci recordSimpleInfos_->GetTypeInfo(GetNormalizedFileDesc(jsPandaFile), recordName, methodName, callback); 1164514f5e3Sopenharmony_ci } 1174514f5e3Sopenharmony_ci 1184514f5e3Sopenharmony_ci void MatchAndMarkMethod(const JSPandaFile *jsPandaFile, const CString &recordName, const char *methodName, 1194514f5e3Sopenharmony_ci EntityId methodId) 1204514f5e3Sopenharmony_ci { 1214514f5e3Sopenharmony_ci if (!isLoaded_ || !isVerifySuccess_) { 1224514f5e3Sopenharmony_ci return; 1234514f5e3Sopenharmony_ci } 1244514f5e3Sopenharmony_ci recordSimpleInfos_->MatchAndMarkMethod(GetNormalizedFileDesc(jsPandaFile), recordName, methodName, methodId); 1254514f5e3Sopenharmony_ci } 1264514f5e3Sopenharmony_ci 1274514f5e3Sopenharmony_ci void PUBLIC_API GetMismatchResult(const JSPandaFile *jsPandaFile, uint32_t &totalMethodCount, 1284514f5e3Sopenharmony_ci uint32_t &mismatchMethodCount, std::set<std::pair<std::string, CString>> &mismatchMethodSet) const; 1294514f5e3Sopenharmony_ci 1304514f5e3Sopenharmony_ci bool IsMethodMatchEnabled() const 1314514f5e3Sopenharmony_ci { 1324514f5e3Sopenharmony_ci return header_->SupportMethodChecksum(); 1334514f5e3Sopenharmony_ci } 1344514f5e3Sopenharmony_ci 1354514f5e3Sopenharmony_ci bool PUBLIC_API GetHClassTreeDesc(PGOSampleType profileType, PGOHClassTreeDesc **desc) const; 1364514f5e3Sopenharmony_ci 1374514f5e3Sopenharmony_ci template <typename Callback> 1384514f5e3Sopenharmony_ci bool IterateHClassTreeDesc(Callback callback) const 1394514f5e3Sopenharmony_ci { 1404514f5e3Sopenharmony_ci if (!isLoaded_ || !isVerifySuccess_) { 1414514f5e3Sopenharmony_ci return false; 1424514f5e3Sopenharmony_ci } 1434514f5e3Sopenharmony_ci return recordSimpleInfos_->IterateHClassTreeDesc(callback); 1444514f5e3Sopenharmony_ci } 1454514f5e3Sopenharmony_ci 1464514f5e3Sopenharmony_ci template <typename Callback> 1474514f5e3Sopenharmony_ci bool IterateProtoTransitionPool(Callback callback) const 1484514f5e3Sopenharmony_ci { 1494514f5e3Sopenharmony_ci if (!isLoaded_ || !isVerifySuccess_) { 1504514f5e3Sopenharmony_ci return false; 1514514f5e3Sopenharmony_ci } 1524514f5e3Sopenharmony_ci return recordSimpleInfos_->IterateProtoTransitionPool(callback); 1534514f5e3Sopenharmony_ci } 1544514f5e3Sopenharmony_ci 1554514f5e3Sopenharmony_ci bool IsLoaded() const 1564514f5e3Sopenharmony_ci { 1574514f5e3Sopenharmony_ci return isLoaded_; 1584514f5e3Sopenharmony_ci } 1594514f5e3Sopenharmony_ci 1604514f5e3Sopenharmony_ci PGORecordDetailInfos &GetRecordDetailInfos() const 1614514f5e3Sopenharmony_ci { 1624514f5e3Sopenharmony_ci return *recordDetailInfos_; 1634514f5e3Sopenharmony_ci } 1644514f5e3Sopenharmony_ci 1654514f5e3Sopenharmony_ci std::shared_ptr<PGORecordDetailInfos> GetRecordDetailInfosPtr() const 1664514f5e3Sopenharmony_ci { 1674514f5e3Sopenharmony_ci return recordDetailInfos_; 1684514f5e3Sopenharmony_ci } 1694514f5e3Sopenharmony_ci 1704514f5e3Sopenharmony_ci PGORecordSimpleInfos &GetRecordSimpleInfos() const 1714514f5e3Sopenharmony_ci { 1724514f5e3Sopenharmony_ci return *recordSimpleInfos_; 1734514f5e3Sopenharmony_ci } 1744514f5e3Sopenharmony_ci 1754514f5e3Sopenharmony_ci const PGOPandaFileInfos &GetPandaFileInfos() const 1764514f5e3Sopenharmony_ci { 1774514f5e3Sopenharmony_ci return pandaFileInfos_; 1784514f5e3Sopenharmony_ci } 1794514f5e3Sopenharmony_ci 1804514f5e3Sopenharmony_ci bool GetAbcNameById(ApEntityId abcId, CString &abcName) const 1814514f5e3Sopenharmony_ci { 1824514f5e3Sopenharmony_ci ASSERT(header_ != nullptr); 1834514f5e3Sopenharmony_ci if (!header_->SupportProfileTypeWithAbcId()) { 1844514f5e3Sopenharmony_ci return false; 1854514f5e3Sopenharmony_ci } 1864514f5e3Sopenharmony_ci ASSERT(abcFilePool_ != nullptr); 1874514f5e3Sopenharmony_ci ASSERT(abcFilePool_->GetPool() != nullptr); 1884514f5e3Sopenharmony_ci const auto *entry = abcFilePool_->GetPool()->GetEntry(abcId); 1894514f5e3Sopenharmony_ci if (entry == nullptr) { 1904514f5e3Sopenharmony_ci LOG_COMPILER(ERROR) << "Can not find abcId in pgo file. abcId: " << abcId; 1914514f5e3Sopenharmony_ci return false; 1924514f5e3Sopenharmony_ci } 1934514f5e3Sopenharmony_ci abcName = entry->GetData(); 1944514f5e3Sopenharmony_ci return true; 1954514f5e3Sopenharmony_ci } 1964514f5e3Sopenharmony_ci 1974514f5e3Sopenharmony_ci bool GetABCIdByJSPandaFile(const JSPandaFile *jsPandaFile, ApEntityId &entryId) const 1984514f5e3Sopenharmony_ci { 1994514f5e3Sopenharmony_ci if (abcFilePool_ == nullptr) { 2004514f5e3Sopenharmony_ci return false; 2014514f5e3Sopenharmony_ci } 2024514f5e3Sopenharmony_ci CString name = jsPandaFile->GetNormalizedFileDesc(); 2034514f5e3Sopenharmony_ci return abcFilePool_->GetEntryIdByNormalizedName(name, entryId); 2044514f5e3Sopenharmony_ci } 2054514f5e3Sopenharmony_ci 2064514f5e3Sopenharmony_ci bool IsCompatibleWithAOTFile() 2074514f5e3Sopenharmony_ci { 2084514f5e3Sopenharmony_ci // Can be null when AP file path is empty 2094514f5e3Sopenharmony_ci if (header_ == nullptr) { 2104514f5e3Sopenharmony_ci return false; 2114514f5e3Sopenharmony_ci } 2124514f5e3Sopenharmony_ci return header_->IsCompatibleWithAOTFile(); 2134514f5e3Sopenharmony_ci } 2144514f5e3Sopenharmony_ci 2154514f5e3Sopenharmony_ciprivate: 2164514f5e3Sopenharmony_ci bool Load(const std::shared_ptr<PGOAbcFilePool> &externalAbcFilePool); 2174514f5e3Sopenharmony_ci bool Verify(uint32_t checksum); 2184514f5e3Sopenharmony_ci 2194514f5e3Sopenharmony_ci bool LoadAPBinaryFile(int prot = PAGE_PROT_READ); 2204514f5e3Sopenharmony_ci void UnLoadAPBinaryFile(); 2214514f5e3Sopenharmony_ci CString PUBLIC_API GetNormalizedFileDesc(const JSPandaFile *jsPandaFile) const; 2224514f5e3Sopenharmony_ci void LoadAbcIdPool(const std::shared_ptr<PGOAbcFilePool> &externalAbcFilePool, PGOContext &context, 2234514f5e3Sopenharmony_ci void *addr); 2244514f5e3Sopenharmony_ci 2254514f5e3Sopenharmony_ci bool isLoaded_ {false}; 2264514f5e3Sopenharmony_ci bool isVerifySuccess_ {false}; 2274514f5e3Sopenharmony_ci std::string inPath_; 2284514f5e3Sopenharmony_ci uint32_t hotnessThreshold_ {0}; 2294514f5e3Sopenharmony_ci PGOProfilerHeader *header_ {nullptr}; 2304514f5e3Sopenharmony_ci PGOPandaFileInfos pandaFileInfos_; 2314514f5e3Sopenharmony_ci std::shared_ptr<PGOAbcFilePool> abcFilePool_; 2324514f5e3Sopenharmony_ci bool externalAbcFilePool_ {false}; 2334514f5e3Sopenharmony_ci std::shared_ptr<PGORecordDetailInfos> recordDetailInfos_; 2344514f5e3Sopenharmony_ci std::unique_ptr<PGORecordSimpleInfos> recordSimpleInfos_; 2354514f5e3Sopenharmony_ci MemMap fileMapAddr_; 2364514f5e3Sopenharmony_ci}; 2374514f5e3Sopenharmony_ci} // namespace panda::ecmascript::pgo 2384514f5e3Sopenharmony_ci#endif // ECMASCRIPT_PGO_PROFILE_DECODER_H 239