Optimize VM
This commit is contained in:
parent
511bb1a6ca
commit
8c7b5d9959
@ -13,8 +13,8 @@ pub struct Move {
|
|||||||
impl From<Instruction> for Move {
|
impl From<Instruction> for Move {
|
||||||
fn from(instruction: Instruction) -> Self {
|
fn from(instruction: Instruction) -> Self {
|
||||||
Move {
|
Move {
|
||||||
from: instruction.b_field(),
|
from: instruction.a_field(),
|
||||||
to: instruction.c_field(),
|
to: instruction.b_field(),
|
||||||
type_code: instruction.b_type(),
|
type_code: instruction.b_type(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -23,15 +23,15 @@ impl From<Instruction> for Move {
|
|||||||
impl From<Move> for Instruction {
|
impl From<Move> for Instruction {
|
||||||
fn from(r#move: Move) -> Self {
|
fn from(r#move: Move) -> Self {
|
||||||
let operation = Operation::MOVE;
|
let operation = Operation::MOVE;
|
||||||
let b_field = r#move.from;
|
let a_field = r#move.from;
|
||||||
let c_field = r#move.to;
|
let b_field = r#move.to;
|
||||||
let b_type = r#move.type_code;
|
let b_type = r#move.type_code;
|
||||||
|
|
||||||
InstructionBuilder {
|
InstructionBuilder {
|
||||||
operation,
|
operation,
|
||||||
|
a_field,
|
||||||
b_field,
|
b_field,
|
||||||
b_type,
|
b_type,
|
||||||
c_field,
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
.build()
|
.build()
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use std::{
|
use std::{
|
||||||
|
arch::asm,
|
||||||
fmt::{self, Debug, Display, Formatter},
|
fmt::{self, Debug, Display, Formatter},
|
||||||
ptr,
|
ptr,
|
||||||
};
|
};
|
||||||
@ -8,7 +9,7 @@ use tracing::trace;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Instruction, Operation, Type, Value,
|
Instruction, Operation, Type, Value,
|
||||||
instruction::{InstructionBuilder, TypeCode},
|
instruction::{InstructionBuilder, Jump, TypeCode},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{Pointer, Register, thread::ThreadData};
|
use super::{Pointer, Register, thread::ThreadData};
|
||||||
@ -19,15 +20,49 @@ pub struct ActionSequence {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ActionSequence {
|
impl ActionSequence {
|
||||||
pub fn new<T>(actions_iter: T) -> Self
|
pub fn new(instructions: &[Instruction]) -> Self {
|
||||||
where
|
let mut actions = SmallVec::with_capacity(instructions.len());
|
||||||
T: Iterator<Item = Action> + ExactSizeIterator,
|
let mut loop_actions = None;
|
||||||
{
|
|
||||||
let (lower_bound, upper_bound) = actions_iter.size_hint();
|
|
||||||
let mut actions = SmallVec::with_capacity(upper_bound.unwrap_or(lower_bound));
|
|
||||||
|
|
||||||
for action in actions_iter {
|
for instruction in instructions {
|
||||||
actions.push(action);
|
if instruction.operation() == Operation::LESS {
|
||||||
|
loop_actions
|
||||||
|
.get_or_insert(Vec::new())
|
||||||
|
.push(Action::from(instruction));
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if instruction.operation() == Operation::JUMP {
|
||||||
|
let Jump { is_positive, .. } = Jump::from(*instruction);
|
||||||
|
|
||||||
|
loop_actions
|
||||||
|
.get_or_insert(Vec::new())
|
||||||
|
.push(Action::from(instruction));
|
||||||
|
|
||||||
|
if !is_positive {
|
||||||
|
let action = Action {
|
||||||
|
logic: loop_optimized,
|
||||||
|
data: ActionData {
|
||||||
|
name: "LOOP_OPTIMIZED",
|
||||||
|
instruction: InstructionBuilder::from(instruction),
|
||||||
|
pointers: [ptr::null_mut(); 3],
|
||||||
|
runs: 0,
|
||||||
|
condensed_actions: loop_actions.take().unwrap(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
actions.push(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(loop_actions) = &mut loop_actions {
|
||||||
|
loop_actions.push(Action::from(instruction));
|
||||||
|
} else {
|
||||||
|
actions.push(Action::from(instruction));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Self { actions }
|
Self { actions }
|
||||||
@ -42,7 +77,7 @@ impl ActionSequence {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone)]
|
||||||
pub struct Action {
|
pub struct Action {
|
||||||
pub logic: ActionLogic,
|
pub logic: ActionLogic,
|
||||||
pub data: ActionData,
|
pub data: ActionData,
|
||||||
@ -53,7 +88,7 @@ impl From<&Instruction> for Action {
|
|||||||
let builder = InstructionBuilder::from(instruction);
|
let builder = InstructionBuilder::from(instruction);
|
||||||
let operation = builder.operation;
|
let operation = builder.operation;
|
||||||
let logic = match operation {
|
let logic = match operation {
|
||||||
Operation::MOVE => point,
|
Operation::MOVE => r#move,
|
||||||
Operation::CLOSE => close,
|
Operation::CLOSE => close,
|
||||||
Operation::LOAD_INLINE => load_inline,
|
Operation::LOAD_INLINE => load_inline,
|
||||||
Operation::LOAD_CONSTANT => load_constant,
|
Operation::LOAD_CONSTANT => load_constant,
|
||||||
@ -76,7 +111,7 @@ impl From<&Instruction> for Action {
|
|||||||
instruction: builder,
|
instruction: builder,
|
||||||
pointers: [ptr::null_mut(); 3],
|
pointers: [ptr::null_mut(); 3],
|
||||||
runs: 0,
|
runs: 0,
|
||||||
next_optimized: None,
|
condensed_actions: Vec::new(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,21 +129,104 @@ impl Debug for Action {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ActionData {
|
pub struct ActionData {
|
||||||
pub name: &'static str,
|
pub name: &'static str,
|
||||||
pub instruction: InstructionBuilder,
|
pub instruction: InstructionBuilder,
|
||||||
|
|
||||||
pub pointers: [*mut i64; 3],
|
pub pointers: [*mut i64; 3],
|
||||||
pub runs: usize,
|
pub runs: usize,
|
||||||
|
pub condensed_actions: Vec<Action>,
|
||||||
pub next_optimized: Option<*mut Action>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type ActionLogic = fn(&mut ThreadData, &mut ActionData);
|
pub type ActionLogic = fn(&mut ThreadData, &mut ActionData);
|
||||||
|
|
||||||
fn point(thread_data: &mut ThreadData, action_data: &mut ActionData) {
|
fn loop_optimized(thread_data: &mut ThreadData, action_data: &mut ActionData) {
|
||||||
todo!()
|
let mut local_ip = 0;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if local_ip >= action_data.condensed_actions.len() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let action = &mut action_data.condensed_actions[local_ip];
|
||||||
|
local_ip += 1;
|
||||||
|
|
||||||
|
if action.data.runs == 0 {
|
||||||
|
trace!("Condensed action initial: {}", action.data.name);
|
||||||
|
|
||||||
|
(action.logic)(thread_data, &mut action.data);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
trace!("Condensed action optimized: {}", action.data.name);
|
||||||
|
|
||||||
|
match action.data.name {
|
||||||
|
"LESS" => unsafe {
|
||||||
|
asm!(
|
||||||
|
"cmp {0}, {1}",
|
||||||
|
"jns 2f",
|
||||||
|
"add {2}, 1",
|
||||||
|
"2:",
|
||||||
|
in(reg) *action.data.pointers[0],
|
||||||
|
in(reg) *action.data.pointers[1],
|
||||||
|
inout(reg) local_ip,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
"ADD" => unsafe {
|
||||||
|
asm!(
|
||||||
|
"add {0}, {1}",
|
||||||
|
inout(reg) *action.data.pointers[1] => *action.data.pointers[0],
|
||||||
|
in(reg) *action.data.pointers[2],
|
||||||
|
)
|
||||||
|
},
|
||||||
|
"MOVE" => unsafe {
|
||||||
|
asm!(
|
||||||
|
"mov {0}, {1}",
|
||||||
|
inout(reg) *action.data.pointers[1] => *action.data.pointers[0],
|
||||||
|
in(reg) *action.data.pointers[2],
|
||||||
|
)
|
||||||
|
},
|
||||||
|
"JUMP" => {
|
||||||
|
let Jump {
|
||||||
|
offset,
|
||||||
|
is_positive,
|
||||||
|
} = Jump::from(action.data.instruction.build());
|
||||||
|
|
||||||
|
if is_positive {
|
||||||
|
local_ip += offset as usize;
|
||||||
|
} else {
|
||||||
|
local_ip -= (offset + 1) as usize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => todo!(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn r#move(thread_data: &mut ThreadData, action_data: &mut ActionData) {
|
||||||
|
let ActionData { instruction, .. } = action_data;
|
||||||
|
let current_frame = thread_data.current_frame_mut();
|
||||||
|
let destination = instruction.a_field;
|
||||||
|
let source = instruction.b_field;
|
||||||
|
let r#type = instruction.b_type;
|
||||||
|
|
||||||
|
match r#type {
|
||||||
|
TypeCode::BOOLEAN => {
|
||||||
|
let new_register = Register::Pointer(Pointer::RegisterBoolean(source));
|
||||||
|
let old_register = current_frame.registers.get_boolean_mut(destination);
|
||||||
|
|
||||||
|
*old_register = new_register;
|
||||||
|
}
|
||||||
|
TypeCode::INTEGER => {
|
||||||
|
let new_register = Register::Pointer(Pointer::RegisterInteger(source));
|
||||||
|
let old_register = current_frame.registers.get_integer_mut(destination);
|
||||||
|
|
||||||
|
*old_register = new_register;
|
||||||
|
}
|
||||||
|
_ => todo!(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::single_range_in_vec_init)]
|
#[allow(clippy::single_range_in_vec_init)]
|
||||||
@ -428,6 +546,8 @@ fn jump(thread_data: &mut ThreadData, action_data: &mut ActionData) {
|
|||||||
} else {
|
} else {
|
||||||
current_frame.instruction_pointer -= offset + 1;
|
current_frame.instruction_pointer -= offset + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
action_data.runs += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn r#return(thread_data: &mut ThreadData, action_data: &mut ActionData) {
|
fn r#return(thread_data: &mut ThreadData, action_data: &mut ActionData) {
|
||||||
|
@ -38,8 +38,7 @@ impl Thread {
|
|||||||
return_value: None,
|
return_value: None,
|
||||||
spawned_threads: Vec::with_capacity(0),
|
spawned_threads: Vec::with_capacity(0),
|
||||||
};
|
};
|
||||||
let mut action_iter = self.chunk.instructions.iter().map(Action::from);
|
let mut action_sequence = ActionSequence::new(&self.chunk.instructions);
|
||||||
let mut action_sequence = ActionSequence::new(&mut action_iter);
|
|
||||||
|
|
||||||
trace!("Run thread main with actions: {:?}", action_sequence);
|
trace!("Run thread main with actions: {:?}", action_sequence);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user