1e509ee18Sopenharmony_ci/* 2e509ee18Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 3e509ee18Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4e509ee18Sopenharmony_ci * you may not use this file except in compliance with the License. 5e509ee18Sopenharmony_ci * You may obtain a copy of the License at 6e509ee18Sopenharmony_ci * 7e509ee18Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8e509ee18Sopenharmony_ci * 9e509ee18Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10e509ee18Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11e509ee18Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12e509ee18Sopenharmony_ci * See the License for the specific language governing permissions and 13e509ee18Sopenharmony_ci * limitations under the License. 14e509ee18Sopenharmony_ci */ 15e509ee18Sopenharmony_ci 16e509ee18Sopenharmony_ci#include "agent/tracing_impl.h" 17e509ee18Sopenharmony_ci 18e509ee18Sopenharmony_ci#include "tooling/base/pt_events.h" 19e509ee18Sopenharmony_ci#include "protocol_channel.h" 20e509ee18Sopenharmony_ci 21e509ee18Sopenharmony_ci#include "ecmascript/napi/include/dfx_jsnapi.h" 22e509ee18Sopenharmony_ci 23e509ee18Sopenharmony_cinamespace panda::ecmascript::tooling { 24e509ee18Sopenharmony_civoid TracingImpl::DispatcherImpl::Dispatch(const DispatchRequest &request) 25e509ee18Sopenharmony_ci{ 26e509ee18Sopenharmony_ci Method method = GetMethodEnum(request.GetMethod()); 27e509ee18Sopenharmony_ci LOG_DEBUGGER(DEBUG) << "dispatch [" << request.GetMethod() << "] to TracingImpl"; 28e509ee18Sopenharmony_ci switch (method) { 29e509ee18Sopenharmony_ci case Method::END: 30e509ee18Sopenharmony_ci End(request); 31e509ee18Sopenharmony_ci break; 32e509ee18Sopenharmony_ci case Method::GET_CATEGORIES: 33e509ee18Sopenharmony_ci GetCategories(request); 34e509ee18Sopenharmony_ci break; 35e509ee18Sopenharmony_ci case Method::RECORD_CLOCK_SYNC_MARKER: 36e509ee18Sopenharmony_ci RecordClockSyncMarker(request); 37e509ee18Sopenharmony_ci break; 38e509ee18Sopenharmony_ci case Method::REQUEST_MEMORY_DUMP: 39e509ee18Sopenharmony_ci RequestMemoryDump(request); 40e509ee18Sopenharmony_ci break; 41e509ee18Sopenharmony_ci case Method::START: 42e509ee18Sopenharmony_ci Start(request); 43e509ee18Sopenharmony_ci break; 44e509ee18Sopenharmony_ci default: 45e509ee18Sopenharmony_ci SendResponse(request, DispatchResponse::Fail("Unknown method: " + request.GetMethod())); 46e509ee18Sopenharmony_ci break; 47e509ee18Sopenharmony_ci } 48e509ee18Sopenharmony_ci} 49e509ee18Sopenharmony_ci 50e509ee18Sopenharmony_ciTracingImpl::DispatcherImpl::Method TracingImpl::DispatcherImpl::GetMethodEnum(const std::string& method) 51e509ee18Sopenharmony_ci{ 52e509ee18Sopenharmony_ci if (method == "end") { 53e509ee18Sopenharmony_ci return Method::END; 54e509ee18Sopenharmony_ci } else if (method == "getCategories") { 55e509ee18Sopenharmony_ci return Method::GET_CATEGORIES; 56e509ee18Sopenharmony_ci } else if (method == "recordClockSyncMarker") { 57e509ee18Sopenharmony_ci return Method::RECORD_CLOCK_SYNC_MARKER; 58e509ee18Sopenharmony_ci } else if (method == "requestMemoryDump") { 59e509ee18Sopenharmony_ci return Method::REQUEST_MEMORY_DUMP; 60e509ee18Sopenharmony_ci } else if (method == "start") { 61e509ee18Sopenharmony_ci return Method::START; 62e509ee18Sopenharmony_ci } else { 63e509ee18Sopenharmony_ci return Method::UNKNOWN; 64e509ee18Sopenharmony_ci } 65e509ee18Sopenharmony_ci} 66e509ee18Sopenharmony_ci 67e509ee18Sopenharmony_civoid TracingImpl::DispatcherImpl::End(const DispatchRequest &request) 68e509ee18Sopenharmony_ci{ 69e509ee18Sopenharmony_ci auto traceEvents = tracing_->End(); 70e509ee18Sopenharmony_ci if (traceEvents == nullptr) { 71e509ee18Sopenharmony_ci LOG_DEBUGGER(ERROR) << "Transfer DFXJSNApi::StopTracing is failure"; 72e509ee18Sopenharmony_ci SendResponse(request, DispatchResponse::Fail("Stop is failure")); 73e509ee18Sopenharmony_ci return; 74e509ee18Sopenharmony_ci } 75e509ee18Sopenharmony_ci SendResponse(request, DispatchResponse::Ok()); 76e509ee18Sopenharmony_ci 77e509ee18Sopenharmony_ci tracing_->frontend_.DataCollected(std::move(traceEvents)); 78e509ee18Sopenharmony_ci tracing_->frontend_.TracingComplete(); 79e509ee18Sopenharmony_ci} 80e509ee18Sopenharmony_ci 81e509ee18Sopenharmony_civoid TracingImpl::DispatcherImpl::GetCategories(const DispatchRequest &request) 82e509ee18Sopenharmony_ci{ 83e509ee18Sopenharmony_ci std::vector<std::string> categories; 84e509ee18Sopenharmony_ci DispatchResponse response = tracing_->GetCategories(categories); 85e509ee18Sopenharmony_ci SendResponse(request, response); 86e509ee18Sopenharmony_ci} 87e509ee18Sopenharmony_ci 88e509ee18Sopenharmony_civoid TracingImpl::DispatcherImpl::RecordClockSyncMarker(const DispatchRequest &request) 89e509ee18Sopenharmony_ci{ 90e509ee18Sopenharmony_ci std::string syncId; 91e509ee18Sopenharmony_ci DispatchResponse response = tracing_->RecordClockSyncMarker(syncId); 92e509ee18Sopenharmony_ci SendResponse(request, response); 93e509ee18Sopenharmony_ci} 94e509ee18Sopenharmony_ci 95e509ee18Sopenharmony_civoid TracingImpl::DispatcherImpl::RequestMemoryDump(const DispatchRequest &request) 96e509ee18Sopenharmony_ci{ 97e509ee18Sopenharmony_ci std::unique_ptr<RequestMemoryDumpParams> params = 98e509ee18Sopenharmony_ci RequestMemoryDumpParams::Create(request.GetParams()); 99e509ee18Sopenharmony_ci std::string dumpGuid; 100e509ee18Sopenharmony_ci bool success = false; 101e509ee18Sopenharmony_ci DispatchResponse response = tracing_->RequestMemoryDump(std::move(params), dumpGuid, success); 102e509ee18Sopenharmony_ci SendResponse(request, response); 103e509ee18Sopenharmony_ci} 104e509ee18Sopenharmony_ci 105e509ee18Sopenharmony_civoid TracingImpl::DispatcherImpl::Start(const DispatchRequest &request) 106e509ee18Sopenharmony_ci{ 107e509ee18Sopenharmony_ci std::unique_ptr<StartParams> params = 108e509ee18Sopenharmony_ci StartParams::Create(request.GetParams()); 109e509ee18Sopenharmony_ci DispatchResponse response = tracing_->Start(std::move(params)); 110e509ee18Sopenharmony_ci SendResponse(request, response); 111e509ee18Sopenharmony_ci} 112e509ee18Sopenharmony_ci 113e509ee18Sopenharmony_cibool TracingImpl::Frontend::AllowNotify() const 114e509ee18Sopenharmony_ci{ 115e509ee18Sopenharmony_ci return channel_ != nullptr; 116e509ee18Sopenharmony_ci} 117e509ee18Sopenharmony_ci 118e509ee18Sopenharmony_civoid TracingImpl::Frontend::BufferUsage(double percentFull, int32_t eventCount, double value) 119e509ee18Sopenharmony_ci{ 120e509ee18Sopenharmony_ci if (!AllowNotify()) { 121e509ee18Sopenharmony_ci return; 122e509ee18Sopenharmony_ci } 123e509ee18Sopenharmony_ci 124e509ee18Sopenharmony_ci tooling::BufferUsage bufferUsage; 125e509ee18Sopenharmony_ci bufferUsage.SetPercentFull(percentFull).SetEventCount(eventCount).SetValue(value); 126e509ee18Sopenharmony_ci channel_->SendNotification(bufferUsage); 127e509ee18Sopenharmony_ci} 128e509ee18Sopenharmony_ci 129e509ee18Sopenharmony_civoid TracingImpl::Frontend::DataCollected(std::unique_ptr<std::vector<TraceEvent>> traceEvents) 130e509ee18Sopenharmony_ci{ 131e509ee18Sopenharmony_ci if (!AllowNotify()) { 132e509ee18Sopenharmony_ci return; 133e509ee18Sopenharmony_ci } 134e509ee18Sopenharmony_ci 135e509ee18Sopenharmony_ci tooling::DataCollected dataCollected; 136e509ee18Sopenharmony_ci dataCollected.SetTraceEvents(std::move(traceEvents)); 137e509ee18Sopenharmony_ci 138e509ee18Sopenharmony_ci channel_->SendNotification(dataCollected); 139e509ee18Sopenharmony_ci} 140e509ee18Sopenharmony_ci 141e509ee18Sopenharmony_civoid TracingImpl::Frontend::TracingComplete() 142e509ee18Sopenharmony_ci{ 143e509ee18Sopenharmony_ci if (!AllowNotify()) { 144e509ee18Sopenharmony_ci return; 145e509ee18Sopenharmony_ci } 146e509ee18Sopenharmony_ci 147e509ee18Sopenharmony_ci tooling::TracingComplete tracingComplete; 148e509ee18Sopenharmony_ci channel_->SendNotification(tracingComplete); 149e509ee18Sopenharmony_ci} 150e509ee18Sopenharmony_ci 151e509ee18Sopenharmony_cistd::unique_ptr<std::vector<TraceEvent>> TracingImpl::End() 152e509ee18Sopenharmony_ci{ 153e509ee18Sopenharmony_ci#if defined(ECMASCRIPT_SUPPORT_TRACING) 154e509ee18Sopenharmony_ci uv_timer_stop(&handle_); 155e509ee18Sopenharmony_ci#endif 156e509ee18Sopenharmony_ci auto traceEvents = panda::DFXJSNApi::StopTracing(vm_); 157e509ee18Sopenharmony_ci return traceEvents; 158e509ee18Sopenharmony_ci} 159e509ee18Sopenharmony_ci 160e509ee18Sopenharmony_ciDispatchResponse TracingImpl::GetCategories([[maybe_unused]] std::vector<std::string> categories) 161e509ee18Sopenharmony_ci{ 162e509ee18Sopenharmony_ci return DispatchResponse::Fail("GetCategories not support now."); 163e509ee18Sopenharmony_ci} 164e509ee18Sopenharmony_ci 165e509ee18Sopenharmony_ciDispatchResponse TracingImpl::RecordClockSyncMarker([[maybe_unused]] std::string syncId) 166e509ee18Sopenharmony_ci{ 167e509ee18Sopenharmony_ci return DispatchResponse::Fail("RecordClockSyncMarker not support now."); 168e509ee18Sopenharmony_ci} 169e509ee18Sopenharmony_ci 170e509ee18Sopenharmony_ciDispatchResponse TracingImpl::RequestMemoryDump([[maybe_unused]] std::unique_ptr<RequestMemoryDumpParams> params, 171e509ee18Sopenharmony_ci [[maybe_unused]] std::string dumpGuid, [[maybe_unused]] bool success) 172e509ee18Sopenharmony_ci{ 173e509ee18Sopenharmony_ci return DispatchResponse::Fail("RequestMemoryDump not support now."); 174e509ee18Sopenharmony_ci} 175e509ee18Sopenharmony_ci 176e509ee18Sopenharmony_ciDispatchResponse TracingImpl::Start(std::unique_ptr<StartParams> params) 177e509ee18Sopenharmony_ci{ 178e509ee18Sopenharmony_ci std::string categories = params->GetCategories(); 179e509ee18Sopenharmony_ci if (!panda::DFXJSNApi::StartTracing(vm_, categories)) { 180e509ee18Sopenharmony_ci return DispatchResponse::Fail("Start tracing failed"); 181e509ee18Sopenharmony_ci } 182e509ee18Sopenharmony_ci 183e509ee18Sopenharmony_ci#if defined(ECMASCRIPT_SUPPORT_TRACING) 184e509ee18Sopenharmony_ci if (params->HasBufferUsageReportingInterval()) { 185e509ee18Sopenharmony_ci LOG_DEBUGGER(ERROR) << "HasBufferUsageReportingInterval " << params->GetBufferUsageReportingInterval(); 186e509ee18Sopenharmony_ci if (uv_is_active(reinterpret_cast<uv_handle_t*>(&handle_))) { 187e509ee18Sopenharmony_ci LOG_DEBUGGER(ERROR) << "uv_is_active!!!"; 188e509ee18Sopenharmony_ci return DispatchResponse::Ok(); 189e509ee18Sopenharmony_ci } 190e509ee18Sopenharmony_ci 191e509ee18Sopenharmony_ci uv_loop_t *loop = reinterpret_cast<uv_loop_t *>(vm_->GetLoop()); 192e509ee18Sopenharmony_ci if (loop == nullptr) { 193e509ee18Sopenharmony_ci return DispatchResponse::Fail("Loop is nullptr"); 194e509ee18Sopenharmony_ci } 195e509ee18Sopenharmony_ci uv_timer_init(loop, &handle_); 196e509ee18Sopenharmony_ci handle_.data = this; 197e509ee18Sopenharmony_ci uv_timer_start(&handle_, TracingBufferUsageReport, 0, params->GetBufferUsageReportingInterval()); 198e509ee18Sopenharmony_ci if (DebuggerApi::IsMainThread()) { 199e509ee18Sopenharmony_ci uv_async_send(&loop->wq_async); 200e509ee18Sopenharmony_ci } else { 201e509ee18Sopenharmony_ci uv_work_t *work = new uv_work_t; 202e509ee18Sopenharmony_ci uv_queue_work(loop, work, [](uv_work_t *) { }, [](uv_work_t *work, int32_t) { delete work; }); 203e509ee18Sopenharmony_ci } 204e509ee18Sopenharmony_ci } 205e509ee18Sopenharmony_ci#endif 206e509ee18Sopenharmony_ci return DispatchResponse::Ok(); 207e509ee18Sopenharmony_ci} 208e509ee18Sopenharmony_ci 209e509ee18Sopenharmony_ci#if defined(ECMASCRIPT_SUPPORT_TRACING) 210e509ee18Sopenharmony_civoid TracingImpl::TracingBufferUsageReport(uv_timer_t* handle) 211e509ee18Sopenharmony_ci{ 212e509ee18Sopenharmony_ci TracingImpl *tracing = static_cast<TracingImpl *>(handle->data); 213e509ee18Sopenharmony_ci if (tracing == nullptr) { 214e509ee18Sopenharmony_ci LOG_DEBUGGER(ERROR) << "tracing == nullptr"; 215e509ee18Sopenharmony_ci return; 216e509ee18Sopenharmony_ci } 217e509ee18Sopenharmony_ci 218e509ee18Sopenharmony_ci double percentFull = 0.0; 219e509ee18Sopenharmony_ci uint32_t eventCount = 0; 220e509ee18Sopenharmony_ci double value = 0.0; 221e509ee18Sopenharmony_ci panda::DFXJSNApi::GetTracingBufferUseage(tracing->vm_, percentFull, eventCount, value); 222e509ee18Sopenharmony_ci tracing->frontend_.BufferUsage(percentFull, eventCount, value); 223e509ee18Sopenharmony_ci} 224e509ee18Sopenharmony_ci#endif 225e509ee18Sopenharmony_ci} // namespace panda::ecmascript::tooling