• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Debugging and Profiling JS Code Using JSVM-API
2
3## Introduction
4
5JSVM-API provide APIs for retrieving JavaScript virtual machine (JSVM) instances and performing memory analysis, profiling, and debugging, which facilitates code optimization and improves development efficiency.
6
7## Basic Concepts
8
9- JSVM: A JSVM is an environment for executing JavaScript (JS) code. It parses and executes JS code, manages memory, and provides interaction with other system resources. For example, you can use **OH_JSVM_GetVM** to retrieve JSVM instances in a specific environment. This is one of the basic JSVM management operations.
10- Debug: As an important activity in program development, debugging involves locating, analyzing, and rectifying code errors. For example, you can use **OH_JSVM_OpenInspector** to open inspector, a tool used to debug JS code, on a host and port and view the running status of an application on a real-time basis. You can use **OH_JSVM_CloseInspector** to close inspector.
11
12## Available APIs
13
14| API                      | Description                      |
15|----------------------------|--------------------------------|
16| OH_JSVM_GetVM              |  Obtains a VM instance.|
17| OH_JSVM_GetHeapStatistics  |  Obtains heap statistics of a VM.|
18| OH_JSVM_StartCpuProfiler   |  Creates and starts a CPU profiler instance.|
19| OH_JSVM_StopCpuProfiler    |  Stops the CPU profiler and outputs the result to a stream.|
20| OH_JSVM_TakeHeapSnapshot   |  Obtains a snapshot of the current heap and outputs it to a stream.|
21| OH_JSVM_OpenInspector      |  Opens an inspector instance on the specified host and port for debugging JS code.|
22| OH_JSVM_CloseInspector     |  Closes all remaining inspector connections.|
23| OH_JSVM_WaitForDebugger    |  Waits for the host to set up a socket connection with an inspector. After the connection is set up, the application continues to run. You can use **Runtime.runIfWaitingForDebugger** to run paused targets.|
24
25## Example
26
27If you are just starting out with JSVM-API, see [JSVM-API Development Process](use-jsvm-process.md). The following demonstrates only the C++ code involved in debugging and profiling JS code.
28
29### OH_JSVM_GetVM
30
31Use **OH_JSVM_GetVM** to obtain a VM instance.
32
33CPP code:
34
35```cpp
36// hello.cpp
37#include "napi/native_api.h"
38#include "ark_runtime/jsvm.h"
39#include <hilog/log.h>
40
41// Define OH_JSVM_GetVM.
42static JSVM_Value GetVM(JSVM_Env env, JSVM_CallbackInfo info)
43{
44    // Obtain a VM instance for subsequent VM-related operations or analysis.
45    JSVM_VM testVm;
46    JSVM_Status status = OH_JSVM_GetVM(env, &testVm);
47    JSVM_Value result = nullptr;
48    if (status != JSVM_OK || testVm == nullptr) {
49        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_GetVM: failed");
50        OH_JSVM_GetBoolean(env, true, &result);
51    } else {
52        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetVM: success");
53        OH_JSVM_GetBoolean(env, false, &result);
54    }
55    return result;
56}
57// Register the GetVM callback.
58static JSVM_CallbackStruct param[] = {
59    {.data = nullptr, .callback = GetVM},
60};
61static JSVM_CallbackStruct *method = param;
62// Set a property descriptor named getVM and associate it with a callback. This allows the GetVM callback to be called from JS.
63static JSVM_PropertyDescriptor descriptor[] = {
64    {"getVM", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
65};
66```
67
68// Call C++ code from JS.
69
70```c++
71const char *srcCallNative = R"JS(getVM())JS";
72```
73
74Expected result:
75```
76JSVM OH_JSVM_GetVM: success
77```
78
79### OH_JSVM_GetHeapStatistics
80
81Use **OH_JSVM_GetHeapStatistics** to obtain heap statistics of a VM.
82
83CPP code:
84
85```cpp
86// hello.cpp
87#include "napi/native_api.h"
88#include "ark_runtime/jsvm.h"
89#include <hilog/log.h>
90
91// Define OH_JSVM_GetHeapStatistics.
92void PrintHeapStatistics(JSVM_HeapStatistics result)
93{
94    OH_LOG_INFO(LOG_APP, "JSVM API heap totalHeapSize: %{public}zu", result.totalHeapSize);
95    OH_LOG_INFO(LOG_APP, "JSVM API heap totalHeapSizeExecutable: %{public}zu", result.totalHeapSizeExecutable);
96    OH_LOG_INFO(LOG_APP, "JSVM API heap totalPhysicalSize: %{public}zu", result.totalPhysicalSize);
97    OH_LOG_INFO(LOG_APP, "JSVM API heap totalAvailableSize: %{public}zu", result.totalAvailableSize);
98    OH_LOG_INFO(LOG_APP, "JSVM API heap usedHeapSize: %{public}zu", result.usedHeapSize);
99    OH_LOG_INFO(LOG_APP, "JSVM API heap heapSizeLimit: %{public}zu", result.heapSizeLimit);
100    OH_LOG_INFO(LOG_APP, "JSVM API heap mallocedMemory: %{public}zu", result.mallocedMemory);
101    OH_LOG_INFO(LOG_APP, "JSVM API heap externalMemory: %{public}zu", result.externalMemory);
102    OH_LOG_INFO(LOG_APP, "JSVM API heap peakMallocedMemory: %{public}zu", result.peakMallocedMemory);
103    OH_LOG_INFO(LOG_APP, "JSVM API heap numberOfNativeContexts: %{public}zu", result.numberOfNativeContexts);
104    OH_LOG_INFO(LOG_APP, "JSVM API heap numberOfDetachedContexts: %{public}zu", result.numberOfDetachedContexts);
105    OH_LOG_INFO(LOG_APP, "JSVM API heap totalGlobalHandlesSize: %{public}zu", result.totalGlobalHandlesSize);
106    OH_LOG_INFO(LOG_APP, "JSVM API heap usedGlobalHandlesSize: %{public}zu", result.usedGlobalHandlesSize);
107}
108
109static JSVM_Value GetHeapStatistics(JSVM_Env env, JSVM_CallbackInfo info)
110{
111    // Obtain the VM instance.
112    JSVM_VM testVm;
113    OH_JSVM_GetVM(env, &testVm);
114    // Obtain the heap statistics of the VM.
115    JSVM_HeapStatistics result;
116    OH_JSVM_GetHeapStatistics(testVm, &result);
117    // Print VM heap statistics.
118    PrintHeapStatistics(result);
119    // Return the number of local contexts in the VM heap statistics.
120    JSVM_Value nativeContextsCnt = nullptr;
121    OH_JSVM_CreateInt64(env, result.numberOfNativeContexts, &nativeContextsCnt);
122    return nativeContextsCnt;
123}
124// Register the GetHeapStatistics callback.
125static JSVM_CallbackStruct param[] = {
126    {.data = nullptr, .callback = GetHeapStatistics},
127};
128static JSVM_CallbackStruct *method = param;
129// Set a property descriptor named getHeapStatistics and associate it with a callback. This allows the GetHeapStatistics callback to be called from JS.
130static JSVM_PropertyDescriptor descriptor[] = {
131    {"getHeapStatistics", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
132};
133```
134
135// Call C++ code from JS.
136
137```c++
138const char *srcCallNative = R"JS(getHeapStatistics())JS";
139```
140Expected result:
141```
142JSVM API heap totalHeapSize: 1597440
143JSVM API heap totalHeapSizeExecutable: 0
144JSVM API heap totalPhysicalSize: 1323008
145JSVM API heap totalAvailableSize: 1519203688
146JSVM API heap usedHeapSize: 178256
147JSVM API heap heapSizeLimit: 1518338048
148JSVM API heap mallocedMemory: 32848
149JSVM API heap externalMemory: 0
150JSVM API heap peakMallocedMemory: 40960
151JSVM API heap numberOfNativeContexts: 1
152JSVM API heap numberOfDetachedContexts: 0
153JSVM API heap totalGlobalHandlesSize: 8192
154JSVM API heap usedGlobalHandlesSize: 32
155```
156
157For details about the sample code of the previous APIs, see:
158
159[JSVM Debugging and Profiling](jsvm-debugger-cpuprofiler-heapsnapshot.md)
160
161### OH_JSVM_StartCpuProfiler
162
163Creates and starts a CPU profiler instance.
164
165### OH_JSVM_StopCpuProfiler
166
167Stops the CPU profiler and outputs the result to a stream.
168
169### OH_JSVM_TakeHeapSnapshot
170
171Obtains a snapshot of the current heap and outputs it to a stream.
172
173### OH_JSVM_OpenInspector
174
175Opens an inspector instance on the specified host and port for debugging JS code.
176
177### OH_JSVM_CloseInspector
178
179Closes all remaining inspector connections.
180
181### OH_JSVM_WaitForDebugger
182
183Waits for the host to set up a socket connection with an inspector. After the connection is set up, the application continues to run. You can use **Runtime.runIfWaitingForDebugger** to run paused targets.
184