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