GitLab will be upgraded to the 12.10.14-ce.0 on 28 Sept 2020 at 2.00pm (AEDT) to 2.30pm (AEDT). During the update, GitLab and Mattermost services will not be available. If you have any concerns with this, please talk to us at N110 (b) CSIT building.

...
 
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,34 +1103,6 @@ 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('.', "$");
......@@ -1175,6 +1115,7 @@ pub fn name_check(name: MuName) -> MuName {
name
}
impl MuEntityHeader {
pub fn unnamed(id: MuID) -> MuEntityHeader {
MuEntityHeader {
......
......@@ -16,7 +16,9 @@ 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,7 +51,8 @@ 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);
......@@ -62,7 +63,7 @@ pub extern fn throw_exception_internal(exception_obj: Address, frame_cursor: Add
if table_entry.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);
print_backtrace(start_callsite, start_frame);
unreachable!(); // The above function will not return
}
......@@ -120,7 +121,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,9 +130,8 @@ fn print_backtrace(base: Address) -> !{
let mut frame_pointer = base;
let mut frame_count = 0;
let mut callsite = start_callsite;
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();
......@@ -151,6 +151,8 @@ fn print_backtrace(base: Address) -> !{
if frame_pointer.is_zero() {
panic!("Uncaught Mu Exception");
}
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
......@@ -105,16 +105,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 +128,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 +179,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 +223,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) {
println!("PRINTHEX: 0x{:x}", x);
}
\ No newline at end of file
}
......@@ -509,7 +509,7 @@ impl MuThread {
}
}
#[derive(Debug, RustcEncodable, RustcDecodable)]
#[derive(Debug, Serialize, Deserialize)]
pub struct MuPrimordialThread {
pub func_id: MuID,
......
......@@ -24,4 +24,5 @@ crate-type = ["rlib"]
memmap = "0.4.0"
memsec = "0.1.9"
byteorder = "0.5.3"
rustc-serialize = "*"
\ No newline at end of file
serde = "1.0.8"
serde_derive = "1.0.8"
\ No newline at end of file
......@@ -19,7 +19,7 @@ use std::fmt;
use std::mem;
#[repr(C)]
#[derive(Copy, Clone, Eq, Hash)]
#[derive(Copy, Clone, Eq, Hash, Serialize, Deserialize)]
pub struct Address(usize);
impl Address {
......
......@@ -13,8 +13,9 @@
// limitations under the License.
extern crate byteorder;
extern crate rustc_serialize;
#[macro_use]
extern crate serde_derive;
extern crate serde;
pub type BitSize = usize;
pub type ByteOffset = isize;
pub type ByteSize = usize;
......@@ -31,10 +32,12 @@ pub mod mem;
mod linked_hashmap;
mod linked_hashset;
mod doubly;
mod serde_types;
pub use linked_hashmap::LinkedHashMap;
pub use linked_hashset::LinkedHashSet;
pub use doubly::DoublyLinkedList;
pub use serde_types::*;
#[macro_export]
macro_rules! linked_hashmap {
......
......@@ -50,7 +50,7 @@
use std::borrow::Borrow;
use std::cmp::Ordering;
use std::collections::hash_map::{self, HashMap};
use std::collections::hash_map::HashMap;
use std::fmt;
use std::hash::{BuildHasher, Hash, Hasher};
use std::iter;
......@@ -58,48 +58,11 @@ use std::marker;
use std::mem;
use std::ops::{Index, IndexMut};
use std::ptr;
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
impl<K, V, S> Encodable for LinkedHashMap<K, V, S>
where K: Encodable + Eq + Hash,
V: Encodable,
S: BuildHasher
{
fn encode<E: Encoder> (&self, s: &mut E) -> Result<(), E::Error> {
s.emit_map(self.len(), |s| {
let mut i = 0;
for (k, v) in self {
s.emit_map_elt_key(i, |s| k.encode(s)).ok();
s.emit_map_elt_val(i, |s| v.encode(s)).ok();
i += 1;
}
Ok(())
})
}
}
impl<K, V> Decodable for LinkedHashMap<K, V>
where K: Decodable + Eq + Hash,
V: Decodable
{
fn decode<D: Decoder> (d: &mut D) -> Result<LinkedHashMap<K, V>, D::Error> {
d.read_map(|d, len| {
let mut map = LinkedHashMap::new();
for i in 0..len {
let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d)));