Browse Source

Use `Rc` instead of `Gc` for `CompileTimeEnvironment`s (#3025)

* Use `Rc` instead of `Gc` for `CompileTimeEnvironment`s

* Add comment
pull/3056/head
Haled Odat 1 year ago committed by GitHub
parent
commit
610cf2c3c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      boa_engine/src/bytecompiler/env.rs
  2. 6
      boa_engine/src/bytecompiler/function.rs
  3. 13
      boa_engine/src/bytecompiler/mod.rs
  4. 18
      boa_engine/src/environments/compile.rs
  5. 18
      boa_engine/src/environments/runtime/declarative/mod.rs
  6. 17
      boa_engine/src/environments/runtime/mod.rs
  7. 4
      boa_engine/src/module/source.rs
  8. 16
      boa_engine/src/vm/code_block.rs

5
boa_engine/src/bytecompiler/env.rs

@ -1,12 +1,13 @@
use std::{cell::RefCell, rc::Rc};
use super::ByteCompiler; use super::ByteCompiler;
use crate::environments::{BindingLocator, BindingLocatorError, CompileTimeEnvironment}; use crate::environments::{BindingLocator, BindingLocatorError, CompileTimeEnvironment};
use boa_ast::expression::Identifier; use boa_ast::expression::Identifier;
use boa_gc::{Gc, GcRefCell};
impl ByteCompiler<'_, '_> { impl ByteCompiler<'_, '_> {
/// Push either a new declarative or function environment on the compile time environment stack. /// Push either a new declarative or function environment on the compile time environment stack.
pub(crate) fn push_compile_environment(&mut self, function_scope: bool) { pub(crate) fn push_compile_environment(&mut self, function_scope: bool) {
self.current_environment = Gc::new(GcRefCell::new(CompileTimeEnvironment::new( self.current_environment = Rc::new(RefCell::new(CompileTimeEnvironment::new(
self.current_environment.clone(), self.current_environment.clone(),
function_scope, function_scope,
))); )));

6
boa_engine/src/bytecompiler/function.rs

@ -1,3 +1,5 @@
use std::{cell::RefCell, rc::Rc};
use crate::{ use crate::{
builtins::function::ThisMode, builtins::function::ThisMode,
bytecompiler::ByteCompiler, bytecompiler::ByteCompiler,
@ -6,7 +8,7 @@ use crate::{
Context, Context,
}; };
use boa_ast::function::{FormalParameterList, FunctionBody}; use boa_ast::function::{FormalParameterList, FunctionBody};
use boa_gc::{Gc, GcRefCell}; use boa_gc::Gc;
use boa_interner::Sym; use boa_interner::Sym;
/// `FunctionCompiler` is used to compile AST functions to bytecode. /// `FunctionCompiler` is used to compile AST functions to bytecode.
@ -88,7 +90,7 @@ impl FunctionCompiler {
mut self, mut self,
parameters: &FormalParameterList, parameters: &FormalParameterList,
body: &FunctionBody, body: &FunctionBody,
outer_env: Gc<GcRefCell<CompileTimeEnvironment>>, outer_env: Rc<RefCell<CompileTimeEnvironment>>,
context: &mut Context<'_>, context: &mut Context<'_>,
) -> Gc<CodeBlock> { ) -> Gc<CodeBlock> {
self.strict = self.strict || body.strict(); self.strict = self.strict || body.strict();

13
boa_engine/src/bytecompiler/mod.rs

@ -11,7 +11,10 @@ mod module;
mod statement; mod statement;
mod utils; mod utils;
use std::cell::Cell; use std::{
cell::{Cell, RefCell},
rc::Rc,
};
use crate::{ use crate::{
builtins::function::ThisMode, builtins::function::ThisMode,
@ -35,7 +38,7 @@ use boa_ast::{
pattern::Pattern, pattern::Pattern,
Declaration, Expression, Statement, StatementList, StatementListItem, Declaration, Expression, Statement, StatementList, StatementListItem,
}; };
use boa_gc::{Gc, GcRefCell}; use boa_gc::Gc;
use boa_interner::{Interner, Sym}; use boa_interner::{Interner, Sym};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
@ -241,10 +244,10 @@ pub struct ByteCompiler<'ctx, 'host> {
pub(crate) functions: Vec<Gc<CodeBlock>>, pub(crate) functions: Vec<Gc<CodeBlock>>,
/// Compile time environments in this function. /// Compile time environments in this function.
pub(crate) compile_environments: Vec<Gc<GcRefCell<CompileTimeEnvironment>>>, pub(crate) compile_environments: Vec<Rc<RefCell<CompileTimeEnvironment>>>,
/// The environment that is currently active. /// The environment that is currently active.
pub(crate) current_environment: Gc<GcRefCell<CompileTimeEnvironment>>, pub(crate) current_environment: Rc<RefCell<CompileTimeEnvironment>>,
pub(crate) code_block_flags: CodeBlockFlags, pub(crate) code_block_flags: CodeBlockFlags,
@ -273,7 +276,7 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
name: Sym, name: Sym,
strict: bool, strict: bool,
json_parse: bool, json_parse: bool,
current_environment: Gc<GcRefCell<CompileTimeEnvironment>>, current_environment: Rc<RefCell<CompileTimeEnvironment>>,
// TODO: remove when we separate scripts from the context // TODO: remove when we separate scripts from the context
context: &'ctx mut Context<'host>, context: &'ctx mut Context<'host>,
) -> ByteCompiler<'ctx, 'host> { ) -> ByteCompiler<'ctx, 'host> {

18
boa_engine/src/environments/compile.rs

@ -1,6 +1,8 @@
use std::{cell::RefCell, rc::Rc};
use crate::environments::runtime::BindingLocator; use crate::environments::runtime::BindingLocator;
use boa_ast::expression::Identifier; use boa_ast::expression::Identifier;
use boa_gc::{Finalize, Gc, GcRefCell, Trace}; use boa_gc::{empty_trace, Finalize, Trace};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
@ -20,15 +22,19 @@ struct CompileTimeBinding {
/// A compile time environment maps bound identifiers to their binding positions. /// A compile time environment maps bound identifiers to their binding positions.
/// ///
/// A compile time environment also indicates, if it is a function environment. /// A compile time environment also indicates, if it is a function environment.
#[derive(Debug, Finalize, Trace)] #[derive(Debug, Finalize)]
pub(crate) struct CompileTimeEnvironment { pub(crate) struct CompileTimeEnvironment {
outer: Option<Gc<GcRefCell<Self>>>, outer: Option<Rc<RefCell<Self>>>,
environment_index: u32, environment_index: u32,
#[unsafe_ignore_trace]
bindings: FxHashMap<Identifier, CompileTimeBinding>, bindings: FxHashMap<Identifier, CompileTimeBinding>,
function_scope: bool, function_scope: bool,
} }
// Safety: Nothing in this struct needs tracing, so this is safe.
unsafe impl Trace for CompileTimeEnvironment {
empty_trace!();
}
impl CompileTimeEnvironment { impl CompileTimeEnvironment {
/// Creates a new global compile time environment. /// Creates a new global compile time environment.
pub(crate) fn new_global() -> Self { pub(crate) fn new_global() -> Self {
@ -41,7 +47,7 @@ impl CompileTimeEnvironment {
} }
/// Creates a new compile time environment. /// Creates a new compile time environment.
pub(crate) fn new(parent: Gc<GcRefCell<Self>>, function_scope: bool) -> Self { pub(crate) fn new(parent: Rc<RefCell<Self>>, function_scope: bool) -> Self {
let index = parent.borrow().environment_index + 1; let index = parent.borrow().environment_index + 1;
Self { Self {
outer: Some(parent), outer: Some(parent),
@ -291,7 +297,7 @@ impl CompileTimeEnvironment {
} }
/// Gets the outer environment of this environment. /// Gets the outer environment of this environment.
pub(crate) fn outer(&self) -> Option<Gc<GcRefCell<Self>>> { pub(crate) fn outer(&self) -> Option<Rc<RefCell<Self>>> {
self.outer.clone() self.outer.clone()
} }

18
boa_engine/src/environments/runtime/declarative/mod.rs

@ -3,9 +3,12 @@ mod global;
mod lexical; mod lexical;
mod module; mod module;
use std::cell::Cell; use std::{
cell::{Cell, RefCell},
rc::Rc,
};
use boa_gc::{Finalize, Gc, GcRefCell, Trace}; use boa_gc::{Finalize, GcRefCell, Trace};
pub(crate) use function::{FunctionEnvironment, FunctionSlots, ThisBindingStatus}; pub(crate) use function::{FunctionEnvironment, FunctionSlots, ThisBindingStatus};
pub(crate) use global::GlobalEnvironment; pub(crate) use global::GlobalEnvironment;
pub(crate) use lexical::LexicalEnvironment; pub(crate) use lexical::LexicalEnvironment;
@ -36,7 +39,10 @@ use crate::{environments::CompileTimeEnvironment, JsObject, JsResult, JsValue};
#[derive(Debug, Trace, Finalize)] #[derive(Debug, Trace, Finalize)]
pub(crate) struct DeclarativeEnvironment { pub(crate) struct DeclarativeEnvironment {
kind: DeclarativeEnvironmentKind, kind: DeclarativeEnvironmentKind,
compile: Gc<GcRefCell<CompileTimeEnvironment>>,
// Safety: Nothing in CompileTimeEnvironment needs tracing.
#[unsafe_ignore_trace]
compile: Rc<RefCell<CompileTimeEnvironment>>,
} }
impl DeclarativeEnvironment { impl DeclarativeEnvironment {
@ -44,20 +50,20 @@ impl DeclarativeEnvironment {
pub(crate) fn global(global_this: JsObject) -> Self { pub(crate) fn global(global_this: JsObject) -> Self {
Self { Self {
kind: DeclarativeEnvironmentKind::Global(GlobalEnvironment::new(global_this)), kind: DeclarativeEnvironmentKind::Global(GlobalEnvironment::new(global_this)),
compile: Gc::new(GcRefCell::new(CompileTimeEnvironment::new_global())), compile: Rc::new(RefCell::new(CompileTimeEnvironment::new_global())),
} }
} }
/// Creates a new `DeclarativeEnvironment` from its kind and compile environment. /// Creates a new `DeclarativeEnvironment` from its kind and compile environment.
pub(crate) fn new( pub(crate) fn new(
kind: DeclarativeEnvironmentKind, kind: DeclarativeEnvironmentKind,
compile: Gc<GcRefCell<CompileTimeEnvironment>>, compile: Rc<RefCell<CompileTimeEnvironment>>,
) -> Self { ) -> Self {
Self { kind, compile } Self { kind, compile }
} }
/// Gets the compile time environment of this environment. /// Gets the compile time environment of this environment.
pub(crate) fn compile_env(&self) -> Gc<GcRefCell<CompileTimeEnvironment>> { pub(crate) fn compile_env(&self) -> Rc<RefCell<CompileTimeEnvironment>> {
self.compile.clone() self.compile.clone()
} }

17
boa_engine/src/environments/runtime/mod.rs

@ -1,10 +1,12 @@
use std::{cell::RefCell, rc::Rc};
use crate::{ use crate::{
environments::CompileTimeEnvironment, environments::CompileTimeEnvironment,
object::{JsObject, PrivateName}, object::{JsObject, PrivateName},
Context, JsResult, JsString, JsSymbol, JsValue, Context, JsResult, JsString, JsSymbol, JsValue,
}; };
use boa_ast::expression::Identifier; use boa_ast::expression::Identifier;
use boa_gc::{empty_trace, Finalize, Gc, GcRefCell, Trace}; use boa_gc::{empty_trace, Finalize, Gc, Trace};
use rustc_hash::FxHashSet; use rustc_hash::FxHashSet;
mod declarative; mod declarative;
@ -220,7 +222,7 @@ impl EnvironmentStack {
#[track_caller] #[track_caller]
pub(crate) fn push_lexical( pub(crate) fn push_lexical(
&mut self, &mut self,
compile_environment: Gc<GcRefCell<CompileTimeEnvironment>>, compile_environment: Rc<RefCell<CompileTimeEnvironment>>,
) -> u32 { ) -> u32 {
let num_bindings = compile_environment.borrow().num_bindings(); let num_bindings = compile_environment.borrow().num_bindings();
@ -265,7 +267,7 @@ impl EnvironmentStack {
#[track_caller] #[track_caller]
pub(crate) fn push_function( pub(crate) fn push_function(
&mut self, &mut self,
compile_environment: Gc<GcRefCell<CompileTimeEnvironment>>, compile_environment: Rc<RefCell<CompileTimeEnvironment>>,
function_slots: FunctionSlots, function_slots: FunctionSlots,
) { ) {
let num_bindings = compile_environment.borrow().num_bindings(); let num_bindings = compile_environment.borrow().num_bindings();
@ -309,7 +311,7 @@ impl EnvironmentStack {
#[track_caller] #[track_caller]
pub(crate) fn push_function_inherit( pub(crate) fn push_function_inherit(
&mut self, &mut self,
compile_environment: Gc<GcRefCell<CompileTimeEnvironment>>, compile_environment: Rc<RefCell<CompileTimeEnvironment>>,
) { ) {
let num_bindings = compile_environment.borrow().num_bindings(); let num_bindings = compile_environment.borrow().num_bindings();
@ -361,10 +363,7 @@ impl EnvironmentStack {
/// ///
/// Panics if no environment exists on the stack. /// Panics if no environment exists on the stack.
#[track_caller] #[track_caller]
pub(crate) fn push_module( pub(crate) fn push_module(&mut self, compile_environment: Rc<RefCell<CompileTimeEnvironment>>) {
&mut self,
compile_environment: Gc<GcRefCell<CompileTimeEnvironment>>,
) {
let num_bindings = compile_environment.borrow().num_bindings(); let num_bindings = compile_environment.borrow().num_bindings();
self.stack.push(Environment::Declarative(Gc::new( self.stack.push(Environment::Declarative(Gc::new(
DeclarativeEnvironment::new( DeclarativeEnvironment::new(
@ -401,7 +400,7 @@ impl EnvironmentStack {
/// # Panics /// # Panics
/// ///
/// Panics if no environment exists on the stack. /// Panics if no environment exists on the stack.
pub(crate) fn current_compile_environment(&self) -> Gc<GcRefCell<CompileTimeEnvironment>> { pub(crate) fn current_compile_environment(&self) -> Rc<RefCell<CompileTimeEnvironment>> {
self.stack self.stack
.iter() .iter()
.filter_map(Environment::as_declarative) .filter_map(Environment::as_declarative)

4
boa_engine/src/module/source.rs

@ -1,5 +1,5 @@
use std::{ use std::{
cell::Cell, cell::{Cell, RefCell},
collections::HashSet, collections::HashSet,
hash::{BuildHasherDefault, Hash}, hash::{BuildHasherDefault, Hash},
rc::Rc, rc::Rc,
@ -1403,7 +1403,7 @@ impl SourceTextModule {
// 6. Set module.[[Environment]] to env. // 6. Set module.[[Environment]] to env.
let global_env = realm.environment().clone(); let global_env = realm.environment().clone();
let global_compile_env = global_env.compile_env(); let global_compile_env = global_env.compile_env();
let module_compile_env = Gc::new(GcRefCell::new(CompileTimeEnvironment::new( let module_compile_env = Rc::new(RefCell::new(CompileTimeEnvironment::new(
global_compile_env, global_compile_env,
true, true,
))); )));

16
boa_engine/src/vm/code_block.rs

@ -20,10 +20,15 @@ use crate::{
}; };
use bitflags::bitflags; use bitflags::bitflags;
use boa_ast::function::FormalParameterList; use boa_ast::function::FormalParameterList;
use boa_gc::{empty_trace, Finalize, Gc, GcRefCell, Trace}; use boa_gc::{empty_trace, Finalize, Gc, Trace};
use boa_interner::Sym; use boa_interner::Sym;
use boa_profiler::Profiler; use boa_profiler::Profiler;
use std::{cell::Cell, collections::VecDeque, mem::size_of}; use std::{
cell::{Cell, RefCell},
collections::VecDeque,
mem::size_of,
rc::Rc,
};
use thin_vec::ThinVec; use thin_vec::ThinVec;
#[cfg(any(feature = "trace", feature = "flowgraph"))] #[cfg(any(feature = "trace", feature = "flowgraph"))]
@ -129,7 +134,12 @@ pub struct CodeBlock {
pub(crate) functions: Box<[Gc<Self>]>, pub(crate) functions: Box<[Gc<Self>]>,
/// Compile time environments in this function. /// Compile time environments in this function.
pub(crate) compile_environments: Box<[Gc<GcRefCell<CompileTimeEnvironment>>]>, ///
// Safety: Nothing in CompileTimeEnvironment needs tracing, so this is safe.
//
// TODO(#3034): Maybe changing this to Gc after garbage collection would be better than Rc.
#[unsafe_ignore_trace]
pub(crate) compile_environments: Box<[Rc<RefCell<CompileTimeEnvironment>>]>,
} }
/// ---- `CodeBlock` public API ---- /// ---- `CodeBlock` public API ----

Loading…
Cancel
Save