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_MANAGER_H 17 #define ECMASCRIPT_PGO_PROFILER_MANAGER_H 18 19 #include <atomic> 20 #include <csignal> 21 #include <memory> 22 23 #include "ecmascript/pgo_profiler/pgo_profiler.h" 24 #include "ecmascript/pgo_profiler/pgo_profiler_decoder.h" 25 #include "ecmascript/pgo_profiler/pgo_profiler_encoder.h" 26 27 namespace panda::ecmascript { 28 class PGOProfilerManager { 29 public: 30 using ApGenMode = PGOProfilerEncoder::ApGenMode; GetInstance()31 static PGOProfilerManager *GetInstance() 32 { 33 static PGOProfilerManager instance; 34 return &instance; 35 } 36 37 static void SavingSignalHandler(int signo); 38 39 PGOProfilerManager() = default; 40 ~PGOProfilerManager() = default; 41 42 NO_COPY_SEMANTIC(PGOProfilerManager); 43 NO_MOVE_SEMANTIC(PGOProfilerManager); 44 Initialize(const std::string & outDir,uint32_t hotnessThreshold)45 void Initialize(const std::string &outDir, uint32_t hotnessThreshold) 46 { 47 // For FA jsvm, merge with existed output file 48 encoder_ = std::make_unique<PGOProfilerEncoder>(outDir, hotnessThreshold, ApGenMode::MERGE); 49 } 50 Destroy()51 void Destroy() 52 { 53 if (encoder_) { 54 encoder_->Save(); 55 encoder_->Destroy(); 56 encoder_.reset(); 57 } 58 } 59 60 // Factory Build(EcmaVM * vm,bool isEnable)61 PGOProfiler *Build(EcmaVM *vm, bool isEnable) 62 { 63 if (isEnable) { 64 isEnable = InitializeData(); 65 } 66 return new PGOProfiler(vm, isEnable); 67 } 68 IsEnable()69 bool IsEnable() const 70 { 71 return encoder_ && encoder_->IsInitialized(); 72 } 73 Destroy(PGOProfiler * profiler)74 void Destroy(PGOProfiler *profiler) 75 { 76 if (profiler != nullptr) { 77 Merge(profiler); 78 delete profiler; 79 } 80 } 81 Reset(PGOProfiler * profiler,bool isEnable)82 void Reset(PGOProfiler *profiler, bool isEnable) 83 { 84 if (isEnable) { 85 isEnable = InitializeData(); 86 } 87 if (profiler) { 88 profiler->Reset(isEnable); 89 } 90 } 91 SamplePandaFileInfo(uint32_t checksum)92 void SamplePandaFileInfo(uint32_t checksum) 93 { 94 if (encoder_) { 95 encoder_->SamplePandaFileInfo(checksum); 96 } 97 } 98 SetApGenMode(ApGenMode mode)99 void SetApGenMode(ApGenMode mode) 100 { 101 if (encoder_) { 102 encoder_->SetApGenMode(mode); 103 } 104 } 105 Merge(PGOProfiler * profiler)106 void Merge(PGOProfiler *profiler) 107 { 108 if (encoder_ && profiler->isEnable_) { 109 encoder_->TerminateSaveTask(); 110 encoder_->Merge(*profiler->recordInfos_); 111 } 112 } 113 114 void RegisterSavingSignal(); 115 AsynSave()116 void AsynSave() 117 { 118 if (encoder_) { 119 encoder_->PostSaveTask(); 120 } 121 } 122 TextToBinary(const std::string & inPath,const std::string & outPath,uint32_t hotnessThreshold,ApGenMode mode)123 bool PUBLIC_API TextToBinary(const std::string &inPath, const std::string &outPath, uint32_t hotnessThreshold, 124 ApGenMode mode) 125 { 126 PGOProfilerEncoder encoder(outPath, hotnessThreshold, mode); 127 if (!encoder.InitializeData()) { 128 LOG_ECMA(ERROR) << "PGO Profiler encoder initialized failed"; 129 return false; 130 } 131 bool ret = encoder.LoadAPTextFile(inPath); 132 if (ret) { 133 ret = encoder.Save(); 134 } 135 encoder.Destroy(); 136 return ret; 137 } 138 BinaryToText(const std::string & inPath,const std::string & outPath,uint32_t hotnessThreshold)139 bool PUBLIC_API BinaryToText(const std::string &inPath, const std::string &outPath, uint32_t hotnessThreshold) 140 { 141 PGOProfilerDecoder decoder(inPath, hotnessThreshold); 142 if (!decoder.LoadFull()) { 143 return false; 144 } 145 bool ret = decoder.SaveAPTextFile(outPath); 146 decoder.Clear(); 147 return ret; 148 } 149 150 static bool MergeApFiles(const std::string &inFiles, const std::string &outPath, uint32_t hotnessThreshold, 151 ApGenMode mode); 152 static bool MergeApFiles(uint32_t checksum, PGOProfilerDecoder &merger); 153 154 private: InitializeData()155 bool InitializeData() 156 { 157 if (!encoder_) { 158 return false; 159 } 160 if (!enableSignalSaving_) { 161 RegisterSavingSignal(); 162 } 163 return encoder_->InitializeData(); 164 } 165 166 std::unique_ptr<PGOProfilerEncoder> encoder_; 167 std::atomic_bool enableSignalSaving_ { false }; 168 }; 169 } // namespace panda::ecmascript 170 #endif // ECMASCRIPT_PGO_PROFILER_MANAGER_H 171