1 /*
2 * Copyright (c) 2021-2024 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 <semaphore.h>
17 #include "ecmascript/napi/include/dfx_jsnapi.h"
18
19 #include "ecmascript/base/block_hook_scope.h"
20 #include "ecmascript/builtins/builtins_ark_tools.h"
21 #include "ecmascript/checkpoint/thread_state_transition.h"
22 #include "ecmascript/debugger/debugger_api.h"
23 #include "ecmascript/debugger/js_debugger_manager.h"
24 #include "ecmascript/dfx/stackinfo/js_stackinfo.h"
25 #include "ecmascript/dfx/tracing/tracing.h"
26 #include "ecmascript/mem/heap-inl.h"
27 #include "ecmascript/jit/jit.h"
28 #include "ecmascript/dfx/vm_thread_control.h"
29
30 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
31 #include "ecmascript/dfx/cpu_profiler/cpu_profiler.h"
32 #include "ecmascript/dfx/cpu_profiler/samples_record.h"
33 #endif
34 #if defined(ENABLE_DUMP_IN_FAULTLOG)
35 #include "faultloggerd_client.h"
36 #include "uv.h"
37 #endif
38
39 namespace panda {
40 using ecmascript::CString;
41 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
42 using BuiltinsArkTools = ecmascript::builtins::BuiltinsArkTools;
43 using ecmascript::CpuProfiler;
44 #endif
45 using ecmascript::EcmaString;
46 using ecmascript::JSTaggedValue;
47 using ecmascript::GCStats;
48 template<typename T>
49 using JSHandle = ecmascript::JSHandle<T>;
50 using ecmascript::FileStream;
51 using ecmascript::FileDescriptorStream;
52 using ecmascript::CMap;
53 using ecmascript::Tracing;
54 using ecmascript::DumpSnapShotOption;
55 sem_t g_heapdumpCnt;
56
DumpHeapSnapshot(const EcmaVM * vm,const std::string & path,const DumpSnapShotOption & dumpOption)57 void DFXJSNApi::DumpHeapSnapshot([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] const std::string &path,
58 [[maybe_unused]] const DumpSnapShotOption &dumpOption)
59 {
60 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
61 FileStream stream(path);
62 DumpHeapSnapshot(vm, &stream, dumpOption);
63 #else
64 LOG_ECMA(ERROR) << "Not support arkcompiler heap snapshot";
65 #endif
66 }
67
68 // IDE interface.
DumpHeapSnapshot(const EcmaVM * vm,Stream * stream,const DumpSnapShotOption & dumpOption,Progress * progress)69 void DFXJSNApi::DumpHeapSnapshot([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] Stream *stream,
70 [[maybe_unused]] const DumpSnapShotOption &dumpOption,
71 [[maybe_unused]] Progress *progress)
72 {
73 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
74 ecmascript::HeapProfilerInterface *heapProfile = ecmascript::HeapProfilerInterface::GetInstance(
75 const_cast<EcmaVM *>(vm));
76 heapProfile->DumpHeapSnapshot(stream, dumpOption, progress);
77 #else
78 LOG_ECMA(ERROR) << "Not support arkcompiler heap snapshot";
79 #endif
80 }
81
82 [[maybe_unused]] static uint8_t killCount = 0;
83
DumpCpuProfile(const EcmaVM * vm)84 void DFXJSNApi::DumpCpuProfile([[maybe_unused]] const EcmaVM *vm)
85 {
86 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
87 #if defined(ENABLE_DUMP_IN_FAULTLOG)
88 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
89 // for CpuProfiler kill contral
90 if (DFXJSNApi::StopCpuProfilerForColdStart(vm)) {
91 return;
92 }
93
94 (void)killCount;
95 if (DFXJSNApi::CpuProfilerSamplingAnyTime(vm)) {
96 killCount++;
97 return;
98 }
99 #endif // ECMASCRIPT_SUPPORT_CPUPROFILER
100 #endif // ENABLE_DUMP_IN_FAULTLOG
101 #endif // ECMASCRIPT_SUPPORT_SNAPSHOT
102 }
103
104 // kill -39.
DumpHeapSnapshot(const EcmaVM * vm,const DumpSnapShotOption & dumpOption)105 void DFXJSNApi::DumpHeapSnapshot([[maybe_unused]] const EcmaVM *vm,
106 [[maybe_unused]] const DumpSnapShotOption &dumpOption)
107 {
108 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
109 #if defined(ENABLE_DUMP_IN_FAULTLOG)
110 sem_wait(&g_heapdumpCnt);
111 auto &options = const_cast<EcmaVM *>(vm)->GetJSOptions();
112 options.SwitchStartGlobalLeakCheck();
113 if (options.EnableGlobalLeakCheck() && options.IsStartGlobalLeakCheck()) {
114 int32_t stackTraceFd = RequestFileDescriptor(static_cast<int32_t>(FaultLoggerType::JS_STACKTRACE));
115 if (stackTraceFd < 0) {
116 options.SwitchStartGlobalLeakCheck();
117 } else {
118 vm->GetJSThread()->SetStackTraceFd(stackTraceFd);
119 }
120 }
121
122 // Write in faultlog for heap leak.
123 int32_t fd;
124 if (dumpOption.isDumpOOM && dumpOption.dumpFormat == DumpFormat::BINARY) {
125 fd = RequestFileDescriptor(static_cast<int32_t>(FaultLoggerType::JS_RAW_SNAPSHOT));
126 } else {
127 fd = RequestFileDescriptor(static_cast<int32_t>(FaultLoggerType::JS_HEAP_SNAPSHOT));
128 }
129 if (fd < 0) {
130 LOG_ECMA(ERROR) << "Write FD failed, fd" << fd;
131 return;
132 }
133 FileDescriptorStream stream(fd);
134 ecmascript::HeapProfilerInterface *heapProfile = ecmascript::HeapProfilerInterface::GetInstance(
135 const_cast<EcmaVM *>(vm));
136 heapProfile->DumpHeapSnapshot(&stream, dumpOption);
137
138 sem_post(&g_heapdumpCnt);
139 #endif // ENABLE_DUMP_IN_FAULTLOG
140 #else
141 LOG_ECMA(ERROR) << "Not support arkcompiler heap snapshot";
142 #endif // ECMASCRIPT_SUPPORT_SNAPSHOT
143 }
144
145 // tid = 0: dump all vm; tid != 0: dump tid vm, hidumper.
DumpHeapSnapshot(const EcmaVM * vm,const DumpSnapShotOption & dumpOption,uint32_t tid)146 void DFXJSNApi::DumpHeapSnapshot([[maybe_unused]] const EcmaVM *vm,
147 [[maybe_unused]] const DumpSnapShotOption &dumpOption, [[maybe_unused]] uint32_t tid)
148 {
149 const int THREAD_COUNT = 1;
150 if (vm->IsWorkerThread()) {
151 LOG_ECMA(ERROR) << "this is a workthread!";
152 return;
153 }
154 sem_init(&g_heapdumpCnt, 0, THREAD_COUNT);
155 uint32_t curTid = vm->GetTid();
156 LOG_ECMA(INFO) << "DumpHeapSnapshot tid " << tid << " curTid " << curTid;
157 DumpHeapSnapshotWithVm(vm, dumpOption, tid);
158 }
159
DumpHeapSnapshotWithVm(const EcmaVM * vm,const DumpSnapShotOption & dumpOption,uint32_t tid)160 void DFXJSNApi::DumpHeapSnapshotWithVm([[maybe_unused]] const EcmaVM *vm,
161 [[maybe_unused]] const DumpSnapShotOption &dumpOption,
162 [[maybe_unused]] uint32_t tid)
163 {
164 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
165 #if defined(ENABLE_DUMP_IN_FAULTLOG)
166 uv_loop_t *loop = reinterpret_cast<uv_loop_t *>(vm->GetLoop());
167 if (loop == nullptr || uv_loop_alive(loop) == 0) {
168 LOG_ECMA(ERROR) << "loop nullptr or uv_loop_alive dead";
169 return;
170 }
171 struct DumpForSnapShotStruct *dumpStruct = new DumpForSnapShotStruct();
172 dumpStruct->vm = vm;
173 dumpStruct->dumpOption = dumpOption;
174 uv_work_t *work = new(std::nothrow) uv_work_t;
175 if (work == nullptr) {
176 LOG_ECMA(ERROR) << "work nullptr";
177 delete dumpStruct;
178 return;
179 }
180 work->data = static_cast<void *>(dumpStruct);
181
182 uint32_t curTid = vm->GetTid();
183 int ret = 0;
184 if (tid == 0 || tid == curTid) {
185 ret = uv_queue_work(loop, work, [](uv_work_t *) {}, [](uv_work_t *work, int32_t) {
186 struct DumpForSnapShotStruct *dump = static_cast<struct DumpForSnapShotStruct *>(work->data);
187 DFXJSNApi::GetHeapPrepare(dump->vm);
188 DumpSnapShotOption dumpOption = dump->dumpOption;
189 DumpHeapSnapshot(dump->vm, dumpOption);
190 delete dump;
191 delete work;
192 });
193 } else {
194 delete dumpStruct;
195 delete work;
196 }
197
198 // dump worker vm
199 const_cast<EcmaVM *>(vm)->EnumerateWorkerVm([&](const EcmaVM *workerVm) -> void {
200 uint32_t curTid = workerVm->GetTid();
201 LOG_ECMA(INFO) << "DumpHeapSnapshot workthread curTid " << curTid;
202 DumpHeapSnapshotWithVm(workerVm, dumpOption, tid);
203 return;
204 });
205
206 if (ret != 0) {
207 LOG_ECMA(ERROR) << "uv_queue_work fail ret " << ret;
208 delete dumpStruct;
209 delete work;
210 }
211 #endif
212 #endif
213 }
214
GenerateHeapSnapshotByBinFile(const EcmaVM * vm,std::string & inputFilePath,std::string & outputPath)215 void DFXJSNApi::GenerateHeapSnapshotByBinFile([[maybe_unused]] const EcmaVM *vm,
216 [[maybe_unused]] std::string &inputFilePath,
217 [[maybe_unused]] std::string &outputPath)
218 {
219 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
220 auto *heapProfile = ecmascript::HeapProfilerInterface::GetInstance(const_cast<EcmaVM *>(vm));
221 heapProfile->GenerateHeapSnapshot(inputFilePath, outputPath);
222 #else
223 LOG_ECMA(ERROR) << "Not support GenerateHeapSnapshotByBinFile";
224 #endif // ECMASCRIPT_SUPPORT_SNAPSHOT
225 }
226
227 // tid = 0: TriggerGC all vm; tid != 0: TriggerGC tid vm
TriggerGC(const EcmaVM * vm,uint32_t tid)228 void DFXJSNApi::TriggerGC([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] uint32_t tid)
229 {
230 if (vm->IsWorkerThread()) {
231 LOG_ECMA(ERROR) << "this is a workthread!";
232 return;
233 }
234 // triggerGC host vm
235 uint32_t curTid = vm->GetTid();
236 LOG_ECMA(INFO) << "TriggerGC tid " << tid << " curTid " << curTid;
237 if (tid == 0 || tid == curTid) {
238 TriggerGCWithVm(vm);
239 }
240 // triggerGC worker vm
241 const_cast<EcmaVM *>(vm)->EnumerateWorkerVm([&](const EcmaVM *workerVm) -> void {
242 curTid = workerVm->GetTid();
243 LOG_ECMA(INFO) << "TriggerGC tid " << tid << " curTid " << curTid;
244 if (tid == 0 || tid == curTid) {
245 TriggerGCWithVm(workerVm);
246 return;
247 }
248 });
249 // triggerSharedGC
250 TriggerSharedGCWithVm(vm);
251 }
252
TriggerSharedGCWithVm(const EcmaVM * vm)253 void DFXJSNApi::TriggerSharedGCWithVm([[maybe_unused]] const EcmaVM *vm)
254 {
255 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
256 #if defined(ENABLE_DUMP_IN_FAULTLOG)
257 uv_loop_t *loop = reinterpret_cast<uv_loop_t *>(vm->GetLoop());
258 if (loop == nullptr) {
259 LOG_ECMA(ERROR) << "loop nullptr";
260 return;
261 }
262 if (uv_loop_alive(loop) == 0) {
263 LOG_ECMA(ERROR) << "uv_loop_alive dead";
264 return;
265 }
266 uv_work_t *work = new(std::nothrow) uv_work_t;
267 if (work == nullptr) {
268 LOG_ECMA(FATAL) << "DFXJSNApi::TriggerGCWithVm:work is nullptr";
269 return;
270 }
271 work->data = static_cast<void *>(const_cast<EcmaVM *>(vm));
272 int ret = uv_queue_work(loop, work, [](uv_work_t *) {}, [](uv_work_t *work, int32_t) {
273 EcmaVM *vm = static_cast<EcmaVM *>(work->data);
274 ecmascript::SharedHeap* sHeap = ecmascript::SharedHeap::GetInstance();
275 JSThread *thread = vm->GetJSThread();
276 ecmascript::ThreadManagedScope managedScope(thread);
277 sHeap->CollectGarbage<ecmascript::TriggerGCType::SHARED_GC, ecmascript::GCReason::TRIGGER_BY_MEM_TOOLS>(thread);
278 delete work;
279 });
280 if (ret != 0) {
281 LOG_ECMA(ERROR) << "uv_queue_work fail ret " << ret;
282 delete work;
283 }
284 #endif
285 #endif
286 }
287
TriggerGCWithVm(const EcmaVM * vm)288 void DFXJSNApi::TriggerGCWithVm([[maybe_unused]] const EcmaVM *vm)
289 {
290 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
291 #if defined(ENABLE_DUMP_IN_FAULTLOG)
292 uv_loop_t *loop = reinterpret_cast<uv_loop_t *>(vm->GetLoop());
293 if (loop == nullptr) {
294 LOG_ECMA(ERROR) << "loop nullptr";
295 return;
296 }
297 if (uv_loop_alive(loop) == 0) {
298 LOG_ECMA(ERROR) << "uv_loop_alive dead";
299 return;
300 }
301 uv_work_t *work = new(std::nothrow) uv_work_t;
302 if (work == nullptr) {
303 LOG_ECMA(FATAL) << "DFXJSNApi::TriggerGCWithVm:work is nullptr";
304 return;
305 }
306 work->data = static_cast<void *>(const_cast<EcmaVM *>(vm));
307 int ret = uv_queue_work(loop, work, [](uv_work_t *) {}, [](uv_work_t *work, int32_t) {
308 EcmaVM *vm = static_cast<EcmaVM *>(work->data);
309 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
310 vm->CollectGarbage(ecmascript::TriggerGCType::FULL_GC, ecmascript::GCReason::TRIGGER_BY_MEM_TOOLS);
311 delete work;
312 });
313 if (ret != 0) {
314 LOG_ECMA(ERROR) << "uv_queue_work fail ret " << ret;
315 delete work;
316 }
317 #endif
318 #endif
319 }
320
DestroyHeapProfiler(const EcmaVM * vm)321 void DFXJSNApi::DestroyHeapProfiler([[maybe_unused]] const EcmaVM *vm)
322 {
323 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
324 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
325 ecmascript::HeapProfilerInterface::Destroy(const_cast<EcmaVM *>(vm));
326 #else
327 LOG_ECMA(ERROR) << "Not support arkcompiler heap snapshot";
328 #endif
329 }
330
BuildNativeAndJsStackTrace(const EcmaVM * vm,std::string & stackTraceStr)331 bool DFXJSNApi::BuildNativeAndJsStackTrace(const EcmaVM *vm, std::string &stackTraceStr)
332 {
333 stackTraceStr = ecmascript::JsStackInfo::BuildJsStackTrace(vm->GetAssociatedJSThread(), true);
334 if (stackTraceStr.empty()) {
335 return false;
336 }
337 return true;
338 }
339
BuildJsStackTrace(const EcmaVM * vm,std::string & stackTraceStr)340 bool DFXJSNApi::BuildJsStackTrace(const EcmaVM *vm, std::string &stackTraceStr)
341 {
342 stackTraceStr = ecmascript::JsStackInfo::BuildJsStackTrace(vm->GetAssociatedJSThread(), false);
343 if (stackTraceStr.empty()) {
344 return false;
345 }
346 return true;
347 }
348
StartHeapTracking(const EcmaVM * vm,double timeInterval,bool isVmMode,Stream * stream,bool traceAllocation,bool newThread)349 bool DFXJSNApi::StartHeapTracking([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] double timeInterval,
350 [[maybe_unused]] bool isVmMode, [[maybe_unused]] Stream *stream,
351 [[maybe_unused]] bool traceAllocation, [[maybe_unused]] bool newThread)
352 {
353 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
354 ecmascript::base::BlockHookScope blockScope;
355 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
356 ecmascript::HeapProfilerInterface *heapProfile = ecmascript::HeapProfilerInterface::GetInstance(
357 const_cast<EcmaVM *>(vm));
358 return heapProfile->StartHeapTracking(timeInterval, isVmMode, stream, traceAllocation, newThread);
359 #else
360 LOG_ECMA(ERROR) << "Not support arkcompiler heap tracking";
361 return false;
362 #endif
363 }
364
UpdateHeapTracking(const EcmaVM * vm,Stream * stream)365 bool DFXJSNApi::UpdateHeapTracking([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] Stream *stream)
366 {
367 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
368 ecmascript::base::BlockHookScope blockScope;
369 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
370 ecmascript::HeapProfilerInterface *heapProfile = ecmascript::HeapProfilerInterface::GetInstance(
371 const_cast<EcmaVM *>(vm));
372 return heapProfile->UpdateHeapTracking(stream);
373 #else
374 LOG_ECMA(ERROR) << "Not support arkcompiler heap tracking";
375 return false;
376 #endif
377 }
378
StopHeapTracking(const EcmaVM * vm,const std::string & filePath,bool newThread)379 bool DFXJSNApi::StopHeapTracking([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] const std::string &filePath,
380 [[maybe_unused]] bool newThread)
381 {
382 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
383 FileStream stream(filePath);
384 return StopHeapTracking(vm, &stream, nullptr, newThread);
385 #else
386 LOG_ECMA(ERROR) << "Not support arkcompiler heap tracking";
387 return false;
388 #endif
389 }
390
StopHeapTracking(const EcmaVM * vm,Stream * stream,Progress * progress,bool newThread)391 bool DFXJSNApi::StopHeapTracking([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] Stream* stream,
392 [[maybe_unused]] Progress *progress, [[maybe_unused]] bool newThread)
393 {
394 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
395 ecmascript::base::BlockHookScope blockScope;
396 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
397 bool result = false;
398 ecmascript::HeapProfilerInterface *heapProfile = ecmascript::HeapProfilerInterface::GetInstance(
399 const_cast<EcmaVM *>(vm));
400 result = heapProfile->StopHeapTracking(stream, progress, newThread);
401 ecmascript::HeapProfilerInterface::Destroy(const_cast<EcmaVM *>(vm));
402 return result;
403 #else
404 LOG_ECMA(ERROR) << "Not support arkcompiler heap tracking";
405 return false;
406 #endif
407 }
408
PrintStatisticResult(const EcmaVM * vm)409 void DFXJSNApi::PrintStatisticResult(const EcmaVM *vm)
410 {
411 ecmascript::GCStats gcstats(vm->GetHeap());
412 gcstats.PrintStatisticResult();
413 }
414
StartRuntimeStat(EcmaVM * vm)415 void DFXJSNApi::StartRuntimeStat(EcmaVM *vm)
416 {
417 vm->GetJSThread()->GetCurrentEcmaContext()->SetRuntimeStatEnable(true);
418 }
419
StopRuntimeStat(EcmaVM * vm)420 void DFXJSNApi::StopRuntimeStat(EcmaVM *vm)
421 {
422 vm->GetJSThread()->GetCurrentEcmaContext()->SetRuntimeStatEnable(false);
423 }
424
GetArrayBufferSize(const EcmaVM * vm)425 size_t DFXJSNApi::GetArrayBufferSize(const EcmaVM *vm)
426 {
427 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
428 return vm->GetHeap()->GetArrayBufferSize();
429 }
430
GetHeapTotalSize(const EcmaVM * vm)431 size_t DFXJSNApi::GetHeapTotalSize(const EcmaVM *vm)
432 {
433 return vm->GetHeap()->GetCommittedSize();
434 }
435
GetHeapUsedSize(const EcmaVM * vm)436 size_t DFXJSNApi::GetHeapUsedSize(const EcmaVM *vm)
437 {
438 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
439 return vm->GetHeap()->GetLiveObjectSize();
440 }
441
GetHeapObjectSize(const EcmaVM * vm)442 size_t DFXJSNApi::GetHeapObjectSize(const EcmaVM *vm)
443 {
444 return vm->GetHeap()->GetHeapObjectSize();
445 }
446
GetHeapLimitSize(const EcmaVM * vm)447 size_t DFXJSNApi::GetHeapLimitSize(const EcmaVM *vm)
448 {
449 return vm->GetHeap()->GetHeapLimitSize();
450 }
451
GetProcessHeapLimitSize()452 size_t DFXJSNApi::GetProcessHeapLimitSize()
453 {
454 return ecmascript::MemMapAllocator::GetInstance()->GetCapacity();
455 }
456
GetGCCount(const EcmaVM * vm)457 size_t DFXJSNApi::GetGCCount(const EcmaVM *vm)
458 {
459 if (vm->IsWorkerThread()) {
460 return vm->GetEcmaGCStats()->GetGCCount();
461 }
462 return vm->GetEcmaGCStats()->GetGCCount() +
463 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetGCCount();
464 }
465
GetGCDuration(const EcmaVM * vm)466 size_t DFXJSNApi::GetGCDuration(const EcmaVM *vm)
467 {
468 if (vm->IsWorkerThread()) {
469 return vm->GetEcmaGCStats()->GetGCDuration();
470 }
471 return vm->GetEcmaGCStats()->GetGCDuration() +
472 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetGCDuration();
473 }
474
GetAccumulatedAllocateSize(const EcmaVM * vm)475 size_t DFXJSNApi::GetAccumulatedAllocateSize(const EcmaVM *vm)
476 {
477 if (vm->IsWorkerThread()) {
478 return vm->GetEcmaGCStats()->GetAccumulatedAllocateSize();
479 }
480 return vm->GetEcmaGCStats()->GetAccumulatedAllocateSize() +
481 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetAccumulatedAllocateSize();
482 }
483
GetAccumulatedFreeSize(const EcmaVM * vm)484 size_t DFXJSNApi::GetAccumulatedFreeSize(const EcmaVM *vm)
485 {
486 if (vm->IsWorkerThread()) {
487 return vm->GetEcmaGCStats()->GetAccumulatedFreeSize();
488 }
489 return vm->GetEcmaGCStats()->GetAccumulatedFreeSize() +
490 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetAccumulatedFreeSize();
491 }
492
GetFullGCLongTimeCount(const EcmaVM * vm)493 size_t DFXJSNApi::GetFullGCLongTimeCount(const EcmaVM *vm)
494 {
495 return vm->GetEcmaGCStats()->GetFullGCLongTimeCount();
496 }
497
GetHeapPrepare(const EcmaVM * vm)498 void DFXJSNApi::GetHeapPrepare(const EcmaVM *vm)
499 {
500 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
501 const_cast<ecmascript::Heap *>(vm->GetHeap())->GetHeapPrepare();
502 }
503
SetJsDumpThresholds(EcmaVM * vm,size_t thresholds)504 void DFXJSNApi::SetJsDumpThresholds([[maybe_unused]] EcmaVM *vm, [[maybe_unused]] size_t thresholds)
505 {
506 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT) && defined(PANDA_TARGET_OHOS) && defined(ENABLE_HISYSEVENT)
507 vm->GetHeap()->SetJsDumpThresholds(thresholds);
508 #else
509 LOG_ECMA(ERROR) << "Not support set jsdump thresholds";
510 #endif
511 }
512
SetAppFreezeFilterCallback(const EcmaVM * vm,AppFreezeFilterCallback cb)513 void DFXJSNApi::SetAppFreezeFilterCallback(const EcmaVM *vm, AppFreezeFilterCallback cb)
514 {
515 const_cast<ecmascript::Heap *>(vm->GetHeap())->SetAppFreezeFilterCallback(cb);
516 ecmascript::SharedHeap* sHeap = ecmascript::SharedHeap::GetInstance();
517 sHeap->SetAppFreezeFilterCallback(cb);
518 }
519
NotifyApplicationState(EcmaVM * vm,bool inBackground)520 void DFXJSNApi::NotifyApplicationState(EcmaVM *vm, bool inBackground)
521 {
522 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
523 const_cast<ecmascript::Heap *>(vm->GetHeap())->ChangeGCParams(inBackground);
524 ecmascript::Jit::GetInstance()->ChangeTaskPoolState(inBackground);
525 }
526
NotifyIdleStatusControl(const EcmaVM * vm,std::function<void (bool)> callback)527 void DFXJSNApi::NotifyIdleStatusControl(const EcmaVM *vm, std::function<void(bool)> callback)
528 {
529 const_cast<ecmascript::Heap *>(vm->GetHeap())->InitializeIdleStatusControl(callback);
530 }
531
NotifyIdleTime(const EcmaVM * vm,int idleMicroSec)532 void DFXJSNApi::NotifyIdleTime(const EcmaVM *vm, int idleMicroSec)
533 {
534 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
535 const_cast<ecmascript::Heap *>(vm->GetHeap())->TriggerIdleCollection(idleMicroSec);
536 }
537
NotifyMemoryPressure(EcmaVM * vm,bool inHighMemoryPressure)538 void DFXJSNApi::NotifyMemoryPressure(EcmaVM *vm, bool inHighMemoryPressure)
539 {
540 const_cast<ecmascript::Heap *>(vm->GetHeap())->NotifyMemoryPressure(inHighMemoryPressure);
541 }
542
NotifyFinishColdStart(EcmaVM * vm,bool isConvinced)543 void DFXJSNApi::NotifyFinishColdStart(EcmaVM *vm, [[maybe_unused]] bool isConvinced)
544 {
545 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
546 }
547
NotifyHighSensitive(EcmaVM * vm,bool isStart)548 void DFXJSNApi::NotifyHighSensitive(EcmaVM *vm, bool isStart)
549 {
550 const_cast<ecmascript::Heap *>(vm->GetHeap())->NotifyHighSensitive(isStart);
551 }
552
StopCpuProfilerForColdStart(const EcmaVM * vm)553 bool DFXJSNApi::StopCpuProfilerForColdStart([[maybe_unused]] const EcmaVM *vm)
554 {
555 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
556 bool success = false;
557 auto &options = const_cast<EcmaVM *>(vm)->GetJSOptions();
558 if (options.EnableCpuProfilerColdStartMainThread()) {
559 success = true;
560 DFXJSNApi::StopCpuProfilerForFile(vm);
561 }
562
563 if (options.EnableCpuProfilerColdStartWorkerThread()) {
564 success = true;
565 const_cast<EcmaVM *>(vm)->EnumerateWorkerVm([&](const EcmaVM *workerVm) -> void {
566 if (workerVm->GetJSThread()->GetIsProfiling()) {
567 DFXJSNApi::StopCpuProfilerForFile(workerVm);
568 }
569 });
570 }
571
572 return success;
573 #else
574 LOG_ECMA(ERROR) << "Not support arkcompiler cpu profiler";
575 return false;
576 #endif
577 }
578
579 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
CpuProfilerAnyTimeMainThread(const EcmaVM * vm)580 void DFXJSNApi::CpuProfilerAnyTimeMainThread(const EcmaVM *vm)
581 {
582 const uint8_t KILL_COUNT_FACTOR = 2;
583 if (killCount % KILL_COUNT_FACTOR == 0) {
584 uint8_t fileCount = killCount / KILL_COUNT_FACTOR + 1;
585 LOG_ECMA(INFO) << "Start CpuProfiler Any Time Main Thread, killCount = " << killCount;
586 std::string fileName = ConvertToStdString(const_cast<EcmaVM *>(vm)->GetBundleName())
587 + "_" + std::to_string(fileCount) + ".cpuprofile";
588 if (!BuiltinsArkTools::CreateFile(fileName)) {
589 LOG_ECMA(ERROR) << "createFile failed " << fileName;
590 } else {
591 DFXJSNApi::StartCpuProfilerForFile(vm, fileName, CpuProfiler::INTERVAL_OF_INNER_START);
592 }
593 } else {
594 LOG_ECMA(INFO) << "Stop CpuProfiler Any Time Main Thread, killCount = " << killCount;
595 if (vm->GetJSThread()->GetIsProfiling()) {
596 DFXJSNApi::StopCpuProfilerForFile(vm);
597 }
598 }
599 }
600 #endif
601
CpuProfilerSamplingAnyTime(const EcmaVM * vm)602 bool DFXJSNApi::CpuProfilerSamplingAnyTime([[maybe_unused]] const EcmaVM *vm)
603 {
604 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
605 (void)killCount;
606 bool success = false;
607 const uint8_t KILL_COUNT_FACTOR = 2;
608 auto &options = const_cast<EcmaVM *>(vm)->GetJSOptions();
609 if (options.EnableCpuProfilerAnyTimeMainThread()) {
610 success = true;
611 CpuProfilerAnyTimeMainThread(vm);
612 }
613
614 if (options.EnableCpuProfilerAnyTimeWorkerThread()) {
615 success = true;
616 if (killCount % KILL_COUNT_FACTOR == 0) {
617 uint8_t fileCount = killCount / KILL_COUNT_FACTOR + 1;
618 LOG_ECMA(INFO) << "Start CpuProfiler Any Time Worker Thread, killCount = " << killCount;
619 const_cast<EcmaVM *>(vm)->EnumerateWorkerVm([&](const EcmaVM *workerVm) -> void {
620 auto *thread = workerVm->GetAssociatedJSThread();
621 std::string fileName = ConvertToStdString(workerVm->GetBundleName()) + "_"
622 + std::to_string(thread->GetThreadId()) + "_"
623 + std::to_string(fileCount) + ".cpuprofile";
624 if (!BuiltinsArkTools::CreateFile(fileName)) {
625 LOG_ECMA(ERROR) << "createFile failed " << fileName;
626 } else {
627 thread->SetCpuProfileName(fileName);
628 thread->SetNeedProfiling(true);
629 }
630 });
631 } else {
632 LOG_ECMA(INFO) << "Stop CpuProfiler Any Time Worker Thread, killCount = " << killCount;
633 const_cast<EcmaVM *>(vm)->EnumerateWorkerVm([&](const EcmaVM *workerVm) -> void {
634 auto *thread = workerVm->GetAssociatedJSThread();
635 if (thread->GetIsProfiling()) {
636 DFXJSNApi::StopCpuProfilerForFile(workerVm);
637 }
638 thread->SetNeedProfiling(false);
639 });
640 }
641 }
642
643 return success;
644 #else
645 LOG_ECMA(ERROR) << "Not support arkcompiler cpu profiler";
646 return false;
647 #endif
648 }
649
StartCpuProfilerForFile(const EcmaVM * vm,const std::string & fileName,int interval)650 bool DFXJSNApi::StartCpuProfilerForFile([[maybe_unused]] const EcmaVM *vm,
651 [[maybe_unused]] const std::string &fileName,
652 [[maybe_unused]] int interval)
653 {
654 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
655 LOG_ECMA(INFO) << "DFXJSNApi::StartCpuProfilerForFile, vm = " << vm;
656 if (interval <= 0) {
657 LOG_ECMA(ERROR) << "DFXJSNApi::StartCpuProfilerForFile, interval <= 0";
658 return false;
659 }
660 if (vm == nullptr) {
661 LOG_ECMA(ERROR) << "DFXJSNApi::StartCpuProfilerForFile, vm == nullptr";
662 return false;
663 }
664 CpuProfiler *profiler = vm->GetProfiler();
665 if (profiler == nullptr) {
666 profiler = new CpuProfiler(vm, interval);
667 const_cast<EcmaVM *>(vm)->SetProfiler(profiler);
668 }
669 return profiler->StartCpuProfilerForFile(fileName);
670 #else
671 LOG_ECMA(ERROR) << "DFXJSNApi::StartCpuProfilerForFile, not support cpu profiler";
672 return false;
673 #endif
674 }
675
StopCpuProfilerForFile(const EcmaVM * vm)676 void DFXJSNApi::StopCpuProfilerForFile([[maybe_unused]] const EcmaVM *vm)
677 {
678 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
679 LOG_ECMA(INFO) << "DFXJSNApi::StopCpuProfilerForFile, vm = " << vm;
680 if (vm == nullptr) {
681 LOG_ECMA(ERROR) << "DFXJSNApi::StopCpuProfilerForFile, vm == nullptr";
682 return;
683 }
684 CpuProfiler *profiler = vm->GetProfiler();
685 if (profiler == nullptr) {
686 LOG_ECMA(ERROR) << "DFXJSNApi::StopCpuProfilerForFile, profiler == nullptr";
687 return;
688 }
689 bool result = profiler->StopCpuProfilerForFile();
690 if (!result) {
691 LOG_ECMA(ERROR) << "DFXJSNApi::StopCpuProfilerForFile failed";
692 return;
693 }
694 delete profiler;
695 profiler = nullptr;
696 const_cast<EcmaVM *>(vm)->SetProfiler(nullptr);
697 #else
698 LOG_ECMA(ERROR) << "Not support arkcompiler cpu profiler";
699 #endif
700 }
701
StartCpuProfilerForInfo(const EcmaVM * vm,int interval)702 bool DFXJSNApi::StartCpuProfilerForInfo([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] int interval)
703 {
704 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
705 LOG_ECMA(INFO) << "DFXJSNApi::StartCpuProfilerForInfo, vm = " << vm;
706 if (interval <= 0) {
707 LOG_ECMA(ERROR) << "DFXJSNApi::StartCpuProfilerForInfo, interval <= 0";
708 return false;
709 }
710 if (vm == nullptr) {
711 LOG_ECMA(ERROR) << "DFXJSNApi::StartCpuProfilerForInfo, vm == nullptr";
712 return false;
713 }
714 CpuProfiler *profiler = vm->GetProfiler();
715 if (profiler == nullptr) {
716 profiler = new CpuProfiler(vm, interval);
717 const_cast<EcmaVM *>(vm)->SetProfiler(profiler);
718 }
719 return profiler->StartCpuProfilerForInfo();
720 #else
721 LOG_ECMA(ERROR) << "DFXJSNApi::StartCpuProfilerForInfo, not support cpu profiler";
722 return false;
723 #endif
724 }
725
StopCpuProfilerForInfo(const EcmaVM * vm)726 std::unique_ptr<ProfileInfo> DFXJSNApi::StopCpuProfilerForInfo([[maybe_unused]] const EcmaVM *vm)
727 {
728 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
729 LOG_ECMA(INFO) << "DFXJSNApi::StopCpuProfilerForInfo, vm = " << vm;
730 if (vm == nullptr) {
731 LOG_ECMA(ERROR) << "DFXJSNApi::StopCpuProfilerForInfo, vm == nullptr";
732 return nullptr;
733 }
734 CpuProfiler *profiler = vm->GetProfiler();
735 if (profiler == nullptr) {
736 LOG_ECMA(ERROR) << "DFXJSNApi::StopCpuProfilerForInfo, profiler == nullptr";
737 return nullptr;
738 }
739 std::unique_ptr<ProfileInfo> profileInfo;
740 bool result = profiler->StopCpuProfilerForInfo(profileInfo);
741 if (!result) {
742 LOG_ECMA(ERROR) << "DFXJSNApi::StopCpuProfilerForInfo failed";
743 return nullptr;
744 }
745 delete profiler;
746 profiler = nullptr;
747 const_cast<EcmaVM *>(vm)->SetProfiler(nullptr);
748 return profileInfo;
749 #else
750 LOG_ECMA(ERROR) << "Not support arkcompiler cpu profiler";
751 return nullptr;
752 #endif
753 }
754
SetCpuSamplingInterval(const EcmaVM * vm,int interval)755 void DFXJSNApi::SetCpuSamplingInterval([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] int interval)
756 {
757 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
758 if (interval < 0) {
759 LOG_ECMA(ERROR) << "Sampling interval is illegal";
760 return;
761 }
762 LOG_ECMA(INFO) << "SetCpuProfilerSamplingInterval, Sampling interval is: " << interval;
763 if (vm == nullptr) {
764 return;
765 }
766 CpuProfiler *profiler = vm->GetProfiler();
767 if (profiler == nullptr) {
768 profiler = new CpuProfiler(vm, interval);
769 const_cast<EcmaVM *>(vm)->SetProfiler(profiler);
770 return;
771 }
772 profiler->SetCpuSamplingInterval(interval);
773 #else
774 LOG_ECMA(ERROR) << "Not support arkcompiler cpu profiler";
775 #endif
776 }
777
EnableSeriliazationTimeoutCheck(const EcmaVM * ecmaVM,int32_t threshold)778 void DFXJSNApi::EnableSeriliazationTimeoutCheck(const EcmaVM *ecmaVM, int32_t threshold)
779 {
780 ecmaVM->GetJsDebuggerManager()->EnableSerializationTimeoutCheck();
781 ecmaVM->GetJsDebuggerManager()->SetSerializationCheckThreshold(threshold);
782 }
783
DisableSeriliazationTimeoutCheck(const EcmaVM * ecmaVM)784 void DFXJSNApi::DisableSeriliazationTimeoutCheck(const EcmaVM *ecmaVM)
785 {
786 ecmaVM->GetJsDebuggerManager()->DisableSerializationTimeoutCheck();
787 }
788
SuspendVM(const EcmaVM * vm)789 bool DFXJSNApi::SuspendVM([[maybe_unused]] const EcmaVM *vm)
790 {
791 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
792 ecmascript::VmThreadControl* vmThreadControl = vm->GetAssociatedJSThread()->GetVmThreadControl();
793 return vmThreadControl->NotifyVMThreadSuspension();
794 #else
795 LOG_ECMA(ERROR) << "Not support arkcompiler snapshot";
796 return false;
797 #endif
798 }
799
ResumeVM(const EcmaVM * vm)800 void DFXJSNApi::ResumeVM([[maybe_unused]] const EcmaVM *vm)
801 {
802 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
803 ecmascript::VmThreadControl* vmThreadControl = vm->GetAssociatedJSThread()->GetVmThreadControl();
804 vmThreadControl->ResumeVM();
805 #else
806 LOG_ECMA(ERROR) << "Not support arkcompiler snapshot";
807 #endif
808 }
809
IsSuspended(const EcmaVM * vm)810 bool DFXJSNApi::IsSuspended([[maybe_unused]] const EcmaVM *vm)
811 {
812 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
813 ecmascript::VmThreadControl* vmThreadControl = vm->GetAssociatedJSThread()->GetVmThreadControl();
814 return vmThreadControl->IsSuspended();
815 #else
816 LOG_ECMA(ERROR) << "Not support arkcompiler snapshot";
817 return false;
818 #endif
819 }
820
TerminateExecution(const EcmaVM * vm)821 void DFXJSNApi::TerminateExecution(const EcmaVM *vm)
822 {
823 ecmascript::VmThreadControl* vmThreadControl = vm->GetAssociatedJSThread()->GetVmThreadControl();
824 vmThreadControl->RequestTerminateExecution();
825 }
826
CheckSafepoint(const EcmaVM * vm)827 bool DFXJSNApi::CheckSafepoint([[maybe_unused]] const EcmaVM *vm)
828 {
829 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
830 ecmascript::JSThread* thread = vm->GetJSThread();
831 return thread->CheckSafepoint();
832 #else
833 LOG_ECMA(ERROR) << "Not support arkcompiler snapshot";
834 return false;
835 #endif
836 }
837
BuildJsStackInfoList(const EcmaVM * hostVm,uint32_t tid,std::vector<JsFrameInfo> & jsFrames)838 bool DFXJSNApi::BuildJsStackInfoList(const EcmaVM *hostVm, uint32_t tid, std::vector<JsFrameInfo>& jsFrames)
839 {
840 EcmaVM *vm;
841 if (hostVm->GetAssociatedJSThread()->GetThreadId() == tid) {
842 vm = const_cast<EcmaVM*>(hostVm);
843 } else {
844 vm = const_cast<EcmaVM*>(hostVm)->GetWorkerVm(tid);
845 if (vm == nullptr) {
846 return false;
847 }
848 }
849 jsFrames = ecmascript::JsStackInfo::BuildJsStackInfo(vm->GetAssociatedJSThread());
850 if (jsFrames.size() > 0) {
851 return true;
852 }
853 return false;
854 }
855
GetObjectHash(const EcmaVM * vm,Local<JSValueRef> nativeObject)856 int32_t DFXJSNApi::GetObjectHash(const EcmaVM *vm, Local<JSValueRef> nativeObject)
857 {
858 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(nativeObject);
859 return ecmascript::tooling::DebuggerApi::GetObjectHash(vm, obj);
860 }
861
StartSampling(const EcmaVM * vm,uint64_t samplingInterval)862 bool DFXJSNApi::StartSampling([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] uint64_t samplingInterval)
863 {
864 #if defined(ECMASCRIPT_SUPPORT_HEAPSAMPLING)
865 ecmascript::HeapProfilerInterface *heapProfile = ecmascript::HeapProfilerInterface::GetInstance(
866 const_cast<EcmaVM *>(vm));
867 return heapProfile->StartHeapSampling(samplingInterval);
868 #else
869 LOG_ECMA(ERROR) << "Not support arkcompiler heap sampling";
870 return false;
871 #endif
872 }
873
GetAllocationProfile(const EcmaVM * vm)874 const SamplingInfo *DFXJSNApi::GetAllocationProfile([[maybe_unused]] const EcmaVM *vm)
875 {
876 #if defined(ECMASCRIPT_SUPPORT_HEAPSAMPLING)
877 ecmascript::HeapProfilerInterface *heapProfile = ecmascript::HeapProfilerInterface::GetInstance(
878 const_cast<EcmaVM *>(vm));
879 return heapProfile->GetAllocationProfile();
880 #else
881 LOG_ECMA(ERROR) << "Not support arkcompiler heap sampling";
882 return nullptr;
883 #endif
884 }
885
StopSampling(const EcmaVM * vm)886 void DFXJSNApi::StopSampling([[maybe_unused]] const EcmaVM *vm)
887 {
888 #if defined(ECMASCRIPT_SUPPORT_HEAPSAMPLING)
889 ecmascript::HeapProfilerInterface *heapProfile = ecmascript::HeapProfilerInterface::GetInstance(
890 const_cast<EcmaVM *>(vm));
891 heapProfile->StopHeapSampling();
892 #else
893 LOG_ECMA(ERROR) << "Not support arkcompiler heap sampling";
894 #endif
895 }
896
897 // release or debug hap : aa start -p 'dumpheap'
898 // aa start -p 'profile'
StartProfiler(EcmaVM * vm,const ProfilerOption & option,int tid,int32_t instanceId,const DebuggerPostTask & debuggerPostTask,bool isDebugApp)899 bool DFXJSNApi::StartProfiler(EcmaVM *vm, const ProfilerOption &option, int tid,
900 int32_t instanceId, const DebuggerPostTask &debuggerPostTask, bool isDebugApp)
901 {
902 LOG_ECMA(INFO) << "DFXJSNApi::StartProfiler, type = " << (int)option.profilerType
903 << ", tid = " << tid << ", isDebugApp = " << isDebugApp;
904 JSNApi::DebugOption debugOption;
905 debugOption.libraryPath = option.libraryPath;
906 if (option.profilerType == ProfilerType::CPU_PROFILER) {
907 debugOption.isDebugMode = false;
908 if (JSNApi::NotifyDebugMode(tid, vm, debugOption, instanceId, debuggerPostTask, isDebugApp)) {
909 return StartCpuProfilerForInfo(vm, option.interval);
910 } else {
911 LOG_ECMA(ERROR) << "DFXJSNApi::StartProfiler, NotifyDebugMode failed";
912 return false;
913 }
914 } else {
915 debugOption.isDebugMode = true;
916 return JSNApi::NotifyDebugMode(tid, vm, debugOption, instanceId, debuggerPostTask, isDebugApp);
917 }
918 }
919
ResumeVMById(EcmaVM * hostVm,uint32_t tid)920 void DFXJSNApi::ResumeVMById(EcmaVM *hostVm, uint32_t tid)
921 {
922 if (hostVm->GetAssociatedJSThread()->GetThreadId() == tid) {
923 ResumeVM(hostVm);
924 } else {
925 hostVm->ResumeWorkerVm(tid);
926 }
927 }
928
SuspendVMById(EcmaVM * hostVm,uint32_t tid)929 bool DFXJSNApi::SuspendVMById(EcmaVM *hostVm, uint32_t tid)
930 {
931 bool success = false;
932 if (hostVm->GetAssociatedJSThread()->GetThreadId() == tid) {
933 success = SuspendVM(hostVm);
934 LOG_ECMA(INFO) << "The main thread, SuspendVMById succeeded: " << success;
935 return success;
936 } else {
937 success = hostVm->SuspendWorkerVm(tid);
938 LOG_ECMA(INFO) << "The worker thread, SuspendVMById succeeded: " << success;
939 return success;
940 }
941 }
942
StartTracing(const EcmaVM * vm,std::string & categories)943 bool DFXJSNApi::StartTracing([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] std::string &categories)
944 {
945 #if defined(ECMASCRIPT_SUPPORT_TRACING)
946 if (vm == nullptr) {
947 return false;
948 }
949 Tracing *tracing = vm->GetTracing();
950 if (tracing == nullptr) {
951 tracing = new Tracing(vm);
952 const_cast<EcmaVM *>(vm)->SetTracing(tracing);
953 }
954 tracing->StartTracing(categories);
955 return true;
956 #else
957 LOG_ECMA(ERROR) << "Not support arkcompiler tracing";
958 return false;
959 #endif
960 }
961
StopTracing(const EcmaVM * vm)962 std::unique_ptr<std::vector<TraceEvent>> DFXJSNApi::StopTracing([[maybe_unused]] const EcmaVM *vm)
963 {
964 #if defined(ECMASCRIPT_SUPPORT_TRACING)
965 if (vm == nullptr) {
966 return nullptr;
967 }
968 Tracing *tracing = vm->GetTracing();
969 if (tracing == nullptr) {
970 LOG_ECMA(ERROR) << "StopTracing tracing is nullptr";
971 return nullptr;
972 }
973 auto traceEvents = tracing->StopTracing();
974 if (traceEvents == nullptr) {
975 LOG_ECMA(ERROR) << "trace events is nullptr";
976 }
977 delete tracing;
978 tracing = nullptr;
979 const_cast<EcmaVM *>(vm)->SetTracing(nullptr);
980 return traceEvents;
981 #else
982 LOG_ECMA(ERROR) << "Not support arkcompiler tracing";
983 return nullptr;
984 #endif
985 }
986
GetTracingBufferUseage(const EcmaVM * vm,double & percentFull,uint32_t & eventCount,double & value)987 void DFXJSNApi::GetTracingBufferUseage([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] double &percentFull,
988 [[maybe_unused]] uint32_t &eventCount, [[maybe_unused]] double &value)
989 {
990 #if defined(ECMASCRIPT_SUPPORT_TRACING)
991 if (vm == nullptr) {
992 return;
993 }
994 ecmascript::Tracing *tracing = vm->GetTracing();
995 if (tracing == nullptr) {
996 LOG_ECMA(ERROR) << "GetTracingBufferUseage tracing is nullptr";
997 } else {
998 tracing->GetBufferUseage(percentFull, eventCount, value);
999 }
1000 #else
1001 LOG_ECMA(ERROR) << "Not support arkcompiler tracing";
1002 #endif
1003 }
1004
TranslateJSStackInfo(const EcmaVM * vm,std::string & url,int32_t & line,int32_t & column)1005 void DFXJSNApi::TranslateJSStackInfo(const EcmaVM *vm, std::string &url, int32_t &line, int32_t &column)
1006 {
1007 auto cb = vm->GetSourceMapTranslateCallback();
1008 if (cb == nullptr) {
1009 LOG_ECMA(ERROR) << "Translate failed, callback function is nullptr.";
1010 } else if (!cb(url, line, column)) {
1011 LOG_ECMA(ERROR) << "Translate failed, url: " << url;
1012 }
1013 }
1014
GetCurrentThreadId()1015 uint32_t DFXJSNApi::GetCurrentThreadId()
1016 {
1017 return JSThread::GetCurrentThreadId();
1018 }
1019 } // namespace panda
1020