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 useOH_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++ and ArkTS code related to the APIs for debugging and profiling.
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// Register the GetVM callback.
41static JSVM_CallbackStruct param[] = {
42    {.data = nullptr, .callback = GetVM},
43};
44static JSVM_CallbackStruct *method = param;
45// Set a property descriptor named getVM and associate it with a callback. This allows the GetVM callback to be called from JS.
46static JSVM_PropertyDescriptor descriptor[] = {
47    {"getVM", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
48};
49// Define OH_JSVM_GetVM.
50static JSVM_Value GetVM(JSVM_Env env, JSVM_CallbackInfo info)
51{
52    // Obtain a VM instance for subsequent VM-related operations or analysis.
53    JSVM_VM testVm;
54    JSVM_Status status = OH_JSVM_GetVM(env, &testVm);
55    JSVM_Value result = nullptr;
56    if (status != JSVM_OK || testVm == nullptr) {
57        OH_LOG_ERROR(LOG_APP, "JSVM OH_JSVM_GetVM: failed");
58        OH_JSVM_GetBoolean(env, true, &result);
59    } else {
60        OH_LOG_INFO(LOG_APP, "JSVM OH_JSVM_GetVM: success");
61        OH_JSVM_GetBoolean(env, false, &result);
62    }
63    return result;
64}
65```
66
67ArkTS code:
68
69```ts
70import hilog from "@ohos.hilog"
71// Import the native APIs.
72import napitest from "libentry.so"
73let script: string = `
74    getVM()
75`
76let result = napitest.runJsVm(script);
77hilog.info(0x0000, 'testJSVM', 'Test JSVM getVM: %{public}s', result);
78```
79
80### OH_JSVM_GetHeapStatistics
81
82Use **OH_JSVM_GetHeapStatistics** to obtain heap statistics of a VM.
83
84CPP code:
85
86```cpp
87// hello.cpp
88#include "napi/native_api.h"
89#include "ark_runtime/jsvm.h"
90#include <hilog/log.h>
91// Register the GetHeapStatistics callback.
92static JSVM_CallbackStruct param[] = {
93    {.data = nullptr, .callback = GetHeapStatistics},
94};
95static JSVM_CallbackStruct *method = param;
96// Set a property descriptor named getHeapStatistics and associate it with a callback. This allows the GetHeapStatistics callback to be called from JS.
97static JSVM_PropertyDescriptor descriptor[] = {
98    {"getHeapStatistics", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT},
99};
100// Define OH_JSVM_GetHeapStatistics.
101void PrintHeapStatistics(JSVM_HeapStatistics result)
102{
103    OH_LOG_INFO(LOG_APP, "JSVM API heap totalHeapSize: %{public}zu", result.totalHeapSize);
104    OH_LOG_INFO(LOG_APP, "JSVM API heap totalHeapSizeExecutable: %{public}zu", result.totalHeapSizeExecutable);
105    OH_LOG_INFO(LOG_APP, "JSVM API heap totalPhysicalSize: %{public}zu", result.totalPhysicalSize);
106    OH_LOG_INFO(LOG_APP, "JSVM API heap totalAvailableSize: %{public}zu", result.totalAvailableSize);
107    OH_LOG_INFO(LOG_APP, "JSVM API heap usedHeapSize: %{public}zu", result.usedHeapSize);
108    OH_LOG_INFO(LOG_APP, "JSVM API heap heapSizeLimit: %{public}zu", result.heapSizeLimit);
109    OH_LOG_INFO(LOG_APP, "JSVM API heap mallocedMemory: %{public}zu", result.mallocedMemory);
110    OH_LOG_INFO(LOG_APP, "JSVM API heap externalMemory: %{public}zu", result.externalMemory);
111    OH_LOG_INFO(LOG_APP, "JSVM API heap peakMallocedMemory: %{public}zu", result.peakMallocedMemory);
112    OH_LOG_INFO(LOG_APP, "JSVM API heap numberOfNativeContexts: %{public}zu", result.numberOfNativeContexts);
113    OH_LOG_INFO(LOG_APP, "JSVM API heap numberOfDetachedContexts: %{public}zu", result.numberOfDetachedContexts);
114    OH_LOG_INFO(LOG_APP, "JSVM API heap totalGlobalHandlesSize: %{public}zu", result.totalGlobalHandlesSize);
115    OH_LOG_INFO(LOG_APP, "JSVM API heap usedGlobalHandlesSize: %{public}zu", result.usedGlobalHandlesSize);
116}
117
118static JSVM_Value GetHeapStatistics(JSVM_Env env, JSVM_CallbackInfo info)
119{
120    // Obtain the VM instance.
121    JSVM_VM testVm;
122    OH_JSVM_GetVM(env, &testVm);
123    // Obtain the heap statistics of the VM.
124    JSVM_HeapStatistics result;
125    OH_JSVM_GetHeapStatistics(testVm, &result);
126    // Print VM heap statistics.
127    PrintHeapStatistics(result);
128    // Return the number of local contexts in the VM heap statistics.
129    JSVM_Value nativeContextsCnt = nullptr;
130    OH_JSVM_CreateInt64(env, result.numberOfNativeContexts, &nativeContextsCnt);
131    return nativeContextsCnt;
132}
133```
134
135ArkTS code:
136
137```ts
138import hilog from "@ohos.hilog"
139// Import the native APIs.
140import napitest from "libentry.so"
141let script: string = `
142    getHeapStatistics()
143`
144let numberOfNativeContexts = napitest.runJsVm(script);
145hilog.info(0x0000, 'testJSVM', 'Test JSVM getHeapStatistics: %{public}s', numberOfNativeContexts);
146```
147
148For details about the sample code of the previous APIs, see:
149
150[JSVM Debugging and Profiling](jsvm-debugger-cpuprofiler-heapsnapshot.md)
151
152### OH_JSVM_StartCpuProfiler
153
154Use **OH_JSVM_StartCpuProfiler** to create and start a CPU profiler instance.
155
156### OH_JSVM_StopCpuProfiler
157
158Use **OH_JSVM_StopCpuProfiler** to stop the CPU profiler and output the result to a stream.
159
160### OH_JSVM_TakeHeapSnapshot
161
162Use **OH_JSVM_TakeHeapSnapshot** to obtain a snapshot of the current heap and output it to a stream.
163
164### OH_JSVM_OpenInspector
165
166Use **OH_JSVM_OpenInspector** to open an inspector instance on the specified host and port for debugging JS code.
167
168### OH_JSVM_CloseInspector
169
170Use **OH_JSVM_CloseInspector** to close all remaining inspector connections.
171
172### OH_JSVM_WaitForDebugger
173
174Use **OH_JSVM_WaitForDebugger** to wait for the host to set up a socket connection with inspector. After the connection is set up, the application continues to run. You can use **Runtime.runIfWaitingForDebugger** to run paused targets.
175