mirror of
https://github.com/denoland/deno.git
synced 2025-02-01 20:25:12 -05:00
perf(core): avoid isolate slots for ModuleMap (#16409)
This commit is contained in:
parent
34fb380ed3
commit
f242d98280
1 changed files with 34 additions and 16 deletions
|
@ -78,6 +78,7 @@ struct IsolateAllocations {
|
||||||
/// and an optional zero copy buffer, each async Op is tied to a Promise in JavaScript.
|
/// and an optional zero copy buffer, each async Op is tied to a Promise in JavaScript.
|
||||||
pub struct JsRuntime {
|
pub struct JsRuntime {
|
||||||
state: Rc<RefCell<JsRuntimeState>>,
|
state: Rc<RefCell<JsRuntimeState>>,
|
||||||
|
module_map: Option<Rc<RefCell<ModuleMap>>>,
|
||||||
// This is an Option<OwnedIsolate> instead of just OwnedIsolate to workaround
|
// This is an Option<OwnedIsolate> instead of just OwnedIsolate to workaround
|
||||||
// a safety issue with SnapshotCreator. See JsRuntime::drop.
|
// a safety issue with SnapshotCreator. See JsRuntime::drop.
|
||||||
v8_isolate: Option<v8::OwnedIsolate>,
|
v8_isolate: Option<v8::OwnedIsolate>,
|
||||||
|
@ -448,7 +449,7 @@ impl JsRuntime {
|
||||||
let module_map_rc = Rc::new(RefCell::new(ModuleMap::new(loader, op_state)));
|
let module_map_rc = Rc::new(RefCell::new(ModuleMap::new(loader, op_state)));
|
||||||
isolate.set_data(
|
isolate.set_data(
|
||||||
Self::MODULE_MAP_DATA_OFFSET,
|
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 {
|
let mut js_runtime = Self {
|
||||||
|
@ -458,6 +459,7 @@ impl JsRuntime {
|
||||||
event_loop_middlewares: Vec::with_capacity(options.extensions.len()),
|
event_loop_middlewares: Vec::with_capacity(options.extensions.len()),
|
||||||
extensions: options.extensions,
|
extensions: options.extensions,
|
||||||
state: state_rc,
|
state: state_rc,
|
||||||
|
module_map: Some(module_map_rc),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Init resources and ops before extensions to make sure they are
|
// Init resources and ops before extensions to make sure they are
|
||||||
|
@ -491,6 +493,11 @@ impl JsRuntime {
|
||||||
drop(module_map_rc);
|
drop(module_map_rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn get_module_map(&mut self) -> &Rc<RefCell<ModuleMap>> {
|
||||||
|
self.module_map.as_ref().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn global_context(&mut self) -> v8::Global<v8::Context> {
|
pub fn global_context(&mut self) -> v8::Global<v8::Context> {
|
||||||
self.global_realm().0
|
self.global_realm().0
|
||||||
|
@ -782,6 +789,7 @@ impl JsRuntime {
|
||||||
|
|
||||||
// Drop existing ModuleMap to drop v8::Global handles
|
// Drop existing ModuleMap to drop v8::Global handles
|
||||||
{
|
{
|
||||||
|
self.module_map.take();
|
||||||
let v8_isolate = self.v8_isolate();
|
let v8_isolate = self.v8_isolate();
|
||||||
Self::drop_state_and_module_map(v8_isolate);
|
Self::drop_state_and_module_map(v8_isolate);
|
||||||
}
|
}
|
||||||
|
@ -964,7 +972,6 @@ impl JsRuntime {
|
||||||
) -> Poll<Result<(), Error>> {
|
) -> Poll<Result<(), Error>> {
|
||||||
// We always poll the inspector first
|
// We always poll the inspector first
|
||||||
let _ = self.inspector().borrow_mut().poll_unpin(cx);
|
let _ = self.inspector().borrow_mut().poll_unpin(cx);
|
||||||
let module_map_rc = Self::module_map(self.v8_isolate());
|
|
||||||
{
|
{
|
||||||
let state = self.state.borrow();
|
let state = self.state.borrow();
|
||||||
state.waker.register(cx.waker());
|
state.waker.register(cx.waker());
|
||||||
|
@ -1033,7 +1040,6 @@ impl JsRuntime {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut state = self.state.borrow_mut();
|
let mut state = self.state.borrow_mut();
|
||||||
let module_map = module_map_rc.borrow();
|
|
||||||
|
|
||||||
// Check if more async ops have been dispatched
|
// Check if more async ops have been dispatched
|
||||||
// during this turn of event loop.
|
// during this turn of event loop.
|
||||||
|
@ -1075,6 +1081,7 @@ impl JsRuntime {
|
||||||
} else if state.dyn_module_evaluate_idle_counter >= 1 {
|
} 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.
|
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();
|
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 {
|
for pending_evaluate in &state.pending_dyn_mod_evaluate {
|
||||||
let module_info = module_map
|
let module_info = module_map
|
||||||
.get_info_by_id(&pending_evaluate.module_id)
|
.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 {
|
fn event_loop_pending_state(&mut self) -> EventLoopPendingState {
|
||||||
let isolate = self.v8_isolate.as_mut().unwrap();
|
let isolate = self.v8_isolate.as_mut().unwrap();
|
||||||
let module_map_rc = Self::module_map(isolate);
|
|
||||||
let state = self.state.borrow_mut();
|
let state = self.state.borrow_mut();
|
||||||
let module_map = module_map_rc.borrow();
|
let module_map = self.module_map.as_mut().unwrap().borrow();
|
||||||
|
|
||||||
EventLoopPendingState {
|
EventLoopPendingState {
|
||||||
has_pending_refed_ops: state.pending_ops.len() > state.unrefed_ops.len(),
|
has_pending_refed_ops: state.pending_ops.len() > state.unrefed_ops.len(),
|
||||||
|
@ -1524,12 +1530,17 @@ impl JsRuntime {
|
||||||
&mut self,
|
&mut self,
|
||||||
cx: &mut Context,
|
cx: &mut Context,
|
||||||
) -> Poll<Result<(), Error>> {
|
) -> Poll<Result<(), Error>> {
|
||||||
let module_map_rc = Self::module_map(self.v8_isolate());
|
if self
|
||||||
|
.get_module_map()
|
||||||
if module_map_rc.borrow().preparing_dynamic_imports.is_empty() {
|
.borrow()
|
||||||
|
.preparing_dynamic_imports
|
||||||
|
.is_empty()
|
||||||
|
{
|
||||||
return Poll::Ready(Ok(()));
|
return Poll::Ready(Ok(()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let module_map_rc = self.get_module_map().clone();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let poll_result = module_map_rc
|
let poll_result = module_map_rc
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
|
@ -1562,12 +1573,17 @@ impl JsRuntime {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll_dyn_imports(&mut self, cx: &mut Context) -> Poll<Result<(), Error>> {
|
fn poll_dyn_imports(&mut self, cx: &mut Context) -> Poll<Result<(), Error>> {
|
||||||
let module_map_rc = Self::module_map(self.v8_isolate());
|
if self
|
||||||
|
.get_module_map()
|
||||||
if module_map_rc.borrow().pending_dynamic_imports.is_empty() {
|
.borrow()
|
||||||
|
.pending_dynamic_imports
|
||||||
|
.is_empty()
|
||||||
|
{
|
||||||
return Poll::Ready(Ok(()));
|
return Poll::Ready(Ok(()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let module_map_rc = self.get_module_map().clone();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let poll_result = module_map_rc
|
let poll_result = module_map_rc
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
|
@ -1653,16 +1669,15 @@ impl JsRuntime {
|
||||||
/// resolved or rejected the promise. If the promise is still pending
|
/// resolved or rejected the promise. If the promise is still pending
|
||||||
/// then another turn of event loop must be performed.
|
/// then another turn of event loop must be performed.
|
||||||
fn evaluate_pending_module(&mut self) {
|
fn evaluate_pending_module(&mut self) {
|
||||||
let state_rc = self.state.clone();
|
|
||||||
|
|
||||||
let maybe_module_evaluation =
|
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() {
|
if maybe_module_evaluation.is_none() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut module_evaluation = maybe_module_evaluation.unwrap();
|
let mut module_evaluation = maybe_module_evaluation.unwrap();
|
||||||
|
let state_rc = self.state.clone();
|
||||||
let scope = &mut self.handle_scope();
|
let scope = &mut self.handle_scope();
|
||||||
|
|
||||||
let promise_global = module_evaluation.promise.clone().unwrap();
|
let promise_global = module_evaluation.promise.clone().unwrap();
|
||||||
|
@ -1703,10 +1718,13 @@ impl JsRuntime {
|
||||||
|
|
||||||
// Returns true if some dynamic import was resolved.
|
// Returns true if some dynamic import was resolved.
|
||||||
fn evaluate_dyn_imports(&mut self) -> bool {
|
fn evaluate_dyn_imports(&mut self) -> bool {
|
||||||
let mut resolved_any = false;
|
|
||||||
let mut still_pending = vec![];
|
|
||||||
let pending =
|
let pending =
|
||||||
std::mem::take(&mut self.state.borrow_mut().pending_dyn_mod_evaluate);
|
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 {
|
for pending_dyn_evaluate in pending {
|
||||||
let maybe_result = {
|
let maybe_result = {
|
||||||
let scope = &mut self.handle_scope();
|
let scope = &mut self.handle_scope();
|
||||||
|
|
Loading…
Add table
Reference in a new issue