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

perf(core): avoid isolate slots for ModuleMap (#16409)

This commit is contained in:
Divy Srivastava 2022-10-25 17:57:33 +05:30 committed by GitHub
parent 34fb380ed3
commit f242d98280
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -78,6 +78,7 @@ struct IsolateAllocations {
/// and an optional zero copy buffer, each async Op is tied to a Promise in JavaScript.
pub struct JsRuntime {
state: Rc<RefCell<JsRuntimeState>>,
module_map: Option<Rc<RefCell<ModuleMap>>>,
// This is an Option<OwnedIsolate> instead of just OwnedIsolate to workaround
// a safety issue with SnapshotCreator. See JsRuntime::drop.
v8_isolate: Option<v8::OwnedIsolate>,
@ -448,7 +449,7 @@ impl JsRuntime {
let module_map_rc = Rc::new(RefCell::new(ModuleMap::new(loader, op_state)));
isolate.set_data(
Self::MODULE_MAP_DATA_OFFSET,
Rc::into_raw(module_map_rc) as *mut c_void,
Rc::into_raw(module_map_rc.clone()) as *mut c_void,
);
let mut js_runtime = Self {
@ -458,6 +459,7 @@ impl JsRuntime {
event_loop_middlewares: Vec::with_capacity(options.extensions.len()),
extensions: options.extensions,
state: state_rc,
module_map: Some(module_map_rc),
};
// Init resources and ops before extensions to make sure they are
@ -491,6 +493,11 @@ impl JsRuntime {
drop(module_map_rc);
}
#[inline]
fn get_module_map(&mut self) -> &Rc<RefCell<ModuleMap>> {
self.module_map.as_ref().unwrap()
}
#[inline]
pub fn global_context(&mut self) -> v8::Global<v8::Context> {
self.global_realm().0
@ -782,6 +789,7 @@ impl JsRuntime {
// Drop existing ModuleMap to drop v8::Global handles
{
self.module_map.take();
let v8_isolate = self.v8_isolate();
Self::drop_state_and_module_map(v8_isolate);
}
@ -964,7 +972,6 @@ impl JsRuntime {
) -> Poll<Result<(), Error>> {
// We always poll the inspector first
let _ = self.inspector().borrow_mut().poll_unpin(cx);
let module_map_rc = Self::module_map(self.v8_isolate());
{
let state = self.state.borrow();
state.waker.register(cx.waker());
@ -1033,7 +1040,6 @@ impl JsRuntime {
}
let mut state = self.state.borrow_mut();
let module_map = module_map_rc.borrow();
// Check if more async ops have been dispatched
// during this turn of event loop.
@ -1075,6 +1081,7 @@ impl JsRuntime {
} else if state.dyn_module_evaluate_idle_counter >= 1 {
let mut msg = "Dynamically imported module evaluation is still pending but there are no pending ops. This situation is often caused by unresolved promises.
Pending dynamic modules:\n".to_string();
let module_map = self.module_map.as_mut().unwrap().borrow_mut();
for pending_evaluate in &state.pending_dyn_mod_evaluate {
let module_info = module_map
.get_info_by_id(&pending_evaluate.module_id)
@ -1097,9 +1104,8 @@ Pending dynamic modules:\n".to_string();
fn event_loop_pending_state(&mut self) -> EventLoopPendingState {
let isolate = self.v8_isolate.as_mut().unwrap();
let module_map_rc = Self::module_map(isolate);
let state = self.state.borrow_mut();
let module_map = module_map_rc.borrow();
let module_map = self.module_map.as_mut().unwrap().borrow();
EventLoopPendingState {
has_pending_refed_ops: state.pending_ops.len() > state.unrefed_ops.len(),
@ -1524,12 +1530,17 @@ impl JsRuntime {
&mut self,
cx: &mut Context,
) -> Poll<Result<(), Error>> {
let module_map_rc = Self::module_map(self.v8_isolate());
if module_map_rc.borrow().preparing_dynamic_imports.is_empty() {
if self
.get_module_map()
.borrow()
.preparing_dynamic_imports
.is_empty()
{
return Poll::Ready(Ok(()));
}
let module_map_rc = self.get_module_map().clone();
loop {
let poll_result = module_map_rc
.borrow_mut()
@ -1562,12 +1573,17 @@ impl JsRuntime {
}
fn poll_dyn_imports(&mut self, cx: &mut Context) -> Poll<Result<(), Error>> {
let module_map_rc = Self::module_map(self.v8_isolate());
if module_map_rc.borrow().pending_dynamic_imports.is_empty() {
if self
.get_module_map()
.borrow()
.pending_dynamic_imports
.is_empty()
{
return Poll::Ready(Ok(()));
}
let module_map_rc = self.get_module_map().clone();
loop {
let poll_result = module_map_rc
.borrow_mut()
@ -1653,16 +1669,15 @@ impl JsRuntime {
/// resolved or rejected the promise. If the promise is still pending
/// then another turn of event loop must be performed.
fn evaluate_pending_module(&mut self) {
let state_rc = self.state.clone();
let maybe_module_evaluation =
state_rc.borrow_mut().pending_mod_evaluate.take();
self.state.borrow_mut().pending_mod_evaluate.take();
if maybe_module_evaluation.is_none() {
return;
}
let mut module_evaluation = maybe_module_evaluation.unwrap();
let state_rc = self.state.clone();
let scope = &mut self.handle_scope();
let promise_global = module_evaluation.promise.clone().unwrap();
@ -1703,10 +1718,13 @@ impl JsRuntime {
// Returns true if some dynamic import was resolved.
fn evaluate_dyn_imports(&mut self) -> bool {
let mut resolved_any = false;
let mut still_pending = vec![];
let pending =
std::mem::take(&mut self.state.borrow_mut().pending_dyn_mod_evaluate);
if pending.is_empty() {
return false;
}
let mut resolved_any = false;
let mut still_pending = vec![];
for pending_dyn_evaluate in pending {
let maybe_result = {
let scope = &mut self.handle_scope();