From 4c6db7aa1493139f5a832c1e9ebfe44a1c80af80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 22 Feb 2023 01:55:31 +0100 Subject: perf(core, runtime): Further improve startup time (#17860) This commit further improves startup time by: - no relying on "JsRuntime::execute_script" for runtime bootstrapping, this is instead done using V8 APIs directly - registering error classes during the snapshot time, instead of on startup Further improvements can be made, mainly around removing "core.initializeAsyncOps()" which takes around 2ms. This commit should result in ~1ms startup time improvement. --- core/bindings.rs | 24 +++++++++++++++++++----- core/runtime.rs | 35 ++++++++++++++++++++++++++++++----- 2 files changed, 49 insertions(+), 10 deletions(-) (limited to 'core') diff --git a/core/bindings.rs b/core/bindings.rs index 50308b931..8ac308250 100644 --- a/core/bindings.rs +++ b/core/bindings.rs @@ -111,12 +111,29 @@ pub fn initialize_context<'s>( let scope = &mut v8::ContextScope::new(scope, context); + let deno_str = v8::String::new(scope, "Deno").unwrap(); + let core_str = v8::String::new(scope, "core").unwrap(); + let ops_str = v8::String::new(scope, "ops").unwrap(); + // Snapshot already registered `Deno.core.ops` but // extensions may provide ops that aren't part of the snapshot. if snapshot_options.loaded() { // Grab the Deno.core.ops object & init it - let ops_obj = JsRuntime::eval::(scope, "Deno.core.ops") - .expect("Deno.core.ops to exist"); + let deno_obj: v8::Local = global + .get(scope, deno_str.into()) + .unwrap() + .try_into() + .unwrap(); + let core_obj: v8::Local = deno_obj + .get(scope, core_str.into()) + .unwrap() + .try_into() + .unwrap(); + let ops_obj: v8::Local = core_obj + .get(scope, ops_str.into()) + .expect("Deno.core.ops to exist") + .try_into() + .unwrap(); initialize_ops(scope, ops_obj, op_ctxs, snapshot_options); if snapshot_options != SnapshotOptions::CreateFromExisting { initialize_async_ops_info(scope, ops_obj, op_ctxs); @@ -126,11 +143,9 @@ pub fn initialize_context<'s>( // global.Deno = { core: { } }; let deno_obj = v8::Object::new(scope); - let deno_str = v8::String::new(scope, "Deno").unwrap(); global.set(scope, deno_str.into(), deno_obj.into()); let core_obj = v8::Object::new(scope); - let core_str = v8::String::new(scope, "core").unwrap(); deno_obj.set(scope, core_str.into(), core_obj.into()); // Bind functions to Deno.core.* @@ -144,7 +159,6 @@ pub fn initialize_context<'s>( // Bind functions to Deno.core.ops.* let ops_obj = v8::Object::new(scope); - let ops_str = v8::String::new(scope, "ops").unwrap(); core_obj.set(scope, ops_str.into(), ops_obj.into()); if !snapshot_options.will_snapshot() { diff --git a/core/runtime.rs b/core/runtime.rs index 9c6b7afea..c028d97c2 100644 --- a/core/runtime.rs +++ b/core/runtime.rs @@ -985,11 +985,36 @@ impl JsRuntime { fn init_cbs(&mut self, realm: &JsRealm) { let (recv_cb, build_custom_error_cb) = { let scope = &mut realm.handle_scope(self.v8_isolate()); - let recv_cb = - Self::eval::(scope, "Deno.core.opresolve").unwrap(); - let build_custom_error_cb = - Self::eval::(scope, "Deno.core.buildCustomError") - .expect("Deno.core.buildCustomError is undefined in the realm"); + let context = realm.context(); + let context_local = v8::Local::new(scope, context); + let global = context_local.global(scope); + let deno_str = v8::String::new(scope, "Deno").unwrap(); + let core_str = v8::String::new(scope, "core").unwrap(); + let opresolve_str = v8::String::new(scope, "opresolve").unwrap(); + let build_custom_error_str = + v8::String::new(scope, "buildCustomError").unwrap(); + + let deno_obj: v8::Local = global + .get(scope, deno_str.into()) + .unwrap() + .try_into() + .unwrap(); + let core_obj: v8::Local = deno_obj + .get(scope, core_str.into()) + .unwrap() + .try_into() + .unwrap(); + + let recv_cb: v8::Local = core_obj + .get(scope, opresolve_str.into()) + .unwrap() + .try_into() + .unwrap(); + let build_custom_error_cb: v8::Local = core_obj + .get(scope, build_custom_error_str.into()) + .unwrap() + .try_into() + .unwrap(); ( v8::Global::new(scope, recv_cb), v8::Global::new(scope, build_custom_error_cb), -- cgit v1.2.3