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