Skip to content

Commit

Permalink
Speedup function calling by using RC
Browse files Browse the repository at this point in the history
  • Loading branch information
mliezun committed Jan 14, 2024
1 parent 613c453 commit 88fa78d
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 26 deletions.
45 changes: 45 additions & 0 deletions Cargo.lock

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

48 changes: 35 additions & 13 deletions src/interpreter.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::vm::StackEntry;
use crate::vm::{StackEntry, VMFnPrototype};
use crate::{compiler, lexer, native, parser, state, stmt, value, vm};
use std::collections::{HashMap, HashSet};
use std::panic;
use std::rc::Rc;

static mut ABSOLUTE_PATH: &'static str = "";

Expand Down Expand Up @@ -40,9 +41,9 @@ fn setup_global_interpreter() {
globals: HashSet::new(),
};
let mut my_vm = vm::VM {
instructions: vec![],
instructions_data: vec![],
prototypes: vec![],
instructions: Rc::new(vec![]),
instructions_data: Rc::new(vec![]),
prototypes: Rc::new(vec![]),
constants: vec![],
globals: HashMap::new(),
builtins: HashMap::new(),
Expand Down Expand Up @@ -132,9 +133,16 @@ pub fn run_interpreter_from_bytecode(bytecode: &[u8]) -> bool {
.map(|c| c.instructions.clone())
.flatten()
.collect();
interpreter.vm.instructions = instructions.iter().map(|i| i.inst.clone()).collect();
interpreter.vm.instructions_data = instructions.iter().map(|i| i.src.clone()).collect();
interpreter.vm.prototypes = interpreter.compiler.prototypes.clone();
interpreter.vm.instructions = Rc::new(instructions.iter().map(|i| i.inst.clone()).collect());
interpreter.vm.instructions_data = Rc::new(instructions.iter().map(|i| i.src.clone()).collect());
interpreter.vm.prototypes = Rc::new(interpreter.compiler.prototypes.iter().map(|p| VMFnPrototype{
instructions: Rc::new(p.instructions.clone()),
register_count: p.register_count,
upvalues: p.upvalues.clone(),
instruction_data: Rc::new(p.instruction_data.clone()),
param_count: p.param_count,
name: p.name.clone(),
}).collect());
interpreter.vm.constants = interpreter
.compiler
.constants
Expand Down Expand Up @@ -165,9 +173,16 @@ pub fn run_bytecode_interpreter(source: String) {
.map(|c| c.instructions.clone())
.flatten()
.collect();
interpreter.vm.instructions = instructions.iter().map(|i| i.inst.clone()).collect();
interpreter.vm.instructions_data = instructions.iter().map(|i| i.src.clone()).collect();
interpreter.vm.prototypes = interpreter.compiler.prototypes.clone();
interpreter.vm.instructions = Rc::new(instructions.iter().map(|i| i.inst.clone()).collect());
interpreter.vm.instructions_data = Rc::new(instructions.iter().map(|i| i.src.clone()).collect());
interpreter.vm.prototypes = Rc::new(interpreter.compiler.prototypes.iter().map(|p| VMFnPrototype{
instructions: Rc::new(p.instructions.clone()),
register_count: p.register_count,
upvalues: p.upvalues.clone(),
instruction_data: Rc::new(p.instruction_data.clone()),
param_count: p.param_count,
name: p.name.clone(),
}).collect());
interpreter.vm.constants = interpreter
.compiler
.constants
Expand Down Expand Up @@ -210,9 +225,16 @@ pub fn import_module(source: String) -> HashMap<String, value::Value> {
.map(|c| c.instructions.clone())
.flatten()
.collect();
interpreter.vm.instructions = instructions.iter().map(|i| i.inst.clone()).collect();
interpreter.vm.instructions_data = instructions.iter().map(|i| i.src.clone()).collect();
interpreter.vm.prototypes = interpreter.compiler.prototypes.clone();
interpreter.vm.instructions = Rc::new(instructions.iter().map(|i| i.inst.clone()).collect());
interpreter.vm.instructions_data = Rc::new(instructions.iter().map(|i| i.src.clone()).collect());
interpreter.vm.prototypes = Rc::new(interpreter.compiler.prototypes.iter().map(|p| VMFnPrototype{
instructions: Rc::new(p.instructions.clone()),
register_count: p.register_count,
upvalues: p.upvalues.clone(),
instruction_data: Rc::new(p.instruction_data.clone()),
param_count: p.param_count,
name: p.name.clone(),
}).collect());
interpreter.vm.constants = interpreter
.compiler
.constants
Expand Down
27 changes: 14 additions & 13 deletions src/vm.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![allow(dead_code)]

use crate::compiler::FnPrototype;
use crate::compiler::UpvalueRef;
use crate::errors::*;
use crate::instruction::*;
use crate::interpreter;
Expand Down Expand Up @@ -67,7 +67,6 @@ macro_rules! make_call {
$instructions = prototype.instructions.clone();
$pc = 0;
// Point to new instructions metadata
// TODO: use reference instead of cloning
$self.instructions_data = prototype.instruction_data.clone();
}};
}
Expand All @@ -93,11 +92,9 @@ macro_rules! throw_exception {

if let Some(func) = &stack.function {
let proto = &$self.prototypes[func.0.borrow().prototype as usize];
// TODO: use reference instead of cloning
$self.instructions = proto.instructions.clone();
$self.instructions_data = proto.instruction_data.clone();
} else {
// TODO: use reference instead of cloning
$self.instructions = $original_instructions.clone();
$self.instructions_data = $original_instructions_data.clone();
}
Expand Down Expand Up @@ -152,16 +149,26 @@ pub struct CatchException {
exception: Option<RuntimeErr>,
}

#[derive(Debug)]
pub struct VMFnPrototype {
pub instructions: Rc<Vec<Instruction>>,
pub register_count: u8,
pub upvalues: Vec<UpvalueRef>,
pub instruction_data: Rc<Vec<Option<TokenData>>>,
pub param_count: usize,
pub name: String,
}

#[derive(Debug)]
pub struct VM {
pub instructions: Vec<Instruction>,
pub prototypes: Vec<FnPrototype>,
pub instructions: Rc<Vec<Instruction>>,
pub prototypes: Rc<Vec<VMFnPrototype>>,
pub constants: Vec<Value>,
pub globals: HashMap<String, Value>,
pub builtins: HashMap<String, Value>,
pub stack: Vec<StackEntry>,
pub activation_records: Vec<Record>,
pub instructions_data: Vec<Option<TokenData>>,
pub instructions_data: Rc<Vec<Option<TokenData>>>,
pub catch_exceptions: Vec<CatchException>,
}

Expand Down Expand Up @@ -351,16 +358,13 @@ impl VM {
sp = stack.sp;
if let Some(func) = &self.stack.last().unwrap().function {
let proto = &self.prototypes[func.0.borrow().prototype as usize];
// TODO: use reference instead of cloning
self.instructions = proto.instructions.clone();
self.instructions_data = proto.instruction_data.clone();
} else {
// TODO: use reference instead of cloning
self.instructions = original_instructions.clone();
self.instructions_data = original_instructions_data.clone();
}
}

OpCode::Jmp => {
pc = pc.wrapping_add(inst.sbx() as usize);
}
Expand Down Expand Up @@ -1013,7 +1017,6 @@ impl VM {
sp,
ERR_EXPECTED_STRING
);
unreachable!();
};
match val_b.get(prop) {
Ok(v) => {
Expand Down Expand Up @@ -1203,7 +1206,6 @@ impl VM {
sp,
ERR_EXPECTED_NUMBER
);
0
};
match val_b.as_val() {
Value::Dict(d) => {
Expand Down Expand Up @@ -1269,7 +1271,6 @@ impl VM {
sp,
ERR_EXPECTED_NUMBER
);
0
};
match val_b.as_val() {
Value::Dict(d) => {
Expand Down

0 comments on commit 88fa78d

Please sign in to comment.