Make experimental optimizations
This commit is contained in:
parent
452443b5b2
commit
6ba16bca0d
@ -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,
|
||||||
|
@ -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(());
|
||||||
|
@ -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, "]")
|
||||||
|
@ -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;
|
||||||
|
@ -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};
|
||||||
|
|
||||||
|
@ -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})"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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,
|
||||||
|
@ -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]>,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user