Skip to content

Commit

Permalink
Shrink Shared Shape from 128 to 72 bytes
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat committed Mar 25, 2023
1 parent 752a010 commit 05791d5
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 53 deletions.
52 changes: 35 additions & 17 deletions boa_engine/src/object/shape/shared_shape/forward_transition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T> = FxHashMap<T, WeakGc<SharedShapeInner>>;

#[derive(Default, Debug, Trace, Finalize)]
struct Inner {
properties: Option<Box<TransitionMap<TransitionKey>>>,
prototypes: Option<Box<TransitionMap<JsPrototype>>>,
}

/// 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>>>,
#[derive(Default, Debug, Trace, Finalize)]
pub(super) struct ForwardTransition {
inner: GcRefCell<Inner>,
}

impl<T: Hash + Eq + Trace + 'static> Default for ForwardTransition<T> {
fn default() -> Self {
Self {
transitions: GcRefCell::default(),
}
impl ForwardTransition {
pub(super) fn insert_property(&self, key: TransitionKey, value: &Gc<SharedShapeInner>) {
let mut this = self.inner.borrow_mut();
let properties = this.properties.get_or_insert_with(Box::default);
properties.insert(key, WeakGc::new(value));
}
}

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 insert_prototype(&self, key: JsPrototype, value: &Gc<SharedShapeInner>) {
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<WeakGc<SharedShapeInner>> {
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<WeakGc<SharedShapeInner>> {
let transitions = self.transitions.borrow();
pub(super) fn get_prototype(&self, key: &JsPrototype) -> Option<WeakGc<SharedShapeInner>> {
let this = self.inner.borrow();
let Some(transitions) = this.prototypes.as_ref() else {
return None;
};
transitions.get(key).cloned()
}
}
51 changes: 15 additions & 36 deletions boa_engine/src/object/shape/shared_shape/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ unsafe impl Trace for TransitionType {
/// TODO: doc
#[derive(Debug, Trace, Finalize)]
struct Inner {
forward_property_transitions: ForwardTransition<TransitionKey>,
forward_prototype_transitions: ForwardTransition<JsPrototype>,
forward_transitions: ForwardTransition,

property_count: u32,

Expand Down Expand Up @@ -108,11 +107,8 @@ impl SharedShape {
pub(crate) fn is_root(&self) -> bool {
self.inner.previous.is_none()
}
fn forward_property_transitions(&self) -> &ForwardTransition<TransitionKey> {
&self.inner.forward_property_transitions
}
fn forward_prototype_transitions(&self) -> &ForwardTransition<JsPrototype> {
&self.inner.forward_prototype_transitions
fn forward_transitions(&self) -> &ForwardTransition {
&self.inner.forward_transitions
}
fn new(inner: Inner) -> Self {
Self {
Expand All @@ -121,25 +117,11 @@ impl SharedShape {
}

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 {
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,
})
Expand All @@ -159,23 +141,22 @@ 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()),
transition_type: TransitionType::Insert,
};
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");
Expand All @@ -184,25 +165,24 @@ 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()),
transition_type: TransitionType::Prototype,
};
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");
}
Expand All @@ -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
}
Expand Down

0 comments on commit 05791d5

Please sign in to comment.