...
 
Commits (3)
# Copyright 2017 The Australian National University
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Copyright 2017 The Australian National University
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
[package]
name = "mu"
version = "0.0.1"
......@@ -34,8 +34,10 @@ gcc = "0.3"
ast = {path = "src/ast"}
utils = {path = "src/utils"}
gc = {path = "src/gc"}
serde_json = "1.0.2"
bincode = "0.8.0"
serde = "1.0.8"
serde_derive = "1.0.8"
field-offset = "0.1.1"
libloading = "0.3"
lazy_static = "0.1.15"
......@@ -44,10 +46,9 @@ stderrlog = "0.2.2"
hprof = "0.1.3"
memmap = "0.4.0"
memsec = "0.1.9"
rustc-serialize = "*"
time = "0.1.34"
maplit = "0.1.4"
docopt = "0.6"
docopt = "0.8"
petgraph = "0.4.1"
extprim = "*"
num-traits = "*"
File mode changed from 100644 to 100755
......@@ -25,4 +25,10 @@ utils = {path = "../utils"}
lazy_static = "0.1.15"
log = "0.3.5"
simple_logger = "0.4.0"
rustc-serialize = "*"
\ No newline at end of file
serde_derive = "1.0.8"
serde = "1.0.8"
#[dependencies.serde]
#default-features = false
#version= "1.0.8"
#features = ["rc", "std", "alloc", "collections"]
\ No newline at end of file
......@@ -22,8 +22,8 @@ use utils::vec_utils;
use std::fmt;
#[derive(Debug)]
// this implements RustcEncodable, RustcDecodable, Clone and Display
#[derive(Debug, Serialize, Deserialize)]
// this implements Serialize, Deserialize, Clone and Display
pub struct Instruction {
pub hdr: MuEntityHeader,
pub value : Option<Vec<P<Value>>>,
......@@ -33,43 +33,6 @@ pub struct Instruction {
impl_mu_entity!(Instruction);
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
impl Encodable for Instruction {
fn encode<S: Encoder> (&self, s: &mut S) -> Result<(), S::Error> {
s.emit_struct("Instruction", 4, |s| {
try!(s.emit_struct_field("hdr", 0, |s| self.hdr.encode(s)));
try!(s.emit_struct_field("value", 1, |s| self.value.encode(s)));
let ref ops = self.ops;
try!(s.emit_struct_field("ops", 2, |s| ops.encode(s)));
try!(s.emit_struct_field("v", 3, |s| self.v.encode(s)));
Ok(())
})
}
}
impl Decodable for Instruction {
fn decode<D: Decoder>(d: &mut D) -> Result<Instruction, D::Error> {
d.read_struct("Instruction", 4, |d| {
let hdr = try!(d.read_struct_field("hdr", 0, |d| Decodable::decode(d)));
let value = try!(d.read_struct_field("value", 1, |d| Decodable::decode(d)));
let ops = try!(d.read_struct_field("ops", 2, |d| Decodable::decode(d)));
let v = try!(d.read_struct_field("v", 3, |d| Decodable::decode(d)));
Ok(Instruction{
hdr: hdr,
value: value,
ops: ops,
v: v
})
})
}
}
impl Clone for Instruction {
fn clone(&self) -> Self {
Instruction {
......@@ -164,7 +127,7 @@ impl fmt::Display for Instruction {
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, RustcEncodable, RustcDecodable)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Instruction_ {
// non-terminal instruction
......@@ -494,7 +457,7 @@ impl Instruction_ {
}
}
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Serialize, Deserialize)]
pub struct BinOpStatus {
pub flag_n: bool,
pub flag_z: bool,
......@@ -542,7 +505,7 @@ impl fmt::Debug for BinOpStatus {
}
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
pub enum MemoryOrder {
NotAtomic,
Relaxed,
......@@ -553,18 +516,18 @@ pub enum MemoryOrder {
SeqCst
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
pub enum CallConvention {
Mu,
Foreign(ForeignFFI)
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
pub enum ForeignFFI {
C
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct CallData {
pub func: OpIndex,
pub args: Vec<OpIndex>,
......@@ -581,7 +544,7 @@ impl CallData {
}
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ResumptionData {
pub normal_dest: Destination,
pub exn_dest: Destination
......@@ -593,7 +556,7 @@ impl ResumptionData {
}
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Destination {
pub target: MuID,
pub args: Vec<DestArg>
......@@ -636,7 +599,7 @@ impl Destination {
}
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum DestArg {
Normal(OpIndex),
Freshbound(usize)
......
......@@ -20,6 +20,8 @@ use op::*;
use utils::vec_utils;
use utils::LinkedHashMap;
use utils::LinkedHashSet;
use utils::AtomicUsizeSerde;
use utils::ATOMIC_USIZE_SERDE_INIT;
use std::fmt;
use std::default;
......@@ -77,7 +79,7 @@ pub fn new_internal_id() -> MuID {
ret
}
#[derive(Debug, RustcEncodable, RustcDecodable)]
#[derive(Debug, Serialize, Deserialize)]
pub struct MuFunction {
pub hdr: MuEntityHeader,
......@@ -112,7 +114,7 @@ impl fmt::Display for MuFunction {
}
}
#[derive(RustcEncodable, RustcDecodable)]
#[derive(Serialize, Deserialize)]
pub struct MuFunctionVersion {
pub hdr: MuEntityHeader,
......@@ -315,7 +317,7 @@ impl MuFunctionVersion {
}
}
#[derive(Clone, RustcEncodable, RustcDecodable)]
#[derive(Clone, Serialize, Deserialize)]
pub struct FunctionContent {
pub entry: MuID,
pub blocks: LinkedHashMap<MuID, Block>,
......@@ -384,7 +386,7 @@ impl FunctionContent {
}
}
#[derive(Default, Debug, RustcEncodable, RustcDecodable)]
#[derive(Default, Debug, Serialize, Deserialize)]
pub struct FunctionContext {
pub values: LinkedHashMap<MuID, SSAVarEntry>
}
......@@ -427,7 +429,7 @@ impl FunctionContext {
}
}
#[derive(RustcEncodable, RustcDecodable, Clone)]
#[derive(Serialize, Deserialize, Clone)]
pub struct Block {
pub hdr: MuEntityHeader,
pub content: Option<BlockContent>,
......@@ -468,7 +470,7 @@ impl Block {
}
}
#[derive(Debug, RustcEncodable, RustcDecodable, Clone)]
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ControlFlow {
pub preds : Vec<MuID>,
pub succs : Vec<BlockEdge>
......@@ -507,7 +509,7 @@ impl default::Default for ControlFlow {
}
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
pub struct BlockEdge {
pub target: MuID,
pub kind: EdgeKind,
......@@ -521,12 +523,12 @@ impl fmt::Display for BlockEdge {
}
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
pub enum EdgeKind {
Forward, Backward
}
#[derive(RustcEncodable, RustcDecodable, Clone)]
#[derive(Serialize, Deserialize, Clone)]
pub struct BlockContent {
pub args: Vec<P<Value>>,
pub exn_arg: Option<P<Value>>,
......@@ -622,7 +624,7 @@ impl BlockContent {
}
}
#[derive(Debug, RustcEncodable, RustcDecodable, Clone)]
#[derive(Debug, Serialize, Deserialize, Clone)]
/// always use with P<TreeNode>
pub struct TreeNode {
pub op: OpCode,
......@@ -697,14 +699,14 @@ impl fmt::Display for TreeNode {
}
}
#[derive(Debug, RustcEncodable, RustcDecodable, Clone)]
#[derive(Debug, Serialize, Deserialize, Clone)]
pub enum TreeNode_ {
Value(P<Value>),
Instruction(Instruction)
}
/// always use with P<Value>
#[derive(PartialEq, RustcEncodable, RustcDecodable)]
#[derive(PartialEq, Serialize, Deserialize)]
pub struct Value {
pub hdr: MuEntityHeader,
pub ty: P<MuType>,
......@@ -847,7 +849,7 @@ impl fmt::Display for Value {
}
}
#[derive(Debug, Clone, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Value_ {
SSAVar(MuID),
Constant(Constant),
......@@ -855,13 +857,14 @@ pub enum Value_ {
Memory(MemoryLocation)
}
#[derive(Debug)]
#[derive(Debug, Serialize, Deserialize)]
pub struct SSAVarEntry {
val: P<Value>,
// how many times this entry is used
// availalbe after DefUse pass
use_count: AtomicUsize,
//#[serde(with = "AtomicUsizeSerde")]
use_count: AtomicUsizeSerde,
// this field is only used during TreeGeneration pass
expr: Option<Instruction>,
......@@ -870,46 +873,11 @@ pub struct SSAVarEntry {
split: Option<Vec<P<Value>>>
}
impl Encodable for SSAVarEntry {
fn encode<S: Encoder> (&self, s: &mut S) -> Result<(), S::Error> {
s.emit_struct("SSAVarEntry", 3, |s| {
try!(s.emit_struct_field("val", 0, |s| self.val.encode(s)));
let count = self.use_count.load(Ordering::SeqCst);
try!(s.emit_struct_field("use_count", 1, |s| s.emit_usize(count)));
try!(s.emit_struct_field("expr", 2, |s| self.expr.encode(s)));
try!(s.emit_struct_field("split", 3, |s| self.split.encode(s)));
Ok(())
})
}
}
impl Decodable for SSAVarEntry {
fn decode<D: Decoder>(d: &mut D) -> Result<SSAVarEntry, D::Error> {
d.read_struct("SSAVarEntry", 3, |d| {
let val = try!(d.read_struct_field("val", 0, |d| Decodable::decode(d)));
let count = try!(d.read_struct_field("use_count", 1, |d| d.read_usize()));
let expr = try!(d.read_struct_field("expr", 2, |d| Decodable::decode(d)));
let split = try!(d.read_struct_field("split", 3, |d| Decodable::decode(d)));
let ret = SSAVarEntry {
val: val,
use_count: ATOMIC_USIZE_INIT,
expr: expr,
split: split
};
ret.use_count.store(count, Ordering::SeqCst);
Ok(ret)
})
}
}
impl SSAVarEntry {
pub fn new(val: P<Value>) -> SSAVarEntry {
let ret = SSAVarEntry {
val: val,
use_count: ATOMIC_USIZE_INIT,
use_count: ATOMIC_USIZE_SERDE_INIT,
expr: None,
split: None
};
......@@ -965,7 +933,7 @@ impl fmt::Display for SSAVarEntry {
}
}
#[derive(Debug, Clone, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Constant {
Int(u64),
IntEx(Vec<u64>),
......@@ -1015,7 +983,7 @@ impl fmt::Display for Constant {
}
#[cfg(target_arch = "x86_64")]
#[derive(Debug, Clone, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum MemoryLocation {
Address{
base: P<Value>,
......@@ -1059,7 +1027,7 @@ impl fmt::Display for MemoryLocation {
}
#[cfg(target_arch = "aarch64")]
#[derive(Debug, Clone, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum MemoryLocation {
// Represents how an adress should be computed,
// will need to be converted to a real Address before being used
......@@ -1120,7 +1088,7 @@ impl fmt::Display for MemoryLocation {
}
#[repr(C)]
#[derive(Debug)] // Display, PartialEq, Clone
#[derive(Debug, Serialize, Deserialize)] // Display, PartialEq, Clone
pub struct MuEntityHeader {
id: MuID,
name: Option<MuName>
......@@ -1135,46 +1103,32 @@ impl Clone for MuEntityHeader {
}
}
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
impl Encodable for MuEntityHeader {
fn encode<S: Encoder> (&self, s: &mut S) -> Result<(), S::Error> {
s.emit_struct("MuEntityHeader", 2, |s| {
try!(s.emit_struct_field("id", 0, |s| self.id.encode(s)));
let name = &self.name;
try!(s.emit_struct_field("name", 1, |s| name.encode(s)));
Ok(())
})
}
}
impl Decodable for MuEntityHeader {
fn decode<D: Decoder>(d: &mut D) -> Result<MuEntityHeader, D::Error> {
d.read_struct("MuEntityHeader", 2, |d| {
let id = try!(d.read_struct_field("id", 0, |d| {d.read_usize()}));
let name = try!(d.read_struct_field("name", 1, |d| Decodable::decode(d)));
Ok(MuEntityHeader{
id: id,
name: name
})
})
}
}
pub fn name_check(name: MuName) -> MuName {
let name = name.replace('.', "$");
if name.starts_with("@") || name.starts_with("%") {
let (_, name) = name.split_at(1);
// WARNING: A name starting with a '.L' will be interpreted as a local label
// (and so will not be exported to the generated file), however .globl overrides this
pub fn name_mangle(name: MuName) -> MuName {
/*if name.chars().next().unwrap().is_digit(10) {
unimplemented!();
// TODO: we could prefix every name with 'mu_', but this will break things
// that expect mu entities to be named in a certain way
}*/
// Note: we don't wan't symbols starting with this??
let name = if name.starts_with("%") {
warn!("The name {} cannot be loslessly demangled (WE SHOULDN't be passing local names to the VM anyway)", name);
name.split_at(1).0.to_string()
} else {
name
};
return name.to_string();
}
name.replace('-', "$")
}
name
pub fn name_demangle(name: MuName) -> MuName {
name.replace('$', "-")
}
impl MuEntityHeader {
pub fn unnamed(id: MuID) -> MuEntityHeader {
MuEntityHeader {
......@@ -1186,7 +1140,7 @@ impl MuEntityHeader {
pub fn named(id: MuID, name: MuName) -> MuEntityHeader {
MuEntityHeader {
id: id,
name: Some(name_check(name))
name: Some(name_mangle(name))
}
}
......
......@@ -11,12 +11,14 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#[macro_use]
extern crate log;
extern crate simple_logger;
#[macro_use]
extern crate lazy_static;
extern crate rustc_serialize;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate utils;
#[macro_export]
......
......@@ -17,7 +17,7 @@ use types::*;
use inst::*;
use types::MuType_::*;
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
#[allow(non_camel_case_types)]
pub enum OpCode {
// SSA
......@@ -140,7 +140,7 @@ pub fn pick_op_code_for_value(ty: &P<MuType>) -> OpCode {
}
}
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum BinOp {
// Int(n) BinOp Int(n) -> Int(n)
Add,
......@@ -167,7 +167,7 @@ pub enum BinOp {
FRem
}
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum CmpOp {
// for Int comparison
EQ,
......@@ -300,7 +300,7 @@ impl CmpOp {
}
}
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum ConvOp {
TRUNC,
ZEXT,
......@@ -316,7 +316,7 @@ pub enum ConvOp {
PTRCAST
}
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum AtomicRMWOp {
XCHG,
ADD,
......
......@@ -55,9 +55,9 @@
//use std::ops::Deref;
//use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
use std::sync::Arc;
use utils::ArcSerde;
pub type P<T> = Arc<T>;
pub type P<T> = ArcSerde<T>;
//pub struct P<T: MuEntity> {
// ptr: Arc<T>
//}
......@@ -66,7 +66,7 @@ pub type P<T> = Arc<T>;
/// Construct a `P<T>` from a `T` value.
pub fn P<T>(value: T) -> P<T> {
// P {ptr: Arc::new(value)}
Arc::new(value)
ArcSerde::new(value)
}
//impl<T: MuEntity> Deref for P<T> {
......
......@@ -90,7 +90,7 @@ pub fn init_types() {
}
}
#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
#[derive(PartialEq, Debug, Serialize, Deserialize)]
pub struct MuType {
pub hdr: MuEntityHeader,
pub v: MuType_
......@@ -346,7 +346,7 @@ impl MuType {
pub type StructTag = MuName;
pub type HybridTag = MuName;
#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
#[derive(PartialEq, Debug, Serialize, Deserialize)]
pub enum MuType_ {
/// int <length>
Int (usize),
......@@ -432,7 +432,7 @@ lazy_static! {
pub static ref HYBRID_TAG_MAP : RwLock<LinkedHashMap<HybridTag, HybridType_>> = RwLock::new(LinkedHashMap::new());
}
#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
#[derive(PartialEq, Debug, Serialize, Deserialize)]
pub struct StructType_ {
tys: Vec<P<MuType>>
}
......@@ -466,7 +466,7 @@ impl StructType_ {
}
}
#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
#[derive(PartialEq, Debug, Serialize, Deserialize)]
pub struct HybridType_ {
fix_tys: Vec<P<MuType>>,
var_ty : P<MuType>
......@@ -649,7 +649,7 @@ macro_rules! is_type (
pub type CFuncSig = MuFuncSig;
#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
#[derive(PartialEq, Debug, Serialize, Deserialize)]
pub struct MuFuncSig {
pub hdr: MuEntityHeader,
pub ret_tys : Vec<P<MuType>>,
......
......@@ -3383,7 +3383,7 @@ pub fn emit_code(fv: &mut MuFunctionVersion, vm: &VM) {
};
// constants in text section
file.write("\t.text\n".as_bytes()).unwrap();
file.write_all("\t.text\n".as_bytes()).unwrap();
// FIXME: need a more precise way to determine alignment
// (probably use alignment backend info, which require introducing int128 to zebu)
......@@ -3507,7 +3507,6 @@ pub fn emit_context_with_reloc(vm: &VM,
fields : HashMap<Address, String>) {
use std::path;
use std::io::prelude::*;
use rustc_serialize::json;
emit_mu_types(vm);
......@@ -3527,7 +3526,7 @@ pub fn emit_context_with_reloc(vm: &VM,
file.write_fmt(format_args!("\t.bss\n")).unwrap();
// data
file.write("\t.data\n".as_bytes()).unwrap();
file.write_all("\t.data\n".as_bytes()).unwrap();
{
use runtime::mm;
......@@ -3596,7 +3595,7 @@ pub fn emit_context_with_reloc(vm: &VM,
let load_ref = unsafe {cur_addr.load::<Address>()};
if load_ref.is_zero() {
// write 0
file.write("\t.quad 0\n".as_bytes()).unwrap();
file.write_all("\t.quad 0\n".as_bytes()).unwrap();
} else {
let label = match relocatable_refs.get(&load_ref) {
Some(label) => label,
......@@ -3629,15 +3628,34 @@ pub fn emit_context_with_reloc(vm: &VM,
// serialize vm
trace!("start serializing vm");
{
let serialize_vm = json::encode(&vm).unwrap();
use bincode;
let serialize_vm = bincode::serialize(&vm, bincode::Infinite).unwrap();
let vm_size_symbol = "vm_size".to_string();
file.write_fmt(format_args!("{}\n", directive_globl(vm_size_symbol.clone()))).unwrap();
file.write_fmt(format_args!("\t{}: .quad {}\n", vm_size_symbol.clone(), serialize_vm.len())).unwrap();
// Write the VM (as a string, in the most compact way possible)
let vm_symbol = symbol("vm".to_string());
file.write_fmt(format_args!("{}\n", directive_globl(vm_symbol.clone()))).unwrap();
let escape_serialize_vm = serialize_vm.replace("\"", "\\\"");
file.write_fmt(format_args!("\t{}: .asciz \"{}\"", vm_symbol, escape_serialize_vm)).unwrap();
file.write("\n".as_bytes()).unwrap();
}
file.write_fmt(format_args!("{}: .ascii \"", vm_symbol)).unwrap();
for byte in serialize_vm {
// The characters <LF> (0x0a) \ (0x5c) and " (0x22) must be escaped
match byte {
0x0a | 0x5c | 0x22 => file.write_all(&['\\' as u8]).unwrap(),
_ => ()
}
// The character <LF> needs to be printed as \n and not \<LF>
file.write_all(&[match byte {
0x0a => 'n' as u8,
_ => byte,
}]).unwrap();
}
file.write_all("\"\n".as_bytes()).unwrap();
}
// main_thread
// let primordial = vm.primordial.read().unwrap();
// if primordial.is_some() {
......
......@@ -345,7 +345,7 @@ pub fn sequetial_layout(tys: &Vec<P<MuType>>, vm: &VM) -> (ByteSize, ByteSize, V
(ret.size, ret.alignment, ret.struct_layout.unwrap())
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct BackendTypeInfo {
pub size: ByteSize,
pub alignment: ByteSize,
......@@ -388,7 +388,7 @@ impl fmt::Display for BackendTypeInfo {
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum RegGroup {GPR, GPREX, FPR}
impl RegGroup {
......
......@@ -31,7 +31,7 @@ use vm::VM;
// | alloca area
#[derive(RustcEncodable, RustcDecodable, Clone)]
#[derive(Serialize, Deserialize, Clone)]
pub struct Frame {
func_ver_id: MuID,
cur_offset: isize, // offset to frame base pointer
......@@ -152,7 +152,7 @@ impl Frame {
}
}
#[derive(RustcEncodable, RustcDecodable, Clone)]
#[derive(Serialize, Deserialize, Clone)]
pub struct FrameSlot {
pub offset: isize,
pub value: P<Value>,
......
......@@ -14,15 +14,14 @@
use ast::ir::*;
use ast::ptr::*;
use compiler::frame::*;
use runtime::ValueLocation;
use std::ops;
use std::collections::HashMap;
use std::collections::HashSet;
use compiler::frame::Frame;
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
#[derive(Serialize, Deserialize)]
pub struct CompiledFunction {
pub func_id: MuID,
pub func_ver_id: MuID,
......@@ -34,6 +33,7 @@ pub struct CompiledFunction {
pub const_mem: HashMap<MuID, P<Value>>,
// not emitting this
#[serde(skip)]
pub mc: Option<Box<MachineCode + Send + Sync>>,
pub frame: Frame,
......@@ -41,85 +41,6 @@ pub struct CompiledFunction {
pub end: ValueLocation
}
const CF_SERIALIZE_FIELDS : usize = 6;
impl Encodable for CompiledFunction {
fn encode<S: Encoder> (&self, s: &mut S) -> Result<(), S::Error> {
s.emit_struct("CompiledFunction", CF_SERIALIZE_FIELDS, |s| {
let mut i = 0;
try!(s.emit_struct_field("func_id", i, |s| self.func_id.encode(s)));
i += 1;
try!(s.emit_struct_field("func_ver_id", i, |s| self.func_ver_id.encode(s)));
i += 1;
try!(s.emit_struct_field("temps", i, |s| self.temps.encode(s)));
i += 1;
try!(s.emit_struct_field("consts", i, |s| self.consts.encode(s)));
i += 1;
try!(s.emit_struct_field("const_mem", i, |s| self.const_mem.encode(s)));
i += 1;
try!(s.emit_struct_field("frame", i, |s| self.frame.encode(s)));
i += 1;
try!(s.emit_struct_field("start", i, |s| self.start.encode(s)));
i += 1;
try!(s.emit_struct_field("end", i, |s| self.end.encode(s)));
Ok(())
})
}
}
impl Decodable for CompiledFunction {
fn decode<D: Decoder>(d: &mut D) -> Result<CompiledFunction, D::Error> {
d.read_struct("CompiledFunction", CF_SERIALIZE_FIELDS, |d| {
let mut i = 0;
let func_id =
try!(d.read_struct_field("func_id", i, |d| Decodable::decode(d)));
i += 1;
let func_ver_id =
try!(d.read_struct_field("func_ver_id", i, |d| Decodable::decode(d)));
i += 1;
let temps =
try!(d.read_struct_field("temps", i, |d| Decodable::decode(d)));
i += 1;
let consts =
try!(d.read_struct_field("consts", i, |d| Decodable::decode(d)));
i += 1;
let const_mem =
try!(d.read_struct_field("const_mem", i, |d| Decodable::decode(d)));
i += 1;
let frame =
try!(d.read_struct_field("frame", i, |d| Decodable::decode(d)));
i += 1;
let start =
try!(d.read_struct_field("start", i, |d| Decodable::decode(d)));
i += 1;
let end =
try!(d.read_struct_field("end", i, |d| Decodable::decode(d)));
Ok(CompiledFunction{
func_id: func_id,
func_ver_id: func_ver_id,
temps: temps,
consts: consts,
const_mem: const_mem,
mc: None,
frame: frame,
start: start,
end: end
})
})
}
}
impl CompiledFunction {
pub fn new(func_id: MuID, fv_id: MuID, mc: Box<MachineCode + Send + Sync>,
constants: HashMap<MuID, P<Value>>, constant_locs: HashMap<MuID, P<Value>>,
......
......@@ -37,5 +37,6 @@ log = "0.3.5"
simple_logger = "0.4.0"
aligned_alloc = "0.1.2"
crossbeam = "0.2.8"
rustc-serialize = "*"
serde = "1.0.8"
serde_derive = "1.0.8"
field-offset = "0.1.1"
\ No newline at end of file
......@@ -14,15 +14,15 @@
#![allow(dead_code)]
use std::sync::Arc;
use utils::POINTER_SIZE;
use utils::ByteSize;
use utils::ArcSerde;
use objectmodel;
use std::u32;
pub const GCTYPE_INIT_ID: u32 = u32::MAX;
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct GCType {
pub id: u32,
pub alignment: ByteSize,
......@@ -148,13 +148,13 @@ impl GCType {
}
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum RefPattern {
Map{
offsets: Vec<ByteSize>,
size : usize
},
NestedType(Vec<Arc<GCType>>),
NestedType(Vec<ArcSerde <GCType>>),
Repeat{
pattern: Box<RefPattern>,
count: usize
......@@ -217,7 +217,7 @@ impl RefPattern {
#[cfg(test)]
mod tests {
use super::*;
use std::sync::Arc;
use utils::ArcSerde;
use utils::ByteSize;
fn create_types() -> Vec<GCType> {
......@@ -261,7 +261,7 @@ mod tests {
fix_size: 1600,
fix_refs: Some(RefPattern::Repeat {
pattern: Box::new(RefPattern::NestedType(vec![Arc::new(b.clone()).clone()])),
pattern: Box::new(RefPattern::NestedType(vec![ArcSerde::new(b.clone()).clone()])),
count : 10
}),
......
......@@ -21,7 +21,7 @@ use MY_GC;
use objectmodel;
use std::collections::HashMap;
use std::sync::Arc;
use utils::ArcSerde;
pub struct HeapDump {
pub objects: HashMap<Address, ObjectDump>,
......@@ -100,7 +100,7 @@ impl HeapDump {
trace!("fix size, type id as {}", gctype_id);
let gc_lock = MY_GC.read().unwrap();
let gctype : Arc<GCType> = gc_lock.as_ref().unwrap().gc_types[gctype_id as usize].clone();
let gctype : ArcSerde<GCType> = gc_lock.as_ref().unwrap().gc_types[gctype_id as usize].clone();
ObjectDump {
reference_addr: obj,
......@@ -117,7 +117,7 @@ impl HeapDump {
trace!("var sized, type id as {}", gctype_id);
let gc_lock = MY_GC.read().unwrap();
let gctype : Arc<GCType> = gc_lock.as_ref().unwrap().gc_types[gctype_id as usize].clone();
let gctype : ArcSerde<GCType> = gc_lock.as_ref().unwrap().gc_types[gctype_id as usize].clone();
ObjectDump {
reference_addr: obj,
......
......@@ -18,13 +18,13 @@ mod treadmill;
//pub use heap::freelist::malloc_list::FreeListSpace;
pub use heap::freelist::treadmill::FreeListSpace;
use std::sync::Arc;
use utils::ArcSerde;
use heap::gc;
use utils::Address;
use heap::immix;
#[inline(never)]
pub fn alloc_large(size: usize, align: usize, mutator: &mut immix::ImmixMutatorLocal, space: Arc<FreeListSpace>) -> Address {
pub fn alloc_large(size: usize, align: usize, mutator: &mut immix::ImmixMutatorLocal, space: ArcSerde<FreeListSpace>) -> Address {
loop {
mutator.yieldpoint();
......
......@@ -24,9 +24,10 @@ use MY_GC;
use utils::{Address, ObjectReference};
use utils::POINTER_SIZE;
use utils::ArcSerde;
use std::sync::atomic::{AtomicIsize, AtomicBool, Ordering};
use std::sync::{Arc, Mutex, Condvar, RwLock};
use std::sync::{Mutex, Condvar, RwLock};
use crossbeam::sync::chase_lev::*;
use std::sync::mpsc;
......@@ -36,8 +37,8 @@ use std::thread;
use std::sync::atomic;
lazy_static! {
static ref STW_COND : Arc<(Mutex<usize>, Condvar)> = {
Arc::new((Mutex::new(0), Condvar::new()))
static ref STW_COND : ArcSerde<(Mutex<usize>, Condvar)> = {
ArcSerde::new((Mutex::new(0), Condvar::new()))
};
static ref ROOTS : RwLock<Vec<ObjectReference>> = RwLock::new(vec![]);
......@@ -289,7 +290,7 @@ pub static GC_THREADS : atomic::AtomicUsize = atomic::ATOMIC_USIZE_INIT;
#[allow(unused_variables)]
#[inline(never)]
pub fn start_trace(work_stack: &mut Vec<ObjectReference>, immix_space: Arc<ImmixSpace>, lo_space: Arc<FreeListSpace>) {
pub fn start_trace(work_stack: &mut Vec<ObjectReference>, immix_space: ArcSerde<ImmixSpace>, lo_space: ArcSerde<FreeListSpace>) {
// creates root deque
let (mut worker, stealer) = deque();
......@@ -331,7 +332,7 @@ pub fn start_trace(work_stack: &mut Vec<ObjectReference>, immix_space: Arc<Immix
}
#[allow(unused_variables)]
fn start_steal_trace(stealer: Stealer<ObjectReference>, job_sender:mpsc::Sender<ObjectReference>, immix_space: Arc<ImmixSpace>, lo_space: Arc<FreeListSpace>) {
fn start_steal_trace(stealer: Stealer<ObjectReference>, job_sender:mpsc::Sender<ObjectReference>, immix_space: ArcSerde<ImmixSpace>, lo_space: ArcSerde<FreeListSpace>) {
use objectmodel;
let mut local_queue = vec![];
......@@ -518,7 +519,7 @@ pub fn steal_trace_object(obj: ObjectReference, local_queue: &mut Vec<ObjectRefe
let gctype_id = objectmodel::header_get_gctype_id(hdr);
let gc_lock = MY_GC.read().unwrap();
let gctype : Arc<GCType> = gc_lock.as_ref().unwrap().gc_types[gctype_id as usize].clone();
let gctype : ArcSerde<GCType> = gc_lock.as_ref().unwrap().gc_types[gctype_id as usize].clone();
for offset in gctype.gen_ref_offsets() {
steal_process_edge(addr, offset, local_queue, job_sender, mark_state, immix_space, lo_space);
......@@ -530,7 +531,7 @@ pub fn steal_trace_object(obj: ObjectReference, local_queue: &mut Vec<ObjectRefe
let var_length = objectmodel::header_get_hybrid_length(hdr);
let gc_lock = MY_GC.read().unwrap();
let gctype : Arc<GCType> = gc_lock.as_ref().unwrap().gc_types[gctype_id as usize].clone();
let gctype : ArcSerde<GCType> = gc_lock.as_ref().unwrap().gc_types[gctype_id as usize].clone();
for offset in gctype.gen_hybrid_ref_offsets(var_length) {
steal_process_edge(addr, offset, local_queue, job_sender, mark_state, immix_space, lo_space);
......
......@@ -20,13 +20,13 @@ use objectmodel;
use utils::Address;
use std::*;
use std::sync::Arc;
use utils::ArcSerde;
use std::sync::RwLock;
use std::sync::atomic::{AtomicBool, Ordering};
const MAX_MUTATORS : usize = 1024;
lazy_static! {
pub static ref MUTATORS : RwLock<Vec<Option<Arc<ImmixMutatorGlobal>>>> = {
pub static ref MUTATORS : RwLock<Vec<Option<ArcSerde<ImmixMutatorGlobal>>>> = {
let mut ret = Vec::with_capacity(MAX_MUTATORS);
for _ in 0..MAX_MUTATORS {
ret.push(None);
......@@ -57,9 +57,9 @@ pub struct ImmixMutatorLocal {
line : usize,
// globally accessible per-thread fields
pub global : Arc<ImmixMutatorGlobal>,
pub global : ArcSerde<ImmixMutatorGlobal>,
space : Arc<ImmixSpace>,
space : ArcSerde<ImmixSpace>,
block : Option<Box<ImmixBlock>>,
mark_state: u8
......@@ -92,8 +92,8 @@ impl ImmixMutatorLocal {
self.mark_state ^= 1;
}
pub fn new(space : Arc<ImmixSpace>) -> ImmixMutatorLocal {
let global = Arc::new(ImmixMutatorGlobal::new());
pub fn new(space : ArcSerde<ImmixSpace>) -> ImmixMutatorLocal {
let global = ArcSerde::new(ImmixMutatorGlobal::new());
let mut id_lock = N_MUTATORS.write().unwrap();
{
......
......@@ -24,7 +24,7 @@ use utils::mem::memsec;
use std::*;
use std::collections::LinkedList;
use std::sync::Mutex;
use std::sync::Arc;
use utils::ArcSerde;
// this table will be accessed through unsafe raw pointers. since Rust doesn't provide a data structure for such guarantees:
// 1. Non-overlapping segments of this table may be accessed parallelly from different mutator threads
......@@ -128,10 +128,10 @@ pub struct ImmixSpace {
end : Address,
// these maps are writable at allocation, read-only at collection
pub alloc_map : Arc<AddressMap<u8>>,
pub alloc_map : ArcSerde<AddressMap<u8>>,
// these maps are only for collection
pub trace_map : Arc<AddressMap<u8>>,
pub trace_map : ArcSerde<AddressMap<u8>>,
// this table will be accessed through unsafe raw pointers. since Rust doesn't provide a data structure for such guarantees:
// 1. Non-overlapping segments of this table may be accessed parallelly from different mutator threads
......@@ -185,8 +185,8 @@ impl ImmixSpace {
mmap: anon_mmap,
line_mark_table: line_mark_table,
trace_map: Arc::new(trace_map),
alloc_map: Arc::new(alloc_map),
trace_map: ArcSerde::new(trace_map),
alloc_map: ArcSerde::new(alloc_map),
usable_blocks: Mutex::new(LinkedList::new()),
used_blocks: Mutex::new(LinkedList::new()),
total_blocks: 0
......
......@@ -24,11 +24,11 @@ pub use self::immix_mutator::N_MUTATORS;
pub use self::immix_mutator::CURSOR_OFFSET;
pub use self::immix_mutator::LIMIT_OFFSET;
use std::sync::Arc;
use utils::ArcSerde;
use std::sync::RwLock;
lazy_static!{
pub static ref SHARED_SPACE : Option<Arc<RwLock<ImmixSpace>>> = None;
pub static ref SHARED_SPACE : Option<ArcSerde<RwLock<ImmixSpace>>> = None;
}
pub const LOG_BYTES_IN_LINE : usize = 8;
......
......@@ -20,9 +20,11 @@ extern crate log;
extern crate simple_logger;
extern crate aligned_alloc;
extern crate crossbeam;
extern crate rustc_serialize;
#[macro_use]
extern crate field_offset;
#[macro_use]
extern crate serde_derive;
extern crate serde;
use std::sync::atomic::Ordering;
......@@ -41,9 +43,9 @@ use common::objectdump;
use utils::LinkedHashSet;
use utils::Address;
use utils::ArcSerde;
use std::fmt;
use std::sync::Arc;
use std::sync::RwLock;
pub const GC_MOVES_OBJECT : bool = false;
......@@ -56,10 +58,10 @@ pub use heap::immix::LIMIT_OFFSET as ALLOCATOR_LIMIT_OFFSET;
#[repr(C)]
pub struct GC {
immix_space: Arc<ImmixSpace>,
lo_space : Arc<FreeListSpace>,
immix_space: ArcSerde<ImmixSpace>,
lo_space : ArcSerde<FreeListSpace>,
gc_types : Vec<Arc<GCType>>,
gc_types : Vec<ArcSerde<GCType>>,
roots : LinkedHashSet<ObjectReference>
}
......@@ -82,7 +84,7 @@ pub extern fn gc_stats() {
}
#[no_mangle]
pub extern fn get_spaces() -> (Arc<ImmixSpace>, Arc<FreeListSpace>) {
pub extern fn get_spaces() -> (ArcSerde<ImmixSpace>, ArcSerde<FreeListSpace>) {
let space_lock = MY_GC.read().unwrap();
let space = space_lock.as_ref().unwrap();
......@@ -90,14 +92,14 @@ pub extern fn get_spaces() -> (Arc<ImmixSpace>, Arc<FreeListSpace>) {
}
#[no_mangle]
pub extern fn add_gc_type(mut ty: GCType) -> Arc<GCType> {
pub extern fn add_gc_type(mut ty: GCType) -> ArcSerde<GCType> {
let mut gc_guard = MY_GC.write().unwrap();
let mut gc = gc_guard.as_mut().unwrap();
let index = gc.gc_types.len() as u32;
ty.id = index;
let ty = Arc::new(ty);
let ty = ArcSerde::new(ty);
gc.gc_types.push(ty.clone());
......@@ -129,8 +131,8 @@ pub extern fn gc_init(immix_size: usize, lo_size: usize, n_gcthreads: usize, ena
heap::LO_SPACE_SIZE.store(lo_size, Ordering::SeqCst);
let (immix_space, lo_space) = {
let immix_space = Arc::new(ImmixSpace::new(immix_size));
let lo_space = Arc::new(FreeListSpace::new(lo_size));
let immix_space = ArcSerde::new(ImmixSpace::new(immix_size));
let lo_space = ArcSerde::new(FreeListSpace::new(lo_size));
heap::gc::init(n_gcthreads);
......
......@@ -227,7 +227,7 @@ mod tests {
use super::*;
use common::gctype::*;
use utils::POINTER_SIZE;
use std::sync::Arc;
use utils::ArcSerde;
#[test]
fn fixsize_header_refmap() {
......@@ -397,7 +397,7 @@ mod tests {
0,
8,
None,
Some(RefPattern::NestedType(vec![Arc::new(b.clone()).clone()])),
Some(RefPattern::NestedType(vec![ArcSerde::new(b.clone()).clone()])),
160
);
println!("gctype: {:?}", a);
......
// Copyright 2017 The Australian National University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Copyright 2017 The Australian National University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate bincode;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
extern crate rustc_serialize;
extern crate stderrlog;
#[macro_use]
extern crate maplit;
......
......@@ -51,23 +51,22 @@ pub extern fn throw_exception_internal(exception_obj: Address, frame_cursor: Add
let mut current_frame_pointer = frame_cursor; // this will be 16 bytes bellow the bottom of the previous frame
let mut callsite = get_return_address(current_frame_pointer);
let mut previous_frame_pointer = get_previous_frame_pointer(current_frame_pointer); // thrower::fp, the starting point of the previous frame
let start_frame = current_frame_pointer; // Used for backtrace printing
let start_callsite = callsite; // Used for backtrace printing
loop {
// Lookup the table for the callsite
trace!("Callsite: 0x{:x}", callsite);
trace!("\tprevious_frame_pointer: 0x{:x}", previous_frame_pointer);
trace!("\tcurrent_frame_pointer: 0x{:x}", current_frame_pointer);
let table_entry = vm.compiled_exception_table.get(&callsite);
if table_entry.is_none() {
let exception_info = vm.get_exception_callsite(callsite);
if exception_info.is_none() {
error!("Cannot find Mu callsite (i.e. we have reached a native frame), either there isn't a catch block to catch the exception or your catch block is above a native function call");
print_backtrace(frame_cursor);
unreachable!(); // The above function will not return
print_backtrace(start_callsite, start_frame);
panic!("Uncaught Mu Exception");
}
let &(catch_address, compiled_func) = table_entry.unwrap();
let (catch_address, compiled_func) = exception_info.unwrap();
// Check for a catch block at this callsite (there won't be one on the first iteration of this loop)
if !catch_address.is_zero() {
trace!("Found catch block: 0x{:x}", catch_address);
......@@ -120,7 +119,7 @@ fn print_frame(base: Address) {
// This function may segfault or panic when it reaches the bottom of the stack
// (TODO: Determine where the bottom is without segfaulting)
fn print_backtrace(base: Address) -> !{
fn print_backtrace(start_callsite: Address, base: Address) {
error!("BACKTRACE: ");
let cur_thread = thread::MuThread::current();
......@@ -129,11 +128,12 @@ fn print_backtrace(base: Address) -> !{
let mut frame_pointer = base;
let mut frame_count = 0;
let mut callsite = start_callsite;
let compiled_exception_table = vm.compiled_exception_table.read().unwrap();
loop {
let callsite = get_return_address(frame_pointer);
if vm.compiled_exception_table.contains_key(&callsite) {
let &(_, compiled_func_ptr) = vm.compiled_exception_table.get(&callsite).unwrap();
let info = compiled_exception_table.get(&callsite);
if info.is_some() {
let &(_, compiled_func_ptr) = info.unwrap();
unsafe {
let ref compiled_func = *compiled_func_ptr;
......@@ -149,8 +149,10 @@ fn print_backtrace(base: Address) -> !{
frame_pointer = get_previous_frame_pointer(frame_pointer);
if frame_pointer.is_zero() {
panic!("Uncaught Mu Exception");
return;
}
callsite = get_return_address(frame_pointer);
frame_count += 1;
}
}
\ No newline at end of file
......@@ -17,13 +17,13 @@
#include <stdint.h>
#include <string.h>
extern void* vm;
extern void mu_main(char*, int, char**);
extern size_t vm_size;
extern char vm;
extern void mu_main(size_t, char*, int, char**);
extern uint32_t mu_retval;
int main(int argc, char** argv) {
char* serialize_vm = (char*) &vm;
mu_main(serialize_vm, argc, argv);
mu_main(vm_size, &vm, argc, argv);
return (int) mu_retval;
}
}
\ No newline at end of file
......@@ -55,6 +55,7 @@ extern "C" {
// TODO: this actually returns the name and address of the nearest symbol (of any type)
// that starts before function_addr (instead we want the nearest function symbol)
// Note: this is not expected to be called on Mu entitiees
pub fn get_function_info(function_addr: Address) -> (CName, Address) {
use std::ptr;
......@@ -81,14 +82,35 @@ pub fn get_function_info(function_addr: Address) -> (CName, Address) {
} else {
("UNKOWN".to_string(), Address::from_ptr(info.dli_saddr))
}
}
// Returns None if the address isn't the address of a symbol
pub fn resolve_address(address: Address) -> Option<MuName> {
use std::ptr;
pub fn resolve_symbol(symbol: String) -> Address {
// Rust requires this to be initialised
let mut info = Dl_info {
dli_fname: ptr::null::<c_char>(),
dli_fbase: ptr::null_mut::<c_void>(),
dli_sname: ptr::null::<c_char>(),
dli_saddr: ptr::null_mut::<c_void>(),
};
unsafe {dladdr(address.to_ptr_mut::<c_void>(), &mut info)};
let error = unsafe {dlerror()};
if !error.is_null() || info.dli_sname.is_null() || Address::from_ptr(info.dli_saddr) != address {
// No symbol located at exactly address was found
None
} else {
Some(name_demangle(unsafe { CStr::from_ptr(info.dli_sname) }.to_str().unwrap().to_string()))
}
}
pub fn resolve_symbol(symbol: MuName) -> Address {
use std::ptr;
let symbol = name_check(symbol);
let symbol = name_mangle(symbol);
let rtld_default = unsafe {dlopen(ptr::null(), 0)};
let ret = unsafe {dlsym(rtld_default, CString::new(symbol.clone()).unwrap().as_ptr())};
......@@ -105,16 +127,15 @@ pub fn resolve_symbol(symbol: String) -> Address {
Address::from_ptr(ret)
}
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
#[derive(Serialize, Deserialize, PartialEq, Eq, Hash, Clone, Debug)]
pub enum ValueLocation {
Register(RegGroup, MuID), // 0
Constant(RegGroup, Word), // 1
Relocatable(RegGroup, MuName),// 2
Direct(RegGroup, Address), // 3
Indirect(RegGroup, Address), // 4
Register(RegGroup, MuID),
Constant(RegGroup, Word),
Relocatable(RegGroup, MuName),
// #[serde(skip_deserializing)]
Direct(RegGroup, Address),
// #[serde(skip_deserializing)]
Indirect(RegGroup, Address),
}
impl fmt::Display for ValueLocation {
......@@ -129,74 +150,6 @@ impl fmt::Display for ValueLocation {
}
}
impl Encodable for ValueLocation {
fn encode<S: Encoder> (&self, s: &mut S) -> Result<(), S::Error> {
s.emit_enum("ValueLocation", |s| {
match self {
&ValueLocation::Register(grp, id) => {
s.emit_enum_variant("Register", 0, 2, |s| {
try!(s.emit_enum_variant_arg(0, |s| grp.encode(s)));
try!(s.emit_enum_variant_arg(1, |s| id.encode(s)));
Ok(())
})
}
&ValueLocation::Constant(grp, val) => {
s.emit_enum_variant("Constant", 1, 2, |s| {
try!(s.emit_enum_variant_arg(0, |s| grp.encode(s)));
try!(s.emit_enum_variant_arg(1, |s| val.encode(s)));
Ok(())
})
}
&ValueLocation::Relocatable(grp, ref name) => {
s.emit_enum_variant("Relocatable", 2, 2, |s| {
try!(s.emit_enum_variant_arg(0, |s| grp.encode(s)));
try!(s.emit_enum_variant_arg(1, |s| name.encode(s)));
Ok(())
})
}
&ValueLocation::Direct(_, _)
| &ValueLocation::Indirect(_, _) => {
panic!("trying to encode an address location (not persistent)")
}
}
})
}
}
impl Decodable for ValueLocation {
fn decode<D: Decoder>(d: &mut D) -> Result<ValueLocation, D::Error> {
d.read_enum("ValueLocation", |d| {
d.read_enum_variant(
&vec!["Register", "Constant", "Relocatable"],
|d, idx| {
match idx {
0 => {
// Register variant
let grp = try!(d.read_enum_variant_arg(0, |d| Decodable::decode(d)));
let id = try!(d.read_enum_variant_arg(1, |d| Decodable::decode(d)));
Ok(ValueLocation::Register(grp, id))
}
1 => {
// Constant
let grp = try!(d.read_enum_variant_arg(0, |d| Decodable::decode(d)));
let val = try!(d.read_enum_variant_arg(1, |d| Decodable::decode(d)));
Ok(ValueLocation::Constant(grp, val))
}
2 => {
// Relocatable
let grp = try!(d.read_enum_variant_arg(0, |d| Decodable::decode(d)));
let name = try!(d.read_enum_variant_arg(1, |d| Decodable::decode(d)));
Ok(ValueLocation::Relocatable(grp, name))
}
_ => panic!("unexpected enum variant for ValueLocation: {}", idx)
}
}
)
})
}
}
impl ValueLocation {
pub fn load_value(&self) -> (RegGroup, Word) {
match self {
......@@ -248,12 +201,12 @@ pub extern fn mu_trace_level_log() {
}
#[no_mangle]
pub extern fn mu_main(serialized_vm : *const c_char, argc: c_int, argv: *const *const c_char) {
pub extern fn mu_main(serialized_vm_length: usize, serialized_vm : *const u8, argc: c_int, argv: *const *const c_char) {
use std::slice;
debug!("mu_main() started...");
let str_vm = unsafe{CStr::from_ptr(serialized_vm)}.to_str().unwrap();
let vm : Arc<VM> = Arc::new(VM::resume_vm(str_vm));
let ref bytes_vm = unsafe{slice::from_raw_parts(serialized_vm, serialized_vm_length)};
let vm : Arc<VM> = Arc::new(VM::resume_vm(bytes_vm));
let primordial = vm.primordial.read().unwrap();
if primordial.is_none() {
......@@ -292,4 +245,4 @@ pub extern fn mu_main(serialized_vm : *const c_char, argc: c_int, argv: *const *
#[allow(unreachable_code)]
pub extern fn muentry_print_hex(x: u64) {