• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &params)
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 &params)
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 &params)
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