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_ENCODER_H 17 #define ECMASCRIPT_PGO_PROFILER_ENCODER_H 18 19 #include <atomic> 20 #include <memory> 21 #include <utility> 22 23 #include "ecmascript/pgo_profiler/pgo_profiler_info.h" 24 #include "macros.h" 25 26 namespace panda::ecmascript::pgo { 27 class PGOProfilerDecoder; 28 class PGOProfilerEncoder { 29 public: 30 enum ApGenMode { OVERWRITE, MERGE }; 31 PGOProfilerEncoder(const std::string & outDir,uint32_t hotnessThreshold,ApGenMode mode)32 PGOProfilerEncoder(const std::string &outDir, uint32_t hotnessThreshold, ApGenMode mode) 33 : outDir_(outDir), hotnessThreshold_(hotnessThreshold), mode_(mode) 34 { 35 pandaFileInfos_ = std::make_unique<PGOPandaFileInfos>(); 36 abcFilePool_ = std::make_shared<PGOAbcFilePool>(); 37 } 38 ~PGOProfilerEncoder()39 ~PGOProfilerEncoder() 40 { 41 Destroy(); 42 } 43 44 NO_COPY_SEMANTIC(PGOProfilerEncoder); 45 NO_MOVE_SEMANTIC(PGOProfilerEncoder); 46 47 static void AddChecksum(std::fstream& fileStream); 48 49 bool PUBLIC_API InitializeData(); 50 51 void PUBLIC_API Destroy(); 52 SetBundleName(const std::string & bundleName)53 void SetBundleName(const std::string &bundleName) 54 { 55 bundleName_ = bundleName; 56 } 57 GetBundleName()58 const std::string GetBundleName() 59 { 60 return bundleName_; 61 } 62 IsInitialized()63 bool IsInitialized() const 64 { 65 return isProfilingInitialized_; 66 } 67 68 void SamplePandaFileInfo(uint32_t checksum, const CString &abcName); 69 bool GetPandaFileId(const CString &abcName, ApEntityId &entryId); 70 bool GetPandaFileDesc(ApEntityId abcId, CString &desc); 71 void Merge(const PGORecordDetailInfos &recordInfos); 72 void Merge(const PGOPandaFileInfos &pandaFileInfos); 73 void Merge(const PGOProfilerEncoder &encoder); 74 bool VerifyPandaFileMatched(const PGOPandaFileInfos &pandaFileInfos, const std::string &base, 75 const std::string &incoming) const; GetAbcFilePool()76 std::shared_ptr<PGOAbcFilePool> GetAbcFilePool() const 77 { 78 return abcFilePool_; 79 } 80 void TerminateSaveTask(); 81 void PostSaveTask(); SetApGenMode(ApGenMode mode)82 void SetApGenMode(ApGenMode mode) 83 { 84 mode_ = mode; 85 } 86 87 bool PUBLIC_API Save(); 88 89 bool PUBLIC_API LoadAPTextFile(const std::string &inPath); 90 91 void PostResetOutPathTask(const std::string &moduleName); 92 93 bool ResetOutPathByModuleName(const std::string &moduleName); 94 95 protected: 96 PGOProfilerHeader *header_ {nullptr}; 97 98 private: 99 void StartSaveTask(const SaveTask *task); 100 bool InternalSave(const SaveTask *task = nullptr); 101 bool SaveAndRename(const SaveTask *task = nullptr); 102 void MergeWithExistProfile(PGOProfilerEncoder &runtimeEncoder, PGOProfilerDecoder &decoder, 103 const SaveTask *task = nullptr); 104 void RequestAot(); 105 bool ResetOutPath(const std::string& profileFileName); 106 107 bool isProfilingInitialized_ {false}; 108 std::string outDir_; 109 uint32_t hotnessThreshold_ {2}; 110 std::string realOutPath_; 111 std::unique_ptr<PGOPandaFileInfos> pandaFileInfos_; 112 std::shared_ptr<PGOAbcFilePool> abcFilePool_; 113 std::shared_ptr<PGORecordDetailInfos> globalRecordInfos_; 114 Mutex mutex_; 115 RWLock rwLock_; 116 std::atomic_bool hasPostModuleName_ {false}; 117 std::string moduleName_; 118 std::string bundleName_; 119 ApGenMode mode_ {OVERWRITE}; 120 friend SaveTask; 121 }; 122 123 class SaveTask : public Task { 124 public: SaveTask(PGOProfilerEncoder * encoder,int32_t id)125 explicit SaveTask(PGOProfilerEncoder *encoder, int32_t id) : Task(id), encoder_(encoder) {}; 126 virtual ~SaveTask() override = default; 127 Run(uint32_t threadIndex)128 bool Run([[maybe_unused]] uint32_t threadIndex) override 129 { 130 encoder_->StartSaveTask(this); 131 return true; 132 } 133 GetTaskType()134 TaskType GetTaskType() const override 135 { 136 return TaskType::PGO_SAVE_TASK; 137 } 138 139 NO_COPY_SEMANTIC(SaveTask); 140 NO_MOVE_SEMANTIC(SaveTask); 141 private: 142 PGOProfilerEncoder *encoder_; 143 }; 144 145 class ResetOutPathTask : public Task { 146 public: ResetOutPathTask(PGOProfilerEncoder * encoder,std::string moduleName,int32_t id)147 ResetOutPathTask(PGOProfilerEncoder *encoder, std::string moduleName, int32_t id) 148 : Task(id), encoder_(encoder), moduleName_(std::move(moduleName)) {}; 149 virtual ~ResetOutPathTask() override = default; 150 Run(uint32_t threadIndex)151 bool Run([[maybe_unused]] uint32_t threadIndex) override 152 { 153 encoder_->ResetOutPathByModuleName(moduleName_); 154 return true; 155 } 156 GetTaskType()157 TaskType GetTaskType() const override 158 { 159 return TaskType::PGO_RESET_OUT_PATH_TASK; 160 } 161 162 NO_COPY_SEMANTIC(ResetOutPathTask); 163 NO_MOVE_SEMANTIC(ResetOutPathTask); 164 165 private: 166 PGOProfilerEncoder *encoder_; 167 std::string moduleName_; 168 }; 169 } // namespace panda::ecmascript::pgo 170 #endif // ECMASCRIPT_PGO_PROFILER_ENCODER_H 171