1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-24 15:19:26 -05:00

perf(core): minimize trivial heap allocations in resolve_async_ops (#16584)

* Use stack allocated array for 16 promises and spill rest to heap. the
exact number can change, maybe 128? (tokio's coop budget limit)
* Avoid v8::Global::clone for global context.
* Do not open global opresolve when its not needed.
This commit is contained in:
Divy Srivastava 2022-11-10 03:56:02 -08:00 committed by GitHub
parent bc33a4b2e0
commit 110a0ebe69
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 15 additions and 5 deletions

1
Cargo.lock generated
View file

@ -943,6 +943,7 @@ dependencies = [
"serde",
"serde_json",
"serde_v8",
"smallvec",
"sourcemap",
"tokio",
"url",

View file

@ -32,6 +32,7 @@ pin-project = "1.0.11"
serde = { version = "1.0.136", features = ["derive"] }
serde_json = { version = "1.0.79", features = ["preserve_order"] }
serde_v8 = { version = "0.69.0", path = "../serde_v8" }
smallvec = "1.8"
sourcemap = "6.1"
url = { version = "2.3.1", features = ["serde", "expose_internals"] }
v8 = { version = "0.54.0", default-features = false }

View file

@ -32,6 +32,7 @@ use futures::future::FutureExt;
use futures::stream::FuturesUnordered;
use futures::stream::StreamExt;
use futures::task::AtomicWaker;
use smallvec::SmallVec;
use std::any::Any;
use std::cell::RefCell;
use std::collections::HashMap;
@ -1972,10 +1973,13 @@ impl JsRuntime {
// Send finished responses to JS
fn resolve_async_ops(&mut self, cx: &mut Context) -> Result<(), Error> {
let isolate = self.v8_isolate.as_mut().unwrap();
let js_recv_cb_handle = self.state.borrow().js_recv_cb.clone().unwrap();
let global_realm = self.state.borrow().global_realm.clone().unwrap();
let scope = &mut global_realm.handle_scope(isolate);
let scope = &mut self
.state
.borrow()
.global_realm
.as_ref()
.unwrap()
.handle_scope(isolate);
// We return async responses to JS in unbounded batches (may change),
// each batch is a flat vector of tuples:
@ -1984,7 +1988,10 @@ impl JsRuntime {
// which contains a value OR an error, encoded as a tuple.
// This batch is received in JS via the special `arguments` variable
// and then each tuple is used to resolve or reject promises
let mut args: Vec<v8::Local<v8::Value>> = vec![];
//
// This can handle 16 promises (32 / 2) futures in a single batch without heap
// allocations.
let mut args: SmallVec<[v8::Local<v8::Value>; 32]> = SmallVec::new();
// Now handle actual ops.
{
@ -2010,6 +2017,7 @@ impl JsRuntime {
return Ok(());
}
let js_recv_cb_handle = self.state.borrow().js_recv_cb.clone().unwrap();
let tc_scope = &mut v8::TryCatch::new(scope);
let js_recv_cb = js_recv_cb_handle.open(tc_scope);
let this = v8::undefined(tc_scope).into();