Skip to content

Commit 8fbace1

Browse files
Gabriel Schulhofmhdawson
Gabriel Schulhof
authored andcommitted
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: #12246 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
1 parent ca8ccb9 commit 8fbace1

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
@@ -23,12 +23,16 @@ void napi_clear_last_error(napi_env env);
2323

2424
class napi_env__ {
2525
public:
26-
explicit napi_env__(v8::Isolate* _isolate): isolate(_isolate), last_error() {}
26+
explicit napi_env__(v8::Isolate* _isolate): isolate(_isolate),
27+
has_instance_available(true), last_error() {}
2728
~napi_env__() {
2829
last_exception.Reset();
30+
has_instance.Reset();
2931
}
3032
v8::Isolate* isolate;
3133
v8::Persistent<v8::Value> last_exception;
34+
v8::Persistent<v8::Value> has_instance;
35+
bool has_instance_available;
3236
napi_extended_error_info last_error;
3337
};
3438

@@ -2156,28 +2160,43 @@ napi_status napi_instanceof(napi_env env,
21562160
return napi_set_last_error(env, napi_function_expected);
21572161
}
21582162

2159-
napi_value value, js_result;
2160-
napi_status status;
2161-
napi_valuetype value_type;
2163+
if (env->has_instance_available) {
2164+
napi_value value, js_result, has_instance = nullptr;
2165+
napi_status status;
2166+
napi_valuetype value_type;
21622167

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

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

2178-
// Retrieve the function at the Symbol(hasInstance) key of the constructor
2179-
if (value_type == napi_symbol) {
2180-
status = napi_get_property(env, constructor, value, &value);
2198+
if (has_instance) {
2199+
status = napi_get_property(env, constructor, has_instance, &value);
21812200
if (status != napi_ok) return status;
21822201
status = napi_typeof(env, value, &value_type);
21832202
if (status != napi_ok) return status;
@@ -2191,6 +2210,8 @@ napi_status napi_instanceof(napi_env env,
21912210
return napi_get_value_bool(env, js_result, result);
21922211
}
21932212
}
2213+
2214+
env->has_instance_available = false;
21942215
}
21952216

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

0 commit comments

Comments
 (0)