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