14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2023 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_ENCODER_H
174514f5e3Sopenharmony_ci#define ECMASCRIPT_PGO_PROFILER_ENCODER_H
184514f5e3Sopenharmony_ci
194514f5e3Sopenharmony_ci#include <atomic>
204514f5e3Sopenharmony_ci#include <memory>
214514f5e3Sopenharmony_ci#include <utility>
224514f5e3Sopenharmony_ci
234514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/pgo_profiler_info.h"
244514f5e3Sopenharmony_ci#include "macros.h"
254514f5e3Sopenharmony_ci
264514f5e3Sopenharmony_cinamespace panda::ecmascript::pgo {
274514f5e3Sopenharmony_ciclass PGOProfilerDecoder;
284514f5e3Sopenharmony_ciclass PGOProfilerEncoder {
294514f5e3Sopenharmony_cipublic:
304514f5e3Sopenharmony_ci    enum ApGenMode { OVERWRITE, MERGE };
314514f5e3Sopenharmony_ci
324514f5e3Sopenharmony_ci    PGOProfilerEncoder(const std::string &outDir, uint32_t hotnessThreshold, ApGenMode mode)
334514f5e3Sopenharmony_ci        : outDir_(outDir), hotnessThreshold_(hotnessThreshold), mode_(mode)
344514f5e3Sopenharmony_ci    {
354514f5e3Sopenharmony_ci        pandaFileInfos_ = std::make_unique<PGOPandaFileInfos>();
364514f5e3Sopenharmony_ci        abcFilePool_ = std::make_shared<PGOAbcFilePool>();
374514f5e3Sopenharmony_ci    }
384514f5e3Sopenharmony_ci
394514f5e3Sopenharmony_ci    ~PGOProfilerEncoder()
404514f5e3Sopenharmony_ci    {
414514f5e3Sopenharmony_ci        Destroy();
424514f5e3Sopenharmony_ci    }
434514f5e3Sopenharmony_ci
444514f5e3Sopenharmony_ci    NO_COPY_SEMANTIC(PGOProfilerEncoder);
454514f5e3Sopenharmony_ci    NO_MOVE_SEMANTIC(PGOProfilerEncoder);
464514f5e3Sopenharmony_ci
474514f5e3Sopenharmony_ci    static void AddChecksum(std::fstream& fileStream);
484514f5e3Sopenharmony_ci
494514f5e3Sopenharmony_ci    bool PUBLIC_API InitializeData();
504514f5e3Sopenharmony_ci
514514f5e3Sopenharmony_ci    void PUBLIC_API Destroy();
524514f5e3Sopenharmony_ci
534514f5e3Sopenharmony_ci    void SetBundleName(const std::string &bundleName)
544514f5e3Sopenharmony_ci    {
554514f5e3Sopenharmony_ci        bundleName_ = bundleName;
564514f5e3Sopenharmony_ci    }
574514f5e3Sopenharmony_ci
584514f5e3Sopenharmony_ci    const std::string GetBundleName()
594514f5e3Sopenharmony_ci    {
604514f5e3Sopenharmony_ci        return bundleName_;
614514f5e3Sopenharmony_ci    }
624514f5e3Sopenharmony_ci
634514f5e3Sopenharmony_ci    bool IsInitialized() const
644514f5e3Sopenharmony_ci    {
654514f5e3Sopenharmony_ci        return isProfilingInitialized_;
664514f5e3Sopenharmony_ci    }
674514f5e3Sopenharmony_ci
684514f5e3Sopenharmony_ci    void SamplePandaFileInfo(uint32_t checksum, const CString &abcName);
694514f5e3Sopenharmony_ci    bool PUBLIC_API GetPandaFileId(const CString &abcName, ApEntityId &entryId);
704514f5e3Sopenharmony_ci    bool GetPandaFileDesc(ApEntityId abcId, CString &desc);
714514f5e3Sopenharmony_ci    void Merge(const PGORecordDetailInfos &recordInfos);
724514f5e3Sopenharmony_ci    void Merge(const PGOPandaFileInfos &pandaFileInfos);
734514f5e3Sopenharmony_ci    void Merge(const PGOProfilerEncoder &encoder);
744514f5e3Sopenharmony_ci    bool VerifyPandaFileMatched(const PGOPandaFileInfos &pandaFileInfos, const std::string &base,
754514f5e3Sopenharmony_ci                                const std::string &incoming) const;
764514f5e3Sopenharmony_ci    std::shared_ptr<PGOAbcFilePool> GetAbcFilePool() const
774514f5e3Sopenharmony_ci    {
784514f5e3Sopenharmony_ci        return abcFilePool_;
794514f5e3Sopenharmony_ci    }
804514f5e3Sopenharmony_ci    void TerminateSaveTask();
814514f5e3Sopenharmony_ci    void PostSaveTask();
824514f5e3Sopenharmony_ci    void SetApGenMode(ApGenMode mode)
834514f5e3Sopenharmony_ci    {
844514f5e3Sopenharmony_ci        mode_ = mode;
854514f5e3Sopenharmony_ci    }
864514f5e3Sopenharmony_ci
874514f5e3Sopenharmony_ci    bool PUBLIC_API Save();
884514f5e3Sopenharmony_ci
894514f5e3Sopenharmony_ci    bool PUBLIC_API LoadAPTextFile(const std::string &inPath);
904514f5e3Sopenharmony_ci
914514f5e3Sopenharmony_ci    void PostResetOutPathTask(const std::string &moduleName);
924514f5e3Sopenharmony_ci
934514f5e3Sopenharmony_ci    bool ResetOutPathByModuleName(const std::string &moduleName);
944514f5e3Sopenharmony_ci
954514f5e3Sopenharmony_ciprotected:
964514f5e3Sopenharmony_ci    PGOProfilerHeader *header_ {nullptr};
974514f5e3Sopenharmony_ci
984514f5e3Sopenharmony_ciprivate:
994514f5e3Sopenharmony_ci    void StartSaveTask(const SaveTask *task);
1004514f5e3Sopenharmony_ci    bool InternalSave(const SaveTask *task = nullptr);
1014514f5e3Sopenharmony_ci    bool SaveAndRename(const SaveTask *task = nullptr);
1024514f5e3Sopenharmony_ci    void MergeWithExistProfile(PGOProfilerEncoder &runtimeEncoder, PGOProfilerDecoder &decoder,
1034514f5e3Sopenharmony_ci                               const SaveTask *task = nullptr);
1044514f5e3Sopenharmony_ci    void RequestAot();
1054514f5e3Sopenharmony_ci    bool ResetOutPath(const std::string& profileFileName);
1064514f5e3Sopenharmony_ci
1074514f5e3Sopenharmony_ci    bool isProfilingInitialized_ {false};
1084514f5e3Sopenharmony_ci    std::string outDir_;
1094514f5e3Sopenharmony_ci    uint32_t hotnessThreshold_ {2};
1104514f5e3Sopenharmony_ci    std::string realOutPath_;
1114514f5e3Sopenharmony_ci    std::unique_ptr<PGOPandaFileInfos> pandaFileInfos_;
1124514f5e3Sopenharmony_ci    std::shared_ptr<PGOAbcFilePool> abcFilePool_;
1134514f5e3Sopenharmony_ci    std::shared_ptr<PGORecordDetailInfos> globalRecordInfos_;
1144514f5e3Sopenharmony_ci    // rwLock_ is used to protect the pandaFileInfos_ and abcFilePool_
1154514f5e3Sopenharmony_ci    RWLock rwLock_;
1164514f5e3Sopenharmony_ci    // mutex_ is used to protect the others
1174514f5e3Sopenharmony_ci    Mutex mutex_;
1184514f5e3Sopenharmony_ci    std::atomic_bool hasPostModuleName_ {false};
1194514f5e3Sopenharmony_ci    std::string moduleName_;
1204514f5e3Sopenharmony_ci    std::string bundleName_;
1214514f5e3Sopenharmony_ci    ApGenMode mode_ {OVERWRITE};
1224514f5e3Sopenharmony_ci    friend SaveTask;
1234514f5e3Sopenharmony_ci};
1244514f5e3Sopenharmony_ci
1254514f5e3Sopenharmony_ciclass SaveTask : public Task {
1264514f5e3Sopenharmony_cipublic:
1274514f5e3Sopenharmony_ci    explicit SaveTask(PGOProfilerEncoder *encoder, int32_t id) : Task(id), encoder_(encoder) {};
1284514f5e3Sopenharmony_ci    virtual ~SaveTask() override = default;
1294514f5e3Sopenharmony_ci
1304514f5e3Sopenharmony_ci    bool Run([[maybe_unused]] uint32_t threadIndex) override
1314514f5e3Sopenharmony_ci    {
1324514f5e3Sopenharmony_ci        ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "SaveTask::Run");
1334514f5e3Sopenharmony_ci        encoder_->StartSaveTask(this);
1344514f5e3Sopenharmony_ci        return true;
1354514f5e3Sopenharmony_ci    }
1364514f5e3Sopenharmony_ci
1374514f5e3Sopenharmony_ci    TaskType GetTaskType() const override
1384514f5e3Sopenharmony_ci    {
1394514f5e3Sopenharmony_ci        return TaskType::PGO_SAVE_TASK;
1404514f5e3Sopenharmony_ci    }
1414514f5e3Sopenharmony_ci
1424514f5e3Sopenharmony_ci    NO_COPY_SEMANTIC(SaveTask);
1434514f5e3Sopenharmony_ci    NO_MOVE_SEMANTIC(SaveTask);
1444514f5e3Sopenharmony_ciprivate:
1454514f5e3Sopenharmony_ci    PGOProfilerEncoder *encoder_;
1464514f5e3Sopenharmony_ci};
1474514f5e3Sopenharmony_ci
1484514f5e3Sopenharmony_ciclass ResetOutPathTask : public Task {
1494514f5e3Sopenharmony_cipublic:
1504514f5e3Sopenharmony_ci    ResetOutPathTask(PGOProfilerEncoder *encoder, std::string moduleName, int32_t id)
1514514f5e3Sopenharmony_ci        : Task(id), encoder_(encoder), moduleName_(std::move(moduleName)) {};
1524514f5e3Sopenharmony_ci    virtual ~ResetOutPathTask() override = default;
1534514f5e3Sopenharmony_ci
1544514f5e3Sopenharmony_ci    bool Run([[maybe_unused]] uint32_t threadIndex) override
1554514f5e3Sopenharmony_ci    {
1564514f5e3Sopenharmony_ci        ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "ResetOutPathTask::Run");
1574514f5e3Sopenharmony_ci        encoder_->ResetOutPathByModuleName(moduleName_);
1584514f5e3Sopenharmony_ci        return true;
1594514f5e3Sopenharmony_ci    }
1604514f5e3Sopenharmony_ci
1614514f5e3Sopenharmony_ci    TaskType GetTaskType() const override
1624514f5e3Sopenharmony_ci    {
1634514f5e3Sopenharmony_ci        return TaskType::PGO_RESET_OUT_PATH_TASK;
1644514f5e3Sopenharmony_ci    }
1654514f5e3Sopenharmony_ci
1664514f5e3Sopenharmony_ci    NO_COPY_SEMANTIC(ResetOutPathTask);
1674514f5e3Sopenharmony_ci    NO_MOVE_SEMANTIC(ResetOutPathTask);
1684514f5e3Sopenharmony_ci
1694514f5e3Sopenharmony_ciprivate:
1704514f5e3Sopenharmony_ci    PGOProfilerEncoder *encoder_;
1714514f5e3Sopenharmony_ci    std::string moduleName_;
1724514f5e3Sopenharmony_ci};
1734514f5e3Sopenharmony_ci} // namespace panda::ecmascript::pgo
1744514f5e3Sopenharmony_ci#endif  // ECMASCRIPT_PGO_PROFILER_ENCODER_H
175