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