1 /*
2 * Copyright (c) 2021-2023 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 "ecmascript/napi/include/dfx_jsnapi.h"
17
18 #include "ecmascript/base/block_hook_scope.h"
19 #include "ecmascript/builtins/builtins_ark_tools.h"
20 #include "ecmascript/dfx/hprof/heap_profiler.h"
21 #include "ecmascript/dfx/stackinfo/js_stackinfo.h"
22 #include "ecmascript/ecma_vm.h"
23 #include "ecmascript/mem/c_string.h"
24 #include "ecmascript/mem/heap-inl.h"
25 #include "ecmascript/mem/gc_stats.h"
26 #include "ecmascript/napi/include/jsnapi.h"
27 #include "ecmascript/dfx/hprof/file_stream.h"
28
29 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
30 #include "ecmascript/dfx/cpu_profiler/cpu_profiler.h"
31 #include "ecmascript/dfx/cpu_profiler/samples_record.h"
32 #endif
33 #if defined(ENABLE_DUMP_IN_FAULTLOG)
34 #include "faultloggerd_client.h"
35 #endif
36
37 namespace panda {
38 using ecmascript::CString;
39 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
40 using BuiltinsArkTools = ecmascript::builtins::BuiltinsArkTools;
41 using ecmascript::CpuProfiler;
42 #endif
43 using ecmascript::EcmaString;
44 using ecmascript::JSTaggedValue;
45 using ecmascript::GCStats;
46 template<typename T>
47 using JSHandle = ecmascript::JSHandle<T>;
48 using ecmascript::FileStream;
49 using ecmascript::FileDescriptorStream;
50 using ecmascript::Stream;
51 using ecmascript::CMap;
52
DumpHeapSnapshot(const EcmaVM * vm,int dumpFormat,const std::string & path,bool isVmMode,bool isPrivate,bool captureNumericValue)53 void DFXJSNApi::DumpHeapSnapshot([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] int dumpFormat,
54 [[maybe_unused]] const std::string &path, [[maybe_unused]] bool isVmMode,
55 [[maybe_unused]] bool isPrivate, [[maybe_unused]] bool captureNumericValue)
56 {
57 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
58 FileStream stream(path);
59 DumpHeapSnapshot(vm, dumpFormat, &stream, nullptr, isVmMode, isPrivate, captureNumericValue);
60 #else
61 LOG_ECMA(ERROR) << "Not support arkcompiler heap snapshot";
62 #endif
63 }
64
DumpHeapSnapshot(const EcmaVM * vm,int dumpFormat,Stream * stream,Progress * progress,bool isVmMode,bool isPrivate,bool captureNumericValue)65 void DFXJSNApi::DumpHeapSnapshot([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] int dumpFormat,
66 [[maybe_unused]] Stream *stream, [[maybe_unused]] Progress *progress,
67 [[maybe_unused]] bool isVmMode, [[maybe_unused]] bool isPrivate,
68 [[maybe_unused]] bool captureNumericValue)
69 {
70 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
71 ecmascript::base::BlockHookScope blockScope;
72 ecmascript::HeapProfilerInterface *heapProfile = ecmascript::HeapProfilerInterface::GetInstance(
73 const_cast<EcmaVM *>(vm));
74 heapProfile->DumpHeapSnapshot(ecmascript::DumpFormat(dumpFormat), stream, progress,
75 isVmMode, isPrivate, captureNumericValue);
76 #else
77 LOG_ECMA(ERROR) << "Not support arkcompiler heap snapshot";
78 #endif
79 }
80
81 [[maybe_unused]] static uint8_t killCount = 0;
82
DumpHeapSnapshot(const EcmaVM * vm,int dumpFormat,bool isVmMode,bool isPrivate,bool captureNumericValue)83 void DFXJSNApi::DumpHeapSnapshot([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] int dumpFormat,
84 [[maybe_unused]] bool isVmMode, [[maybe_unused]] bool isPrivate,
85 [[maybe_unused]] bool captureNumericValue)
86 {
87 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
88 #if defined(ENABLE_DUMP_IN_FAULTLOG)
89 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
90 // for CpuProfiler kill contral
91 if (DFXJSNApi::StopCpuProfilerForColdStart(vm)) {
92 return;
93 }
94
95 (void)killCount;
96 if (DFXJSNApi::CpuProfilerSamplingAnyTime(vm)) {
97 killCount++;
98 return;
99 }
100 #endif // ECMASCRIPT_SUPPORT_CPUPROFILER
101 auto &options = const_cast<EcmaVM *>(vm)->GetJSOptions();
102 options.SwitchStartGlobalLeakCheck();
103 if (options.EnableGlobalLeakCheck() && options.IsStartGlobalLeakCheck()) {
104 int32_t stackTraceFd = RequestFileDescriptor(static_cast<int32_t>(FaultLoggerType::JS_STACKTRACE));
105 if (stackTraceFd < 0) {
106 options.SwitchStartGlobalLeakCheck();
107 } else {
108 vm->GetJSThread()->SetStackTraceFd(stackTraceFd);
109 }
110 }
111 // Write in faultlog for heap leak.
112 int32_t fd = RequestFileDescriptor(static_cast<int32_t>(FaultLoggerType::JS_HEAP_SNAPSHOT));
113 if (fd < 0) {
114 LOG_ECMA(ERROR) << "Write FD failed, fd" << fd;
115 return;
116 }
117 FileDescriptorStream stream(fd);
118 DumpHeapSnapshot(vm, dumpFormat, &stream, nullptr, isVmMode, isPrivate, captureNumericValue);
119 #endif // ENABLE_DUMP_IN_FAULTLOG
120 #else
121 LOG_ECMA(ERROR) << "Not support arkcompiler heap snapshot";
122 #endif // ECMASCRIPT_SUPPORT_SNAPSHOT
123 }
124
DestroyHeapProfiler(const EcmaVM * vm)125 void DFXJSNApi::DestroyHeapProfiler([[maybe_unused]] const EcmaVM *vm)
126 {
127 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
128 ecmascript::HeapProfilerInterface::Destroy(const_cast<EcmaVM *>(vm));
129 #else
130 LOG_ECMA(ERROR) << "Not support arkcompiler heap snapshot";
131 #endif
132 }
133
BuildNativeAndJsStackTrace(const EcmaVM * vm,std::string & stackTraceStr)134 bool DFXJSNApi::BuildNativeAndJsStackTrace(const EcmaVM *vm, std::string &stackTraceStr)
135 {
136 LOG_ECMA(INFO) <<"BuildJsStackInfoList start";
137 std::vector<JsFrameInfo> jf = ecmascript::JsStackInfo::BuildJsStackInfo(vm->GetAssociatedJSThread());
138 LOG_ECMA(INFO) <<"BuildJsStackInfoList JsFrameInfo";
139 for (uint32_t i = 0; i < jf.size(); ++i) {
140 std::string functionname = jf[i].functionName;
141 std::string filename = jf[i].fileName;
142 std::string pos = jf[i].pos;
143 uintptr_t *nativepointer = jf[i].nativePointer;
144 LOG_ECMA(INFO) << "BuildJsStackInfoList functionname: " << functionname;
145 LOG_ECMA(INFO) << "BuildJsStackInfoList filenaem: " << filename;
146 LOG_ECMA(INFO) << "BuildJsStackInfoList pos: " << pos;
147 LOG_ECMA(INFO) << "BuildJsStackInfoList nativepointer: " << nativepointer;
148 }
149 stackTraceStr = ecmascript::JsStackInfo::BuildJsStackTrace(vm->GetAssociatedJSThread(), true);
150 if (stackTraceStr.empty()) {
151 return false;
152 }
153 return true;
154 }
155
BuildJsStackTrace(const EcmaVM * vm,std::string & stackTraceStr)156 bool DFXJSNApi::BuildJsStackTrace(const EcmaVM *vm, std::string &stackTraceStr)
157 {
158 stackTraceStr = ecmascript::JsStackInfo::BuildJsStackTrace(vm->GetAssociatedJSThread(), false);
159 if (stackTraceStr.empty()) {
160 return false;
161 }
162 return true;
163 }
164
StartHeapTracking(const EcmaVM * vm,double timeInterval,bool isVmMode,Stream * stream,bool traceAllocation,bool newThread)165 bool DFXJSNApi::StartHeapTracking([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] double timeInterval,
166 [[maybe_unused]] bool isVmMode, [[maybe_unused]] Stream *stream,
167 [[maybe_unused]] bool traceAllocation, [[maybe_unused]] bool newThread)
168 {
169 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
170 ecmascript::base::BlockHookScope blockScope;
171 ecmascript::HeapProfilerInterface *heapProfile = ecmascript::HeapProfilerInterface::GetInstance(
172 const_cast<EcmaVM *>(vm));
173 return heapProfile->StartHeapTracking(timeInterval, isVmMode, stream, traceAllocation, newThread);
174 #else
175 LOG_ECMA(ERROR) << "Not support arkcompiler heap tracking";
176 return false;
177 #endif
178 }
179
UpdateHeapTracking(const EcmaVM * vm,Stream * stream)180 bool DFXJSNApi::UpdateHeapTracking([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] Stream *stream)
181 {
182 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
183 ecmascript::base::BlockHookScope blockScope;
184 ecmascript::HeapProfilerInterface *heapProfile = ecmascript::HeapProfilerInterface::GetInstance(
185 const_cast<EcmaVM *>(vm));
186 return heapProfile->UpdateHeapTracking(stream);
187 #else
188 LOG_ECMA(ERROR) << "Not support arkcompiler heap tracking";
189 return false;
190 #endif
191 }
192
StopHeapTracking(const EcmaVM * vm,const std::string & filePath,bool newThread)193 bool DFXJSNApi::StopHeapTracking([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] const std::string &filePath,
194 [[maybe_unused]] bool newThread)
195 {
196 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
197 FileStream stream(filePath);
198 return StopHeapTracking(vm, &stream, nullptr, newThread);
199 #else
200 LOG_ECMA(ERROR) << "Not support arkcompiler heap tracking";
201 return false;
202 #endif
203 }
204
StopHeapTracking(const EcmaVM * vm,Stream * stream,Progress * progress,bool newThread)205 bool DFXJSNApi::StopHeapTracking([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] Stream* stream,
206 [[maybe_unused]] Progress *progress, [[maybe_unused]] bool newThread)
207 {
208 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
209 ecmascript::base::BlockHookScope blockScope;
210 bool result = false;
211 ecmascript::HeapProfilerInterface *heapProfile = ecmascript::HeapProfilerInterface::GetInstance(
212 const_cast<EcmaVM *>(vm));
213 result = heapProfile->StopHeapTracking(stream, progress, newThread);
214 ecmascript::HeapProfilerInterface::Destroy(const_cast<EcmaVM *>(vm));
215 return result;
216 #else
217 LOG_ECMA(ERROR) << "Not support arkcompiler heap tracking";
218 return false;
219 #endif
220 }
221
PrintStatisticResult(const EcmaVM * vm)222 void DFXJSNApi::PrintStatisticResult(const EcmaVM *vm)
223 {
224 ecmascript::GCStats gcstats(vm->GetHeap());
225 gcstats.PrintStatisticResult();
226 }
227
StartRuntimeStat(EcmaVM * vm)228 void DFXJSNApi::StartRuntimeStat(EcmaVM *vm)
229 {
230 vm->GetJSThread()->GetCurrentEcmaContext()->SetRuntimeStatEnable(true);
231 }
232
StopRuntimeStat(EcmaVM * vm)233 void DFXJSNApi::StopRuntimeStat(EcmaVM *vm)
234 {
235 vm->GetJSThread()->GetCurrentEcmaContext()->SetRuntimeStatEnable(false);
236 }
237
GetArrayBufferSize(const EcmaVM * vm)238 size_t DFXJSNApi::GetArrayBufferSize(const EcmaVM *vm)
239 {
240 return vm->GetHeap()->GetArrayBufferSize();
241 }
242
GetHeapTotalSize(const EcmaVM * vm)243 size_t DFXJSNApi::GetHeapTotalSize(const EcmaVM *vm)
244 {
245 return vm->GetHeap()->GetCommittedSize();
246 }
247
GetHeapUsedSize(const EcmaVM * vm)248 size_t DFXJSNApi::GetHeapUsedSize(const EcmaVM *vm)
249 {
250 return vm->GetHeap()->GetHeapObjectSize();
251 }
252
NotifyApplicationState(EcmaVM * vm,bool inBackground)253 void DFXJSNApi::NotifyApplicationState(EcmaVM *vm, bool inBackground)
254 {
255 const_cast<ecmascript::Heap *>(vm->GetHeap())->ChangeGCParams(inBackground);
256 }
257
NotifyIdleStatusControl(const EcmaVM * vm,std::function<void (bool)> callback)258 void DFXJSNApi::NotifyIdleStatusControl(const EcmaVM *vm, std::function<void(bool)> callback)
259 {
260 const_cast<ecmascript::Heap *>(vm->GetHeap())->InitializeIdleStatusControl(callback);
261 }
262
NotifyIdleTime(const EcmaVM * vm,int idleMicroSec)263 void DFXJSNApi::NotifyIdleTime(const EcmaVM *vm, int idleMicroSec)
264 {
265 const_cast<ecmascript::Heap *>(vm->GetHeap())->TriggerIdleCollection(idleMicroSec);
266 }
267
NotifyMemoryPressure(EcmaVM * vm,bool inHighMemoryPressure)268 void DFXJSNApi::NotifyMemoryPressure(EcmaVM *vm, bool inHighMemoryPressure)
269 {
270 const_cast<ecmascript::Heap *>(vm->GetHeap())->NotifyMemoryPressure(inHighMemoryPressure);
271 }
272
StopCpuProfilerForColdStart(const EcmaVM * vm)273 bool DFXJSNApi::StopCpuProfilerForColdStart([[maybe_unused]] const EcmaVM *vm)
274 {
275 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
276 bool success = false;
277 auto &options = const_cast<EcmaVM *>(vm)->GetJSOptions();
278 if (options.EnableCpuProfilerColdStartMainThread()) {
279 success = true;
280 DFXJSNApi::StopCpuProfilerForFile(vm);
281 }
282
283 if (options.EnableCpuProfilerColdStartWorkerThread()) {
284 success = true;
285 const_cast<EcmaVM *>(vm)->EnumerateWorkerVm([&](const EcmaVM *workerVm) -> void {
286 if (workerVm->GetJSThread()->GetIsProfiling()) {
287 DFXJSNApi::StopCpuProfilerForFile(workerVm);
288 }
289 });
290 }
291
292 return success;
293 #else
294 LOG_ECMA(ERROR) << "Not support arkcompiler cpu profiler";
295 return false;
296 #endif
297 }
298
CpuProfilerSamplingAnyTime(const EcmaVM * vm)299 bool DFXJSNApi::CpuProfilerSamplingAnyTime([[maybe_unused]] const EcmaVM *vm)
300 {
301 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
302 (void)killCount;
303 bool success = false;
304 const uint8_t KILL_COUNT_FACTOR = 2;
305 auto &options = const_cast<EcmaVM *>(vm)->GetJSOptions();
306 if (options.EnableCpuProfilerAnyTimeMainThread()) {
307 success = true;
308 if (killCount % KILL_COUNT_FACTOR == 0) {
309 uint8_t fileCount = killCount / KILL_COUNT_FACTOR + 1;
310 LOG_ECMA(INFO) << "Start CpuProfiler Any Time Main Thread, killCount = " << killCount;
311 std::string fileName = ConvertToStdString(const_cast<EcmaVM *>(vm)->GetBundleName())
312 + "_" + std::to_string(fileCount) + ".cpuprofile";
313 if (!BuiltinsArkTools::CreateFile(fileName)) {
314 LOG_ECMA(ERROR) << "createFile failed " << fileName;
315 } else {
316 DFXJSNApi::StartCpuProfilerForFile(vm, fileName, CpuProfiler::INTERVAL_OF_INNER_START);
317 }
318 } else {
319 LOG_ECMA(INFO) << "Stop CpuProfiler Any Time Main Thread, killCount = " << killCount;
320 if (vm->GetJSThread()->GetIsProfiling()) {
321 DFXJSNApi::StopCpuProfilerForFile(vm);
322 }
323 }
324 }
325
326 if (options.EnableCpuProfilerAnyTimeWorkerThread()) {
327 success = true;
328 if (killCount % KILL_COUNT_FACTOR == 0) {
329 uint8_t fileCount = killCount / KILL_COUNT_FACTOR + 1;
330 LOG_ECMA(INFO) << "Start CpuProfiler Any Time Worker Thread, killCount = " << killCount;
331 const_cast<EcmaVM *>(vm)->EnumerateWorkerVm([&](const EcmaVM *workerVm) -> void {
332 auto *thread = workerVm->GetAssociatedJSThread();
333 std::string fileName = ConvertToStdString(workerVm->GetBundleName()) + "_"
334 + std::to_string(thread->GetThreadId()) + "_"
335 + std::to_string(fileCount) + ".cpuprofile";
336 if (!BuiltinsArkTools::CreateFile(fileName)) {
337 LOG_ECMA(ERROR) << "createFile failed " << fileName;
338 } else {
339 thread->SetCpuProfileName(fileName);
340 thread->SetNeedProfiling(true);
341 }
342 });
343 } else {
344 LOG_ECMA(INFO) << "Stop CpuProfiler Any Time Worker Thread, killCount = " << killCount;
345 const_cast<EcmaVM *>(vm)->EnumerateWorkerVm([&](const EcmaVM *workerVm) -> void {
346 auto *thread = workerVm->GetAssociatedJSThread();
347 if (thread->GetIsProfiling()) {
348 DFXJSNApi::StopCpuProfilerForFile(workerVm);
349 }
350 thread->SetNeedProfiling(false);
351 });
352 }
353 }
354
355 return success;
356 #else
357 LOG_ECMA(ERROR) << "Not support arkcompiler cpu profiler";
358 return false;
359 #endif
360 }
361
StartCpuProfilerForFile(const EcmaVM * vm,const std::string & fileName,int interval)362 void DFXJSNApi::StartCpuProfilerForFile([[maybe_unused]] const EcmaVM *vm,
363 [[maybe_unused]] const std::string &fileName,
364 [[maybe_unused]] int interval)
365 {
366 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
367 if (vm == nullptr) {
368 return;
369 }
370 CpuProfiler *profiler = vm->GetProfiler();
371 if (profiler == nullptr) {
372 profiler = new CpuProfiler(vm, interval);
373 const_cast<EcmaVM *>(vm)->SetProfiler(profiler);
374 }
375 profiler->StartCpuProfilerForFile(fileName);
376 #else
377 LOG_ECMA(ERROR) << "Not support arkcompiler cpu profiler";
378 #endif
379 }
380
StopCpuProfilerForFile(const EcmaVM * vm)381 void DFXJSNApi::StopCpuProfilerForFile([[maybe_unused]] const EcmaVM *vm)
382 {
383 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
384 if (vm == nullptr) {
385 return;
386 }
387 CpuProfiler *profiler = vm->GetProfiler();
388 if (profiler == nullptr) {
389 return;
390 }
391 profiler->StopCpuProfilerForFile();
392 delete profiler;
393 profiler = nullptr;
394 const_cast<EcmaVM *>(vm)->SetProfiler(nullptr);
395 #else
396 LOG_ECMA(ERROR) << "Not support arkcompiler cpu profiler";
397 #endif
398 }
399
StartCpuProfilerForInfo(const EcmaVM * vm,int interval)400 void DFXJSNApi::StartCpuProfilerForInfo([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] int interval)
401 {
402 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
403 if (vm == nullptr) {
404 return;
405 }
406 CpuProfiler *profiler = vm->GetProfiler();
407 if (profiler == nullptr) {
408 profiler = new CpuProfiler(vm, interval);
409 const_cast<EcmaVM *>(vm)->SetProfiler(profiler);
410 }
411 profiler->StartCpuProfilerForInfo();
412 #else
413 LOG_ECMA(ERROR) << "Not support arkcompiler cpu profiler";
414 #endif
415 }
416
StopCpuProfilerForInfo(const EcmaVM * vm)417 std::unique_ptr<ProfileInfo> DFXJSNApi::StopCpuProfilerForInfo([[maybe_unused]] const EcmaVM *vm)
418 {
419 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
420 if (vm == nullptr) {
421 return nullptr;
422 }
423 CpuProfiler *profiler = vm->GetProfiler();
424 if (profiler == nullptr) {
425 return nullptr;
426 }
427 auto profile = profiler->StopCpuProfilerForInfo();
428 if (profile == nullptr) {
429 LOG_DEBUGGER(ERROR) << "Transfer CpuProfiler::StopCpuProfilerImpl is failure";
430 }
431 delete profiler;
432 profiler = nullptr;
433 const_cast<EcmaVM *>(vm)->SetProfiler(nullptr);
434 return profile;
435 #else
436 LOG_ECMA(ERROR) << "Not support arkcompiler cpu profiler";
437 return nullptr;
438 #endif
439 }
440
SetCpuSamplingInterval(const EcmaVM * vm,int interval)441 void DFXJSNApi::SetCpuSamplingInterval([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] int interval)
442 {
443 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
444 LOG_ECMA(INFO) << "SetCpuProfilerSamplingInterval, Sampling interval is: " << interval;
445 if (vm == nullptr) {
446 return;
447 }
448 CpuProfiler *profiler = vm->GetProfiler();
449 if (profiler == nullptr) {
450 profiler = new CpuProfiler(vm, interval);
451 const_cast<EcmaVM *>(vm)->SetProfiler(profiler);
452 return;
453 }
454 profiler->SetCpuSamplingInterval(interval);
455 #else
456 LOG_ECMA(ERROR) << "Not support arkcompiler cpu profiler";
457 #endif
458 }
459
SuspendVM(const EcmaVM * vm)460 bool DFXJSNApi::SuspendVM([[maybe_unused]] const EcmaVM *vm)
461 {
462 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
463 ecmascript::VmThreadControl* vmThreadControl = vm->GetAssociatedJSThread()->GetVmThreadControl();
464 return vmThreadControl->NotifyVMThreadSuspension();
465 #else
466 LOG_ECMA(ERROR) << "Not support arkcompiler snapshot";
467 return false;
468 #endif
469 }
470
ResumeVM(const EcmaVM * vm)471 void DFXJSNApi::ResumeVM([[maybe_unused]] const EcmaVM *vm)
472 {
473 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
474 ecmascript::VmThreadControl* vmThreadControl = vm->GetAssociatedJSThread()->GetVmThreadControl();
475 vmThreadControl->ResumeVM();
476 #else
477 LOG_ECMA(ERROR) << "Not support arkcompiler snapshot";
478 #endif
479 }
480
IsSuspended(const EcmaVM * vm)481 bool DFXJSNApi::IsSuspended([[maybe_unused]] const EcmaVM *vm)
482 {
483 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
484 ecmascript::VmThreadControl* vmThreadControl = vm->GetAssociatedJSThread()->GetVmThreadControl();
485 return vmThreadControl->IsSuspended();
486 #else
487 LOG_ECMA(ERROR) << "Not support arkcompiler snapshot";
488 return false;
489 #endif
490 }
491
CheckSafepoint(const EcmaVM * vm)492 bool DFXJSNApi::CheckSafepoint([[maybe_unused]] const EcmaVM *vm)
493 {
494 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
495 ecmascript::JSThread* thread = vm->GetJSThread();
496 return thread->CheckSafepoint();
497 #else
498 LOG_ECMA(ERROR) << "Not support arkcompiler snapshot";
499 return false;
500 #endif
501 }
502
BuildJsStackInfoList(const EcmaVM * hostVm,uint32_t tid,std::vector<JsFrameInfo> & jsFrames)503 bool DFXJSNApi::BuildJsStackInfoList(const EcmaVM *hostVm, uint32_t tid, std::vector<JsFrameInfo>& jsFrames)
504 {
505 EcmaVM *vm;
506 if (hostVm->GetAssociatedJSThread()->GetThreadId() == tid) {
507 vm = const_cast<EcmaVM*>(hostVm);
508 } else {
509 vm = const_cast<EcmaVM*>(hostVm)->GetWorkerVm(tid);
510 if (vm == nullptr) {
511 return false;
512 }
513 }
514 jsFrames = ecmascript::JsStackInfo::BuildJsStackInfo(vm->GetAssociatedJSThread());
515 if (jsFrames.size() > 0) {
516 return true;
517 }
518 return false;
519 }
520
StartSampling(const EcmaVM * vm,uint64_t samplingInterval)521 bool DFXJSNApi::StartSampling([[maybe_unused]] const EcmaVM *vm, [[maybe_unused]] uint64_t samplingInterval)
522 {
523 #if defined(ECMASCRIPT_SUPPORT_HEAPSAMPLING)
524 ecmascript::HeapProfilerInterface *heapProfile = ecmascript::HeapProfilerInterface::GetInstance(
525 const_cast<EcmaVM *>(vm));
526 return heapProfile->StartHeapSampling(samplingInterval);
527 #else
528 LOG_ECMA(ERROR) << "Not support arkcompiler heap sampling";
529 return false;
530 #endif
531 }
532
GetAllocationProfile(const EcmaVM * vm)533 const SamplingInfo *DFXJSNApi::GetAllocationProfile([[maybe_unused]] const EcmaVM *vm)
534 {
535 #if defined(ECMASCRIPT_SUPPORT_HEAPSAMPLING)
536 ecmascript::HeapProfilerInterface *heapProfile = ecmascript::HeapProfilerInterface::GetInstance(
537 const_cast<EcmaVM *>(vm));
538 return heapProfile->GetAllocationProfile();
539 #else
540 LOG_ECMA(ERROR) << "Not support arkcompiler heap sampling";
541 return nullptr;
542 #endif
543 }
544
StopSampling(const EcmaVM * vm)545 void DFXJSNApi::StopSampling([[maybe_unused]] const EcmaVM *vm)
546 {
547 #if defined(ECMASCRIPT_SUPPORT_HEAPSAMPLING)
548 ecmascript::HeapProfilerInterface *heapProfile = ecmascript::HeapProfilerInterface::GetInstance(
549 const_cast<EcmaVM *>(vm));
550 heapProfile->StopHeapSampling();
551 #else
552 LOG_ECMA(ERROR) << "Not support arkcompiler heap sampling";
553 #endif
554 }
555
StartProfiler(EcmaVM * vm,const ProfilerOption & option,int32_t instanceId,const DebuggerPostTask & debuggerPostTask)556 bool DFXJSNApi::StartProfiler(EcmaVM *vm, const ProfilerOption &option, int32_t instanceId,
557 const DebuggerPostTask &debuggerPostTask)
558 {
559 JSNApi::DebugOption debugOption;
560 debugOption.libraryPath = option.libraryPath;
561 if (option.profilerType == ProfilerType::CPU_PROFILER) {
562 debugOption.isDebugMode = false;
563 if (JSNApi::StartDebugger(vm, debugOption, instanceId, debuggerPostTask)) {
564 StartCpuProfilerForInfo(vm, option.interval);
565 return true;
566 } else {
567 LOG_ECMA(ERROR) << "DFXJSNApi:Failed to StartDebugger";
568 return false;
569 }
570 } else {
571 debugOption.isDebugMode = true;
572 return JSNApi::StartDebugger(vm, debugOption, instanceId, debuggerPostTask);
573 }
574 }
575
ResumeVMById(EcmaVM * hostVm,uint32_t tid)576 void DFXJSNApi::ResumeVMById(EcmaVM *hostVm, uint32_t tid)
577 {
578 if (hostVm->GetAssociatedJSThread()->GetThreadId() == tid) {
579 ResumeVM(hostVm);
580 } else {
581 hostVm->ResumeWorkerVm(tid);
582 }
583 }
584
SuspendVMById(EcmaVM * hostVm,uint32_t tid)585 bool DFXJSNApi::SuspendVMById(EcmaVM *hostVm, uint32_t tid)
586 {
587 if (hostVm->GetAssociatedJSThread()->GetThreadId() == tid) {
588 return SuspendVM(hostVm);
589 } else {
590 return hostVm->SuspendWorkerVm(tid);
591 }
592 }
593 } // namespace panda
594