diff --git a/jsvm/interface/kits/jsvm_types.h b/jsvm/interface/kits/jsvm_types.h index 188cbb5c56995822285c08e8277598d0f707288a..66c855fc34afb1e071c9eac5eb042650658aca78 100644 --- a/jsvm/interface/kits/jsvm_types.h +++ b/jsvm/interface/kits/jsvm_types.h @@ -329,6 +329,10 @@ typedef enum { JSVM_NO_EXTERNAL_BUFFERS_ALLOWED, /** cannot run +js status. */ JSVM_CANNOT_RUN_JS, + /** jit mode expected status. + * @since 15 + */ + JSVM_JIT_MODE_EXPECTED, /** invalid input type status. * @since 16 */ diff --git a/jsvm/src/js_native_api_v8.cpp b/jsvm/src/js_native_api_v8.cpp index dfc11a22e678e644fd7f905c1247bf961e551105..8311452365db67aff7347b265e0caa9d57f2cf61 100644 --- a/jsvm/src/js_native_api_v8.cpp +++ b/jsvm/src/js_native_api_v8.cpp @@ -1011,11 +1011,11 @@ JSVM_Status JSVM_CDECL OH_JSVM_Init(const JSVM_InitOptions* options) OHOS_API_CALL(platform::ohos::ReportKeyThread(platform::ohos::ThreadRole::IMPORTANT_DISPLAY)); v8::V8::InitializePlatform(v8impl::g_platform.get()); - OHOS_API_CALL(platform::ohos::SetSecurityMode()); - if (options && options->argc && options->argv) { v8::V8::SetFlagsFromCommandLine(options->argc, options->argv, options->removeFlags); } + OHOS_API_CALL(platform::ohos::SetSecurityMode()); + v8::V8::Initialize(); const auto cb = v8impl::FunctionCallbackWrapper::Invoke; @@ -1679,32 +1679,32 @@ JSVM_EXTERN JSVM_Status JSVM_CDECL OH_JSVM_PerformMicrotaskCheckpoint(JSVM_VM vm } // Warning: Keep in-sync with JSVM_Status enum -static const char* errorMessages[] = { - nullptr, - "Invalid argument", - "An object was expected", - "A string was expected", - "A string or symbol was expected", - "A function was expected", - "A number was expected", - "A boolean was expected", - "An array was expected", - "Unknown failure", - "An exception is pending", - "The async work item was cancelled", - "OH_JSVM_EscapeHandle already called on scope", - "Invalid handle scope usage", - "Invalid callback scope usage", - "Thread-safe function queue is full", - "Thread-safe function handle is closing", - "A bigint was expected", - "A date was expected", - "An arraybuffer was expected", - "A detachable arraybuffer was expected", - "Main thread would deadlock", - "External buffers are not allowed", - "Cannot run JavaScript", -}; +static const char* errorMessages[] = { nullptr, + "Invalid argument", + "An object was expected", + "A string was expected", + "A string or symbol was expected", + "A function was expected", + "A number was expected", + "A boolean was expected", + "An array was expected", + "Unknown failure", + "An exception is pending", + "The async work item was cancelled", + "OH_JSVM_EscapeHandle already called on scope", + "Invalid handle scope usage", + "Invalid callback scope usage", + "Thread-safe function queue is full", + "Thread-safe function handle is closing", + "A bigint was expected", + "A date was expected", + "An arraybuffer was expected", + "A detachable arraybuffer was expected", + "Main thread would deadlock", + "External buffers are not allowed", + "Cannot run JavaScript", + "Cannot run in Jitless Mode", + "Invalid type" }; JSVM_Status JSVM_CDECL OH_JSVM_GetLastErrorInfo(JSVM_Env env, const JSVM_ExtendedErrorInfo** result) { @@ -1715,7 +1715,7 @@ JSVM_Status JSVM_CDECL OH_JSVM_GetLastErrorInfo(JSVM_Env env, const JSVM_Extende // message in the `JSVM_Status` enum each time a new error message is added. // We don't have a jsvm_status_last as this would result in an ABI // change each time a message was added. - const int lastStatus = JSVM_CANNOT_RUN_JS; + const int lastStatus = JSVM_INVALID_TYPE; static_assert(jsvm::ArraySize(errorMessages) == lastStatus + 1, "Count of error messages must match count of error values"); @@ -4563,6 +4563,8 @@ JSVM_Status JSVM_CDECL OH_JSVM_CompileWasmModule(JSVM_Env env, JSVM_Value* wasmModule) { JSVM_PREAMBLE(env); + // add jit mode check + RETURN_STATUS_IF_FALSE(env, platform::ohos::InJitMode(), JSVM_JIT_MODE_EXPECTED); CHECK_ARG(env, wasmBytecode); RETURN_STATUS_IF_FALSE(env, wasmBytecodeLength > 0, JSVM_INVALID_ARG); v8::MaybeLocal maybeModule; @@ -4590,7 +4592,10 @@ JSVM_Status JSVM_CDECL OH_JSVM_CompileWasmFunction(JSVM_Env env, JSVM_WasmOptLevel optLevel) { JSVM_PREAMBLE(env); + // add jit mode check + RETURN_STATUS_IF_FALSE(env, platform::ohos::InJitMode(), JSVM_JIT_MODE_EXPECTED); CHECK_ARG(env, wasmModule); + v8::Local val = v8impl::V8LocalValueFromJsValue(wasmModule); RETURN_STATUS_IF_FALSE(env, val->IsWasmModuleObject(), JSVM_INVALID_ARG); @@ -4632,6 +4637,8 @@ JSVM_Status JSVM_CDECL OH_JSVM_CreateWasmCache(JSVM_Env env, size_t* length) { JSVM_PREAMBLE(env); + // add jit mode check + RETURN_STATUS_IF_FALSE(env, platform::ohos::InJitMode(), JSVM_JIT_MODE_EXPECTED); CHECK_ARG(env, wasmModule); CHECK_ARG(env, data); CHECK_ARG(env, length); diff --git a/jsvm/src/platform/platform_ohos.cpp b/jsvm/src/platform/platform_ohos.cpp index 57fa3b4f8e52a09cc27fbfec732720ebdda957d0..af200fcbd7c47fe9cf2ff566a689790fdd0a6881 100644 --- a/jsvm/src/platform/platform_ohos.cpp +++ b/jsvm/src/platform/platform_ohos.cpp @@ -22,8 +22,13 @@ #ifdef ENABLE_HILOG #include "hilog/log.h" #endif +#include +#include +#include + #include "hitrace_meter.h" #include "init_param.h" +#include "jsvm_log.h" #include "unistd.h" #ifdef ENABLE_HISYSEVENT #include "hisysevent.h" @@ -32,7 +37,7 @@ extern "C" void ReportData(uint32_t resType, int64_t value, const std::unordered_map& mapPayLoad); - +static bool isJitMode = true; namespace ResourceSchedule { namespace ResType { enum : uint32_t { RES_TYPE_REPORT_KEY_THREAD = 39 }; @@ -133,6 +138,42 @@ RunJsTrace::~RunJsTrace() } namespace ohos { +#define JITFORT_QUERY_ENCAPS 'E' +#define HM_PR_SET_JITFORT 0x6a6974 + +const std::string ENABLE_JIT_CONF_PATH = "/etc/jsvm/app_jit_enable_list.conf"; +bool ProcessBundleName(std::string& bundleName); + +void ReadEnableList(const std::string& jitConfigPath, std::unordered_set& enableSet) +{ + std::ifstream file(jitConfigPath); + if (file.is_open()) { + std::string line; + while (std::getline(file, line)) { + if (!line.empty()) { + enableSet.insert(line); + } + } + file.close(); + } else { + LOG(Error) << "Failed to open file: " << jitConfigPath << std::endl; + } +} + +bool InJitMode() { + return isJitMode; +} + +inline bool InAppEnableList(const std::string& bundleName, std::unordered_set& enableSet) +{ + return (enableSet.count(bundleName) != 0); +} + +inline bool HasJitfortACL() +{ + return (prctl(HM_PR_SET_JITFORT, JITFORT_QUERY_ENCAPS, 0) == 0); +} + void ReportKeyThread(ThreadRole role) { uint64_t uid = OS::GetUid(); @@ -161,7 +202,16 @@ inline bool ReadSystemXpmState() void SetSecurityMode() { constexpr size_t SEC_ARG_CNT = 2; - if (ReadSystemXpmState()) { + std::string bundleName; + if (!ProcessBundleName(bundleName)) { + LOG(Error) << "Failed to get bundleName" << std::endl; + bundleName = "INVALID_BUNDLE_NAME"; + } + std::unordered_set enableList {}; + ReadEnableList(ENABLE_JIT_CONF_PATH, enableList); + + if (ReadSystemXpmState() || (!InAppEnableList(bundleName, enableList) && !HasJitfortACL())) { + isJitMode = false; int secArgc = SEC_ARG_CNT; constexpr bool removeFlag = false; const char* secArgv[SEC_ARG_CNT] = { "jsvm", "--jitless" }; diff --git a/jsvm/src/platform/platform_ohos.h b/jsvm/src/platform/platform_ohos.h index 46628592b38704ad046c59979e6c73264665d548..12f06e2ec8189a9f16226b9ee5e109ff97d2d408 100644 --- a/jsvm/src/platform/platform_ohos.h +++ b/jsvm/src/platform/platform_ohos.h @@ -35,6 +35,8 @@ void ReportKeyThread(ThreadRole role); void SetSecurityMode(); void WriteHisysevent(); + +bool InJitMode(); } // namespace ohos } // namespace platform #endif \ No newline at end of file