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 24namespace panda::ecmascript::tooling { 25// Whenever adding a new protocol which is not a standard CDP protocol, 26// must add its methodName to the profilerProtocolList 27void 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 39void 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 92ProfilerImpl::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 127void ProfilerImpl::DispatcherImpl::Disable(const DispatchRequest &request) 128{ 129 DispatchResponse response = profiler_->Disable(); 130 SendResponse(request, response); 131} 132 133void 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 141void ProfilerImpl::DispatcherImpl::Start(const DispatchRequest &request) 142{ 143 DispatchResponse response = profiler_->Start(); 144 SendResponse(request, response); 145} 146 147void 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 160void 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 172void ProfilerImpl::DispatcherImpl::DisableSerializationTimeoutCheck(const DispatchRequest &request) 173{ 174 DispatchResponse response = profiler_->DisableSerializationTimeoutCheck(); 175 SendResponse(request, response); 176} 177 178void 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 189void ProfilerImpl::DispatcherImpl::GetBestEffortCoverage(const DispatchRequest &request) 190{ 191 DispatchResponse response = profiler_->GetBestEffortCoverage(); 192 SendResponse(request, response); 193} 194 195void ProfilerImpl::DispatcherImpl::StopPreciseCoverage(const DispatchRequest &request) 196{ 197 DispatchResponse response = profiler_->StopPreciseCoverage(); 198 SendResponse(request, response); 199} 200 201void ProfilerImpl::DispatcherImpl::TakePreciseCoverage(const DispatchRequest &request) 202{ 203 DispatchResponse response = profiler_->TakePreciseCoverage(); 204 SendResponse(request, response); 205} 206 207void 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 218void ProfilerImpl::DispatcherImpl::StartTypeProfile(const DispatchRequest &request) 219{ 220 DispatchResponse response = profiler_->StartTypeProfile(); 221 SendResponse(request, response); 222} 223 224void ProfilerImpl::DispatcherImpl::StopTypeProfile(const DispatchRequest &request) 225{ 226 DispatchResponse response = profiler_->StopTypeProfile(); 227 SendResponse(request, response); 228} 229 230void ProfilerImpl::DispatcherImpl::TakeTypeProfile(const DispatchRequest &request) 231{ 232 DispatchResponse response = profiler_->TakeTypeProfile(); 233 SendResponse(request, response); 234} 235 236bool ProfilerImpl::Frontend::AllowNotify() const 237{ 238 return channel_ != nullptr; 239} 240 241void ProfilerImpl::Frontend::PreciseCoverageDeltaUpdate() 242{ 243 if (!AllowNotify()) { 244 return; 245 } 246 247 tooling::PreciseCoverageDeltaUpdate preciseCoverageDeltaUpdate; 248 channel_->SendNotification(preciseCoverageDeltaUpdate); 249} 250 251DispatchResponse ProfilerImpl::Disable() 252{ 253 return DispatchResponse::Ok(); 254} 255 256DispatchResponse ProfilerImpl::Enable() 257{ 258 return DispatchResponse::Ok(); 259} 260 261DispatchResponse 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 272DispatchResponse 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 284DispatchResponse 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 292DispatchResponse ProfilerImpl::DisableSerializationTimeoutCheck() 293{ 294 panda::DFXJSNApi::DisableSeriliazationTimeoutCheck(vm_); 295 LOG_DEBUGGER(DEBUG) << "Profiler Serialization check is disabled"; 296 return DispatchResponse::Ok(); 297} 298 299DispatchResponse ProfilerImpl::SetSamplingInterval(const SetSamplingIntervalParams ¶ms) 300{ 301 panda::DFXJSNApi::SetCpuSamplingInterval(vm_, params.GetInterval()); 302 return DispatchResponse::Ok(); 303} 304 305DispatchResponse ProfilerImpl::GetBestEffortCoverage() 306{ 307 return DispatchResponse::Fail("GetBestEffortCoverage not support now"); 308} 309 310DispatchResponse ProfilerImpl::StopPreciseCoverage() 311{ 312 return DispatchResponse::Fail("StopPreciseCoverage not support now"); 313} 314 315DispatchResponse ProfilerImpl::TakePreciseCoverage() 316{ 317 return DispatchResponse::Fail("TakePreciseCoverage not support now"); 318} 319 320DispatchResponse ProfilerImpl::StartPreciseCoverage([[maybe_unused]] const StartPreciseCoverageParams ¶ms) 321{ 322 return DispatchResponse::Fail("StartPreciseCoverage not support now"); 323} 324 325DispatchResponse ProfilerImpl::StartTypeProfile() 326{ 327 return DispatchResponse::Fail("StartTypeProfile not support now"); 328} 329 330DispatchResponse ProfilerImpl::StopTypeProfile() 331{ 332 return DispatchResponse::Fail("StopTypeProfile not support now"); 333} 334 335DispatchResponse ProfilerImpl::TakeTypeProfile() 336{ 337 return DispatchResponse::Fail("TakeTypeProfile not support now"); 338} 339} // namespace panda::ecmascript::tooling 340