• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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_loader.h"
17 
18 #include "ecmascript/log_wrapper.h"
19 #include "ecmascript/pgo_profiler/pgo_profiler_info.h"
20 #include "ecmascript/platform/file.h"
21 
22 namespace panda::ecmascript {
Load()23 bool PGOProfilerLoader::Load()
24 {
25     if (isLoaded_) {
26         Clear();
27     }
28     if (!LoadAPBinaryFile()) {
29         return false;
30     }
31     void *addr = fileMapAddr_.GetOriginAddr();
32 
33     if (!PGOProfilerHeader::ParseFromBinary(addr, &header_)) {
34         UnLoadAPBinaryFile();
35         LOG_ECMA(ERROR) << "Parse profiler header failed";
36         return false;
37     }
38     pandaFileInfos_.ParseFromBinary(addr, header_->GetPandaInfoSection());
39     if (!recordSimpleInfos_) {
40         recordSimpleInfos_ = std::make_unique<PGORecordSimpleInfos>(hotnessThreshold_);
41     }
42     recordSimpleInfos_->ParseFromBinary(addr, header_->GetRecordInfoSection());
43     UnLoadAPBinaryFile();
44 
45     isLoaded_ = true;
46     return true;
47 }
48 
Verify(uint32_t checksum)49 bool PGOProfilerLoader::Verify(uint32_t checksum)
50 {
51     if (!isLoaded_) {
52         return false;
53     }
54     isVerifySuccess_ = pandaFileInfos_.CheckSum(checksum);
55     return isVerifySuccess_;
56 }
57 
LoadAndVerify(uint32_t checksum)58 bool PGOProfilerLoader::LoadAndVerify(uint32_t checksum)
59 {
60     // The file does not exist. Enter full compiler mode.
61     if (inPath_.empty()) {
62         LOG_ECMA(INFO) << "When the file is empty. Enter full compiler mode.";
63         Clear();
64         return true;
65     }
66     if (Load() && Verify(checksum)) {
67         return true;
68     }
69     return false;
70 }
71 
LoadFull()72 bool PGOProfilerLoader::LoadFull()
73 {
74     if (isLoaded_) {
75         Clear();
76     }
77     if (!LoadAPBinaryFile()) {
78         return false;
79     }
80     void *addr = fileMapAddr_.GetOriginAddr();
81 
82     if (!PGOProfilerHeader::ParseFromBinary(addr, &header_)) {
83         UnLoadAPBinaryFile();
84         LOG_ECMA(ERROR) << "Parse profiler header failed";
85         return false;
86     }
87     pandaFileInfos_.ParseFromBinary(addr, header_->GetPandaInfoSection());
88     if (!recordDetailInfos_) {
89         recordDetailInfos_ = std::make_unique<PGORecordDetailInfos>(hotnessThreshold_);
90     }
91     recordDetailInfos_->ParseFromBinary(addr, header_->GetRecordInfoSection());
92 
93     isLoaded_ = true;
94     return true;
95 }
96 
SaveAPTextFile(const std::string & outPath)97 bool PGOProfilerLoader::SaveAPTextFile(const std::string &outPath)
98 {
99     if (!isLoaded_) {
100         return false;
101     }
102     std::string realOutPath;
103     if (!RealPath(outPath, realOutPath, false)) {
104         return false;
105     }
106     std::ofstream fileStream(realOutPath.c_str());
107     if (!fileStream.is_open()) {
108         LOG_ECMA(ERROR) << "The file path(" << realOutPath << ") open failure!";
109         return false;
110     }
111 
112     if (!header_->ProcessToText(fileStream)) {
113         return false;
114     }
115     pandaFileInfos_.ProcessToText(fileStream);
116     recordDetailInfos_->ProcessToText(fileStream);
117     return true;
118 }
119 
LoadAPBinaryFile()120 bool PGOProfilerLoader::LoadAPBinaryFile()
121 {
122     std::string realPath;
123     if (!RealPath(inPath_, realPath)) {
124         return false;
125     }
126 
127     static const std::string endString = ".ap";
128     if (realPath.compare(realPath.length() - endString.length(), endString.length(), endString)) {
129         LOG_ECMA(ERROR) << "The file path( " << realPath << ") does not end with .ap";
130         return false;
131     }
132     LOG_ECMA(INFO) << "Load profiler from file:" << realPath;
133     fileMapAddr_ = FileMap(realPath.c_str(), FILE_RDONLY, PAGE_PROT_READ);
134     if (fileMapAddr_.GetOriginAddr() == nullptr) {
135         LOG_ECMA(ERROR) << "File mmap failed";
136         return false;
137     }
138     return true;
139 }
140 
UnLoadAPBinaryFile()141 void PGOProfilerLoader::UnLoadAPBinaryFile()
142 {
143     if (fileMapAddr_.GetOriginAddr() != nullptr && fileMapAddr_.GetSize() > 0) {
144         FileUnMap(fileMapAddr_);
145         fileMapAddr_.Reset();
146     }
147 }
148 
Clear()149 void PGOProfilerLoader::Clear()
150 {
151     if (isLoaded_) {
152         UnLoadAPBinaryFile();
153         isVerifySuccess_ = true;
154         hotnessThreshold_ = 0;
155         PGOProfilerHeader::Destroy(&header_);
156         pandaFileInfos_.Clear();
157         if (recordDetailInfos_) {
158             recordDetailInfos_->Clear();
159         }
160         if (recordSimpleInfos_) {
161             recordSimpleInfos_->Clear();
162         }
163         isLoaded_ = false;
164     }
165 }
166 
Match(const CString & recordName,EntityId methodId)167 bool PGOProfilerLoader::Match(const CString &recordName, EntityId methodId)
168 {
169     if (!isLoaded_) {
170         return true;
171     }
172     if (!isVerifySuccess_) {
173         return false;
174     }
175     return recordSimpleInfos_->Match(recordName, methodId);
176 }
177 } // namespace panda::ecmascript
178