Skip to content

Commit

Permalink
A round of optimization
Browse files Browse the repository at this point in the history
Fix a bunch of unnecessary copies in Var/List operations.
List operations that were taking references and then cloning, are now moving the value.
Changed mutating operations on Lists to attempt to be CoW; if there's only one reference, they will mutate in-place on it. Substantial improvement in list append performance in the vm_bench.
Stack-allocate the BitArray storage, speeds up some local-variable set/get ops. But probably blows the cache line for DB benches, so move the uses there into boxes.
Increase the # of ticks used in the vm benches to reduce the measurement impact of setup/dispatch.
Optimize the VM opcode exec loop by cutting out the middle-man in the "exec state" and reference the top of the activation stack directly.
  • Loading branch information
rdaum committed Jan 18, 2024
1 parent 8e819ac commit f0cac53
Show file tree
Hide file tree
Showing 28 changed files with 508 additions and 456 deletions.
3 changes: 2 additions & 1 deletion crates/compiler/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

/// Takes the AST and turns it into a list of opcodes.
use std::collections::HashMap;
use std::sync::Arc;

use itertools::Itertools;
use tracing::error;
Expand Down Expand Up @@ -794,7 +795,7 @@ pub fn compile(program: &str) -> Result<Program, CompileError> {
literals: cg_state.literals,
jump_labels: cg_state.jumps,
var_names: cg_state.var_names,
main_vector: cg_state.ops,
main_vector: Arc::new(cg_state.ops),
fork_vectors: cg_state.fork_vectors,
line_number_spans: cg_state.line_number_spans,
};
Expand Down
84 changes: 42 additions & 42 deletions crates/compiler/src/codegen_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ mod tests {
let program = "1 + 2;";
let binary = compile(program).unwrap();
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![ImmInt(1), ImmInt(2), Add, Pop, Done]
);
}
Expand All @@ -51,7 +51,7 @@ mod tests {
" 6: 030 010 * AND 10",
*/
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![ImmInt(1), ImmInt(2), Add, Put(a), Pop, Done],
);
}
Expand All @@ -64,7 +64,7 @@ mod tests {
let a = binary.find_var("a");

assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
ImmInt(1),
ImmInt(2),
Expand Down Expand Up @@ -103,7 +103,7 @@ mod tests {
*/
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
ImmInt(1),
ImmInt(2),
Expand Down Expand Up @@ -144,7 +144,7 @@ mod tests {
" 8: 107 000 JUMP 0",
*/
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
ImmInt(1),
While(1.into()),
Expand Down Expand Up @@ -186,7 +186,7 @@ mod tests {
22: 107 000 JUMP 0
*/
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
ImmInt(1),
WhileId {
Expand Down Expand Up @@ -236,7 +236,7 @@ mod tests {
" 23: 107 000 JUMP 0"
*/
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
ImmInt(1),
While(1.into()),
Expand Down Expand Up @@ -291,7 +291,7 @@ mod tests {
*/
// The label for the ForList is not quite right here
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
ImmInt(1),
MakeSingletonList,
Expand Down Expand Up @@ -340,7 +340,7 @@ mod tests {
12: 107 002 JUMP 2
*/
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
ImmInt(1),
ImmInt(5),
Expand Down Expand Up @@ -370,7 +370,7 @@ mod tests {
let tell = binary.find_literal("tell".into());

assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
ImmInt(5),
Fork {
Expand Down Expand Up @@ -404,7 +404,7 @@ mod tests {
let tell = binary.find_literal("tell".into());

assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
ImmInt(5),
Fork {
Expand Down Expand Up @@ -445,7 +445,7 @@ mod tests {
8: 111 POP
*/
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
ImmInt(1),
And(0.into()),
Expand Down Expand Up @@ -487,7 +487,7 @@ mod tests {
7: 111 POP
*/
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
Push(player), // Player
MakeSingletonList,
Expand Down Expand Up @@ -519,7 +519,7 @@ mod tests {
10: 111 POP
*/
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
ImmInt(1),
ImmInt(2),
Expand Down Expand Up @@ -553,7 +553,7 @@ mod tests {
7: 111 POP
*/
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
Push(player), // Player
Imm(tell),
Expand All @@ -571,7 +571,7 @@ mod tests {
let program = "return \"test\"[1];";
let binary = compile(program).unwrap();
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![Imm(0.into()), ImmInt(1), Ref, Return, Done]
);
}
Expand All @@ -581,7 +581,7 @@ mod tests {
let program = "return \"test\"[1..2];";
let binary = compile(program).unwrap();
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![Imm(0.into()), ImmInt(1), ImmInt(2), RangeRef, Return, Done]
);
}
Expand All @@ -593,7 +593,7 @@ mod tests {
let a = binary.find_var("a");

assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
Push(a),
ImmInt(2),
Expand All @@ -616,7 +616,7 @@ mod tests {
let a = binary.find_var("a");

assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
Push(a),
ImmInt(2),
Expand All @@ -638,7 +638,7 @@ mod tests {
let program = "return {1,2,3}[1];";
let binary = compile(program).unwrap();
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
ImmInt(1),
MakeSingletonList,
Expand All @@ -659,7 +659,7 @@ mod tests {
let program = "return {1,2,3}[1..2];";
let binary = compile(program).unwrap();
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
ImmInt(1),
MakeSingletonList,
Expand Down Expand Up @@ -703,7 +703,7 @@ mod tests {
17: 030 021 * AND 21
*/
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
[
ImmInt(1),
MakeSingletonList,
Expand Down Expand Up @@ -740,7 +740,7 @@ mod tests {
*/
let args = binary.find_var("args");
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
Push(args),
ImmInt(1),
Expand Down Expand Up @@ -771,7 +771,7 @@ mod tests {
11: 112 006 CONTINUE
*/
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
TryFinally(0.into()),
ImmInt(1),
Expand Down Expand Up @@ -821,7 +821,7 @@ mod tests {
*/
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
ImmErr(E_INVARG),
MakeSingletonList,
Expand Down Expand Up @@ -874,7 +874,7 @@ mod tests {
let x = binary.find_var("x");

assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
ImmErr(E_PROPNF),
MakeSingletonList,
Expand Down Expand Up @@ -917,7 +917,7 @@ mod tests {
.position(|b| b.name == "raise")
.unwrap();
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
ImmInt(0),
PushLabel(0.into()),
Expand Down Expand Up @@ -954,7 +954,7 @@ mod tests {
9: 010 * CALL_VERB
*/
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
ImmObjid(SYSTEM_OBJECT),
Imm(string_utils),
Expand All @@ -975,7 +975,7 @@ mod tests {
let binary = compile(program).unwrap();
let verb_metadata = binary.find_literal("verb_metadata".into());
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
ImmObjid(SYSTEM_OBJECT),
Imm(verb_metadata),
Expand Down Expand Up @@ -1006,7 +1006,7 @@ mod tests {
*/

assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
Push(binary.find_var("args")),
Scatter(Box::new(ScatterArgs {
Expand Down Expand Up @@ -1045,7 +1045,7 @@ mod tests {
15: 111 POP
*/
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
Push(binary.find_var("args")),
Scatter(Box::new(ScatterArgs {
Expand Down Expand Up @@ -1090,7 +1090,7 @@ mod tests {
binary.find_var("d"),
);
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
Push(binary.find_var("args")),
Scatter(Box::new(ScatterArgs {
Expand Down Expand Up @@ -1141,7 +1141,7 @@ mod tests {
25: 111 POP
*/
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
Push(binary.find_var("args")),
Scatter(Box::new(ScatterArgs {
Expand Down Expand Up @@ -1208,7 +1208,7 @@ mod tests {
*/

assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
ImmInt(1),
MakeSingletonList,
Expand Down Expand Up @@ -1266,7 +1266,7 @@ mod tests {
10: 106 PUSH_TEMP
*/
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
Push(binary.find_var("this")),
Imm(binary.find_literal("stack".into())),
Expand Down Expand Up @@ -1315,7 +1315,7 @@ mod tests {
*/

assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
ImmInt(1),
Put(x),
Expand Down Expand Up @@ -1346,7 +1346,7 @@ mod tests {
let binary = compile(program).unwrap();

assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
Push(binary.find_var("this")),
Imm(binary.find_literal("stack".into())),
Expand All @@ -1362,7 +1362,7 @@ mod tests {
let program = r#"#0:test_verb();"#;
let binary = compile(program).unwrap();
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
ImmObjid(Objid(0)),
Imm(binary.find_literal("test_verb".into())),
Expand All @@ -1378,7 +1378,7 @@ mod tests {
fn test_0_arg_return() {
let program = r#"return;"#;
let binary = compile(program).unwrap();
assert_eq!(binary.main_vector, vec![Return0, Done])
assert_eq!(*binary.main_vector.as_ref(), vec![Return0, Done])
}

#[test]
Expand All @@ -1396,7 +1396,7 @@ mod tests {
let args = binary.find_var("args");
let blop = binary.find_var("blop");
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
Push(args),
CheckListForSplice,
Expand Down Expand Up @@ -1455,7 +1455,7 @@ mod tests {
33: 110 DONE
*/
assert_eq!(
program.main_vector,
*program.main_vector.as_ref(),
vec![
ImmErr(E_RANGE),
MakeSingletonList,
Expand Down Expand Up @@ -1494,7 +1494,7 @@ mod tests {
19: 030 023 * AND 23
*/
assert_eq!(
binary.main_vector,
*binary.main_vector.as_ref(),
vec![
ImmErr(E_INVIND),
MakeSingletonList,
Expand Down
Loading

0 comments on commit f0cac53

Please sign in to comment.