14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2023-2024 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_PROFILER_INFO_H
174514f5e3Sopenharmony_ci#define ECMASCRIPT_PGO_PROFILER_INFO_H
184514f5e3Sopenharmony_ci
194514f5e3Sopenharmony_ci#include <cstdint>
204514f5e3Sopenharmony_ci#include <memory>
214514f5e3Sopenharmony_ci#include <sstream>
224514f5e3Sopenharmony_ci#include <unordered_map>
234514f5e3Sopenharmony_ci#include <unordered_set>
244514f5e3Sopenharmony_ci#include <utility>
254514f5e3Sopenharmony_ci#include <string.h>
264514f5e3Sopenharmony_ci
274514f5e3Sopenharmony_ci#include "ecmascript/common.h"
284514f5e3Sopenharmony_ci#include "ecmascript/jspandafile/method_literal.h"
294514f5e3Sopenharmony_ci#include "ecmascript/log_wrapper.h"
304514f5e3Sopenharmony_ci#include "ecmascript/mem/c_containers.h"
314514f5e3Sopenharmony_ci#include "ecmascript/mem/c_string.h"
324514f5e3Sopenharmony_ci#include "ecmascript/mem/chunk_containers.h"
334514f5e3Sopenharmony_ci#include "ecmascript/mem/native_area_allocator.h"
344514f5e3Sopenharmony_ci#include "ecmascript/mem/slots.h"
354514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/ap_file/pgo_file_info.h"
364514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/ap_file/pgo_method_type_set.h"
374514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/ap_file/pgo_profile_type_pool.h"
384514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/ap_file/pgo_proto_transition_type_pool.h"
394514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/ap_file/pgo_record_pool.h"
404514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/pgo_context.h"
414514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/pgo_profiler.h"
424514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/pgo_profiler_layout.h"
434514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/pgo_utils.h"
444514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/types/pgo_profiler_type.h"
454514f5e3Sopenharmony_ci#include "ecmascript/property_attributes.h"
464514f5e3Sopenharmony_ci#include "ecmascript/ts_types/global_type_info.h"
474514f5e3Sopenharmony_ci#include "macros.h"
484514f5e3Sopenharmony_ci
494514f5e3Sopenharmony_cinamespace panda::ecmascript::pgo {
504514f5e3Sopenharmony_ciclass SaveTask;
514514f5e3Sopenharmony_ciclass PGOContext;
524514f5e3Sopenharmony_ci
534514f5e3Sopenharmony_ciclass PGOPandaFileInfos {
544514f5e3Sopenharmony_cipublic:
554514f5e3Sopenharmony_ci    void Sample(uint32_t checksum)
564514f5e3Sopenharmony_ci    {
574514f5e3Sopenharmony_ci        fileInfos_.emplace(checksum);
584514f5e3Sopenharmony_ci    }
594514f5e3Sopenharmony_ci
604514f5e3Sopenharmony_ci    void Clear()
614514f5e3Sopenharmony_ci    {
624514f5e3Sopenharmony_ci        fileInfos_.clear();
634514f5e3Sopenharmony_ci    }
644514f5e3Sopenharmony_ci
654514f5e3Sopenharmony_ci    void ParseFromBinary(void *buffer, SectionInfo *const info);
664514f5e3Sopenharmony_ci    void ProcessToBinary(std::fstream &fileStream, SectionInfo *info) const;
674514f5e3Sopenharmony_ci    void Merge(const PGOPandaFileInfos &pandaFileInfos);
684514f5e3Sopenharmony_ci    bool VerifyChecksum(const PGOPandaFileInfos &pandaFileInfos, const std::string &base,
694514f5e3Sopenharmony_ci                        const std::string &incoming) const;
704514f5e3Sopenharmony_ci
714514f5e3Sopenharmony_ci    void ProcessToText(std::ofstream &stream) const;
724514f5e3Sopenharmony_ci    bool ParseFromText(std::ifstream &stream);
734514f5e3Sopenharmony_ci
744514f5e3Sopenharmony_ci    bool Checksum(uint32_t checksum) const;
754514f5e3Sopenharmony_ci
764514f5e3Sopenharmony_ciprivate:
774514f5e3Sopenharmony_ci    class FileInfo {
784514f5e3Sopenharmony_ci    public:
794514f5e3Sopenharmony_ci        FileInfo() = default;
804514f5e3Sopenharmony_ci        FileInfo(uint32_t checksum) : size_(LastSize()), checksum_(checksum) {}
814514f5e3Sopenharmony_ci
824514f5e3Sopenharmony_ci        static size_t LastSize()
834514f5e3Sopenharmony_ci        {
844514f5e3Sopenharmony_ci            return sizeof(FileInfo);
854514f5e3Sopenharmony_ci        }
864514f5e3Sopenharmony_ci
874514f5e3Sopenharmony_ci        size_t Size() const
884514f5e3Sopenharmony_ci        {
894514f5e3Sopenharmony_ci            return static_cast<size_t>(size_);
904514f5e3Sopenharmony_ci        }
914514f5e3Sopenharmony_ci
924514f5e3Sopenharmony_ci        bool operator<(const FileInfo &right) const
934514f5e3Sopenharmony_ci        {
944514f5e3Sopenharmony_ci            return checksum_ < right.checksum_;
954514f5e3Sopenharmony_ci        }
964514f5e3Sopenharmony_ci
974514f5e3Sopenharmony_ci        uint32_t GetChecksum() const
984514f5e3Sopenharmony_ci        {
994514f5e3Sopenharmony_ci            return checksum_;
1004514f5e3Sopenharmony_ci        }
1014514f5e3Sopenharmony_ci
1024514f5e3Sopenharmony_ci    private:
1034514f5e3Sopenharmony_ci        // Support extended fields
1044514f5e3Sopenharmony_ci        uint32_t size_;
1054514f5e3Sopenharmony_ci        uint32_t checksum_;
1064514f5e3Sopenharmony_ci    };
1074514f5e3Sopenharmony_ci
1084514f5e3Sopenharmony_ci    std::set<FileInfo> fileInfos_;
1094514f5e3Sopenharmony_ci};
1104514f5e3Sopenharmony_ci
1114514f5e3Sopenharmony_ciclass PGOMethodInfo {
1124514f5e3Sopenharmony_cipublic:
1134514f5e3Sopenharmony_ci    static constexpr int METHOD_INFO_COUNT = 4;
1144514f5e3Sopenharmony_ci    static constexpr int METHOD_ID_INDEX = 0;
1154514f5e3Sopenharmony_ci    static constexpr int METHOD_COUNT_INDEX = 1;
1164514f5e3Sopenharmony_ci    static constexpr int METHOD_MODE_INDEX = 2;
1174514f5e3Sopenharmony_ci    static constexpr int METHOD_NAME_INDEX = 3;
1184514f5e3Sopenharmony_ci    static constexpr uint32_t METHOD_MAX_HIT_COUNT = 10000U;
1194514f5e3Sopenharmony_ci
1204514f5e3Sopenharmony_ci    explicit PGOMethodInfo(PGOMethodId id) : id_(id) {}
1214514f5e3Sopenharmony_ci
1224514f5e3Sopenharmony_ci    PGOMethodInfo(PGOMethodId id, uint32_t count, SampleMode mode, const char *methodName)
1234514f5e3Sopenharmony_ci        : id_(id), count_(count), mode_(mode)
1244514f5e3Sopenharmony_ci    {
1254514f5e3Sopenharmony_ci        size_t len = strlen(methodName);
1264514f5e3Sopenharmony_ci        size_ = static_cast<uint32_t>(Size(len));
1274514f5e3Sopenharmony_ci        if (len > 0 && memcpy_s(&methodName_, len, methodName, len) != EOK) {
1284514f5e3Sopenharmony_ci            LOG_ECMA(ERROR) << "SetMethodName memcpy_s failed" << methodName << ", len = " << len;
1294514f5e3Sopenharmony_ci            UNREACHABLE();
1304514f5e3Sopenharmony_ci        }
1314514f5e3Sopenharmony_ci        *(&methodName_ + len) = '\0';
1324514f5e3Sopenharmony_ci    }
1334514f5e3Sopenharmony_ci
1344514f5e3Sopenharmony_ci    static uint32_t PUBLIC_API CalcChecksum(const char *name, const uint8_t *byteCodeArray, uint32_t byteCodeLength);
1354514f5e3Sopenharmony_ci
1364514f5e3Sopenharmony_ci    static uint32_t CalcOpCodeChecksum(const uint8_t *byteCodeArray, uint32_t byteCodeLength);
1374514f5e3Sopenharmony_ci
1384514f5e3Sopenharmony_ci    static int32_t Size(uint32_t length)
1394514f5e3Sopenharmony_ci    {
1404514f5e3Sopenharmony_ci        return sizeof(PGOMethodInfo) + AlignUp(length, GetAlignmentInBytes(ALIGN_SIZE));
1414514f5e3Sopenharmony_ci    }
1424514f5e3Sopenharmony_ci
1434514f5e3Sopenharmony_ci    int32_t Size() const
1444514f5e3Sopenharmony_ci    {
1454514f5e3Sopenharmony_ci        return size_;
1464514f5e3Sopenharmony_ci    }
1474514f5e3Sopenharmony_ci
1484514f5e3Sopenharmony_ci    static bool GetSampleMode(std::string content, SampleMode &mode)
1494514f5e3Sopenharmony_ci    {
1504514f5e3Sopenharmony_ci        if (content == "HOTNESS_MODE") {
1514514f5e3Sopenharmony_ci            mode = SampleMode::HOTNESS_MODE;
1524514f5e3Sopenharmony_ci        } else if (content == "CALL_MODE") {
1534514f5e3Sopenharmony_ci            mode = SampleMode::CALL_MODE;
1544514f5e3Sopenharmony_ci        } else {
1554514f5e3Sopenharmony_ci            return false;
1564514f5e3Sopenharmony_ci        }
1574514f5e3Sopenharmony_ci        return true;
1584514f5e3Sopenharmony_ci    }
1594514f5e3Sopenharmony_ci
1604514f5e3Sopenharmony_ci    void IncreaseCount()
1614514f5e3Sopenharmony_ci    {
1624514f5e3Sopenharmony_ci        count_++;
1634514f5e3Sopenharmony_ci    }
1644514f5e3Sopenharmony_ci
1654514f5e3Sopenharmony_ci    void ClearCount()
1664514f5e3Sopenharmony_ci    {
1674514f5e3Sopenharmony_ci        count_ = 0;
1684514f5e3Sopenharmony_ci    }
1694514f5e3Sopenharmony_ci
1704514f5e3Sopenharmony_ci    void Merge(const PGOMethodInfo *info)
1714514f5e3Sopenharmony_ci    {
1724514f5e3Sopenharmony_ci        if (!(id_ == info->GetMethodId())) {
1734514f5e3Sopenharmony_ci            LOG_ECMA(ERROR) << "The method id must same for merging";
1744514f5e3Sopenharmony_ci            return;
1754514f5e3Sopenharmony_ci        }
1764514f5e3Sopenharmony_ci        count_ = std::min(count_ + info->GetCount(), METHOD_MAX_HIT_COUNT);
1774514f5e3Sopenharmony_ci        SetSampleMode(info->GetSampleMode());
1784514f5e3Sopenharmony_ci    }
1794514f5e3Sopenharmony_ci
1804514f5e3Sopenharmony_ci    PGOMethodId GetMethodId() const
1814514f5e3Sopenharmony_ci    {
1824514f5e3Sopenharmony_ci        return id_;
1834514f5e3Sopenharmony_ci    }
1844514f5e3Sopenharmony_ci
1854514f5e3Sopenharmony_ci    uint32_t GetCount() const
1864514f5e3Sopenharmony_ci    {
1874514f5e3Sopenharmony_ci        return count_;
1884514f5e3Sopenharmony_ci    }
1894514f5e3Sopenharmony_ci
1904514f5e3Sopenharmony_ci    const char *GetMethodName() const
1914514f5e3Sopenharmony_ci    {
1924514f5e3Sopenharmony_ci        return &methodName_;
1934514f5e3Sopenharmony_ci    }
1944514f5e3Sopenharmony_ci
1954514f5e3Sopenharmony_ci    void SetSampleMode(SampleMode mode)
1964514f5e3Sopenharmony_ci    {
1974514f5e3Sopenharmony_ci        if (mode_ == SampleMode::HOTNESS_MODE) {
1984514f5e3Sopenharmony_ci            return;
1994514f5e3Sopenharmony_ci        }
2004514f5e3Sopenharmony_ci        mode_ = mode;
2014514f5e3Sopenharmony_ci    }
2024514f5e3Sopenharmony_ci
2034514f5e3Sopenharmony_ci    SampleMode GetSampleMode() const
2044514f5e3Sopenharmony_ci    {
2054514f5e3Sopenharmony_ci        return mode_;
2064514f5e3Sopenharmony_ci    }
2074514f5e3Sopenharmony_ci
2084514f5e3Sopenharmony_ci    std::string GetSampleModeToString() const
2094514f5e3Sopenharmony_ci    {
2104514f5e3Sopenharmony_ci        std::string result;
2114514f5e3Sopenharmony_ci        switch (mode_) {
2124514f5e3Sopenharmony_ci            case SampleMode::HOTNESS_MODE:
2134514f5e3Sopenharmony_ci                result = "HOTNESS_MODE";
2144514f5e3Sopenharmony_ci                break;
2154514f5e3Sopenharmony_ci            case SampleMode::CALL_MODE:
2164514f5e3Sopenharmony_ci                result = "CALL_MODE";
2174514f5e3Sopenharmony_ci                break;
2184514f5e3Sopenharmony_ci            default:
2194514f5e3Sopenharmony_ci                LOG_ECMA(ERROR) << "mode error";
2204514f5e3Sopenharmony_ci        }
2214514f5e3Sopenharmony_ci        return result;
2224514f5e3Sopenharmony_ci    }
2234514f5e3Sopenharmony_ci
2244514f5e3Sopenharmony_ci    bool IsFilter(uint32_t threshold) const
2254514f5e3Sopenharmony_ci    {
2264514f5e3Sopenharmony_ci        if (count_ < threshold && mode_ == SampleMode::CALL_MODE) {
2274514f5e3Sopenharmony_ci            return true;
2284514f5e3Sopenharmony_ci        }
2294514f5e3Sopenharmony_ci        return false;
2304514f5e3Sopenharmony_ci    }
2314514f5e3Sopenharmony_ci
2324514f5e3Sopenharmony_ci    void ParseFromBinary(void **buffer);
2334514f5e3Sopenharmony_ci    void ProcessToBinary(std::ofstream &fileStream) const;
2344514f5e3Sopenharmony_ci
2354514f5e3Sopenharmony_ci    static std::vector<std::string> ParseFromText(const std::string &infoString);
2364514f5e3Sopenharmony_ci    void ProcessToText(std::string &text) const;
2374514f5e3Sopenharmony_ci
2384514f5e3Sopenharmony_ci    void ProcessToJson(ProfileType::VariantMap &function) const;
2394514f5e3Sopenharmony_ci
2404514f5e3Sopenharmony_ci    NO_COPY_SEMANTIC(PGOMethodInfo);
2414514f5e3Sopenharmony_ci    NO_MOVE_SEMANTIC(PGOMethodInfo);
2424514f5e3Sopenharmony_ci
2434514f5e3Sopenharmony_ciprivate:
2444514f5e3Sopenharmony_ci    uint32_t size_ {0};
2454514f5e3Sopenharmony_ci    PGOMethodId id_;
2464514f5e3Sopenharmony_ci    uint32_t count_ {0};
2474514f5e3Sopenharmony_ci    SampleMode mode_ {SampleMode::CALL_MODE};
2484514f5e3Sopenharmony_ci    char methodName_ {0};
2494514f5e3Sopenharmony_ci};
2504514f5e3Sopenharmony_ci
2514514f5e3Sopenharmony_ciclass PGODecodeMethodInfo {
2524514f5e3Sopenharmony_cipublic:
2534514f5e3Sopenharmony_ci    explicit PGODecodeMethodInfo(PGOMethodId id) : methodId_(id) {}
2544514f5e3Sopenharmony_ci
2554514f5e3Sopenharmony_ci    PGOMethodId GetMethodId() const
2564514f5e3Sopenharmony_ci    {
2574514f5e3Sopenharmony_ci        return methodId_;
2584514f5e3Sopenharmony_ci    }
2594514f5e3Sopenharmony_ci
2604514f5e3Sopenharmony_ci    PGOMethodTypeSet &GetPGOMethodTypeSet()
2614514f5e3Sopenharmony_ci    {
2624514f5e3Sopenharmony_ci        return pgoMethodTypeSet_;
2634514f5e3Sopenharmony_ci    }
2644514f5e3Sopenharmony_ci
2654514f5e3Sopenharmony_ci    void Merge(const PGODecodeMethodInfo &from);
2664514f5e3Sopenharmony_ci
2674514f5e3Sopenharmony_ciprivate:
2684514f5e3Sopenharmony_ci    PGOMethodId methodId_ {0};
2694514f5e3Sopenharmony_ci    PGOMethodTypeSet pgoMethodTypeSet_ {};
2704514f5e3Sopenharmony_ci};
2714514f5e3Sopenharmony_ci
2724514f5e3Sopenharmony_ciclass PGOMethodInfoMap {
2734514f5e3Sopenharmony_cipublic:
2744514f5e3Sopenharmony_ci    PGOMethodInfoMap() = default;
2754514f5e3Sopenharmony_ci
2764514f5e3Sopenharmony_ci    void Clear()
2774514f5e3Sopenharmony_ci    {
2784514f5e3Sopenharmony_ci        // PGOMethodInfo release by chunk
2794514f5e3Sopenharmony_ci        for (auto &entry : methodTypeInfos_) {
2804514f5e3Sopenharmony_ci            entry.second->Clear();
2814514f5e3Sopenharmony_ci        }
2824514f5e3Sopenharmony_ci        methodInfos_.clear();
2834514f5e3Sopenharmony_ci        methodTypeInfos_.clear();
2844514f5e3Sopenharmony_ci    }
2854514f5e3Sopenharmony_ci
2864514f5e3Sopenharmony_ci    bool AddMethod(Chunk *chunk, Method *jsMethod, SampleMode mode);
2874514f5e3Sopenharmony_ci    bool AddType(Chunk *chunk, PGOMethodId methodId, int32_t offset, PGOSampleType type);
2884514f5e3Sopenharmony_ci    bool AddCallTargetType(Chunk *chunk, PGOMethodId methodId, int32_t offset, PGOSampleType type);
2894514f5e3Sopenharmony_ci    bool AddObjectInfo(Chunk *chunk, PGOMethodId methodId, int32_t offset, const PGOObjectInfo &info);
2904514f5e3Sopenharmony_ci    bool AddDefine(Chunk *chunk, PGOMethodId methodId, int32_t offset, PGODefineOpType type);
2914514f5e3Sopenharmony_ci    void Merge(Chunk *chunk, PGOMethodInfoMap *methodInfos);
2924514f5e3Sopenharmony_ci
2934514f5e3Sopenharmony_ci    bool ParseFromBinary(Chunk *chunk, PGOContext &context, void **buffer);
2944514f5e3Sopenharmony_ci    bool ProcessToBinary(PGOContext &context, ProfileTypeRef recordProfileRef, const SaveTask *task,
2954514f5e3Sopenharmony_ci                         std::fstream &fileStream, PGOProfilerHeader *const header) const;
2964514f5e3Sopenharmony_ci
2974514f5e3Sopenharmony_ci    bool ParseFromText(Chunk *chunk, uint32_t threshold, const std::vector<std::string> &content);
2984514f5e3Sopenharmony_ci    void ProcessToText(uint32_t threshold, const CString &recordName, std::ofstream &stream) const;
2994514f5e3Sopenharmony_ci
3004514f5e3Sopenharmony_ci    void ProcessToJson(uint32_t threshold, ProfileType::jModuleType &jModule) const;
3014514f5e3Sopenharmony_ci
3024514f5e3Sopenharmony_ci    const CMap<PGOMethodId, PGOMethodInfo *> &GetMethodInfos() const
3034514f5e3Sopenharmony_ci    {
3044514f5e3Sopenharmony_ci        return methodInfos_;
3054514f5e3Sopenharmony_ci    }
3064514f5e3Sopenharmony_ci
3074514f5e3Sopenharmony_ci    NO_COPY_SEMANTIC(PGOMethodInfoMap);
3084514f5e3Sopenharmony_ci    NO_MOVE_SEMANTIC(PGOMethodInfoMap);
3094514f5e3Sopenharmony_ci
3104514f5e3Sopenharmony_ciprivate:
3114514f5e3Sopenharmony_ci    PGOMethodTypeSet *GetOrInsertMethodTypeSet(Chunk *chunk, PGOMethodId methodId);
3124514f5e3Sopenharmony_ci
3134514f5e3Sopenharmony_ci    CMap<PGOMethodId, PGOMethodInfo *> methodInfos_;
3144514f5e3Sopenharmony_ci    CMap<PGOMethodId, PGOMethodTypeSet *> methodTypeInfos_;
3154514f5e3Sopenharmony_ci    CMap<PGOMethodId, uint32_t> methodsChecksum_;
3164514f5e3Sopenharmony_ci    CMap<PGOSampleType, CMap<CString, TrackType>> globalLayoutDescInfos_;
3174514f5e3Sopenharmony_ci};
3184514f5e3Sopenharmony_ci
3194514f5e3Sopenharmony_ciclass PGOMethodIdSet {
3204514f5e3Sopenharmony_cipublic:
3214514f5e3Sopenharmony_ci    explicit PGOMethodIdSet(Chunk* chunk): chunk_(chunk), methodInfoMap_(chunk) {};
3224514f5e3Sopenharmony_ci    ~PGOMethodIdSet() = default;
3234514f5e3Sopenharmony_ci
3244514f5e3Sopenharmony_ci    void Clear()
3254514f5e3Sopenharmony_ci    {
3264514f5e3Sopenharmony_ci        candidateSet_.clear();
3274514f5e3Sopenharmony_ci        for (auto &methodNameSet : methodInfoMap_) {
3284514f5e3Sopenharmony_ci            methodNameSet.second.Clear();
3294514f5e3Sopenharmony_ci        }
3304514f5e3Sopenharmony_ci        methodInfoMap_.clear();
3314514f5e3Sopenharmony_ci    }
3324514f5e3Sopenharmony_ci
3334514f5e3Sopenharmony_ci    bool Match(EntityId methodId)
3344514f5e3Sopenharmony_ci    {
3354514f5e3Sopenharmony_ci        return candidateSet_.find(methodId) != candidateSet_.end();
3364514f5e3Sopenharmony_ci    }
3374514f5e3Sopenharmony_ci
3384514f5e3Sopenharmony_ci    template <typename Callback>
3394514f5e3Sopenharmony_ci    bool Update(const CString &recordName, Callback callback)
3404514f5e3Sopenharmony_ci    {
3414514f5e3Sopenharmony_ci        std::unordered_set<EntityId> newIds = callback(recordName, candidateSet_);
3424514f5e3Sopenharmony_ci        if (!newIds.empty()) {
3434514f5e3Sopenharmony_ci            candidateSet_.insert(newIds.begin(), newIds.end());
3444514f5e3Sopenharmony_ci            return true;
3454514f5e3Sopenharmony_ci        }
3464514f5e3Sopenharmony_ci        return false;
3474514f5e3Sopenharmony_ci    }
3484514f5e3Sopenharmony_ci
3494514f5e3Sopenharmony_ci    template <typename Callback>
3504514f5e3Sopenharmony_ci    void GetTypeInfo(const char *methodName, Callback callback)
3514514f5e3Sopenharmony_ci    {
3524514f5e3Sopenharmony_ci        // for no function checksum in ap file
3534514f5e3Sopenharmony_ci        auto iter = methodInfoMap_.find(methodName);
3544514f5e3Sopenharmony_ci        if ((iter != methodInfoMap_.end()) && (iter->second.GetFirstMethodInfo() != nullptr)) {
3554514f5e3Sopenharmony_ci            iter->second.GetFirstMethodInfo()->GetPGOMethodTypeSet().GetTypeInfo(callback);
3564514f5e3Sopenharmony_ci        }
3574514f5e3Sopenharmony_ci    }
3584514f5e3Sopenharmony_ci
3594514f5e3Sopenharmony_ci    template <typename Callback>
3604514f5e3Sopenharmony_ci    void GetTypeInfo(const char *methodName, uint32_t checksum, Callback callback)
3614514f5e3Sopenharmony_ci    {
3624514f5e3Sopenharmony_ci        auto iter = methodInfoMap_.find(methodName);
3634514f5e3Sopenharmony_ci        if ((iter != methodInfoMap_.end()) && (iter->second.GetMethodInfo(checksum) != nullptr)) {
3644514f5e3Sopenharmony_ci            return iter->second.GetMethodInfo(checksum)->GetPGOMethodTypeSet().GetTypeInfo(callback);
3654514f5e3Sopenharmony_ci        }
3664514f5e3Sopenharmony_ci        LOG_ECMA(DEBUG) << "Method checksum mismatched, name: " << methodName;
3674514f5e3Sopenharmony_ci    }
3684514f5e3Sopenharmony_ci
3694514f5e3Sopenharmony_ci    void MatchAndMarkMethod(const char *methodName, EntityId methodId)
3704514f5e3Sopenharmony_ci    {
3714514f5e3Sopenharmony_ci        const auto &iter = methodInfoMap_.find(methodName);
3724514f5e3Sopenharmony_ci        if (iter == methodInfoMap_.end()) {
3734514f5e3Sopenharmony_ci            // no matching method in PGO file.
3744514f5e3Sopenharmony_ci            return;
3754514f5e3Sopenharmony_ci        }
3764514f5e3Sopenharmony_ci        candidateSet_.emplace(methodId);
3774514f5e3Sopenharmony_ci        iter->second.SetMatch();
3784514f5e3Sopenharmony_ci    }
3794514f5e3Sopenharmony_ci
3804514f5e3Sopenharmony_ci    bool ParseFromBinary(PGOContext &context, void **buffer);
3814514f5e3Sopenharmony_ci
3824514f5e3Sopenharmony_ci    void GetMismatchResult(const CString &recordName, uint32_t &totalMethodCount, uint32_t &mismatchMethodCount,
3834514f5e3Sopenharmony_ci                           std::set<std::pair<std::string, CString>> &mismatchMethodSet) const;
3844514f5e3Sopenharmony_ci
3854514f5e3Sopenharmony_ci    void Merge(const PGOMethodIdSet &from);
3864514f5e3Sopenharmony_ci
3874514f5e3Sopenharmony_ci    class PGOMethodNameSet {
3884514f5e3Sopenharmony_ci    public:
3894514f5e3Sopenharmony_ci        explicit PGOMethodNameSet(Chunk* chunk): methodMap_(chunk) {};
3904514f5e3Sopenharmony_ci        void SetMatch()
3914514f5e3Sopenharmony_ci        {
3924514f5e3Sopenharmony_ci            methodNameMatch_ = true;
3934514f5e3Sopenharmony_ci        }
3944514f5e3Sopenharmony_ci
3954514f5e3Sopenharmony_ci        bool IsMatch() const
3964514f5e3Sopenharmony_ci        {
3974514f5e3Sopenharmony_ci            return methodNameMatch_;
3984514f5e3Sopenharmony_ci        }
3994514f5e3Sopenharmony_ci
4004514f5e3Sopenharmony_ci        PGODecodeMethodInfo& GetOrCreateMethodInfo(uint32_t checksum, PGOMethodId methodId)
4014514f5e3Sopenharmony_ci        {
4024514f5e3Sopenharmony_ci            auto methodIter = methodMap_.find(checksum);
4034514f5e3Sopenharmony_ci            if (methodIter == methodMap_.end()) {
4044514f5e3Sopenharmony_ci                auto ret = methodMap_.emplace(checksum, methodId);
4054514f5e3Sopenharmony_ci                ASSERT(ret.second);
4064514f5e3Sopenharmony_ci                methodIter = ret.first;
4074514f5e3Sopenharmony_ci            }
4084514f5e3Sopenharmony_ci            return methodIter->second;
4094514f5e3Sopenharmony_ci        }
4104514f5e3Sopenharmony_ci
4114514f5e3Sopenharmony_ci        void Merge(const PGOMethodNameSet &from)
4124514f5e3Sopenharmony_ci        {
4134514f5e3Sopenharmony_ci            for (const auto &method : from.methodMap_) {
4144514f5e3Sopenharmony_ci                uint32_t checksum = method.first;
4154514f5e3Sopenharmony_ci                auto methodInfo = methodMap_.find(checksum);
4164514f5e3Sopenharmony_ci                if (methodInfo == methodMap_.end()) {
4174514f5e3Sopenharmony_ci                    auto ret = methodMap_.emplace(checksum, method.second.GetMethodId());
4184514f5e3Sopenharmony_ci                    ASSERT(ret.second);
4194514f5e3Sopenharmony_ci                    methodInfo = ret.first;
4204514f5e3Sopenharmony_ci                }
4214514f5e3Sopenharmony_ci                methodInfo->second.Merge(method.second);
4224514f5e3Sopenharmony_ci            }
4234514f5e3Sopenharmony_ci        }
4244514f5e3Sopenharmony_ci
4254514f5e3Sopenharmony_ci        PGODecodeMethodInfo *GetFirstMethodInfo()
4264514f5e3Sopenharmony_ci        {
4274514f5e3Sopenharmony_ci            if (methodMap_.empty()) {
4284514f5e3Sopenharmony_ci                return nullptr;
4294514f5e3Sopenharmony_ci            }
4304514f5e3Sopenharmony_ci            return &(methodMap_.begin()->second);
4314514f5e3Sopenharmony_ci        }
4324514f5e3Sopenharmony_ci
4334514f5e3Sopenharmony_ci        PGODecodeMethodInfo *GetMethodInfo(uint32_t checksum)
4344514f5e3Sopenharmony_ci        {
4354514f5e3Sopenharmony_ci            auto methodInfo = methodMap_.find(checksum);
4364514f5e3Sopenharmony_ci            if (methodInfo == methodMap_.end()) {
4374514f5e3Sopenharmony_ci                return nullptr;
4384514f5e3Sopenharmony_ci            }
4394514f5e3Sopenharmony_ci            return &(methodInfo->second);
4404514f5e3Sopenharmony_ci        }
4414514f5e3Sopenharmony_ci
4424514f5e3Sopenharmony_ci        void Clear()
4434514f5e3Sopenharmony_ci        {
4444514f5e3Sopenharmony_ci            methodMap_.clear();
4454514f5e3Sopenharmony_ci        }
4464514f5e3Sopenharmony_ci
4474514f5e3Sopenharmony_ci    private:
4484514f5e3Sopenharmony_ci        bool methodNameMatch_ {false};
4494514f5e3Sopenharmony_ci        ChunkUnorderedMap<uint32_t, PGODecodeMethodInfo> methodMap_;
4504514f5e3Sopenharmony_ci    };
4514514f5e3Sopenharmony_ci
4524514f5e3Sopenharmony_ci    NO_COPY_SEMANTIC(PGOMethodIdSet);
4534514f5e3Sopenharmony_ci    NO_MOVE_SEMANTIC(PGOMethodIdSet);
4544514f5e3Sopenharmony_ci
4554514f5e3Sopenharmony_ciprivate:
4564514f5e3Sopenharmony_ci    Chunk* chunk_;
4574514f5e3Sopenharmony_ci    std::unordered_set<EntityId> candidateSet_; // methodId in abc file, DO NOT for pgo internal use
4584514f5e3Sopenharmony_ci    ChunkUnorderedMap<CString, PGOMethodNameSet> methodInfoMap_;
4594514f5e3Sopenharmony_ci};
4604514f5e3Sopenharmony_ci
4614514f5e3Sopenharmony_ciclass PGORecordDetailInfos : public PGOContext {
4624514f5e3Sopenharmony_cipublic:
4634514f5e3Sopenharmony_ci    explicit PGORecordDetailInfos(uint32_t hotnessThreshold);
4644514f5e3Sopenharmony_ci
4654514f5e3Sopenharmony_ci    ~PGORecordDetailInfos() override;
4664514f5e3Sopenharmony_ci
4674514f5e3Sopenharmony_ci    void Clear();
4684514f5e3Sopenharmony_ci    void InitSections();
4694514f5e3Sopenharmony_ci
4704514f5e3Sopenharmony_ci    // If it is a new method, return true.
4714514f5e3Sopenharmony_ci    bool AddMethod(ProfileType recordProfileType, Method *jsMethod, SampleMode mode);
4724514f5e3Sopenharmony_ci    bool AddType(ProfileType recordProfileType, PGOMethodId methodId, int32_t offset, PGOSampleType type);
4734514f5e3Sopenharmony_ci    bool AddCallTargetType(ProfileType recordProfileType, PGOMethodId methodId, int32_t offset, PGOSampleType type);
4744514f5e3Sopenharmony_ci    bool AddObjectInfo(ProfileType recordProfileType, PGOMethodId methodId, int32_t offset, const PGOObjectInfo &info);
4754514f5e3Sopenharmony_ci    bool AddDefine(ProfileType recordProfileType, PGOMethodId methodId, int32_t offset, PGODefineOpType type);
4764514f5e3Sopenharmony_ci
4774514f5e3Sopenharmony_ci    bool AddRwUseInfo(ProfileType rootType);
4784514f5e3Sopenharmony_ci    bool AddRootLayout(JSTaggedType hclass, ProfileType rootType);
4794514f5e3Sopenharmony_ci    bool UpdateTransitionLayout(
4804514f5e3Sopenharmony_ci        ProfileType rootType, JSTaggedType parent, ProfileType parentType, JSTaggedType child, ProfileType childType);
4814514f5e3Sopenharmony_ci    bool UpdateLayout(ProfileType rootType, JSTaggedType hclass, ProfileType curType);
4824514f5e3Sopenharmony_ci    void AddRootPtType(ProfileType rootType, ProfileType ptType);
4834514f5e3Sopenharmony_ci    bool IsDumped(ProfileType rootType, ProfileType curType) const;
4844514f5e3Sopenharmony_ci
4854514f5e3Sopenharmony_ci    void Merge(const PGORecordDetailInfos &recordInfos);
4864514f5e3Sopenharmony_ci
4874514f5e3Sopenharmony_ci    void UpdateLayout();
4884514f5e3Sopenharmony_ci
4894514f5e3Sopenharmony_ci    bool ParseFromBinary(void *buffer, PGOProfilerHeader *const header);
4904514f5e3Sopenharmony_ci    void ProcessToBinary(const SaveTask *task, std::fstream &fileStream, PGOProfilerHeader *const header);
4914514f5e3Sopenharmony_ci
4924514f5e3Sopenharmony_ci    bool ParseFromText(std::ifstream &stream);
4934514f5e3Sopenharmony_ci    void ProcessToText(std::ofstream &stream) const;
4944514f5e3Sopenharmony_ci
4954514f5e3Sopenharmony_ci    const CMap<ProfileType, PGOMethodInfoMap *> &GetRecordInfos() const
4964514f5e3Sopenharmony_ci    {
4974514f5e3Sopenharmony_ci        return recordInfos_;
4984514f5e3Sopenharmony_ci    }
4994514f5e3Sopenharmony_ci
5004514f5e3Sopenharmony_ci    std::shared_ptr<PGORecordPool> GetRecordPool() const
5014514f5e3Sopenharmony_ci    {
5024514f5e3Sopenharmony_ci        return recordPool_;
5034514f5e3Sopenharmony_ci    }
5044514f5e3Sopenharmony_ci
5054514f5e3Sopenharmony_ci    std::shared_ptr<PGOProfileTypePool> GetProfileTypePool() const override
5064514f5e3Sopenharmony_ci    {
5074514f5e3Sopenharmony_ci        return profileTypePool_;
5084514f5e3Sopenharmony_ci    }
5094514f5e3Sopenharmony_ci
5104514f5e3Sopenharmony_ci    std::shared_ptr<PGOProtoTransitionPool> GetProtoTransitionPool() const
5114514f5e3Sopenharmony_ci    {
5124514f5e3Sopenharmony_ci        return protoTransitionPool_;
5134514f5e3Sopenharmony_ci    }
5144514f5e3Sopenharmony_ci
5154514f5e3Sopenharmony_ci    uint32_t GetHotnessThreshold() const override
5164514f5e3Sopenharmony_ci    {
5174514f5e3Sopenharmony_ci        return hotnessThreshold_;
5184514f5e3Sopenharmony_ci    }
5194514f5e3Sopenharmony_ci
5204514f5e3Sopenharmony_ci    PGOProfilerHeader *GetHeader() const override
5214514f5e3Sopenharmony_ci    {
5224514f5e3Sopenharmony_ci        return header_;
5234514f5e3Sopenharmony_ci    }
5244514f5e3Sopenharmony_ci
5254514f5e3Sopenharmony_ci    bool SupportElementsKind() const override
5264514f5e3Sopenharmony_ci    {
5274514f5e3Sopenharmony_ci        ASSERT(header_ != nullptr);
5284514f5e3Sopenharmony_ci        return header_->SupportElementsKind();
5294514f5e3Sopenharmony_ci    }
5304514f5e3Sopenharmony_ci
5314514f5e3Sopenharmony_ci    bool SupportElementsTrackInfo() const override
5324514f5e3Sopenharmony_ci    {
5334514f5e3Sopenharmony_ci        ASSERT(header_ != nullptr);
5344514f5e3Sopenharmony_ci        return header_->SupportElementsTrackInfo();
5354514f5e3Sopenharmony_ci    }
5364514f5e3Sopenharmony_ci
5374514f5e3Sopenharmony_ci    void ResetAbcIdRemap() const override
5384514f5e3Sopenharmony_ci    {
5394514f5e3Sopenharmony_ci        abcIdRemap_.clear();
5404514f5e3Sopenharmony_ci    }
5414514f5e3Sopenharmony_ci
5424514f5e3Sopenharmony_ci    void AddAbcIdRemap(ApEntityId oldId, ApEntityId newId) const override
5434514f5e3Sopenharmony_ci    {
5444514f5e3Sopenharmony_ci        abcIdRemap_[oldId] = newId;
5454514f5e3Sopenharmony_ci    }
5464514f5e3Sopenharmony_ci
5474514f5e3Sopenharmony_ci    const std::map<ApEntityId, ApEntityId> &GetAbcIdRemap() const override
5484514f5e3Sopenharmony_ci    {
5494514f5e3Sopenharmony_ci        return abcIdRemap_;
5504514f5e3Sopenharmony_ci    }
5514514f5e3Sopenharmony_ci
5524514f5e3Sopenharmony_ci    NO_COPY_SEMANTIC(PGORecordDetailInfos);
5534514f5e3Sopenharmony_ci    NO_MOVE_SEMANTIC(PGORecordDetailInfos);
5544514f5e3Sopenharmony_ci
5554514f5e3Sopenharmony_ciprivate:
5564514f5e3Sopenharmony_ci    PGOMethodInfoMap *GetMethodInfoMap(ProfileType recordProfileType);
5574514f5e3Sopenharmony_ci    bool ParseFromBinaryForLayout(void **buffer);
5584514f5e3Sopenharmony_ci    bool ProcessToBinaryForLayout(NativeAreaAllocator *allocator, const SaveTask *task, std::fstream &stream);
5594514f5e3Sopenharmony_ci
5604514f5e3Sopenharmony_ci    uint32_t hotnessThreshold_ {2};
5614514f5e3Sopenharmony_ci    NativeAreaAllocator nativeAreaAllocator_;
5624514f5e3Sopenharmony_ci    std::unique_ptr<Chunk> chunk_;
5634514f5e3Sopenharmony_ci    CMap<ProfileType, PGOMethodInfoMap *> recordInfos_;
5644514f5e3Sopenharmony_ci    std::set<PGOHClassTreeDesc> hclassTreeDescInfos_;
5654514f5e3Sopenharmony_ci    PGOProfilerHeader *header_ {nullptr};
5664514f5e3Sopenharmony_ci    std::shared_ptr<PGORecordPool> recordPool_;
5674514f5e3Sopenharmony_ci    std::shared_ptr<PGOProtoTransitionPool> protoTransitionPool_;
5684514f5e3Sopenharmony_ci    std::shared_ptr<PGOProfileTypePool> profileTypePool_;
5694514f5e3Sopenharmony_ci    mutable std::map<ApEntityId, ApEntityId> abcIdRemap_;
5704514f5e3Sopenharmony_ci};
5714514f5e3Sopenharmony_ci
5724514f5e3Sopenharmony_ciclass PGORecordSimpleInfos : public PGOContext {
5734514f5e3Sopenharmony_cipublic:
5744514f5e3Sopenharmony_ci    explicit PGORecordSimpleInfos(uint32_t threshold);
5754514f5e3Sopenharmony_ci
5764514f5e3Sopenharmony_ci    ~PGORecordSimpleInfos() override;
5774514f5e3Sopenharmony_ci
5784514f5e3Sopenharmony_ci    void Clear();
5794514f5e3Sopenharmony_ci
5804514f5e3Sopenharmony_ci    void InitSections();
5814514f5e3Sopenharmony_ci
5824514f5e3Sopenharmony_ci    bool Match(const CString &abcNormalizedDesc, const CString &recordName, EntityId methodId);
5834514f5e3Sopenharmony_ci
5844514f5e3Sopenharmony_ci    template <typename Callback>
5854514f5e3Sopenharmony_ci    void Update(const CString &abcNormalizedDesc, Callback callback)
5864514f5e3Sopenharmony_ci    {
5874514f5e3Sopenharmony_ci        auto abcMethodIds = methodIds_.find(abcNormalizedDesc);
5884514f5e3Sopenharmony_ci        if (abcMethodIds == methodIds_.end()) {
5894514f5e3Sopenharmony_ci            return;
5904514f5e3Sopenharmony_ci        }
5914514f5e3Sopenharmony_ci        for (auto iter = abcMethodIds->second.begin(); iter != abcMethodIds->second.end(); iter++) {
5924514f5e3Sopenharmony_ci            auto recordName = iter->first;
5934514f5e3Sopenharmony_ci            auto methodIds = iter->second;
5944514f5e3Sopenharmony_ci            methodIds->Update(recordName, callback);
5954514f5e3Sopenharmony_ci        }
5964514f5e3Sopenharmony_ci    }
5974514f5e3Sopenharmony_ci
5984514f5e3Sopenharmony_ci    template <typename Callback>
5994514f5e3Sopenharmony_ci    void Update(const CString &abcNormalizedDesc, const CString &recordName, Callback callback)
6004514f5e3Sopenharmony_ci    {
6014514f5e3Sopenharmony_ci        auto abcMethodIds = methodIds_.find(abcNormalizedDesc);
6024514f5e3Sopenharmony_ci        if (abcMethodIds == methodIds_.end()) {
6034514f5e3Sopenharmony_ci            return;
6044514f5e3Sopenharmony_ci        }
6054514f5e3Sopenharmony_ci        auto iter = abcMethodIds->second.find(recordName);
6064514f5e3Sopenharmony_ci        if (iter != abcMethodIds->second.end()) {
6074514f5e3Sopenharmony_ci            iter->second->Update(recordName, callback);
6084514f5e3Sopenharmony_ci        } else {
6094514f5e3Sopenharmony_ci            PGOMethodIdSet *methodIdSet = nativeAreaAllocator_.New<PGOMethodIdSet>(chunk_.get());
6104514f5e3Sopenharmony_ci            if (methodIdSet->Update(recordName, callback)) {
6114514f5e3Sopenharmony_ci                abcMethodIds->second.emplace(recordName, methodIdSet);
6124514f5e3Sopenharmony_ci            } else {
6134514f5e3Sopenharmony_ci                nativeAreaAllocator_.Delete(methodIdSet);
6144514f5e3Sopenharmony_ci            }
6154514f5e3Sopenharmony_ci        }
6164514f5e3Sopenharmony_ci    }
6174514f5e3Sopenharmony_ci
6184514f5e3Sopenharmony_ci    template <typename Callback>
6194514f5e3Sopenharmony_ci    void GetTypeInfo(const CString &abcNormalizedDesc, const CString &recordName, const char *methodName,
6204514f5e3Sopenharmony_ci                     Callback callback)
6214514f5e3Sopenharmony_ci    {
6224514f5e3Sopenharmony_ci        auto abcMethodIds = methodIds_.find(abcNormalizedDesc);
6234514f5e3Sopenharmony_ci        if (abcMethodIds == methodIds_.end()) {
6244514f5e3Sopenharmony_ci            return;
6254514f5e3Sopenharmony_ci        }
6264514f5e3Sopenharmony_ci        auto iter = abcMethodIds->second.find(recordName);
6274514f5e3Sopenharmony_ci        if (iter != abcMethodIds->second.end()) {
6284514f5e3Sopenharmony_ci            iter->second->GetTypeInfo(methodName, callback);
6294514f5e3Sopenharmony_ci        }
6304514f5e3Sopenharmony_ci    }
6314514f5e3Sopenharmony_ci
6324514f5e3Sopenharmony_ci    template <typename Callback>
6334514f5e3Sopenharmony_ci    void GetTypeInfo(const CString &abcNormalizedDesc, const CString &recordName, const char *methodName,
6344514f5e3Sopenharmony_ci                     uint32_t checksum, Callback callback)
6354514f5e3Sopenharmony_ci    {
6364514f5e3Sopenharmony_ci        auto abcMethodIds = methodIds_.find(abcNormalizedDesc);
6374514f5e3Sopenharmony_ci        if (abcMethodIds == methodIds_.end()) {
6384514f5e3Sopenharmony_ci            return;
6394514f5e3Sopenharmony_ci        }
6404514f5e3Sopenharmony_ci        auto iter = abcMethodIds->second.find(recordName);
6414514f5e3Sopenharmony_ci        if (iter != abcMethodIds->second.end()) {
6424514f5e3Sopenharmony_ci            iter->second->GetTypeInfo(methodName, checksum, callback);
6434514f5e3Sopenharmony_ci        }
6444514f5e3Sopenharmony_ci    }
6454514f5e3Sopenharmony_ci
6464514f5e3Sopenharmony_ci    std::shared_ptr<PGOProtoTransitionPool> GetProtoTransitionPool() const
6474514f5e3Sopenharmony_ci    {
6484514f5e3Sopenharmony_ci        return protoTransitionPool_;
6494514f5e3Sopenharmony_ci    }
6504514f5e3Sopenharmony_ci
6514514f5e3Sopenharmony_ci    bool GetHClassTreeDesc(PGOSampleType profileType, PGOHClassTreeDesc **desc) const
6524514f5e3Sopenharmony_ci    {
6534514f5e3Sopenharmony_ci        auto iter = hclassTreeDescInfos_.find(PGOHClassTreeDesc(profileType.GetProfileType()));
6544514f5e3Sopenharmony_ci        if (iter != hclassTreeDescInfos_.end()) {
6554514f5e3Sopenharmony_ci            *desc = &(const_cast<PGOHClassTreeDesc &>(*iter));
6564514f5e3Sopenharmony_ci            return true;
6574514f5e3Sopenharmony_ci        }
6584514f5e3Sopenharmony_ci        return false;
6594514f5e3Sopenharmony_ci    }
6604514f5e3Sopenharmony_ci
6614514f5e3Sopenharmony_ci    template <typename Callback>
6624514f5e3Sopenharmony_ci    bool IterateHClassTreeDesc(Callback callback) const
6634514f5e3Sopenharmony_ci    {
6644514f5e3Sopenharmony_ci        for (auto treeDescInfo : hclassTreeDescInfos_) {
6654514f5e3Sopenharmony_ci            callback(&treeDescInfo);
6664514f5e3Sopenharmony_ci        }
6674514f5e3Sopenharmony_ci        return true;
6684514f5e3Sopenharmony_ci    }
6694514f5e3Sopenharmony_ci
6704514f5e3Sopenharmony_ci    template <typename Callback>
6714514f5e3Sopenharmony_ci    bool IterateProtoTransitionPool(Callback callback) const
6724514f5e3Sopenharmony_ci    {
6734514f5e3Sopenharmony_ci        protoTransitionPool_->Iterate(callback);
6744514f5e3Sopenharmony_ci        return true;
6754514f5e3Sopenharmony_ci    }
6764514f5e3Sopenharmony_ci
6774514f5e3Sopenharmony_ci    void MatchAndMarkMethod(const CString &abcNormalizedDesc, const CString &recordName, const char *methodName,
6784514f5e3Sopenharmony_ci                            EntityId methodId)
6794514f5e3Sopenharmony_ci    {
6804514f5e3Sopenharmony_ci        auto abcMethodIds = methodIds_.find(abcNormalizedDesc);
6814514f5e3Sopenharmony_ci        if (abcMethodIds == methodIds_.end()) {
6824514f5e3Sopenharmony_ci            return;
6834514f5e3Sopenharmony_ci        }
6844514f5e3Sopenharmony_ci        auto iter = abcMethodIds->second.find(recordName);
6854514f5e3Sopenharmony_ci        if (iter != abcMethodIds->second.end()) {
6864514f5e3Sopenharmony_ci            return iter->second->MatchAndMarkMethod(methodName, methodId);
6874514f5e3Sopenharmony_ci        }
6884514f5e3Sopenharmony_ci    }
6894514f5e3Sopenharmony_ci
6904514f5e3Sopenharmony_ci    void GetMismatchResult(const CString &abcNormalizedDesc, uint32_t &totalMethodCount, uint32_t &mismatchMethodCount,
6914514f5e3Sopenharmony_ci                           std::set<std::pair<std::string, CString>> &mismatchMethodSet) const
6924514f5e3Sopenharmony_ci    {
6934514f5e3Sopenharmony_ci        auto abcMethodIds = methodIds_.find(abcNormalizedDesc);
6944514f5e3Sopenharmony_ci        if (abcMethodIds == methodIds_.end()) {
6954514f5e3Sopenharmony_ci            return;
6964514f5e3Sopenharmony_ci        }
6974514f5e3Sopenharmony_ci        for (const auto &methodId : abcMethodIds->second) {
6984514f5e3Sopenharmony_ci            methodId.second->GetMismatchResult(methodId.first, totalMethodCount, mismatchMethodCount,
6994514f5e3Sopenharmony_ci                                               mismatchMethodSet);
7004514f5e3Sopenharmony_ci        }
7014514f5e3Sopenharmony_ci    }
7024514f5e3Sopenharmony_ci
7034514f5e3Sopenharmony_ci    void ParseFromBinary(void *buffer, PGOProfilerHeader *const header, std::shared_ptr<PGOAbcFilePool> &abcFilePool);
7044514f5e3Sopenharmony_ci
7054514f5e3Sopenharmony_ci    void Merge(const PGORecordSimpleInfos &simpleInfos);
7064514f5e3Sopenharmony_ci
7074514f5e3Sopenharmony_ci    std::shared_ptr<PGOProfileTypePool> GetProfileTypePool() const override
7084514f5e3Sopenharmony_ci    {
7094514f5e3Sopenharmony_ci        return profileTypePool_;
7104514f5e3Sopenharmony_ci    }
7114514f5e3Sopenharmony_ci
7124514f5e3Sopenharmony_ci    uint32_t GetHotnessThreshold() const override
7134514f5e3Sopenharmony_ci    {
7144514f5e3Sopenharmony_ci        return hotnessThreshold_;
7154514f5e3Sopenharmony_ci    }
7164514f5e3Sopenharmony_ci
7174514f5e3Sopenharmony_ci    PGOProfilerHeader *GetHeader() const override
7184514f5e3Sopenharmony_ci    {
7194514f5e3Sopenharmony_ci        return header_;
7204514f5e3Sopenharmony_ci    }
7214514f5e3Sopenharmony_ci
7224514f5e3Sopenharmony_ci    bool SupportElementsKind() const override
7234514f5e3Sopenharmony_ci    {
7244514f5e3Sopenharmony_ci        ASSERT(header_ != nullptr);
7254514f5e3Sopenharmony_ci        return header_->SupportElementsKind();
7264514f5e3Sopenharmony_ci    }
7274514f5e3Sopenharmony_ci
7284514f5e3Sopenharmony_ci    bool SupportElementsTrackInfo() const override
7294514f5e3Sopenharmony_ci    {
7304514f5e3Sopenharmony_ci        ASSERT(header_ != nullptr);
7314514f5e3Sopenharmony_ci        return header_->SupportElementsTrackInfo();
7324514f5e3Sopenharmony_ci    }
7334514f5e3Sopenharmony_ci
7344514f5e3Sopenharmony_ci    void ResetAbcIdRemap() const override
7354514f5e3Sopenharmony_ci    {
7364514f5e3Sopenharmony_ci        abcIdRemap_.clear();
7374514f5e3Sopenharmony_ci    }
7384514f5e3Sopenharmony_ci
7394514f5e3Sopenharmony_ci    const std::map<ApEntityId, ApEntityId> &GetAbcIdRemap() const override
7404514f5e3Sopenharmony_ci    {
7414514f5e3Sopenharmony_ci        return abcIdRemap_;
7424514f5e3Sopenharmony_ci    }
7434514f5e3Sopenharmony_ci
7444514f5e3Sopenharmony_ci    void AddAbcIdRemap(ApEntityId oldId, ApEntityId newId) const override
7454514f5e3Sopenharmony_ci    {
7464514f5e3Sopenharmony_ci        abcIdRemap_[oldId] = newId;
7474514f5e3Sopenharmony_ci    }
7484514f5e3Sopenharmony_ci
7494514f5e3Sopenharmony_ci    NO_COPY_SEMANTIC(PGORecordSimpleInfos);
7504514f5e3Sopenharmony_ci    NO_MOVE_SEMANTIC(PGORecordSimpleInfos);
7514514f5e3Sopenharmony_ci
7524514f5e3Sopenharmony_ciprivate:
7534514f5e3Sopenharmony_ci    bool ParseFromBinaryForLayout(void **buffer);
7544514f5e3Sopenharmony_ci
7554514f5e3Sopenharmony_ci    uint32_t hotnessThreshold_ {2};
7564514f5e3Sopenharmony_ci    NativeAreaAllocator nativeAreaAllocator_;
7574514f5e3Sopenharmony_ci    std::unique_ptr<Chunk> chunk_;
7584514f5e3Sopenharmony_ci    CUnorderedMap<CString, CUnorderedMap<CString, PGOMethodIdSet *>> methodIds_;
7594514f5e3Sopenharmony_ci    PGOProfilerHeader *header_ {nullptr};
7604514f5e3Sopenharmony_ci    // std::list<std::weak_ptr<PGOFileSectionInterface>> apSectionList_;
7614514f5e3Sopenharmony_ci    std::shared_ptr<PGORecordPool> recordPool_;
7624514f5e3Sopenharmony_ci    std::shared_ptr<PGOProtoTransitionPool> protoTransitionPool_;
7634514f5e3Sopenharmony_ci    std::shared_ptr<PGOProfileTypePool> profileTypePool_;
7644514f5e3Sopenharmony_ci    std::set<PGOHClassTreeDesc> hclassTreeDescInfos_;
7654514f5e3Sopenharmony_ci    mutable std::map<ApEntityId, ApEntityId> abcIdRemap_;
7664514f5e3Sopenharmony_ci};
7674514f5e3Sopenharmony_ci} // namespace panda::ecmascript::pgo
7684514f5e3Sopenharmony_ci#endif // ECMASCRIPT_PGO_PROFILER_INFO_H
769