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