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