Skip to content

Commit

Permalink
Use slotmap instead of Rc for BasicBlocks
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat committed Dec 9, 2023
1 parent b7b6293 commit bc23182
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 245 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 1 addition & 6 deletions cli/src/debug/optimizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@ use boa_engine::{
builtins::function::OrdinaryFunction,
js_string,
object::{FunctionObjectBuilder, ObjectInitializer},
optimizer::{
control_flow_graph::{
ControlFlowGraph, GraphEliminateUnreachableBasicBlocks, GraphSimplification,
},
OptimizerOptions,
},
optimizer::{control_flow_graph::ControlFlowGraph, OptimizerOptions},
property::Attribute,
Context, JsArgs, JsNativeError, JsObject, JsResult, JsValue, NativeFunction,
};
Expand Down
1 change: 1 addition & 0 deletions core/engine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ bytemuck = { version = "1.14.0", features = ["derive"] }
arrayvec = "0.7.4"
intrusive-collections = "0.9.6"
cfg-if = "1.0.0"
slotmap = { version = "1.0", default-features = false }

# intl deps
boa_icu_provider = {workspace = true, features = ["std"], optional = true }
Expand Down
105 changes: 13 additions & 92 deletions core/engine/src/optimizer/control_flow_graph/basic_block.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
use std::{
cell::RefCell,
hash::{Hash, Hasher},
ops::Deref,
rc::{Rc, Weak},
};
use std::hash::Hash;

use bitflags::bitflags;

use crate::vm::Instruction;

use super::Terminator;
use super::{BasicBlockKey, Terminator};

bitflags! {
#[derive(Default, Clone, Copy, Debug, PartialEq, Eq, Hash)]
Expand All @@ -21,10 +16,10 @@ bitflags! {
/// TODO: doc
#[derive(Default, Clone)]
pub struct BasicBlock {
pub(crate) predecessors: Vec<WeakBasicBlock>,
pub(crate) predecessors: Vec<BasicBlockKey>,
pub(crate) instructions: Vec<Instruction>,
pub(crate) terminator: Terminator,
pub(crate) handler: Option<RcBasicBlock>,
pub(crate) handler: Option<BasicBlockKey>,

pub(crate) flags: BasicBlockFlags,
}
Expand Down Expand Up @@ -59,105 +54,31 @@ impl BasicBlock {
self.flags.contains(BasicBlockFlags::REACHABLE)
}

pub(crate) fn successors(&self) -> Vec<RcBasicBlock> {
match &self.terminator {
pub(crate) fn successors(&self) -> Vec<BasicBlockKey> {
match self.terminator {
Terminator::None => vec![],
Terminator::JumpUnconditional { target, .. } => {
vec![target.clone()]
vec![target]
}
Terminator::JumpConditional { no, yes, .. }
| Terminator::TemplateLookup { no, yes, .. } => {
vec![no.clone(), yes.clone()]
vec![no, yes]
}
Terminator::Return => Vec::new(),
}
}

pub(crate) fn next(&self, nexts: &mut Vec<RcBasicBlock>) {
match &self.terminator {
pub(crate) fn next(&self, nexts: &mut Vec<BasicBlockKey>) {
match self.terminator {
Terminator::None | Terminator::Return => {}
Terminator::JumpUnconditional { target, .. } => {
nexts.push(target.clone());
nexts.push(target);
}
Terminator::JumpConditional { no, yes, .. }
| Terminator::TemplateLookup { no, yes, .. } => {
nexts.push(no.clone());
nexts.push(yes.clone());
nexts.push(no);
nexts.push(yes);
}
}
}
}

/// Reference counted [`BasicBlock`] with interor mutability.
#[derive(Default, Clone)]
pub struct RcBasicBlock {
inner: Rc<RefCell<BasicBlock>>,
}

impl From<Rc<RefCell<BasicBlock>>> for RcBasicBlock {
fn from(inner: Rc<RefCell<BasicBlock>>) -> Self {
Self { inner }
}
}

impl Deref for RcBasicBlock {
type Target = Rc<RefCell<BasicBlock>>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}

impl PartialEq<RcBasicBlock> for RcBasicBlock {
fn eq(&self, other: &RcBasicBlock) -> bool {
Rc::ptr_eq(&self.inner, &other.inner)
}
}

impl Eq for RcBasicBlock {}

impl Hash for RcBasicBlock {
fn hash<H: Hasher>(&self, state: &mut H) {
(self.as_ptr() as usize).hash(state);
}
}

impl RcBasicBlock {
/// TODO: doc
#[must_use]
pub fn downgrade(&self) -> WeakBasicBlock {
WeakBasicBlock::from(Rc::downgrade(&self.inner))
}
}

/// Reference counted [`BasicBlock`] with interor mutability.
#[derive(Default, Clone)]
pub struct WeakBasicBlock {
inner: Weak<RefCell<BasicBlock>>,
}

impl From<Weak<RefCell<BasicBlock>>> for WeakBasicBlock {
fn from(inner: Weak<RefCell<BasicBlock>>) -> Self {
Self { inner }
}
}

impl Deref for WeakBasicBlock {
type Target = Weak<RefCell<BasicBlock>>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}

impl PartialEq<WeakBasicBlock> for WeakBasicBlock {
fn eq(&self, other: &WeakBasicBlock) -> bool {
Weak::ptr_eq(&self.inner, &other.inner)
}
}

impl WeakBasicBlock {
/// TODO: doc
#[must_use]
pub fn upgrade(&self) -> Option<RcBasicBlock> {
Some(RcBasicBlock::from(self.inner.upgrade()?))
}
}
Loading

0 comments on commit bc23182

Please sign in to comment.