• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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_info.h"
17 
18 #include "ecmascript/pgo_profiler/pgo_profiler_decoder.h"
19 #include "ecmascript/pgo_profiler/pgo_profiler_encoder.h"
20 #include "ecmascript/pgo_profiler/pgo_profiler_info.h"
21 #include "ecmascript/pgo_profiler/pgo_trace.h"
22 #include "ecmascript/pgo_profiler/pgo_utils.h"
23 
24 namespace panda::ecmascript::pgo {
25 
PGOInfo(uint32_t hotnessThreshold)26 PGOInfo::PGOInfo(uint32_t hotnessThreshold): hotnessThreshold_(hotnessThreshold)
27 {
28     abcFilePool_ = std::make_shared<PGOAbcFilePool>();
29     pandaFileInfos_ = std::make_unique<PGOPandaFileInfos>();
30     PGOProfilerHeader::Build(&header_, PGOProfilerHeader::LastSize());
31     recordDetailInfos_ = std::make_shared<PGORecordDetailInfos>(hotnessThreshold_);
32 }
33 
~PGOInfo()34 PGOInfo::~PGOInfo()
35 {
36     Clear();
37 }
38 
GetHeader() const39 PGOProfilerHeader& PGOInfo::GetHeader() const
40 {
41     return *header_;
42 }
43 
GetHeaderPtr() const44 PGOProfilerHeader* PGOInfo::GetHeaderPtr() const
45 {
46     return header_;
47 }
48 
SetHeader(PGOProfilerHeader * header)49 void PGOInfo::SetHeader(PGOProfilerHeader* header)
50 {
51     header_ = header;
52 }
53 
GetPandaFileInfos() const54 PGOPandaFileInfos& PGOInfo::GetPandaFileInfos() const
55 {
56     return *pandaFileInfos_;
57 }
58 
SetPandaFileInfos(std::unique_ptr<PGOPandaFileInfos> pandaFileInfos)59 void PGOInfo::SetPandaFileInfos(std::unique_ptr<PGOPandaFileInfos> pandaFileInfos)
60 {
61     pandaFileInfos_ = std::move(pandaFileInfos);
62 }
63 
GetAbcFilePool() const64 PGOAbcFilePool& PGOInfo::GetAbcFilePool() const
65 {
66     return *abcFilePool_;
67 }
68 
GetAbcFilePoolPtr() const69 std::shared_ptr<PGOAbcFilePool> PGOInfo::GetAbcFilePoolPtr() const
70 {
71     return abcFilePool_;
72 }
73 
SetAbcFilePool(std::shared_ptr<PGOAbcFilePool> abcFilePool)74 void PGOInfo::SetAbcFilePool(std::shared_ptr<PGOAbcFilePool> abcFilePool)
75 {
76     abcFilePool_ = abcFilePool;
77 }
78 
GetRecordDetailInfos() const79 PGORecordDetailInfos& PGOInfo::GetRecordDetailInfos() const
80 {
81     return *recordDetailInfos_;
82 }
83 
SetRecordDetailInfos(std::shared_ptr<PGORecordDetailInfos> recordDetailInfos)84 void PGOInfo::SetRecordDetailInfos(std::shared_ptr<PGORecordDetailInfos> recordDetailInfos)
85 {
86     recordDetailInfos_ = recordDetailInfos;
87 }
88 
GetRecordDetailInfosPtr() const89 std::shared_ptr<PGORecordDetailInfos> PGOInfo::GetRecordDetailInfosPtr() const
90 {
91     return recordDetailInfos_;
92 }
93 
SetHotnessThreshold(uint32_t threshold)94 void PGOInfo::SetHotnessThreshold(uint32_t threshold)
95 {
96     hotnessThreshold_ = threshold;
97 }
98 
GetHotnessThreshold() const99 uint32_t PGOInfo::GetHotnessThreshold() const
100 {
101     return hotnessThreshold_;
102 }
103 
SamplePandaFileInfoSafe(uint32_t checksum,const CString & abcName)104 void PGOInfo::SamplePandaFileInfoSafe(uint32_t checksum, const CString& abcName)
105 {
106     LockHolder lock(sampleMutexLock_);
107     ConcurrentGuard guard(v_, "SafeSamplePandaFileInfo");
108     ApEntityId entryId(0);
109     abcFilePool_->TryAddSafe(abcName, entryId);
110     pandaFileInfos_->SampleSafe(checksum, entryId);
111 }
112 
Clear()113 void PGOInfo::Clear()
114 {
115     if (pandaFileInfos_) {
116         pandaFileInfos_->ClearSafe();
117     }
118     if (abcFilePool_) {
119         abcFilePool_->ClearSafe();
120     }
121     if (header_) {
122         PGOProfilerHeader::Destroy(&header_);
123     }
124     if (recordDetailInfos_) {
125         recordDetailInfos_->ClearSafe();
126     }
127 }
128 
GetPandaFileIdSafe(const CString & abcName,ApEntityId & entryId)129 bool PGOInfo::GetPandaFileIdSafe(const CString& abcName, ApEntityId& entryId)
130 {
131     return abcFilePool_->GetEntryIdSafe(abcName, entryId);
132 }
133 
GetPandaFileDescSafe(ApEntityId abcId,CString & desc)134 bool PGOInfo::GetPandaFileDescSafe(ApEntityId abcId, CString& desc)
135 {
136     return abcFilePool_->GetPandaFileDescSafe(abcId, desc);
137 }
138 
MergeSafe(const PGORecordDetailInfos & recordInfos)139 void PGOInfo::MergeSafe(const PGORecordDetailInfos& recordInfos)
140 {
141     recordDetailInfos_->MergeSafe(recordInfos);
142 }
143 
MergeSafe(const PGOPandaFileInfos & pandaFileInfos)144 void PGOInfo::MergeSafe(const PGOPandaFileInfos& pandaFileInfos)
145 {
146     pandaFileInfos_->MergeSafe(pandaFileInfos);
147 }
148 
MergeSafe(const PGOInfo & other)149 void PGOInfo::MergeSafe(const PGOInfo& other)
150 {
151     MergeSafe(other.GetPandaFileInfos());
152     MergeSafe(other.GetRecordDetailInfos());
153 }
154 
VerifyPandaFileMatched(const PGOPandaFileInfos & pandaFileInfos,const std::string & base,const std::string & incoming) const155 bool PGOInfo::VerifyPandaFileMatched(const PGOPandaFileInfos& pandaFileInfos,
156                                      const std::string& base,
157                                      const std::string& incoming) const
158 {
159     return GetPandaFileInfos().VerifyChecksum(pandaFileInfos, base, incoming);
160 }
161 
MergeWithExistProfile(PGOInfo & rtInfo,PGOProfilerDecoder & decoder,const SaveTask * task)162 void PGOInfo::MergeWithExistProfile(PGOInfo& rtInfo, PGOProfilerDecoder& decoder, const SaveTask* task)
163 {
164     ClockScope start;
165     // inherit some info from runtime encoder
166     ASSERT(header_ != nullptr);
167     ASSERT(rtInfo.header_ != nullptr);
168     header_->SetVersion(rtInfo.header_->GetVersion());
169     ASSERT(abcFilePool_->GetPool()->Empty());
170     {
171         // copy abcFilePool from runtime to temp merger.
172         // Lock for avoid sampling fileInfos during merge, it will cause pandafile ApEntityId different in abcFilePool
173         // and pandaFileInfos, which will cause checksum verification failed or an ApEntityId only in one of pools.
174         // when PGOProfilerManager::MergeApFiles, ApEntityId in abcFilePool not exist will cause crash.
175         LockHolder lock(rtInfo.GetSampleMutexLock());
176         ConcurrentGuard guard(rtInfo.GetConcurrentGuardValue(), "MergeWithExistProfile");
177         abcFilePool_->CopySafe(rtInfo.GetAbcFilePoolPtr());
178         pandaFileInfos_->MergeSafe(rtInfo.GetPandaFileInfos());
179     }
180     if (task && task->IsTerminate()) {
181         return;
182     }
183     if (decoder.LoadFull(abcFilePool_)) {
184         MergeSafe(decoder.GetPandaFileInfos());
185         SetRecordDetailInfos(decoder.GetRecordDetailInfosPtr());
186     } else {
187         LOG_PGO(ERROR) << "fail to load ap: " << decoder.GetInPath();
188     }
189     if (task && task->IsTerminate()) {
190         return;
191     }
192     MergeSafe(rtInfo.GetRecordDetailInfos());
193     if (PGOTrace::GetInstance()->IsEnable()) {
194         PGOTrace::GetInstance()->SetMergeWithExistProfileTime(start.TotalSpentTime());
195     }
196 }
197 
GetSampleMutexLock()198 Mutex& PGOInfo::GetSampleMutexLock()
199 {
200     return sampleMutexLock_;
201 }
202 
GetConcurrentGuardValue()203 ConcurrentGuardValue& PGOInfo::GetConcurrentGuardValue()
204 {
205     return v_;
206 }
207 } // namespace panda::ecmascript::pgo
208