• 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 #include "ecmascript/pgo_profiler/pgo_profiler_manager.h"
17 #include <fstream>
18 
19 #include "ecmascript/log.h"
20 #include "ecmascript/log_wrapper.h"
21 #include "ecmascript/mem/mem.h"
22 #include "ecmascript/platform/file.h"
23 namespace panda::ecmascript::pgo {
24 namespace {
25     constexpr int32_t PGO_SAVING_SIGNAL = 50;
26 } // namespace
27 
GetInstance()28 PGOProfilerManager* PGOProfilerManager::GetInstance()
29 {
30     static PGOProfilerManager* instance = new PGOProfilerManager();
31     return instance;
32 }
33 
MergeApFiles(const std::string & inFiles,const std::string & outPath,uint32_t hotnessThreshold,ApGenMode mode)34 bool PGOProfilerManager::MergeApFiles(const std::string &inFiles, const std::string &outPath, uint32_t hotnessThreshold,
35                                       ApGenMode mode)
36 {
37     arg_list_t apFileNames = base::StringHelper::SplitString(inFiles, GetFileDelimiter());
38     PGOProfilerEncoder merger(outPath, hotnessThreshold, mode);
39     if (!merger.InitializeData()) {
40         LOG_ECMA(ERROR) << "PGO Profiler encoder initialized failed. outPath: " << outPath
41                         << " ,hotnessThreshold: " << hotnessThreshold;
42         return false;
43     }
44     bool isFirstFile = true;
45     std::string firstApFileName;
46     for (const auto &fileName : apFileNames) {
47         if (!base::StringHelper::EndsWith(fileName, ".ap")) {
48             LOG_ECMA(ERROR) << "The file path(" << fileName << ") does not end with .ap";
49             continue;
50         }
51         PGOProfilerDecoder decoder(fileName, hotnessThreshold);
52         if (!decoder.LoadFull(merger.GetAbcFilePool())) {
53             LOG_ECMA(ERROR) << "Fail to load file path(" << fileName << "), skip it.";
54             continue;
55         }
56         if (isFirstFile) {
57             firstApFileName = fileName;
58         } else {
59             if (!merger.VerifyPandaFileMatched(decoder.GetPandaFileInfos(), firstApFileName, fileName)) {
60                 continue;
61             }
62         }
63         merger.Merge(decoder.GetRecordDetailInfos());
64         merger.Merge(decoder.GetPandaFileInfos());
65         isFirstFile = false;
66     }
67     if (isFirstFile) {
68         LOG_ECMA(ERROR) << "No input file processed. Input files: " << inFiles;
69         return false;
70     }
71     merger.Save();
72     return true;
73 }
74 
MergeApFiles(uint32_t checksum,PGOProfilerDecoder & merger)75 bool PGOProfilerManager::MergeApFiles(uint32_t checksum, PGOProfilerDecoder &merger)
76 {
77     uint32_t hotnessThreshold = merger.GetHotnessThreshold();
78     std::string inFiles(merger.GetInPath());
79     arg_list_t pandaFileNames = base::StringHelper::SplitString(inFiles, GetFileDelimiter());
80     if (pandaFileNames.empty()) {
81         return true;
82     }
83     merger.InitMergeData();
84     bool isFirstFile = true;
85     std::string firstApFileName;
86     for (const auto &fileName : pandaFileNames) {
87         PGOProfilerDecoder decoder(fileName, hotnessThreshold);
88         if (!decoder.LoadAndVerify(checksum, merger.GetAbcFilePool())) {
89             LOG_ECMA(ERROR) << "Load and verify file(" << fileName << ") failed, skip it.";
90             continue;
91         }
92         if (isFirstFile) {
93             firstApFileName = fileName;
94         } else {
95             if (!merger.GetPandaFileInfos().VerifyChecksum(decoder.GetPandaFileInfos(), firstApFileName, fileName)) {
96                 continue;
97             }
98         }
99         merger.Merge(decoder);
100         isFirstFile = false;
101     }
102     if (isFirstFile) {
103         LOG_ECMA(ERROR) << "No input file processed. Input files: " << inFiles;
104         return false;
105     }
106     return true;
107 }
108 
RegisterSavingSignal()109 void PGOProfilerManager::RegisterSavingSignal()
110 {
111     LOG_ECMA(INFO) << "Register Pgo Saving Signal";
112     if (encoder_ == nullptr) {
113         LOG_ECMA(ERROR) << "Can not register pgo saving signal, because encoder is null.";
114         return;
115     }
116     if (!encoder_->IsInitialized()) {
117         LOG_ECMA(DEBUG) << "Can not register pgo saving signal, because encoder is initialized.";
118         return;
119     }
120     signal(PGO_SAVING_SIGNAL, SavingSignalHandler);
121     enableSignalSaving_ = true;
122 }
123 
SavingSignalHandler(int signo)124 void PGOProfilerManager::SavingSignalHandler(int signo)
125 {
126     if (signo != PGO_SAVING_SIGNAL) {
127         return;
128     }
129 
130     PGOProfilerManager::GetInstance()->ForceSave();
131 }
132 } // namespace panda::ecmascript::pgo
133