summaryrefslogtreecommitdiff
path: root/core/runtime.rs
diff options
context:
space:
mode:
authorDivy Srivastava <dj.srivastava23@gmail.com>2022-11-10 03:56:02 -0800
committerGitHub <noreply@github.com>2022-11-10 17:26:02 +0530
commit110a0ebe690f83a21c87f1ef1a6a51af67e2a5fc (patch)
tree7da8bbe4db832f3011913e65654e3ef4cb1b63c3 /core/runtime.rs
parentbc33a4b2e06dd5518e0d1bbf7b538d0b00df214d (diff)
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.
Diffstat (limited to 'core/runtime.rs')
-rw-r--r--core/runtime.rs18
1 files changed, 13 insertions, 5 deletions
diff --git a/core/runtime.rs b/core/runtime.rs
index b5e2141fb..21e6e7570 100644
--- a/core/runtime.rs
+++ b/core/runtime.rs
@@ -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();