Skip to content

Commit 2a72622

Browse files
Gabriel SchulhofMylesBorins
Gabriel Schulhof
authored andcommittedApr 16, 2018
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. Backport-PR-URL: #19447 PR-URL: #12246 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
1 parent db36ca5 commit 2a72622

File tree

1 file changed

+41
-20
lines changed

1 file changed

+41
-20
lines changed
 

‎src/node_api.cc

+41-20
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,16 @@ void napi_clear_last_error(napi_env env);
2525

2626
class napi_env__ {
2727
public:
28-
explicit napi_env__(v8::Isolate* _isolate): isolate(_isolate), last_error() {}
28+
explicit napi_env__(v8::Isolate* _isolate): isolate(_isolate),
29+
has_instance_available(true), last_error() {}
2930
~napi_env__() {
3031
last_exception.Reset();
32+
has_instance.Reset();
3133
}
3234
v8::Isolate* isolate;
3335
v8::Persistent<v8::Value> last_exception;
36+
v8::Persistent<v8::Value> has_instance;
37+
bool has_instance_available;
3438
napi_extended_error_info last_error;
3539
};
3640

@@ -2158,28 +2162,43 @@ napi_status napi_instanceof(napi_env env,
21582162
return napi_set_last_error(env, napi_function_expected);
21592163
}
21602164

2161-
napi_value value, js_result;
2162-
napi_status status;
2163-
napi_valuetype value_type;
2165+
if (env->has_instance_available) {
2166+
napi_value value, js_result, has_instance = nullptr;
2167+
napi_status status;
2168+
napi_valuetype value_type;
21642169

2165-
// Get "Symbol" from the global object
2166-
status = napi_get_global(env, &value);
2167-
if (status != napi_ok) return status;
2168-
status = napi_get_named_property(env, value, "Symbol", &value);
2169-
if (status != napi_ok) return status;
2170-
status = napi_typeof(env, value, &value_type);
2171-
if (status != napi_ok) return status;
2170+
// Get "Symbol" from the global object
2171+
if (env->has_instance.IsEmpty()) {
2172+
status = napi_get_global(env, &value);
2173+
if (status != napi_ok) return status;
2174+
status = napi_get_named_property(env, value, "Symbol", &value);
2175+
if (status != napi_ok) return status;
2176+
status = napi_typeof(env, value, &value_type);
2177+
if (status != napi_ok) return status;
21722178

2173-
// Get "hasInstance" from Symbol
2174-
if (value_type == napi_function) {
2175-
status = napi_get_named_property(env, value, "hasInstance", &value);
2176-
if (status != napi_ok) return status;
2177-
status = napi_typeof(env, value, &value_type);
2178-
if (status != napi_ok) return status;
2179+
// Get "hasInstance" from Symbol
2180+
if (value_type == napi_function) {
2181+
status = napi_get_named_property(env, value, "hasInstance", &value);
2182+
if (status != napi_ok) return status;
2183+
status = napi_typeof(env, value, &value_type);
2184+
if (status != napi_ok) return status;
2185+
2186+
// Store Symbol.hasInstance in a global persistent reference
2187+
if (value_type == napi_symbol) {
2188+
env->has_instance.Reset(env->isolate,
2189+
v8impl::V8LocalValueFromJsValue(value));
2190+
if (status != napi_ok) return status;
2191+
has_instance = value;
2192+
}
2193+
}
2194+
} else {
2195+
has_instance = v8impl::JsValueFromV8LocalValue(
2196+
v8::Local<v8::Value>::New(env->isolate, env->has_instance));
2197+
if (status != napi_ok) return status;
2198+
}
21792199

2180-
// Retrieve the function at the Symbol(hasInstance) key of the constructor
2181-
if (value_type == napi_symbol) {
2182-
status = napi_get_property(env, constructor, value, &value);
2200+
if (has_instance) {
2201+
status = napi_get_property(env, constructor, has_instance, &value);
21832202
if (status != napi_ok) return status;
21842203
status = napi_typeof(env, value, &value_type);
21852204
if (status != napi_ok) return status;
@@ -2193,6 +2212,8 @@ napi_status napi_instanceof(napi_env env,
21932212
return napi_get_value_bool(env, js_result, result);
21942213
}
21952214
}
2215+
2216+
env->has_instance_available = false;
21962217
}
21972218

21982219
// If running constructor[Symbol.hasInstance](object) did not work, we perform

0 commit comments

Comments
 (0)
Please sign in to comment.