Skip to content

Commit

Permalink
trace strings in localscopes and last bugfixes
Browse files Browse the repository at this point in the history
  • Loading branch information
y21 committed Dec 27, 2023
1 parent 100ed25 commit d9e93ab
Show file tree
Hide file tree
Showing 17 changed files with 175 additions and 566 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

4 changes: 2 additions & 2 deletions cli/src/cmd/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ pub fn eval(args: &ArgMatches) -> anyhow::Result<()> {

match scope.eval(source, opt) {
Ok(value) => println!("{}", format_value(value.root(&mut scope), &mut scope).unwrap()),
Err((EvalError::Exception(value), _)) => {
Err(EvalError::Exception(value)) => {
println!("{}", format_value(value.root(&mut scope), &mut scope).unwrap())
}
Err((EvalError::Middle(errs), _)) => println!("{}", errs.formattable(source, true)),
Err(EvalError::Middle(errs)) => println!("{}", errs.formattable(source, true)),
};

scope.process_async_tasks();
Expand Down
4 changes: 2 additions & 2 deletions cli/src/cmd/repl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ pub fn repl() -> anyhow::Result<()> {

match scope.eval(&input, OptLevel::Aggressive) {
Ok(value) => println!("{}", format_value(value.root(&mut scope), &mut scope).unwrap()),
Err((EvalError::Exception(value), _)) => {
Err(EvalError::Exception(value)) => {
println!("{}", format_value(value.root(&mut scope), &mut scope).unwrap())
}
Err((EvalError::Middle(errs), _)) => println!("{}", errs.formattable(&input, true)),
Err(EvalError::Middle(errs)) => println!("{}", errs.formattable(&input, true)),
}

scope.process_async_tasks();
Expand Down
4 changes: 2 additions & 2 deletions cli/src/cmd/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ async fn inner(source: String, opt: OptLevel, quiet: bool, initial_gc_threshold:
let mut scope = rt.vm_mut().scope();
let value = match scope.eval(&source, opt) {
Ok(val) => val.root(&mut scope),
Err((EvalError::Exception(val), _)) => val.root(&mut scope),
Err((EvalError::Middle(errs), _)) => {
Err(EvalError::Exception(val)) => val.root(&mut scope),
Err(EvalError::Middle(errs)) => {
println!("{}", errs.formattable(&source, true));
return Ok(());
}
Expand Down
49 changes: 40 additions & 9 deletions crates/dash_middle/src/interner.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::cell::Cell;
use std::hash::{BuildHasherDefault, Hash, Hasher};
use std::rc::Rc;
use std::{borrow, fmt};
Expand Down Expand Up @@ -256,9 +257,15 @@ pub mod sym {
}
}

#[derive(Debug)]
struct StringData {
visited: Cell<bool>,
value: Rc<str>,
}

#[derive(Default, Debug)]
pub struct StringInterner {
store: Vec<Option<Rc<str>>>,
store: Vec<Option<StringData>>,
mapping: hashbrown::HashMap<Rc<str>, RawSymbol, BuildHasherDefault<FxHasher>>,
/// List of free indices in the storage
free: Vec<RawSymbol>,
Expand All @@ -280,7 +287,10 @@ impl StringInterner {
let s: Rc<str> = Rc::from(*s);
debug_assert!(store.len() == index.0 as usize);
mapping.insert(s.clone(), index.0);
store.push(Some(s));
store.push(Some(StringData {
visited: Cell::new(false),
value: s,
}));
}

Self {
Expand All @@ -291,7 +301,7 @@ impl StringInterner {
}

pub fn resolve(&self, symbol: Symbol) -> &str {
self.store[symbol.0 as usize].as_ref().unwrap()
self.store[symbol.0 as usize].as_ref().unwrap().value.as_ref()
}

// TODO: perf improvement idea: use interior mutability and allow calling with just a `&self`
Expand All @@ -305,13 +315,19 @@ impl StringInterner {
RawEntryMut::Vacant(entry) => {
if let Some(id) = self.free.pop() {
let value: Rc<str> = Rc::from(value);
self.store[id as usize] = Some(Rc::clone(&value));
self.store[id as usize] = Some(StringData {
value: Rc::clone(&value),
visited: Cell::new(false),
});
entry.insert_hashed_nocheck(hash, value, id);
Symbol(id)
} else {
let id = self.store.len() as RawSymbol;
let value: Rc<str> = Rc::from(value);
self.store.push(Some(Rc::clone(&value)));
self.store.push(Some(StringData {
value: Rc::clone(&value),
visited: Cell::new(false),
}));
entry.insert_hashed_nocheck(hash, value, id);
Symbol(id)
}
Expand All @@ -337,10 +353,25 @@ impl StringInterner {
self.intern(string.as_ref())
}

// pub fn remove(&mut self, symbol: Symbol) {
// self.storage[symbol.0 as usize] = None;
// self.free.push(symbol.0);
// }
pub fn mark(&self, sym: Symbol) {
self.store[sym.0 as usize].as_ref().unwrap().visited.set(true);
}

/// You must mark all reachable symbols before calling this.
/// It won't cause undefined behavior if you don't (hence not unsafe), but it can lead to oddities such as panics.
pub fn sweep(&mut self) {
for i in 0..self.store.len() {
if let Some(data) = self.store[i].as_ref() {
if !data.visited.get() {
self.mapping.remove(&data.value);
self.store[i] = None;
self.free.push(i as RawSymbol);
} else {
data.visited.set(false);
}
}
}
}
}

type RawSymbol = u32;
Expand Down
18 changes: 9 additions & 9 deletions crates/dash_vm/src/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ mod handlers {
) -> Result<Option<HandleResult>, Unrooted> {
let (args, refs) = {
let mut args = Vec::with_capacity(argc);
let mut refs = Vec::new();
// let mut refs = Vec::new();

let len = cx.fetch_and_inc_ip();
let spread_indices: SmallVec<[_; 4]> = (0..len).map(|_| cx.fetch_and_inc_ip()).collect();
Expand All @@ -605,9 +605,9 @@ mod handlers {
if len == 0 {
// Fast path for no spread arguments
for value in iter {
if let Value::Object(handle) = &value {
refs.push(handle.clone());
}
// if let Value::Object(handle) = &value {
// refs.push(handle.clone());
// }

args.push(value);
}
Expand All @@ -626,18 +626,18 @@ mod handlers {
}
indices_iter.next();
} else {
if let Value::Object(handle) = &value {
refs.push(handle.clone());
}
// if let Value::Object(handle) = &value {
// refs.push(handle.clone());
// }
args.push(value);
}
}
}

(args, refs)
(args, ())
};

cx.scope.add_many(refs);
cx.scope.add_many(&args);

let ret = if is_constructor {
callee.construct(&mut cx, this, args)?
Expand Down
3 changes: 2 additions & 1 deletion crates/dash_vm/src/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ pub struct Exports {
unsafe impl Trace for Exports {
fn trace(&self, cx: &mut TraceCtxt<'_>) {
self.default.trace(cx);
for (_, v) in &self.named {
for (k, v) in &self.named {
k.trace(cx);
v.trace(cx);
}
}
Expand Down
Loading

0 comments on commit d9e93ab

Please sign in to comment.