diff options
author | Divy Srivastava <dj.srivastava23@gmail.com> | 2022-11-10 03:56:02 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-10 17:26:02 +0530 |
commit | 110a0ebe690f83a21c87f1ef1a6a51af67e2a5fc (patch) | |
tree | 7da8bbe4db832f3011913e65654e3ef4cb1b63c3 /core/runtime.rs | |
parent | bc33a4b2e06dd5518e0d1bbf7b538d0b00df214d (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.rs | 18 |
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(); |