diff options
author | Gabriel Schulhof <gabriel.schulhof@intel.com> | 2017-03-31 16:40:33 +0300 |
---|---|---|
committer | Michael Dawson <michael_dawson@ca.ibm.com> | 2017-04-07 18:39:08 -0400 |
commit | 8fbace163afbd61b5efc57cf94414be904bf0188 (patch) | |
tree | 3c4145cdda3115ba48471c2a8aee3f932e3d63a2 /src | |
parent | ca8ccb917637a1b54b49419e7392099ac1bfb929 (diff) | |
download | android-node-v8-8fbace163afbd61b5efc57cf94414be904bf0188.tar.gz android-node-v8-8fbace163afbd61b5efc57cf94414be904bf0188.tar.bz2 android-node-v8-8fbace163afbd61b5efc57cf94414be904bf0188.zip |
n-api: cache Symbol.hasInstance
This improves the performance of napi_instanceof() by retrieving
Symbol.hasInstance from the global object once and then storing a
persistent reference to it in the env.
PR-URL: https://github.com/nodejs/node/pull/12246
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/node_api.cc | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/src/node_api.cc b/src/node_api.cc index be30a8461a..cac4c113dc 100644 --- a/src/node_api.cc +++ b/src/node_api.cc @@ -23,12 +23,16 @@ void napi_clear_last_error(napi_env env); class napi_env__ { public: - explicit napi_env__(v8::Isolate* _isolate): isolate(_isolate), last_error() {} + explicit napi_env__(v8::Isolate* _isolate): isolate(_isolate), + has_instance_available(true), last_error() {} ~napi_env__() { last_exception.Reset(); + has_instance.Reset(); } v8::Isolate* isolate; v8::Persistent<v8::Value> last_exception; + v8::Persistent<v8::Value> has_instance; + bool has_instance_available; napi_extended_error_info last_error; }; @@ -2156,28 +2160,43 @@ napi_status napi_instanceof(napi_env env, return napi_set_last_error(env, napi_function_expected); } - napi_value value, js_result; - napi_status status; - napi_valuetype value_type; + if (env->has_instance_available) { + napi_value value, js_result, has_instance = nullptr; + napi_status status; + napi_valuetype value_type; - // Get "Symbol" from the global object - status = napi_get_global(env, &value); - if (status != napi_ok) return status; - status = napi_get_named_property(env, value, "Symbol", &value); - if (status != napi_ok) return status; - status = napi_typeof(env, value, &value_type); - if (status != napi_ok) return status; + // Get "Symbol" from the global object + if (env->has_instance.IsEmpty()) { + status = napi_get_global(env, &value); + if (status != napi_ok) return status; + status = napi_get_named_property(env, value, "Symbol", &value); + if (status != napi_ok) return status; + status = napi_typeof(env, value, &value_type); + if (status != napi_ok) return status; - // Get "hasInstance" from Symbol - if (value_type == napi_function) { - status = napi_get_named_property(env, value, "hasInstance", &value); - if (status != napi_ok) return status; - status = napi_typeof(env, value, &value_type); - if (status != napi_ok) return status; + // Get "hasInstance" from Symbol + if (value_type == napi_function) { + status = napi_get_named_property(env, value, "hasInstance", &value); + if (status != napi_ok) return status; + status = napi_typeof(env, value, &value_type); + if (status != napi_ok) return status; + + // Store Symbol.hasInstance in a global persistent reference + if (value_type == napi_symbol) { + env->has_instance.Reset(env->isolate, + v8impl::V8LocalValueFromJsValue(value)); + if (status != napi_ok) return status; + has_instance = value; + } + } + } else { + has_instance = v8impl::JsValueFromV8LocalValue( + v8::Local<v8::Value>::New(env->isolate, env->has_instance)); + if (status != napi_ok) return status; + } - // Retrieve the function at the Symbol(hasInstance) key of the constructor - if (value_type == napi_symbol) { - status = napi_get_property(env, constructor, value, &value); + if (has_instance) { + status = napi_get_property(env, constructor, has_instance, &value); if (status != napi_ok) return status; status = napi_typeof(env, value, &value_type); if (status != napi_ok) return status; @@ -2191,6 +2210,8 @@ napi_status napi_instanceof(napi_env env, return napi_get_value_bool(env, js_result, result); } } + + env->has_instance_available = false; } // If running constructor[Symbol.hasInstance](object) did not work, we perform |