diff --git a/boa_engine/src/object/shape/shared_shape/forward_transition.rs b/boa_engine/src/object/shape/shared_shape/forward_transition.rs index 6c7e6703110..b3063010da5 100644 --- a/boa_engine/src/object/shape/shared_shape/forward_transition.rs +++ b/boa_engine/src/object/shape/shared_shape/forward_transition.rs @@ -3,30 +3,48 @@ use std::hash::Hash; use boa_gc::{Finalize, Gc, GcRefCell, Trace, WeakGc}; use rustc_hash::FxHashMap; -use super::Inner as SharedShapeInner; +use crate::object::JsPrototype; + +use super::{Inner as SharedShapeInner, TransitionKey}; + +type TransitionMap = FxHashMap>; + +#[derive(Default, Debug, Trace, Finalize)] +struct Inner { + properties: Option>>, + prototypes: Option>>, +} /// Holds a forward reference to a previously created transition. /// The reference is weak, therefore it can be garbage collected if it is not in use. -#[derive(Debug, Clone, Trace, Finalize)] -pub(super) struct ForwardTransition { - transitions: GcRefCell>>, +#[derive(Default, Debug, Trace, Finalize)] +pub(super) struct ForwardTransition { + inner: GcRefCell, } -impl Default for ForwardTransition { - fn default() -> Self { - Self { - transitions: GcRefCell::default(), - } +impl ForwardTransition { + pub(super) fn insert_property(&self, key: TransitionKey, value: &Gc) { + let mut this = self.inner.borrow_mut(); + let properties = this.properties.get_or_insert_with(Box::default); + properties.insert(key, WeakGc::new(value)); } -} - -impl ForwardTransition { - pub(super) fn insert(&self, key: T, value: &Gc) { - let mut transitions = self.transitions.borrow_mut(); - transitions.insert(key, WeakGc::new(value)); + pub(super) fn insert_prototype(&self, key: JsPrototype, value: &Gc) { + let mut this = self.inner.borrow_mut(); + let prototypes = this.prototypes.get_or_insert_with(Box::default); + prototypes.insert(key, WeakGc::new(value)); + } + pub(super) fn get_property(&self, key: &TransitionKey) -> Option> { + let this = self.inner.borrow(); + let Some(transitions) = this.properties.as_ref() else { + return None; + }; + transitions.get(key).cloned() } - pub(super) fn get(&self, key: &T) -> Option> { - let transitions = self.transitions.borrow(); + pub(super) fn get_prototype(&self, key: &JsPrototype) -> Option> { + let this = self.inner.borrow(); + let Some(transitions) = this.prototypes.as_ref() else { + return None; + }; transitions.get(key).cloned() } } diff --git a/boa_engine/src/object/shape/shared_shape/mod.rs b/boa_engine/src/object/shape/shared_shape/mod.rs index 2f72b864be6..b8e970760ff 100644 --- a/boa_engine/src/object/shape/shared_shape/mod.rs +++ b/boa_engine/src/object/shape/shared_shape/mod.rs @@ -55,8 +55,7 @@ unsafe impl Trace for TransitionType { /// TODO: doc #[derive(Debug, Trace, Finalize)] struct Inner { - forward_property_transitions: ForwardTransition, - forward_prototype_transitions: ForwardTransition, + forward_transitions: ForwardTransition, property_count: u32, @@ -108,11 +107,8 @@ impl SharedShape { pub(crate) fn is_root(&self) -> bool { self.inner.previous.is_none() } - fn forward_property_transitions(&self) -> &ForwardTransition { - &self.inner.forward_property_transitions - } - fn forward_prototype_transitions(&self) -> &ForwardTransition { - &self.inner.forward_prototype_transitions + fn forward_transitions(&self) -> &ForwardTransition { + &self.inner.forward_transitions } fn new(inner: Inner) -> Self { Self { @@ -121,25 +117,11 @@ impl SharedShape { } pub(crate) fn root() -> Self { - println!("sizeof Inner: {}", std::mem::size_of::()); - println!( - "sizeof Innerff: {}", - std::mem::size_of::>>>() - ); - println!( - "sizeof Innerff: {}", - std::mem::size_of::>() - ); - println!( - "sizeof JsObject: {}", - std::mem::size_of::() - ); Self::new(Inner { + forward_transitions: ForwardTransition::default(), prototype: None, property_count: 0, property_table: PropertyTable::default(), - forward_property_transitions: ForwardTransition::default(), - forward_prototype_transitions: ForwardTransition::default(), previous: None, transition_type: TransitionType::Insert, }) @@ -159,8 +141,7 @@ impl SharedShape { ); let new_inner_shape = Inner { prototype: self.prototype(), - forward_property_transitions: ForwardTransition::default(), - forward_prototype_transitions: ForwardTransition::default(), + forward_transitions: ForwardTransition::default(), property_table, property_count: self.property_count() + 1, previous: Some(self.clone()), @@ -168,14 +149,14 @@ impl SharedShape { }; let new_shape = Self::new(new_inner_shape); - self.forward_property_transitions() - .insert(key, &new_shape.inner); + self.forward_transitions() + .insert_property(key, &new_shape.inner); new_shape } pub(crate) fn change_prototype_transition(&self, prototype: JsPrototype) -> Self { - if let Some(shape) = self.forward_prototype_transitions().get(&prototype) { + if let Some(shape) = self.forward_transitions().get_prototype(&prototype) { if let Some(inner) = shape.upgrade() { if Self::DEBUG { println!(" Shape: Resusing previous prototype change shape"); @@ -184,9 +165,8 @@ impl SharedShape { } } let new_inner_shape = Inner { + forward_transitions: ForwardTransition::default(), prototype: prototype.clone(), - forward_property_transitions: ForwardTransition::default(), - forward_prototype_transitions: ForwardTransition::default(), property_table: self.inner.property_table.clone(), property_count: self.property_count(), previous: Some(self.clone()), @@ -194,15 +174,15 @@ impl SharedShape { }; let new_shape = Self::new(new_inner_shape); - self.forward_prototype_transitions() - .insert(prototype, &new_shape.inner); + self.forward_transitions() + .insert_prototype(prototype, &new_shape.inner); new_shape } pub(crate) fn insert_property_transition(&self, key: TransitionKey) -> Self { // Check if we have already creaded such a transition, if so use it! - if let Some(shape) = self.forward_property_transitions().get(&key) { + if let Some(shape) = self.forward_transitions().get_property(&key) { if Self::DEBUG { println!("Shape: Trying to resuse previous shape"); } @@ -227,18 +207,17 @@ impl SharedShape { let property_table = self.inner.property_table.deep_clone_all(); property_table.set_attributes(&key.property_key, key.attributes); let new_inner_shape = Inner { + forward_transitions: ForwardTransition::default(), prototype: self.prototype(), property_table, property_count: self.property_count(), - forward_property_transitions: ForwardTransition::default(), - forward_prototype_transitions: ForwardTransition::default(), previous: Some(self.clone()), transition_type: TransitionType::Configure, }; let new_shape = Self::new(new_inner_shape); - self.forward_property_transitions() - .insert(key, &new_shape.inner); + self.forward_transitions() + .insert_property(key, &new_shape.inner); new_shape }