diff options
author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2022-10-15 16:01:01 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-15 16:01:01 +0200 |
commit | e32719c2915aee9055327609ef03cf9bfc2b1785 (patch) | |
tree | 8894c93aa320ba3aa0a57637cf584f6f95dd807e | |
parent | 4ea4d3ad603ca06591e33592724cd935afb0185b (diff) |
refactor(core): use isolate get_data/set_data instead of slots (#16286)
-rw-r--r-- | core/modules.rs | 6 | ||||
-rw-r--r-- | core/runtime.rs | 77 |
2 files changed, 63 insertions, 20 deletions
diff --git a/core/modules.rs b/core/modules.rs index 65b3852d9..8d0ae9733 100644 --- a/core/modules.rs +++ b/core/modules.rs @@ -5,6 +5,7 @@ use crate::error::generic_error; use crate::module_specifier::ModuleSpecifier; use crate::resolve_import; use crate::resolve_url; +use crate::JsRuntime; use crate::OpState; use anyhow::Error; use futures::future::FutureExt; @@ -125,10 +126,7 @@ fn json_module_evaluation_steps<'a>( // SAFETY: `CallbackScope` can be safely constructed from `Local<Context>` let scope = &mut unsafe { v8::CallbackScope::new(context) }; let tc_scope = &mut v8::TryCatch::new(scope); - let module_map = tc_scope - .get_slot::<Rc<RefCell<ModuleMap>>>() - .unwrap() - .clone(); + let module_map = JsRuntime::module_map(tc_scope); let handle = v8::Global::<v8::Module>::new(tc_scope, module); let value_handle = module_map diff --git a/core/runtime.rs b/core/runtime.rs index 2b824588c..9867ae821 100644 --- a/core/runtime.rs +++ b/core/runtime.rs @@ -45,6 +45,7 @@ use std::sync::Mutex; use std::sync::Once; use std::task::Context; use std::task::Poll; +use v8::OwnedIsolate; type PendingOpFuture = OpCall<(v8::Global<v8::Context>, PromiseId, OpId, OpResult)>; @@ -280,7 +281,18 @@ pub struct RuntimeOptions { pub compiled_wasm_module_store: Option<CompiledWasmModuleStore>, } +impl Drop for JsRuntime { + fn drop(&mut self) { + if let Some(v8_isolate) = self.v8_isolate.as_mut() { + Self::drop_state_and_module_map(v8_isolate); + } + } +} + impl JsRuntime { + const STATE_DATA_OFFSET: u32 = 0; + const MODULE_MAP_DATA_OFFSET: u32 = 1; + /// Only constructor, configuration is done through `options`. pub fn new(mut options: RuntimeOptions) -> Self { let v8_platform = options.v8_platform.take(); @@ -397,7 +409,7 @@ impl JsRuntime { .unwrap_or_else(|| Rc::new(NoopModuleLoader)); let known_realms = vec![v8::Weak::new(&mut isolate, &global_context)]; - isolate.set_slot(Rc::new(RefCell::new(JsRuntimeState { + let state_rc = Rc::new(RefCell::new(JsRuntimeState { global_realm: Some(JsRealm(global_context.clone())), known_realms, pending_promise_exceptions: HashMap::new(), @@ -418,14 +430,21 @@ impl JsRuntime { dispatched_exceptions: Default::default(), inspector: Some(inspector), waker: AtomicWaker::new(), - }))); + })); + isolate.set_data( + Self::STATE_DATA_OFFSET, + Rc::into_raw(state_rc) as *mut c_void, + ); global_context .open(&mut isolate) .set_slot(&mut isolate, Rc::<RefCell<ContextState>>::default()); - let module_map = ModuleMap::new(loader, op_state); - isolate.set_slot(Rc::new(RefCell::new(module_map))); + 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, + ); let mut js_runtime = Self { v8_isolate: Some(isolate), @@ -451,6 +470,22 @@ impl JsRuntime { js_runtime } + fn drop_state_and_module_map(v8_isolate: &mut OwnedIsolate) { + let state_ptr = v8_isolate.get_data(Self::STATE_DATA_OFFSET); + let state_rc = + // SAFETY: We are sure that it's a valid pointer for whole lifetime of + // the runtime. + unsafe { Rc::from_raw(state_ptr as *const RefCell<JsRuntimeState>) }; + drop(state_rc); + + let module_map_ptr = v8_isolate.get_data(Self::MODULE_MAP_DATA_OFFSET); + let module_map_rc = + // SAFETY: We are sure that it's a valid pointer for whole lifetime of + // the runtime. + unsafe { Rc::from_raw(module_map_ptr as *const RefCell<ModuleMap>) }; + drop(module_map_rc); + } + pub fn global_context(&mut self) -> v8::Global<v8::Context> { self.global_realm().0 } @@ -523,13 +558,25 @@ impl JsRuntime { } pub(crate) fn state(isolate: &v8::Isolate) -> Rc<RefCell<JsRuntimeState>> { - let s = isolate.get_slot::<Rc<RefCell<JsRuntimeState>>>().unwrap(); - s.clone() + let state_ptr = isolate.get_data(Self::STATE_DATA_OFFSET); + let state_rc = + // SAFETY: We are sure that it's a valid pointer for whole lifetime of + // the runtime. + unsafe { Rc::from_raw(state_ptr as *const RefCell<JsRuntimeState>) }; + let state = state_rc.clone(); + Rc::into_raw(state_rc); + state } pub(crate) fn module_map(isolate: &v8::Isolate) -> Rc<RefCell<ModuleMap>> { - let module_map = isolate.get_slot::<Rc<RefCell<ModuleMap>>>().unwrap(); - module_map.clone() + let module_map_ptr = isolate.get_data(Self::MODULE_MAP_DATA_OFFSET); + let module_map_rc = + // SAFETY: We are sure that it's a valid pointer for whole lifetime of + // the runtime. + unsafe { Rc::from_raw(module_map_ptr as *const RefCell<ModuleMap>) }; + let module_map = module_map_rc.clone(); + Rc::into_raw(module_map_rc); + module_map } /// Initializes JS of provided Extensions in the given realm @@ -733,13 +780,11 @@ impl JsRuntime { state.borrow_mut().inspector.take(); - // Overwrite existing ModuleMap to drop v8::Global handles - self - .v8_isolate() - .set_slot(Rc::new(RefCell::new(ModuleMap::new( - Rc::new(NoopModuleLoader), - state.borrow().op_state.clone(), - )))); + // Drop existing ModuleMap to drop v8::Global handles + { + let v8_isolate = self.v8_isolate(); + Self::drop_state_and_module_map(v8_isolate); + } // Drop other v8::Global handles before snapshotting { @@ -763,7 +808,7 @@ impl JsRuntime { state.js_nexttick_cbs.clear(); } - let snapshot_creator = self.v8_isolate.unwrap(); + let snapshot_creator = self.v8_isolate.take().unwrap(); snapshot_creator .create_blob(v8::FunctionCodeHandling::Keep) .unwrap() |