diff --git a/lib/runtime-core/src/state.rs b/lib/runtime-core/src/state.rs index 837e43831..e04f1a4f4 100644 --- a/lib/runtime-core/src/state.rs +++ b/lib/runtime-core/src/state.rs @@ -1,30 +1,100 @@ -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub struct RegisterIndex(pub usize); -#[derive(Clone, Debug, Default)] -pub struct FunctionStateMap { - pub local_to_locations: Vec, - pub diffs: Vec, +#[derive(Clone, Debug)] +pub struct MachineState { + pub stack_values: Vec, + pub register_values: Vec, } #[derive(Clone, Debug, Default)] -pub struct StateDiff { +pub struct MachineStateDiff { pub last: Option, - pub stack_to_locations_push: Vec, - pub stack_to_locations_pop: usize, + pub stack_push: Vec, + pub stack_pop: usize, + pub reg_diff: Vec<(RegisterIndex, MachineValue)>, +} + +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MachineValue { + Undefined, + PreserveRegister(RegisterIndex), + WasmStack(usize), + WasmLocal(usize), } #[derive(Clone, Debug)] -pub enum Location { - Virtual, // no physical storage - Memory(RegisterIndex, i32), - Register(RegisterIndex), +pub struct FunctionStateMap { + pub initial: MachineState, + pub diffs: Vec, +} + +impl FunctionStateMap { + pub fn new(initial: MachineState) -> FunctionStateMap { + FunctionStateMap { + initial, + diffs: vec![], + } + } +} + +impl MachineState { + pub fn diff(&self, old: &MachineState) -> MachineStateDiff { + let first_diff_stack_depth: usize = self.stack_values.iter().zip(old.stack_values.iter()).enumerate() + .find(|&(_, (&a, &b))| a != b).map(|x| x.0) + .unwrap_or(old.stack_values.len().min(self.stack_values.len())); + assert_eq!(self.register_values.len(), old.register_values.len()); + let reg_diff: Vec<_> = self.register_values.iter().zip(old.register_values.iter()).enumerate() + .filter(|&(_, (&a, &b))| a != b) + .map(|(i, (&a, _))| (RegisterIndex(i), a)) + .collect(); + MachineStateDiff { + last: None, + stack_push: self.stack_values[first_diff_stack_depth..].to_vec(), + stack_pop: old.stack_values.len() - first_diff_stack_depth, + reg_diff: reg_diff, + } + } +} + +impl MachineStateDiff { + pub fn build_state(&self, m: &FunctionStateMap) -> MachineState { + let mut chain: Vec<&MachineStateDiff> = vec![]; + chain.push(self); + let mut current = self.last; + while let Some(x) = current { + let that = &m.diffs[x]; + current = that.last; + chain.push(that); + } + chain.reverse(); + let mut state = m.initial.clone(); + for x in chain { + for _ in 0..x.stack_pop { + state.stack_values.pop().unwrap(); + } + for v in &x.stack_push { + state.stack_values.push(*v); + } + for &(index, v) in &x.reg_diff { + state.register_values[index.0] = v; + } + } + state + } } #[cfg(all(unix, target_arch = "x86_64"))] pub mod x64 { use super::*; + pub fn new_machine_state() -> MachineState { + MachineState { + stack_values: vec![], + register_values: vec![MachineValue::Undefined; 16 + 8], + } + } + #[repr(u8)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] pub enum GPR { @@ -68,7 +138,7 @@ pub mod x64 { pub fn to_index(&self) -> RegisterIndex { match *self { X64Register::GPR(x) => RegisterIndex(x as usize), - X64Register::XMM(x) => RegisterIndex(x as usize + 1000), + X64Register::XMM(x) => RegisterIndex(x as usize + 16), } } } diff --git a/lib/singlepass-backend/src/codegen_x64.rs b/lib/singlepass-backend/src/codegen_x64.rs index fa86905de..cf9a3448b 100644 --- a/lib/singlepass-backend/src/codegen_x64.rs +++ b/lib/singlepass-backend/src/codegen_x64.rs @@ -29,7 +29,7 @@ use wasmer_runtime_core::{ TableIndex, Type, }, vm::{self, LocalGlobal, LocalTable, INTERNALS_SIZE}, - state::{FunctionStateMap, StateDiff, x64::X64Register, Location as StateLocation}, + state::{FunctionStateMap, x64::X64Register, MachineState, MachineValue, MachineStateDiff}, }; use wasmparser::{Operator, Type as WpType}; @@ -141,7 +141,6 @@ enum LocalOrTemp { pub struct X64FunctionCode { signatures: Arc>, function_signatures: Arc>, - state_map: FunctionStateMap, assembler: Option, function_labels: Option)>>, diff --git a/lib/singlepass-backend/src/machine.rs b/lib/singlepass-backend/src/machine.rs index d5258f919..c03ff0ad9 100644 --- a/lib/singlepass-backend/src/machine.rs +++ b/lib/singlepass-backend/src/machine.rs @@ -2,6 +2,7 @@ use crate::emitter_x64::*; use smallvec::SmallVec; use std::collections::HashSet; use wasmparser::Type as WpType; +use wasmer_runtime_core::state::*; struct MachineStackOffset(usize); @@ -10,6 +11,7 @@ pub struct Machine { used_xmms: HashSet, stack_offset: MachineStackOffset, save_area_offset: Option, + state: MachineState, } impl Machine {