1
0

Make experimental optimizations

This commit is contained in:
Jeff 2025-01-29 16:10:32 -05:00
parent 452443b5b2
commit 6ba16bca0d
8 changed files with 34 additions and 155 deletions

View File

@ -50,7 +50,7 @@ pub struct Chunk {
} }
impl Chunk { impl Chunk {
#[cfg(any(test, debug_assertions))] #[cfg(debug_assertions)]
pub fn with_data( pub fn with_data(
name: Option<DustString>, name: Option<DustString>,
r#type: FunctionType, r#type: FunctionType,

View File

@ -342,30 +342,6 @@ impl<'src> Compiler<'src> {
.unwrap_or(self.minimum_register) .unwrap_or(self.minimum_register)
} }
fn next_pointer_register(&self) -> u16 {
self.instructions
.iter()
.rev()
.find_map(|(instruction, _, _)| match instruction.operation() {
Operation::CALL => {
let Call { destination, .. } = Call::from(instruction);
Some(destination + 1)
}
Operation::CALL_NATIVE => {
let CallNative {
first_argument,
argument_count,
..
} = CallNative::from(instruction);
Some(first_argument + argument_count as u16)
}
_ => None,
})
.unwrap_or(self.minimum_register)
}
fn advance(&mut self) -> Result<(), CompileError> { fn advance(&mut self) -> Result<(), CompileError> {
if self.is_eof() { if self.is_eof() {
return Ok(()); return Ok(());

View File

@ -1,16 +1,13 @@
use std::fmt::{self, Display, Formatter}; use std::fmt::{self, Display, Formatter};
use crate::{ use crate::{Type, vm::ThreadData};
Type,
vm::{Pointer, ThreadData},
};
use super::DustString; use super::DustString;
#[derive(Clone, Debug, PartialEq, PartialOrd)] #[derive(Clone, Debug, PartialEq, PartialOrd)]
pub struct AbstractList { pub struct AbstractList {
pub item_type: Type, pub item_type: Type,
pub item_pointers: Vec<Pointer>, pub item_registers: Vec<u16>,
} }
impl AbstractList { impl AbstractList {
@ -23,8 +20,16 @@ impl Display for AbstractList {
fn fmt(&self, f: &mut Formatter) -> fmt::Result { fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "[")?; write!(f, "[")?;
for pointer in &self.item_pointers { for index in &self.item_registers {
write!(f, "{}", pointer)?; match self.item_type {
Type::Boolean => write!(f, "R_BOOL_{index}")?,
Type::Byte => write!(f, "R_BYTE_{index}")?,
Type::Character => write!(f, "R_CHAR_{index}")?,
Type::Float => write!(f, "R_FLOAT_{index}")?,
Type::Integer => write!(f, "R_INT_{index}")?,
Type::String => write!(f, "R_STR_{index}")?,
_ => todo!(),
}
} }
write!(f, "]") write!(f, "]")

View File

@ -8,11 +8,11 @@ use smallvec::SmallVec;
use tracing::trace; use tracing::trace;
use crate::{ use crate::{
Instruction, Operation, Type, Value, Instruction, Operation, Value,
instruction::{Jump, TwoOperandLayout, TypeCode}, instruction::{Jump, TwoOperandLayout, TypeCode},
}; };
use super::{Pointer, Register, thread::ThreadData}; use super::{Register, thread::ThreadData};
#[derive(Debug)] #[derive(Debug)]
pub struct ActionSequence { pub struct ActionSequence {
@ -91,21 +91,20 @@ impl From<&Instruction> for Action {
fn from(instruction: &Instruction) -> Self { fn from(instruction: &Instruction) -> Self {
let builder = TwoOperandLayout::from(instruction); let builder = TwoOperandLayout::from(instruction);
let operation = builder.operation; let operation = builder.operation;
let (logic, optimal_logic): (ActionLogic, Option<fn(&mut ActionData, &mut usize)>) = let (logic, optimal_logic): (ActionLogic, Option<OptimalActionLogic>) = match operation {
match operation { Operation::MOVE => (r#move, Some(move_optimal)),
Operation::MOVE => (r#move, Some(move_optimal)), Operation::LOAD_INLINE => (load_inline, None),
Operation::LOAD_INLINE => (load_inline, None), Operation::LOAD_CONSTANT => (load_constant, None),
Operation::LOAD_CONSTANT => (load_constant, None), Operation::LOAD_LIST => (load_list, None),
Operation::LOAD_LIST => (load_list, None), Operation::LOAD_FUNCTION => (load_function, None),
Operation::LOAD_FUNCTION => (load_function, None), Operation::LOAD_SELF => (load_self, None),
Operation::LOAD_SELF => (load_self, None), Operation::SET_LOCAL => (set_local, None),
Operation::SET_LOCAL => (set_local, None), Operation::ADD => (add, Some(add_optimal)),
Operation::ADD => (add, Some(add_optimal)), Operation::LESS => (less, Some(less_optimal)),
Operation::LESS => (less, Some(less_optimal)), Operation::JUMP => (jump, Some(jump_optimal)),
Operation::JUMP => (jump, Some(jump_optimal)), Operation::RETURN => (r#return, None),
Operation::RETURN => (r#return, None), unknown => unknown.panic_from_unknown_code(),
unknown => unknown.panic_from_unknown_code(), };
};
Action { Action {
logic, logic,
@ -148,6 +147,7 @@ pub struct ActionData {
} }
pub type ActionLogic = fn(&mut ThreadData, &mut ActionData); pub type ActionLogic = fn(&mut ThreadData, &mut ActionData);
pub type OptimalActionLogic = fn(&mut ActionData, &mut usize);
fn loop_optimized(thread_data: &mut ThreadData, action_data: &mut ActionData) { fn loop_optimized(thread_data: &mut ThreadData, action_data: &mut ActionData) {
let mut local_ip = 0; let mut local_ip = 0;
@ -229,9 +229,6 @@ fn loop_optimized(thread_data: &mut ThreadData, action_data: &mut ActionData) {
} }
} }
const OPTIMAL_LOGIC: [fn(&mut ActionData, &mut usize); 3] =
[less_optimal, add_optimal, move_optimal];
fn less_optimal(action_data: &mut ActionData, local_ip: &mut usize) { fn less_optimal(action_data: &mut ActionData, local_ip: &mut usize) {
unsafe { unsafe {
asm!( asm!(
@ -633,7 +630,7 @@ fn r#return(thread_data: &mut ThreadData, action_data: &mut ActionData) {
let ThreadData { let ThreadData {
stack, stack,
return_value, return_value,
spawned_threads, ..
} = thread_data; } = thread_data;
let should_return_value = instruction.b_field != 0; let should_return_value = instruction.b_field != 0;
let r#type = instruction.b_type; let r#type = instruction.b_type;

View File

@ -1,7 +1,6 @@
//! Virtual machine and errors //! Virtual machine and errors
mod action; mod action;
mod call_frame; mod call_frame;
mod pointer;
mod register_table; mod register_table;
mod thread; mod thread;
@ -9,7 +8,6 @@ use std::{sync::Arc, thread::Builder};
pub use action::Action; pub use action::Action;
pub use call_frame::CallFrame; pub use call_frame::CallFrame;
pub use pointer::Pointer;
pub use register_table::{Register, RegisterTable}; pub use register_table::{Register, RegisterTable};
pub use thread::{Thread, ThreadData}; pub use thread::{Thread, ThreadData};

View File

@ -1,73 +0,0 @@
use std::fmt::{self, Debug, Display, Formatter};
#[derive(Copy, Clone, PartialEq, PartialOrd)]
pub enum Pointer {
ConstantBoolean(u16),
ConstantByte(u16),
ConstantCharacter(u16),
ConstantFloat(u16),
ConstantInteger(u16),
ConstantString(u16),
RegisterBoolean(u16),
RegisterByte(u16),
RegisterCharacter(u16),
RegisterFloat(u16),
RegisterInteger(u16),
RegisterString(u16),
RegisterList(u16),
ForeignConstantBoolean(u16, u16),
ForeignConstantByte(u16, u16),
ForeignConstantCharacter(u16, u16),
ForeignConstantFloat(u16, u16),
ForeignConstantInteger(u16, u16),
ForeignConstantString(u16, u16),
ForeignRegisterBoolean(u16, u16),
ForeignRegisterByte(u16, u16),
ForeignRegisterCharacter(u16, u16),
ForeignRegisterFloat(u16, u16),
ForeignRegisterInteger(u16, u16),
ForeignRegisterString(u16, u16),
ForeignRegisterList(u16, u16),
}
impl Debug for Pointer {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{self}")
}
}
impl Display for Pointer {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self {
Pointer::ConstantBoolean(index) => write!(f, "P_C_BOOL({index})"),
Pointer::ConstantByte(index) => write!(f, "P_C_BYTE({index})"),
Pointer::ConstantCharacter(index) => write!(f, "P_C_CHAR({index})"),
Pointer::ConstantFloat(index) => write!(f, "P_C_FLOAT({index})"),
Pointer::ConstantInteger(index) => write!(f, "P_C_INT({index})"),
Pointer::ConstantString(index) => write!(f, "P_C_STR({index})"),
Pointer::RegisterBoolean(index) => write!(f, "P_R_BOOL({index})"),
Pointer::RegisterByte(index) => write!(f, "P_R_BYTE({index})"),
Pointer::RegisterCharacter(index) => write!(f, "P_R_CHAR({index})"),
Pointer::RegisterFloat(index) => write!(f, "P_R_FLOAT({index})"),
Pointer::RegisterInteger(index) => write!(f, "P_R_INT({index})"),
Pointer::RegisterString(index) => write!(f, "P_R_STR({index})"),
Pointer::RegisterList(index) => write!(f, "P_R_LIST({index})"),
Pointer::ForeignConstantBoolean(index, _) => write!(f, "P_FC_BOOL({index})"),
Pointer::ForeignConstantByte(index, _) => write!(f, "P_FC_BYTE({index})"),
Pointer::ForeignConstantCharacter(index, _) => write!(f, "P_FC_CHAR({index})"),
Pointer::ForeignConstantFloat(index, _) => write!(f, "P_FC_FLOAT({index})"),
Pointer::ForeignConstantInteger(index, _) => write!(f, "P_FC_INT({index})"),
Pointer::ForeignConstantString(index, _) => write!(f, "P_FC_STR({index})"),
Pointer::ForeignRegisterBoolean(index, _) => write!(f, "P_FR_BOOL({index})"),
Pointer::ForeignRegisterByte(index, _) => write!(f, "P_FR_BYTE({index})"),
Pointer::ForeignRegisterCharacter(index, _) => write!(f, "P_FR_CHAR({index})"),
Pointer::ForeignRegisterFloat(index, _) => write!(f, "P_FR_FLOAT({index})"),
Pointer::ForeignRegisterInteger(index, _) => write!(f, "P_FR_INT({index})"),
Pointer::ForeignRegisterString(index, _) => write!(f, "P_FR_STR({index})"),
Pointer::ForeignRegisterList(index, _) => write!(f, "P_FR_LIST({index})"),
}
}
}

View File

@ -6,8 +6,6 @@ use tracing::trace;
use crate::{AbstractList, DustString}; use crate::{AbstractList, DustString};
use super::Pointer;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Register<T: Clone> { pub enum Register<T: Clone> {
Empty, Empty,

View File

@ -1,18 +1,11 @@
use std::{arch::asm, iter::repeat, ptr, sync::Arc, thread::JoinHandle}; use std::{sync::Arc, thread::JoinHandle};
use smallvec::SmallVec; use smallvec::SmallVec;
use tracing::{info, span, trace}; use tracing::{info, span, trace};
use crate::{ use crate::{Chunk, DustString, Value, vm::action::ActionSequence};
Chunk, DustString, Operation, TypeCode, Value,
instruction::Jump,
vm::{
Register,
action::{ActionData, ActionSequence},
},
};
use super::{Action, CallFrame}; use super::CallFrame;
pub struct Thread { pub struct Thread {
chunk: Arc<Chunk>, chunk: Arc<Chunk>,
@ -65,21 +58,6 @@ impl Thread {
} }
} }
#[derive(Copy, Clone, Debug)]
pub struct Cache {
pub runs: usize,
pub integers: [*mut i64; 3],
}
impl Cache {
pub fn new() -> Self {
Self {
runs: 0,
integers: [ptr::null_mut(); 3],
}
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct ThreadData { pub struct ThreadData {
pub stack: SmallVec<[CallFrame; 10]>, pub stack: SmallVec<[CallFrame; 10]>,