• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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