Skip to content

Commit

Permalink
Make tracing an opt-in feature (#2709)
Browse files Browse the repository at this point in the history
This PR adds the `"trace"` feature flag that enables vm opcode tracing (off by default), most users aren't interested in tracing/debugging that's why I think it should be made out-in.
  • Loading branch information
HalidOdat committed Mar 21, 2023
1 parent 4544362 commit 3b51226
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 6 deletions.
2 changes: 1 addition & 1 deletion boa_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ repository.workspace = true
rust-version.workspace = true

[dependencies]
boa_engine = { workspace = true, features = ["deser", "console", "flowgraph"] }
boa_engine = { workspace = true, features = ["deser", "console", "flowgraph", "trace"] }
boa_ast = { workspace = true, features = ["serde"]}
boa_parser.workspace = true
rustyline = { version = "11.0.0", features = ["derive"]}
Expand Down
3 changes: 3 additions & 0 deletions boa_engine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ fuzz = ["boa_ast/arbitrary", "boa_interner/arbitrary"]
# Enable Boa's VM instruction flowgraph generator.
flowgraph = []

# Enable Boa's VM instruction tracing.
trace = []

# Enable Boa's WHATWG console object implementation.
console = []

Expand Down
1 change: 1 addition & 0 deletions boa_engine/src/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,7 @@ impl Context<'_> {
}

/// Set the value of trace on the context
#[cfg(feature = "trace")]
pub fn set_trace(&mut self, trace: bool) {
self.vm.trace = trace;
}
Expand Down
13 changes: 10 additions & 3 deletions boa_engine/src/vm/code_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,22 @@ use crate::{
},
property::PropertyDescriptor,
string::utf16,
vm::{CallFrame, Opcode},
vm::CallFrame,
Context, JsResult, JsString, JsValue,
};
use boa_ast::{
expression::Identifier,
function::{FormalParameterList, PrivateName},
};
use boa_gc::{Finalize, Gc, GcRefCell, Trace};
use boa_interner::{Interner, Sym, ToInternedString};
use boa_interner::Sym;
use boa_profiler::Profiler;
use std::{collections::VecDeque, convert::TryInto, mem::size_of};
use std::{collections::VecDeque, mem::size_of};

#[cfg(any(feature = "trace", feature = "flowgraph"))]
use crate::vm::Opcode;
#[cfg(any(feature = "trace", feature = "flowgraph"))]
use boa_interner::{Interner, ToInternedString};

/// This represents whether a value can be read from [`CodeBlock`] code.
///
Expand Down Expand Up @@ -190,6 +195,7 @@ impl CodeBlock {
/// Modifies the `pc` to point to the next instruction.
///
/// Returns an empty `String` if no operands are present.
#[cfg(any(feature = "trace", feature = "flowgraph"))]
pub(crate) fn instruction_operands(&self, pc: &mut usize, interner: &Interner) -> String {
let opcode: Opcode = self.bytecode[*pc].try_into().expect("invalid opcode");
*pc += size_of::<Opcode>();
Expand Down Expand Up @@ -450,6 +456,7 @@ impl CodeBlock {
}
}

#[cfg(any(feature = "trace", feature = "flowgraph"))]
impl ToInternedString for CodeBlock {
fn to_interned_string(&self, interner: &Interner) -> String {
let name = interner.resolve_expect(self.name);
Expand Down
21 changes: 19 additions & 2 deletions boa_engine/src/vm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@ use crate::{
};
#[cfg(feature = "fuzz")]
use crate::{JsNativeError, JsNativeErrorKind};
use boa_interner::ToInternedString;
use boa_profiler::Profiler;
use std::{convert::TryInto, mem::size_of, time::Instant};
use std::{convert::TryInto, mem::size_of};

#[cfg(feature = "trace")]
use boa_interner::ToInternedString;
#[cfg(feature = "trace")]
use std::time::Instant;

mod call_frame;
mod code_block;
Expand All @@ -40,6 +44,7 @@ pub struct Vm {
pub(crate) frames: Vec<CallFrame>,
pub(crate) stack: Vec<JsValue>,
pub(crate) err: Option<JsError>,
#[cfg(feature = "trace")]
pub(crate) trace: bool,
pub(crate) stack_size_limit: usize,
}
Expand All @@ -50,6 +55,7 @@ impl Default for Vm {
frames: Vec::with_capacity(16),
stack: Vec::with_capacity(1024),
err: None,
#[cfg(feature = "trace")]
trace: false,
stack_size_limit: 1024,
}
Expand Down Expand Up @@ -133,14 +139,20 @@ impl Context<'_> {
}

pub(crate) fn run(&mut self) -> CompletionRecord {
#[cfg(feature = "trace")]
const COLUMN_WIDTH: usize = 26;
#[cfg(feature = "trace")]
const TIME_COLUMN_WIDTH: usize = COLUMN_WIDTH / 2;
#[cfg(feature = "trace")]
const OPCODE_COLUMN_WIDTH: usize = COLUMN_WIDTH;
#[cfg(feature = "trace")]
const OPERAND_COLUMN_WIDTH: usize = COLUMN_WIDTH;
#[cfg(feature = "trace")]
const NUMBER_OF_COLUMNS: usize = 4;

let _timer = Profiler::global().start_event("run", "vm");

#[cfg(feature = "trace")]
if self.vm.trace {
let msg = if self.vm.frames.last().is_some() {
" Call Frame "
Expand Down Expand Up @@ -203,6 +215,7 @@ impl Context<'_> {
}

// 1. Run the next instruction.
#[cfg(feature = "trace")]
let result = if self.vm.trace {
let mut pc = self.vm.frame().pc;
let opcode: Opcode = self
Expand Down Expand Up @@ -239,6 +252,9 @@ impl Context<'_> {
self.execute_instruction()
};

#[cfg(not(feature = "trace"))]
let result = self.execute_instruction();

// 2. Evaluate the result of executing the instruction.
match result {
Ok(CompletionType::Normal) => {}
Expand Down Expand Up @@ -295,6 +311,7 @@ impl Context<'_> {
}
}

#[cfg(feature = "trace")]
if self.vm.trace {
println!("\nStack:");
if self.vm.stack.is_empty() {
Expand Down

0 comments on commit 3b51226

Please sign in to comment.