# 使用 code cache åŠ é€Ÿç¼–è¯‘ ## code cache 简介 JSVM æä¾›äº†ç”Ÿæˆå¹¶ä½¿ç”¨ code cache åŠ é€Ÿç¼–è¯‘è¿‡ç¨‹çš„æ–¹æ³•, 其获å–和使用分为下é¢å‡ 个部分: - 首先使用 compile 系列接å£ç¼–译得到 JSVM_Script - 使用 OH_JSVM_CreateCodeCache 接å£, ä¼ å…¥ç¼–è¯‘å®ŒæˆåŽç”Ÿæˆçš„ JSVM_Script - å°† OH_JSVM_CreateCodeCache 生æˆçš„ code cache ä¿å˜, ç‰å¾…下一次编译时, ä½œä¸ºå‚æ•°ä¼ 递给 compile ç³»åˆ—æŽ¥å£ é€šè¿‡ä¸Šè¿°æµç¨‹, 将会在使用 code cache 的那次编译ä¸, æžå¤§å‡å°‘编译时间, 其原ç†ä¸ºå°†ç¼–译完æˆçš„ script åºåˆ—化, ç„¶åŽä½¿ç”¨ code cache 编译时就ä¸å†éœ€è¦é‡æ–°è§£æž/编译已ç»è¢«åºåˆ—化的函数, åªéœ€è¦è¿›è¡Œä¸€æ¬¡ååºåˆ—化å³å¯, 编译就简化为了一次数æ®è¯»å–。 ## 场景示例 下é¢çš„ä¼ªä»£ç æ˜¯ä¸€ä¸ªå…¸åž‹çš„使用方法, å…¶ä¸ç¬¬äºŒæ¬¡ç¼–译, 如果 cacheRejected 的值没有被置为 true, 那么说明 code cache 使用æˆåŠŸ, 这次è¿è¡Œå°†ä¼šæžå¤§åŠ å¿«ã€‚ å…¶ä¸ä½¿ç”¨åˆ°çš„ JSVM-API å¯ä»¥å‚考 [JSVM æ•°æ®ç±»åž‹ä¸ŽæŽ¥å£è¯´æ˜Ž](./jsvm-data-types-interfaces.md), 这里仅展示调用的æ¥éª¤ã€‚ 外层跨è¯è¨€äº¤äº’的部分å¯ä»¥å‚考 [使用 JSVM-API 实现 JS 与 C/C++ è¯è¨€äº¤äº’开呿µç¨‹](./use-jsvm-process.md)。 ```c++ #include "napi/native_api.h" #include "ark_runtime/jsvm.h" #include <hilog/log.h> void UseCodeCache(JSVM_Env env, JSVM_CallbackInfo info) { // ç¼–è¯‘å‚æ•°å‡†å¤‡ JSVM_Value jsSrc; JSVM_Script script; size_t length = 0; const uint8_t* dataPtr = nullptr; bool cacheRejected = true; static std::string src = R"JS( a = 65536; b = 32768; c = a + b; )JS"; // ç”Ÿæˆ code cache { JSVM_HandleScope handleScope; OH_JSVM_OpenHandleScope(env, &handleScope); // æºç å—符串转æ¢ä¸º js å—符串 OH_JSVM_CreateStringUtf8(env, src.c_str(), src.size(), &jsSrc); // 编译js代ç OH_JSVM_CompileScript(env, jsSrc, nullptr, 0, true, nullptr, &script); // 执行js代ç JSVM_Value result; OH_JSVM_RunScript(env, script, &result); int value = 0; OH_JSVM_GetValueInt32(env, result, &value); OH_LOG_INFO(LOG_APP, "first run result: %{public}d\n", value); if (dataPtr && lengthPtr && *dataPtr == nullptr) { // å°†jsæºç 编译出的脚本ä¿å˜åˆ° cache, å¯ä»¥é¿å…é‡å¤ç¼–译, å¸¦æ¥æ€§èƒ½æå‡ OH_JSVM_CreateCodeCache(env, script, &dataPtr, &length); } OH_JSVM_CloseHandleScope(env, handleScope); } // 使用 code cache { JSVM_HandleScope handleScope; OH_JSVM_OpenHandleScope(env, &handleScope); // æºç å—符串转æ¢ä¸º js å—符串 OH_JSVM_CreateStringUtf8(env, src.c_str(), src.size(), &jsSrc); // 使用 code cache 编译js代ç OH_JSVM_CompileScript(env, jsSrc, dataPtr, length, true, &cacheRejected, &script); // 执行js代ç JSVM_Value result; OH_JSVM_RunScript(env, script, &result); int value = 0; OH_JSVM_GetValueInt32(env, result, &value); OH_LOG_INFO(LOG_APP, "second run result: %{public}d\n", value); OH_JSVM_CloseHandleScope(env, handleScope); } OH_LOG_INFO(LOG_APP, "cache rejected: %{public}d\n", cacheRejected); } // Register a WasmDemo callback. static JSVM_CallbackStruct param[] = { {.data = nullptr, .callback = UseCodeCache} }; static JSVM_CallbackStruct *method = param; // Register the C++ WasmDemo callback as a JSVM globalThis.UseCodeCache property for the JS to call. static JSVM_PropertyDescriptor descriptor[] = { {"UseCodeCache", nullptr, method++, nullptr, nullptr, nullptr, JSVM_DEFAULT}, }; ``` 预期输出结果 ``` first run result: 98304 second run result: 98304 cache rejected: 0 ``` ## 注æ„事项 上述代ç ä¸ä½¿ç”¨äº† code cache 进行编译: `OH_JSVM_CompileScript(env, jsSrc, dataPtr, length, true, &cacheRejected, &script);` 这个接å£çš„ä¼ å…¥å‚æ•°ä¸åŒ…å«äº† cacheRejected,其作用是接收实际的编译过程ä¸ï¼Œcode cache 是å¦è¢«æ‹’ç»çš„状æ€ï¼Œè¿™é‡ŒåŒ…å«äº†å¤šç§æƒ…况: - code cache æ ¡éªŒå¤±è´¥ - code cache æ ¡éªŒæˆåŠŸ - 内å˜ä¸å˜åœ¨ç¼–译缓å˜ï¼Œcode cache æ²¡æœ‰è¢«æ ¡éªŒ å¯¹äºŽç¬¬ä¸€ç§æƒ…å†µï¼Œè¿™ä¸ªå‚æ•°ä¼šè¢«ç½®ä¸º true,而åŽä¸¤ç§æƒ…况都是 falseï¼Œå› æ¤éœ€è¦æ³¨æ„å³ä½¿ reject 为 false,也ä¸èƒ½è¯´æ˜Ž code cache 被接收了。