1 /*
2 * Copyright (c) 2021 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 "agent/profiler_impl.h"
17
18 #include "tooling/base/pt_events.h"
19 #include "protocol_channel.h"
20 #include "ecmascript/debugger/debugger_api.h"
21
22 #include "ecmascript/napi/include/dfx_jsnapi.h"
23
24 namespace panda::ecmascript::tooling {
25 // Whenever adding a new protocol which is not a standard CDP protocol,
26 // must add its methodName to the profilerProtocolList
InitializeExtendedProtocolsList()27 void ProfilerImpl::InitializeExtendedProtocolsList()
28 {
29 std::vector<std::string> profilerProtocolList {
30 "startTypeProfile",
31 "stopTypeProfile",
32 "takeTypeProfile",
33 "enableSerializationTimeoutCheck",
34 "disableSerializationTimeoutCheck"
35 };
36 profilerExtendedProtocols_ = std::move(profilerProtocolList);
37 }
38
Dispatch(const DispatchRequest & request)39 void ProfilerImpl::DispatcherImpl::Dispatch(const DispatchRequest &request)
40 {
41 Method method = GetMethodEnum(request.GetMethod());
42 LOG_DEBUGGER(DEBUG) << "dispatch [" << request.GetMethod() << "] to ProfilerImpl";
43 switch (method) {
44 case Method::DISABLE:
45 Disable(request);
46 break;
47 case Method::ENABLE:
48 Enable(request);
49 break;
50 case Method::START:
51 Start(request);
52 break;
53 case Method::STOP:
54 Stop(request);
55 break;
56 case Method::SET_SAMPLING_INTERVAL:
57 SetSamplingInterval(request);
58 break;
59 case Method::GET_BEST_EFFORT_COVERAGE:
60 GetBestEffortCoverage(request);
61 break;
62 case Method::STOP_PRECISE_COVERAGE:
63 StopPreciseCoverage(request);
64 break;
65 case Method::TAKE_PRECISE_COVERAGE:
66 TakePreciseCoverage(request);
67 break;
68 case Method::START_PRECISE_COVERAGE:
69 StartPreciseCoverage(request);
70 break;
71 case Method::START_TYPE_PROFILE:
72 StartTypeProfile(request);
73 break;
74 case Method::STOP_TYPE_PROFILE:
75 StopTypeProfile(request);
76 break;
77 case Method::TAKE_TYPE_PROFILE:
78 TakeTypeProfile(request);
79 break;
80 case Method::ENABLE_SERIALIZATION_TIMEOUT_CHECK:
81 EnableSerializationTimeoutCheck(request);
82 break;
83 case Method::DISABLE_SERIALIZATION_TIMEOUT_CHECK:
84 DisableSerializationTimeoutCheck(request);
85 break;
86 default:
87 SendResponse(request, DispatchResponse::Fail("Unknown method: " + request.GetMethod()));
88 break;
89 }
90 }
91
GetMethodEnum(const std::string & method)92 ProfilerImpl::DispatcherImpl::Method ProfilerImpl::DispatcherImpl::GetMethodEnum(const std::string& method)
93 {
94 if (method == "disable") {
95 return Method::DISABLE;
96 } else if (method == "enable") {
97 return Method::ENABLE;
98 } else if (method == "start") {
99 return Method::START;
100 } else if (method == "stop") {
101 return Method::STOP;
102 } else if (method == "setSamplingInterval") {
103 return Method::SET_SAMPLING_INTERVAL;
104 } else if (method == "getBestEffortCoverage") {
105 return Method::GET_BEST_EFFORT_COVERAGE;
106 } else if (method == "stopPreciseCoverage") {
107 return Method::STOP_PRECISE_COVERAGE;
108 } else if (method == "takePreciseCoverage") {
109 return Method::TAKE_PRECISE_COVERAGE;
110 } else if (method == "startPreciseCoverage") {
111 return Method::START_PRECISE_COVERAGE;
112 } else if (method == "startTypeProfile") {
113 return Method::START_TYPE_PROFILE;
114 } else if (method == "stopTypeProfile") {
115 return Method::STOP_TYPE_PROFILE;
116 } else if (method == "takeTypeProfile") {
117 return Method::TAKE_TYPE_PROFILE;
118 } else if (method == "enableSerializationTimeoutCheck") {
119 return Method::ENABLE_SERIALIZATION_TIMEOUT_CHECK;
120 } else if (method == "disableSerializationTimeoutCheck") {
121 return Method::DISABLE_SERIALIZATION_TIMEOUT_CHECK;
122 } else {
123 return Method::UNKNOWN;
124 }
125 }
126
Disable(const DispatchRequest & request)127 void ProfilerImpl::DispatcherImpl::Disable(const DispatchRequest &request)
128 {
129 DispatchResponse response = profiler_->Disable();
130 SendResponse(request, response);
131 }
132
Enable(const DispatchRequest & request)133 void ProfilerImpl::DispatcherImpl::Enable(const DispatchRequest &request)
134 {
135 DispatchResponse response = profiler_->Enable();
136 profiler_->InitializeExtendedProtocolsList();
137 EnableReturns result(profiler_->profilerExtendedProtocols_);
138 SendResponse(request, response, result);
139 }
140
Start(const DispatchRequest & request)141 void ProfilerImpl::DispatcherImpl::Start(const DispatchRequest &request)
142 {
143 DispatchResponse response = profiler_->Start();
144 SendResponse(request, response);
145 }
146
Stop(const DispatchRequest & request)147 void ProfilerImpl::DispatcherImpl::Stop(const DispatchRequest &request)
148 {
149 std::unique_ptr<Profile> profile;
150 DispatchResponse response = profiler_->Stop(&profile);
151 if (profile == nullptr) {
152 SendResponse(request, response);
153 return;
154 }
155
156 StopReturns result(std::move(profile));
157 SendResponse(request, response, result);
158 }
159
EnableSerializationTimeoutCheck(const DispatchRequest & request)160 void ProfilerImpl::DispatcherImpl::EnableSerializationTimeoutCheck(const DispatchRequest &request)
161 {
162 std::unique_ptr<SeriliazationTimeoutCheckEnableParams> params =
163 SeriliazationTimeoutCheckEnableParams::Create(request.GetParams());
164 if (params == nullptr) {
165 SendResponse(request, DispatchResponse::Fail("wrong params"));
166 return;
167 }
168 DispatchResponse response = profiler_->EnableSerializationTimeoutCheck(*params);
169 SendResponse(request, response);
170 }
171
DisableSerializationTimeoutCheck(const DispatchRequest & request)172 void ProfilerImpl::DispatcherImpl::DisableSerializationTimeoutCheck(const DispatchRequest &request)
173 {
174 DispatchResponse response = profiler_->DisableSerializationTimeoutCheck();
175 SendResponse(request, response);
176 }
177
SetSamplingInterval(const DispatchRequest & request)178 void ProfilerImpl::DispatcherImpl::SetSamplingInterval(const DispatchRequest &request)
179 {
180 std::unique_ptr<SetSamplingIntervalParams> params = SetSamplingIntervalParams::Create(request.GetParams());
181 if (params == nullptr) {
182 SendResponse(request, DispatchResponse::Fail("wrong params"));
183 return;
184 }
185 DispatchResponse response = profiler_->SetSamplingInterval(*params);
186 SendResponse(request, response);
187 }
188
GetBestEffortCoverage(const DispatchRequest & request)189 void ProfilerImpl::DispatcherImpl::GetBestEffortCoverage(const DispatchRequest &request)
190 {
191 DispatchResponse response = profiler_->GetBestEffortCoverage();
192 SendResponse(request, response);
193 }
194
StopPreciseCoverage(const DispatchRequest & request)195 void ProfilerImpl::DispatcherImpl::StopPreciseCoverage(const DispatchRequest &request)
196 {
197 DispatchResponse response = profiler_->StopPreciseCoverage();
198 SendResponse(request, response);
199 }
200
TakePreciseCoverage(const DispatchRequest & request)201 void ProfilerImpl::DispatcherImpl::TakePreciseCoverage(const DispatchRequest &request)
202 {
203 DispatchResponse response = profiler_->TakePreciseCoverage();
204 SendResponse(request, response);
205 }
206
StartPreciseCoverage(const DispatchRequest & request)207 void ProfilerImpl::DispatcherImpl::StartPreciseCoverage(const DispatchRequest &request)
208 {
209 std::unique_ptr<StartPreciseCoverageParams> params = StartPreciseCoverageParams::Create(request.GetParams());
210 if (params == nullptr) {
211 SendResponse(request, DispatchResponse::Fail("wrong params"));
212 return;
213 }
214 DispatchResponse response = profiler_->StartPreciseCoverage(*params);
215 SendResponse(request, response);
216 }
217
StartTypeProfile(const DispatchRequest & request)218 void ProfilerImpl::DispatcherImpl::StartTypeProfile(const DispatchRequest &request)
219 {
220 DispatchResponse response = profiler_->StartTypeProfile();
221 SendResponse(request, response);
222 }
223
StopTypeProfile(const DispatchRequest & request)224 void ProfilerImpl::DispatcherImpl::StopTypeProfile(const DispatchRequest &request)
225 {
226 DispatchResponse response = profiler_->StopTypeProfile();
227 SendResponse(request, response);
228 }
229
TakeTypeProfile(const DispatchRequest & request)230 void ProfilerImpl::DispatcherImpl::TakeTypeProfile(const DispatchRequest &request)
231 {
232 DispatchResponse response = profiler_->TakeTypeProfile();
233 SendResponse(request, response);
234 }
235
AllowNotify() const236 bool ProfilerImpl::Frontend::AllowNotify() const
237 {
238 return channel_ != nullptr;
239 }
240
PreciseCoverageDeltaUpdate()241 void ProfilerImpl::Frontend::PreciseCoverageDeltaUpdate()
242 {
243 if (!AllowNotify()) {
244 return;
245 }
246
247 tooling::PreciseCoverageDeltaUpdate preciseCoverageDeltaUpdate;
248 channel_->SendNotification(preciseCoverageDeltaUpdate);
249 }
250
Disable()251 DispatchResponse ProfilerImpl::Disable()
252 {
253 return DispatchResponse::Ok();
254 }
255
Enable()256 DispatchResponse ProfilerImpl::Enable()
257 {
258 return DispatchResponse::Ok();
259 }
260
Start()261 DispatchResponse ProfilerImpl::Start()
262 {
263 panda::JSNApi::SetProfilerState(vm_, true);
264 bool result = panda::DFXJSNApi::StartCpuProfilerForInfo(vm_);
265 if (!result) {
266 LOG_DEBUGGER(ERROR) << "ProfilerImpl::Start failed";
267 return DispatchResponse::Fail("Start is failure");
268 }
269 return DispatchResponse::Ok();
270 }
271
Stop(std::unique_ptr<Profile> * profile)272 DispatchResponse ProfilerImpl::Stop(std::unique_ptr<Profile> *profile)
273 {
274 auto profileInfo = panda::DFXJSNApi::StopCpuProfilerForInfo(vm_);
275 if (profileInfo == nullptr) {
276 LOG_DEBUGGER(ERROR) << "Transfer DFXJSNApi::StopCpuProfilerImpl is failure";
277 return DispatchResponse::Fail("Stop is failure");
278 }
279 *profile = Profile::FromProfileInfo(*profileInfo);
280 panda::JSNApi::SetProfilerState(vm_, false);
281 return DispatchResponse::Ok();
282 }
283
EnableSerializationTimeoutCheck(const SeriliazationTimeoutCheckEnableParams & params)284 DispatchResponse ProfilerImpl::EnableSerializationTimeoutCheck(const SeriliazationTimeoutCheckEnableParams ¶ms)
285 {
286 int32_t threshhold = params.GetThreshold();
287 panda::DFXJSNApi::EnableSeriliazationTimeoutCheck(vm_, threshhold);
288 LOG_DEBUGGER(DEBUG) << "Profiler Serialization timeout check is enabled with threshhold: " << threshhold;
289 return DispatchResponse::Ok();
290 }
291
DisableSerializationTimeoutCheck()292 DispatchResponse ProfilerImpl::DisableSerializationTimeoutCheck()
293 {
294 panda::DFXJSNApi::DisableSeriliazationTimeoutCheck(vm_);
295 LOG_DEBUGGER(DEBUG) << "Profiler Serialization check is disabled";
296 return DispatchResponse::Ok();
297 }
298
SetSamplingInterval(const SetSamplingIntervalParams & params)299 DispatchResponse ProfilerImpl::SetSamplingInterval(const SetSamplingIntervalParams ¶ms)
300 {
301 panda::DFXJSNApi::SetCpuSamplingInterval(vm_, params.GetInterval());
302 return DispatchResponse::Ok();
303 }
304
GetBestEffortCoverage()305 DispatchResponse ProfilerImpl::GetBestEffortCoverage()
306 {
307 return DispatchResponse::Fail("GetBestEffortCoverage not support now");
308 }
309
StopPreciseCoverage()310 DispatchResponse ProfilerImpl::StopPreciseCoverage()
311 {
312 return DispatchResponse::Fail("StopPreciseCoverage not support now");
313 }
314
TakePreciseCoverage()315 DispatchResponse ProfilerImpl::TakePreciseCoverage()
316 {
317 return DispatchResponse::Fail("TakePreciseCoverage not support now");
318 }
319
StartPreciseCoverage(const StartPreciseCoverageParams & params)320 DispatchResponse ProfilerImpl::StartPreciseCoverage([[maybe_unused]] const StartPreciseCoverageParams ¶ms)
321 {
322 return DispatchResponse::Fail("StartPreciseCoverage not support now");
323 }
324
StartTypeProfile()325 DispatchResponse ProfilerImpl::StartTypeProfile()
326 {
327 return DispatchResponse::Fail("StartTypeProfile not support now");
328 }
329
StopTypeProfile()330 DispatchResponse ProfilerImpl::StopTypeProfile()
331 {
332 return DispatchResponse::Fail("StopTypeProfile not support now");
333 }
334
TakeTypeProfile()335 DispatchResponse ProfilerImpl::TakeTypeProfile()
336 {
337 return DispatchResponse::Fail("TakeTypeProfile not support now");
338 }
339 } // namespace panda::ecmascript::tooling
340