Skip to content

Commit

Permalink
Abstract forwad transitions
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat committed Mar 25, 2023
1 parent 15c52d3 commit 752a010
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 27 deletions.
32 changes: 32 additions & 0 deletions boa_engine/src/object/shape/shared_shape/forward_transition.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use std::hash::Hash;

use boa_gc::{Finalize, Gc, GcRefCell, Trace, WeakGc};
use rustc_hash::FxHashMap;

use super::Inner as SharedShapeInner;

/// 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<T: Hash + Eq + Trace + 'static> {
transitions: GcRefCell<FxHashMap<T, WeakGc<SharedShapeInner>>>,
}

impl<T: Hash + Eq + Trace + 'static> Default for ForwardTransition<T> {
fn default() -> Self {
Self {
transitions: GcRefCell::default(),
}
}
}

impl<T: Hash + Eq + Trace + 'static> ForwardTransition<T> {
pub(super) fn insert(&self, key: T, value: &Gc<SharedShapeInner>) {
let mut transitions = self.transitions.borrow_mut();
transitions.insert(key, WeakGc::new(value));
}
pub(super) fn get(&self, key: &T) -> Option<WeakGc<SharedShapeInner>> {
let transitions = self.transitions.borrow();
transitions.get(key).cloned()
}
}
66 changes: 39 additions & 27 deletions boa_engine/src/object/shape/shared_shape/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
pub(crate) mod property_table;
mod forward_transition;
mod property_table;

use std::{
cell::{Cell, RefCell},
collections::hash_map::RandomState,
hash::Hash,
rc::Rc,
};

Expand All @@ -15,7 +17,7 @@ use crate::{
property::{Attribute, PropertyDescriptor, PropertyKey},
};

use self::property_table::PropertyTable;
use self::{forward_transition::ForwardTransition, property_table::PropertyTable};

use super::{
slot::{SlotAttribute, SlotIndex},
Expand Down Expand Up @@ -53,8 +55,8 @@ unsafe impl Trace for TransitionType {
/// TODO: doc
#[derive(Debug, Trace, Finalize)]
struct Inner {
forward_property_transitions: GcRefCell<FxHashMap<TransitionKey, WeakGc<Inner>>>,
forward_prototype_transitions: GcRefCell<FxHashMap<JsPrototype, WeakGc<Inner>>>,
forward_property_transitions: ForwardTransition<TransitionKey>,
forward_prototype_transitions: ForwardTransition<JsPrototype>,

property_count: u32,

Expand Down Expand Up @@ -106,28 +108,38 @@ impl SharedShape {
pub(crate) fn is_root(&self) -> bool {
self.inner.previous.is_none()
}
fn get_forward_property_transition(&self, key: &TransitionKey) -> Option<WeakGc<Inner>> {
let map = self.inner.forward_property_transitions.borrow();
map.get(key).cloned()
fn forward_property_transitions(&self) -> &ForwardTransition<TransitionKey> {
&self.inner.forward_property_transitions
}
fn get_forward_prototype_transition(&self, prototype: &JsPrototype) -> Option<WeakGc<Inner>> {
let map = self.inner.forward_prototype_transitions.borrow();
map.get(prototype).cloned()
fn forward_prototype_transitions(&self) -> &ForwardTransition<JsPrototype> {
&self.inner.forward_prototype_transitions
}

fn new(inner: Inner) -> Self {
Self {
inner: Gc::new(inner),
}
}

pub(crate) fn root() -> Self {
println!("sizeof Inner: {}", std::mem::size_of::<Inner>());
println!(
"sizeof Innerff: {}",
std::mem::size_of::<GcRefCell<FxHashMap<TransitionKey, WeakGc<Inner>>>>()
);
println!(
"sizeof Innerff: {}",
std::mem::size_of::<ForwardTransition<TransitionKey>>()
);
println!(
"sizeof JsObject: {}",
std::mem::size_of::<crate::object::JsObject>()
);
Self::new(Inner {
prototype: None,
property_count: 0,
property_table: PropertyTable::default(),
forward_property_transitions: GcRefCell::default(),
forward_prototype_transitions: GcRefCell::default(),
forward_property_transitions: ForwardTransition::default(),
forward_prototype_transitions: ForwardTransition::default(),
previous: None,
transition_type: TransitionType::Insert,
})
Expand All @@ -147,23 +159,23 @@ impl SharedShape {
);
let new_inner_shape = Inner {
prototype: self.prototype(),
forward_property_transitions: GcRefCell::default(),
forward_prototype_transitions: GcRefCell::default(),
forward_property_transitions: ForwardTransition::default(),
forward_prototype_transitions: ForwardTransition::default(),
property_table,
property_count: self.property_count() + 1,
previous: Some(self.clone()),
transition_type: TransitionType::Insert,
};
let new_shape = Self::new(new_inner_shape);

let mut map = self.inner.forward_property_transitions.borrow_mut();
map.insert(key, WeakGc::new(&new_shape.inner));
self.forward_property_transitions()
.insert(key, &new_shape.inner);

new_shape
}

pub(crate) fn change_prototype_transition(&self, prototype: JsPrototype) -> Self {
if let Some(shape) = self.get_forward_prototype_transition(&prototype) {
if let Some(shape) = self.forward_prototype_transitions().get(&prototype) {
if let Some(inner) = shape.upgrade() {
if Self::DEBUG {
println!(" Shape: Resusing previous prototype change shape");
Expand All @@ -173,24 +185,24 @@ impl SharedShape {
}
let new_inner_shape = Inner {
prototype: prototype.clone(),
forward_property_transitions: GcRefCell::default(),
forward_prototype_transitions: GcRefCell::default(),
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()),
transition_type: TransitionType::Prototype,
};
let new_shape = Self::new(new_inner_shape);

let mut map = self.inner.forward_prototype_transitions.borrow_mut();
map.insert(prototype, WeakGc::new(&new_shape.inner));
self.forward_prototype_transitions()
.insert(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.get_forward_property_transition(&key) {
if let Some(shape) = self.forward_property_transitions().get(&key) {
if Self::DEBUG {
println!("Shape: Trying to resuse previous shape");
}
Expand Down Expand Up @@ -218,15 +230,15 @@ impl SharedShape {
prototype: self.prototype(),
property_table,
property_count: self.property_count(),
forward_property_transitions: GcRefCell::default(),
forward_prototype_transitions: GcRefCell::default(),
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);

let mut map = self.inner.forward_property_transitions.borrow_mut();
map.insert(key, WeakGc::new(&new_shape.inner));
self.forward_property_transitions()
.insert(key, &new_shape.inner);

new_shape
}
Expand Down

0 comments on commit 752a010

Please sign in to comment.