• 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, bool isConvinced)
544 {
545     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
546     if (isConvinced) {
547         const_cast<ecmascript::Heap *>(vm->GetHeap())->NotifyFinishColdStart();
548     } else {
549         const_cast<ecmascript::Heap *>(vm->GetHeap())->NotifyFinishColdStartSoon();
550     }
551 }
552 
NotifyHighSensitive(EcmaVM * vm,bool isStart)553 void DFXJSNApi::NotifyHighSensitive(EcmaVM *vm, bool isStart)
554 {
555     const_cast<ecmascript::Heap *>(vm->GetHeap())->NotifyHighSensitive(isStart);
556 }
557 
StopCpuProfilerForColdStart(const EcmaVM * vm)558 bool DFXJSNApi::StopCpuProfilerForColdStart([[maybe_unused]] const EcmaVM *vm)
559 {
560 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
561     bool success = false;
562     auto &options = const_cast<EcmaVM *>(vm)->GetJSOptions();
563     if (options.EnableCpuProfilerColdStartMainThread()) {
564         success = true;
565         DFXJSNApi::StopCpuProfilerForFile(vm);
566     }
567 
568     if (options.EnableCpuProfilerColdStartWorkerThread()) {
569         success = true;
570         const_cast<EcmaVM *>(vm)->EnumerateWorkerVm([&](const EcmaVM *workerVm) -> void {
571             if (workerVm->GetJSThread()->GetIsProfiling()) {
572                 DFXJSNApi::StopCpuProfilerForFile(workerVm);
573             }
574         });
575     }
576 
577     return success;
578 #else
579     LOG_ECMA(ERROR) << "Not support arkcompiler cpu profiler";
580     return false;
581 #endif
582 }
583 
584 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
CpuProfilerAnyTimeMainThread(const EcmaVM * vm)585 void DFXJSNApi::CpuProfilerAnyTimeMainThread(const EcmaVM *vm)
586 {
587     const uint8_t KILL_COUNT_FACTOR = 2;
588     if (killCount % KILL_COUNT_FACTOR == 0) {
589         uint8_t fileCount = killCount / KILL_COUNT_FACTOR + 1;
590         LOG_ECMA(INFO) << "Start CpuProfiler Any Time Main Thread, killCount = " << killCount;
591         std::string fileName = ConvertToStdString(const_cast<EcmaVM *>(vm)->GetBundleName())
592                                + "_" + std::to_string(fileCount) + ".cpuprofile";
593         if (!BuiltinsArkTools::CreateFile(fileName)) {
594             LOG_ECMA(ERROR) << "createFile failed " << fileName;
595         } else {
596             DFXJSNApi::StartCpuProfilerForFile(vm, fileName, CpuProfiler::INTERVAL_OF_INNER_START);
597         }
598     } else {
599         LOG_ECMA(INFO) << "Stop CpuProfiler Any Time Main Thread, killCount = " << killCount;
600         if (vm->GetJSThread()->GetIsProfiling()) {
601             DFXJSNApi::StopCpuProfilerForFile(vm);
602         }
603     }
604 }
605 #endif
606 
CpuProfilerSamplingAnyTime(const EcmaVM * vm)607 bool DFXJSNApi::CpuProfilerSamplingAnyTime([[maybe_unused]] const EcmaVM *vm)
608 {
609 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
610     (void)killCount;
611     bool success = false;
612     const uint8_t KILL_COUNT_FACTOR = 2;
613     auto &options = const_cast<EcmaVM *>(vm)->GetJSOptions();
614     if (options.EnableCpuProfilerAnyTimeMainThread()) {
615         success = true;
616         CpuProfilerAnyTimeMainThread(vm);
617     }
618 
619     if (options.EnableCpuProfilerAnyTimeWorkerThread()) {
620         success = true;
621         if (killCount % KILL_COUNT_FACTOR == 0) {
622             uint8_t fileCount = killCount / KILL_COUNT_FACTOR + 1;
623             LOG_ECMA(INFO) << "Start CpuProfiler Any Time Worker Thread, killCount = " << killCount;
624             const_cast<EcmaVM *>(vm)->EnumerateWorkerVm([&](const EcmaVM *workerVm) -> void {
625                 auto *thread = workerVm->GetAssociatedJSThread();
626                 std::string fileName = ConvertToStdString(workerVm->GetBundleName()) + "_"
627                                        + std::to_string(thread->GetThreadId()) + "_"
628                                        + std::to_string(fileCount) + ".cpuprofile";
629                 if (!BuiltinsArkTools::CreateFile(fileName)) {
630                     LOG_ECMA(ERROR) << "createFile failed " << fileName;
631                 } else {
632                     thread->SetCpuProfileName(fileName);
633                     thread->SetNeedProfiling(true);
634                 }
635             });
636         } else {
637             LOG_ECMA(INFO) << "Stop CpuProfiler Any Time Worker Thread, killCount = " << killCount;
638             const_cast<EcmaVM *>(vm)->EnumerateWorkerVm([&](const EcmaVM *workerVm) -> void {
639                 auto *thread = workerVm->GetAssociatedJSThread();
640                 if (thread->GetIsProfiling()) {
641                     DFXJSNApi::StopCpuProfilerForFile(workerVm);
642                 }
643                 thread->SetNeedProfiling(false);
644             });
645         }
646     }
647 
648     return success;
649 #else
650     LOG_ECMA(ERROR) << "Not support arkcompiler cpu profiler";
651     return false;
652 #endif
653 }
654 
StartCpuProfilerForFile(const EcmaVM * vm,const std::string & fileName,int interval)655 bool DFXJSNApi::StartCpuProfilerForFile([[maybe_unused]] const EcmaVM *vm,
656                                         [[maybe_unused]] const std::string &fileName,
657                                         [[maybe_unused]] int interval)
658 {
659 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
660     LOG_ECMA(INFO) << "DFXJSNApi::StartCpuProfilerForFile, vm = " << vm;
661     if (interval <= 0) {
662         LOG_ECMA(ERROR) << "DFXJSNApi::StartCpuProfilerForFile, interval <= 0";
663         return false;
664     }
665     if (vm == nullptr) {
666         LOG_ECMA(ERROR) << "DFXJSNApi::StartCpuProfilerForFile, vm == nullptr";
667         return false;
668     }
669     CpuProfiler *profiler = vm->GetProfiler();
670     if (profiler == nullptr) {
671         profiler = new CpuProfiler(vm, interval);
672         const_cast<EcmaVM *>(vm)->SetProfiler(profiler);
673     }
674     return profiler->StartCpuProfilerForFile(fileName);
675 #else
676     LOG_ECMA(ERROR) << "DFXJSNApi::StartCpuProfilerForFile, not support cpu profiler";
677     return false;
678 #endif
679 }
680 
StopCpuProfilerForFile(const EcmaVM * vm)681 void DFXJSNApi::StopCpuProfilerForFile([[maybe_unused]] const EcmaVM *vm)
682 {
683 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
684     LOG_ECMA(INFO) << "DFXJSNApi::StopCpuProfilerForFile, vm = " << vm;
685     if (vm == nullptr) {
686         LOG_ECMA(ERROR) << "DFXJSNApi::StopCpuProfilerForFile, vm == nullptr";
687         return;
688     }
689     CpuProfiler *profiler = vm->GetProfiler();
690     if (profiler == nullptr) {
691         LOG_ECMA(ERROR) << "DFXJSNApi::StopCpuProfilerForFile, profiler == nullptr";
692         return;
693     }
694     bool result = profiler->StopCpuProfilerForFile();
695     if (!result) {
696         LOG_ECMA(ERROR) << "DFXJSNApi::StopCpuProfilerForFile failed";
697         return;
698     }
699     delete profiler;
700     profiler = nullptr;
701     const_cast<EcmaVM *>(vm)->SetProfiler(nullptr);
702 #else
703     LOG_ECMA(ERROR) << "Not support arkcompiler cpu profiler";
704 #endif
705 }
706 
StartCpuProfilerForInfo(const EcmaVM * vm,int interval)707 bool DFXJSNApi::StartCpuProfilerForInfo([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] int interval)
708 {
709 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
710     LOG_ECMA(INFO) << "DFXJSNApi::StartCpuProfilerForInfo, vm = " << vm;
711     if (interval <= 0) {
712         LOG_ECMA(ERROR) << "DFXJSNApi::StartCpuProfilerForInfo, interval <= 0";
713         return false;
714     }
715     if (vm == nullptr) {
716         LOG_ECMA(ERROR) << "DFXJSNApi::StartCpuProfilerForInfo, vm == nullptr";
717         return false;
718     }
719     CpuProfiler *profiler = vm->GetProfiler();
720     if (profiler == nullptr) {
721         profiler = new CpuProfiler(vm, interval);
722         const_cast<EcmaVM *>(vm)->SetProfiler(profiler);
723     }
724     return profiler->StartCpuProfilerForInfo();
725 #else
726     LOG_ECMA(ERROR) << "DFXJSNApi::StartCpuProfilerForInfo, not support cpu profiler";
727     return false;
728 #endif
729 }
730 
StopCpuProfilerForInfo(const EcmaVM * vm)731 std::unique_ptr<ProfileInfo> DFXJSNApi::StopCpuProfilerForInfo([[maybe_unused]] const EcmaVM *vm)
732 {
733 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
734     LOG_ECMA(INFO) << "DFXJSNApi::StopCpuProfilerForInfo, vm = " << vm;
735     if (vm == nullptr) {
736         LOG_ECMA(ERROR) << "DFXJSNApi::StopCpuProfilerForInfo, vm == nullptr";
737         return nullptr;
738     }
739     CpuProfiler *profiler = vm->GetProfiler();
740     if (profiler == nullptr) {
741         LOG_ECMA(ERROR) << "DFXJSNApi::StopCpuProfilerForInfo, profiler == nullptr";
742         return nullptr;
743     }
744     std::unique_ptr<ProfileInfo> profileInfo;
745     bool result = profiler->StopCpuProfilerForInfo(profileInfo);
746     if (!result) {
747         LOG_ECMA(ERROR) << "DFXJSNApi::StopCpuProfilerForInfo failed";
748         return nullptr;
749     }
750     delete profiler;
751     profiler = nullptr;
752     const_cast<EcmaVM *>(vm)->SetProfiler(nullptr);
753     return profileInfo;
754 #else
755     LOG_ECMA(ERROR) << "Not support arkcompiler cpu profiler";
756     return nullptr;
757 #endif
758 }
759 
SetCpuSamplingInterval(const EcmaVM * vm,int interval)760 void DFXJSNApi::SetCpuSamplingInterval([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] int interval)
761 {
762 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
763     if (interval < 0) {
764         LOG_ECMA(ERROR) << "Sampling interval is illegal";
765         return;
766     }
767     LOG_ECMA(INFO) << "SetCpuProfilerSamplingInterval, Sampling interval is: " << interval;
768     if (vm == nullptr) {
769         return;
770     }
771     CpuProfiler *profiler = vm->GetProfiler();
772     if (profiler == nullptr) {
773         profiler = new CpuProfiler(vm, interval);
774         const_cast<EcmaVM *>(vm)->SetProfiler(profiler);
775         return;
776     }
777     profiler->SetCpuSamplingInterval(interval);
778 #else
779     LOG_ECMA(ERROR) << "Not support arkcompiler cpu profiler";
780 #endif
781 }
782 
EnableSeriliazationTimeoutCheck(const EcmaVM * ecmaVM,int32_t threshold)783 void DFXJSNApi::EnableSeriliazationTimeoutCheck(const EcmaVM *ecmaVM, int32_t threshold)
784 {
785     ecmaVM->GetJsDebuggerManager()->EnableSerializationTimeoutCheck();
786     ecmaVM->GetJsDebuggerManager()->SetSerializationCheckThreshold(threshold);
787 }
788 
DisableSeriliazationTimeoutCheck(const EcmaVM * ecmaVM)789 void DFXJSNApi::DisableSeriliazationTimeoutCheck(const EcmaVM *ecmaVM)
790 {
791     ecmaVM->GetJsDebuggerManager()->DisableSerializationTimeoutCheck();
792 }
793 
SuspendVM(const EcmaVM * vm)794 bool DFXJSNApi::SuspendVM([[maybe_unused]] const EcmaVM *vm)
795 {
796 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
797     ecmascript::VmThreadControl* vmThreadControl = vm->GetAssociatedJSThread()->GetVmThreadControl();
798     return vmThreadControl->NotifyVMThreadSuspension();
799 #else
800     LOG_ECMA(ERROR) << "Not support arkcompiler snapshot";
801     return false;
802 #endif
803 }
804 
ResumeVM(const EcmaVM * vm)805 void DFXJSNApi::ResumeVM([[maybe_unused]] const EcmaVM *vm)
806 {
807 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
808     ecmascript::VmThreadControl* vmThreadControl = vm->GetAssociatedJSThread()->GetVmThreadControl();
809     vmThreadControl->ResumeVM();
810 #else
811     LOG_ECMA(ERROR) << "Not support arkcompiler snapshot";
812 #endif
813 }
814 
IsSuspended(const EcmaVM * vm)815 bool DFXJSNApi::IsSuspended([[maybe_unused]] const EcmaVM *vm)
816 {
817 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
818     ecmascript::VmThreadControl* vmThreadControl = vm->GetAssociatedJSThread()->GetVmThreadControl();
819     return vmThreadControl->IsSuspended();
820 #else
821     LOG_ECMA(ERROR) << "Not support arkcompiler snapshot";
822     return false;
823 #endif
824 }
825 
TerminateExecution(const EcmaVM * vm)826 void DFXJSNApi::TerminateExecution(const EcmaVM *vm)
827 {
828     ecmascript::VmThreadControl* vmThreadControl = vm->GetAssociatedJSThread()->GetVmThreadControl();
829     vmThreadControl->RequestTerminateExecution();
830 }
831 
CheckSafepoint(const EcmaVM * vm)832 bool DFXJSNApi::CheckSafepoint([[maybe_unused]] const EcmaVM *vm)
833 {
834 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
835     ecmascript::JSThread* thread = vm->GetJSThread();
836     return thread->CheckSafepoint();
837 #else
838     LOG_ECMA(ERROR) << "Not support arkcompiler snapshot";
839     return false;
840 #endif
841 }
842 
BuildJsStackInfoList(const EcmaVM * hostVm,uint32_t tid,std::vector<JsFrameInfo> & jsFrames)843 bool DFXJSNApi::BuildJsStackInfoList(const EcmaVM *hostVm, uint32_t tid, std::vector<JsFrameInfo>& jsFrames)
844 {
845     EcmaVM *vm;
846     if (hostVm->GetAssociatedJSThread()->GetThreadId() == tid) {
847         vm = const_cast<EcmaVM*>(hostVm);
848     } else {
849         vm = const_cast<EcmaVM*>(hostVm)->GetWorkerVm(tid);
850         if (vm == nullptr) {
851             return false;
852         }
853     }
854     jsFrames = ecmascript::JsStackInfo::BuildJsStackInfo(vm->GetAssociatedJSThread());
855     if (jsFrames.size() > 0) {
856         return true;
857     }
858     return false;
859 }
860 
GetObjectHash(const EcmaVM * vm,Local<JSValueRef> nativeObject)861 int32_t DFXJSNApi::GetObjectHash(const EcmaVM *vm, Local<JSValueRef> nativeObject)
862 {
863     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(nativeObject);
864     return ecmascript::tooling::DebuggerApi::GetObjectHash(vm, obj);
865 }
866 
StartSampling(const EcmaVM * vm,uint64_t samplingInterval)867 bool DFXJSNApi::StartSampling([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] uint64_t samplingInterval)
868 {
869 #if defined(ECMASCRIPT_SUPPORT_HEAPSAMPLING)
870     ecmascript::HeapProfilerInterface *heapProfile = ecmascript::HeapProfilerInterface::GetInstance(
871         const_cast<EcmaVM *>(vm));
872     return heapProfile->StartHeapSampling(samplingInterval);
873 #else
874     LOG_ECMA(ERROR) << "Not support arkcompiler heap sampling";
875     return false;
876 #endif
877 }
878 
GetAllocationProfile(const EcmaVM * vm)879 const SamplingInfo *DFXJSNApi::GetAllocationProfile([[maybe_unused]] const EcmaVM *vm)
880 {
881 #if defined(ECMASCRIPT_SUPPORT_HEAPSAMPLING)
882     ecmascript::HeapProfilerInterface *heapProfile = ecmascript::HeapProfilerInterface::GetInstance(
883         const_cast<EcmaVM *>(vm));
884     return heapProfile->GetAllocationProfile();
885 #else
886     LOG_ECMA(ERROR) << "Not support arkcompiler heap sampling";
887     return nullptr;
888 #endif
889 }
890 
StopSampling(const EcmaVM * vm)891 void DFXJSNApi::StopSampling([[maybe_unused]] const EcmaVM *vm)
892 {
893 #if defined(ECMASCRIPT_SUPPORT_HEAPSAMPLING)
894     ecmascript::HeapProfilerInterface *heapProfile = ecmascript::HeapProfilerInterface::GetInstance(
895         const_cast<EcmaVM *>(vm));
896     heapProfile->StopHeapSampling();
897 #else
898     LOG_ECMA(ERROR) << "Not support arkcompiler heap sampling";
899 #endif
900 }
901 
902 // release or debug hap : aa start -p 'dumpheap'
903 //                        aa start -p 'profile'
StartProfiler(EcmaVM * vm,const ProfilerOption & option,int tid,int32_t instanceId,const DebuggerPostTask & debuggerPostTask,bool isDebugApp)904 bool DFXJSNApi::StartProfiler(EcmaVM *vm, const ProfilerOption &option, int tid,
905                               int32_t instanceId, const DebuggerPostTask &debuggerPostTask, bool isDebugApp)
906 {
907     LOG_ECMA(INFO) << "DFXJSNApi::StartProfiler, type = " << (int)option.profilerType
908         << ", tid = " << tid << ", isDebugApp = " << isDebugApp;
909     JSNApi::DebugOption debugOption;
910     debugOption.libraryPath = option.libraryPath;
911     if (option.profilerType == ProfilerType::CPU_PROFILER) {
912         debugOption.isDebugMode = false;
913         if (JSNApi::NotifyDebugMode(tid, vm, debugOption, instanceId, debuggerPostTask, isDebugApp)) {
914             return StartCpuProfilerForInfo(vm, option.interval);
915         } else {
916             LOG_ECMA(ERROR) << "DFXJSNApi::StartProfiler, NotifyDebugMode failed";
917             return false;
918         }
919     } else {
920         debugOption.isDebugMode = true;
921         return JSNApi::NotifyDebugMode(tid, vm, debugOption, instanceId, debuggerPostTask, isDebugApp);
922     }
923 }
924 
ResumeVMById(EcmaVM * hostVm,uint32_t tid)925 void DFXJSNApi::ResumeVMById(EcmaVM *hostVm, uint32_t tid)
926 {
927     if (hostVm->GetAssociatedJSThread()->GetThreadId() == tid) {
928         ResumeVM(hostVm);
929     } else {
930         hostVm->ResumeWorkerVm(tid);
931     }
932 }
933 
SuspendVMById(EcmaVM * hostVm,uint32_t tid)934 bool DFXJSNApi::SuspendVMById(EcmaVM *hostVm, uint32_t tid)
935 {
936     bool success = false;
937     if (hostVm->GetAssociatedJSThread()->GetThreadId() == tid) {
938         success = SuspendVM(hostVm);
939         LOG_ECMA(INFO) << "The main thread, SuspendVMById succeeded: " << success;
940         return success;
941     } else {
942         success = hostVm->SuspendWorkerVm(tid);
943         LOG_ECMA(INFO) << "The worker thread, SuspendVMById succeeded: " << success;
944         return success;
945     }
946 }
947 
StartTracing(const EcmaVM * vm,std::string & categories)948 bool DFXJSNApi::StartTracing([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] std::string &categories)
949 {
950 #if defined(ECMASCRIPT_SUPPORT_TRACING)
951     if (vm == nullptr) {
952         return false;
953     }
954     Tracing *tracing = vm->GetTracing();
955     if (tracing == nullptr) {
956         tracing = new Tracing(vm);
957         const_cast<EcmaVM *>(vm)->SetTracing(tracing);
958     }
959     tracing->StartTracing(categories);
960     return true;
961 #else
962     LOG_ECMA(ERROR) << "Not support arkcompiler tracing";
963     return false;
964 #endif
965 }
966 
StopTracing(const EcmaVM * vm)967 std::unique_ptr<std::vector<TraceEvent>> DFXJSNApi::StopTracing([[maybe_unused]] const EcmaVM *vm)
968 {
969 #if defined(ECMASCRIPT_SUPPORT_TRACING)
970     if (vm == nullptr) {
971         return nullptr;
972     }
973     Tracing *tracing = vm->GetTracing();
974     if (tracing == nullptr) {
975         LOG_ECMA(ERROR) << "StopTracing tracing is nullptr";
976         return nullptr;
977     }
978     auto traceEvents = tracing->StopTracing();
979     if (traceEvents == nullptr) {
980         LOG_ECMA(ERROR) << "trace events is nullptr";
981     }
982     delete tracing;
983     tracing = nullptr;
984     const_cast<EcmaVM *>(vm)->SetTracing(nullptr);
985     return traceEvents;
986 #else
987     LOG_ECMA(ERROR) << "Not support arkcompiler tracing";
988     return nullptr;
989 #endif
990 }
991 
GetTracingBufferUseage(const EcmaVM * vm,double & percentFull,uint32_t & eventCount,double & value)992 void DFXJSNApi::GetTracingBufferUseage([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] double &percentFull,
993                                        [[maybe_unused]] uint32_t &eventCount, [[maybe_unused]] double &value)
994 {
995 #if defined(ECMASCRIPT_SUPPORT_TRACING)
996     if (vm == nullptr) {
997         return;
998     }
999     ecmascript::Tracing *tracing = vm->GetTracing();
1000     if (tracing == nullptr) {
1001         LOG_ECMA(ERROR) << "GetTracingBufferUseage tracing is nullptr";
1002     } else {
1003         tracing->GetBufferUseage(percentFull, eventCount, value);
1004     }
1005 #else
1006     LOG_ECMA(ERROR) << "Not support arkcompiler tracing";
1007 #endif
1008 }
1009 
TranslateJSStackInfo(const EcmaVM * vm,std::string & url,int32_t & line,int32_t & column)1010 void DFXJSNApi::TranslateJSStackInfo(const EcmaVM *vm, std::string &url, int32_t &line, int32_t &column)
1011 {
1012     auto cb = vm->GetSourceMapTranslateCallback();
1013     if (cb == nullptr) {
1014         LOG_ECMA(ERROR) << "Translate failed, callback function is nullptr.";
1015     } else if (!cb(url, line, column)) {
1016         LOG_ECMA(ERROR) << "Translate failed, url: " << url;
1017     }
1018 }
1019 
GetCurrentThreadId()1020 uint32_t DFXJSNApi::GetCurrentThreadId()
1021 {
1022     return JSThread::GetCurrentThreadId();
1023 }
1024 } // namespace panda
1025