Machine state diff

This commit is contained in:
losfair 2019-06-11 20:49:30 +08:00
parent 082b8376ae
commit da9bf05218
3 changed files with 86 additions and 15 deletions

View File

@ -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<Location>,
pub diffs: Vec<StateDiff>,
#[derive(Clone, Debug)]
pub struct MachineState {
pub stack_values: Vec<MachineValue>,
pub register_values: Vec<MachineValue>,
}
#[derive(Clone, Debug, Default)]
pub struct StateDiff {
pub struct MachineStateDiff {
pub last: Option<usize>,
pub stack_to_locations_push: Vec<Location>,
pub stack_to_locations_pop: usize,
pub stack_push: Vec<MachineValue>,
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<MachineStateDiff>,
}
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),
}
}
}

View File

@ -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<Map<SigIndex, FuncSig>>,
function_signatures: Arc<Map<FuncIndex, SigIndex>>,
state_map: FunctionStateMap,
assembler: Option<Assembler>,
function_labels: Option<HashMap<usize, (DynamicLabel, Option<AssemblyOffset>)>>,

View File

@ -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<XMM>,
stack_offset: MachineStackOffset,
save_area_offset: Option<MachineStackOffset>,
state: MachineState,
}
impl Machine {