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