Commit 55d83865 authored by qinsoon's avatar qinsoon

Merge remote-tracking branch 'origin/develop' into open-source

parents 25edf86a e9d49a43
.gitignore
**/target/*
**/__pycache__/*
**/.cache/*
......@@ -18,3 +19,5 @@ cmake-build-debug/*
Notes/*
CMakeLists.txt
*.iml
.rsync-filter
*.so
# 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"
......@@ -28,26 +28,27 @@ aot = []
jit = []
[build-dependencies]
gcc = "0.3"
gcc = "*"
[dependencies]
ast = {path = "src/ast"}
utils = {path = "src/utils"}
gc = {path = "src/gc"}
field-offset = "0.1.1"
libloading = "0.3"
lazy_static = "0.1.15"
log = "0.3.5"
stderrlog = "0.2.2"
hprof = "0.1.3"
memmap = "0.4.0"
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal" }
libc="*"
field-offset = "*"
libloading = "*"
lazy_static = "*"
log = "*"
stderrlog = "*"
hprof = "*"
memmap = "*"
memsec = "0.1.9"
rustc-serialize = "*"
time = "0.1.34"
maplit = "0.1.4"
docopt = "0.6"
petgraph = "0.4.1"
serde = "*"
serde_derive = "*"
time = "*"
maplit = "*"
docopt = "*"
petgraph = "*"
extprim = "*"
num-traits = "*"
......@@ -22,7 +22,8 @@ crate-type = ["rlib"]
[dependencies]
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
lazy_static = "*"
log = "*"
simple_logger = "*"
#rodal = {path = "../../rodal"}
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal" }
......@@ -22,7 +22,7 @@ use utils::vec_utils;
use std::fmt;
/// Instruction represents a Mu instruction
#[derive(Debug)] // RustcEncodable, RustcDecodable, Clone and Display
#[derive(Debug)] // this implements Clone and Display
pub struct Instruction {
pub hdr: MuEntityHeader,
/// the values this instruction holds
......@@ -38,43 +38,6 @@ pub struct Instruction {
// Instruction implements MuEntity
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 {
......@@ -129,6 +92,16 @@ impl Instruction {
| CommonInst_SetThreadLocal(_)
| CommonInst_Pin(_)
| CommonInst_Unpin(_)
| CommonInst_Tr64IsFp(_)
| CommonInst_Tr64IsInt(_)
| CommonInst_Tr64IsRef(_)
| CommonInst_Tr64FromFp(_)
| CommonInst_Tr64FromInt(_)
| CommonInst_Tr64FromRef(_, _)
| CommonInst_Tr64ToFp(_)
| CommonInst_Tr64ToInt(_)
| CommonInst_Tr64ToRef(_)
| CommonInst_Tr64ToTag(_)
| Move(_)
| PrintHex(_)
| SetRetval(_) => false,
......@@ -203,6 +176,16 @@ impl Instruction {
CommonInst_SetThreadLocal(_) => true,
CommonInst_Pin(_) => true,
CommonInst_Unpin(_) => true,
CommonInst_Tr64IsFp(_)
| CommonInst_Tr64IsInt(_)
| CommonInst_Tr64IsRef(_) => false,
CommonInst_Tr64FromFp(_)
| CommonInst_Tr64FromInt(_)
| CommonInst_Tr64FromRef(_, _) => false,
CommonInst_Tr64ToFp(_)
| CommonInst_Tr64ToInt(_)
| CommonInst_Tr64ToRef(_)
| CommonInst_Tr64ToTag(_) => false,
Move(_) => false,
PrintHex(_) => true,
SetRetval(_) => true,
......@@ -258,6 +241,16 @@ impl Instruction {
| CommonInst_SetThreadLocal(_)
| CommonInst_Pin(_)
| CommonInst_Unpin(_)
| CommonInst_Tr64IsFp(_)
| CommonInst_Tr64IsInt(_)
| CommonInst_Tr64IsRef(_)
| CommonInst_Tr64FromFp(_)
| CommonInst_Tr64FromInt(_)
| CommonInst_Tr64FromRef(_, _)
| CommonInst_Tr64ToFp(_)
| CommonInst_Tr64ToInt(_)
| CommonInst_Tr64ToRef(_)
| CommonInst_Tr64ToTag(_)
| Move(_)
| PrintHex(_)
| SetRetval(_) => false
......@@ -318,6 +311,16 @@ impl Instruction {
| CommonInst_SetThreadLocal(_)
| CommonInst_Pin(_)
| CommonInst_Unpin(_)
| CommonInst_Tr64IsFp(_)
| CommonInst_Tr64IsInt(_)
| CommonInst_Tr64IsRef(_)
| CommonInst_Tr64FromFp(_)
| CommonInst_Tr64FromInt(_)
| CommonInst_Tr64FromRef(_, _)
| CommonInst_Tr64ToFp(_)
| CommonInst_Tr64ToInt(_)
| CommonInst_Tr64ToRef(_)
| CommonInst_Tr64ToTag(_)
| Move(_)
| PrintHex(_)
| SetRetval(_) => None
......@@ -342,7 +345,7 @@ impl fmt::Display for Instruction {
/// Instruction_ is used for pattern matching for Instruction
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, RustcEncodable, RustcDecodable)]
#[derive(Debug, Clone)]
pub enum Instruction_ {
// non-terminal instruction
......@@ -570,6 +573,27 @@ pub enum Instruction_ {
/// common inst: unpin an object (the object is automatically managed by GC)
CommonInst_Unpin(OpIndex),
/// common inst: is the tagref a floating point?
CommonInst_Tr64IsFp(OpIndex),
/// common inst: is the tagref an int?
CommonInst_Tr64IsInt(OpIndex),
/// common inst: is the tagref a ref?
CommonInst_Tr64IsRef(OpIndex),
/// common inst: creates a tagref from floating point (double)
CommonInst_Tr64FromFp(OpIndex),
/// common inst: creates a tagref from int<52>
CommonInst_Tr64FromInt(OpIndex),
/// common inst: creates a tagref from reference (a ref-void typed ref, 6 bits tag)
CommonInst_Tr64FromRef(OpIndex, OpIndex),
/// common inst: converts a tagref to floating point (double)
CommonInst_Tr64ToFp(OpIndex),
/// common inst: converts a tagref to integer (int<52>)
CommonInst_Tr64ToInt(OpIndex),
/// common inst: converts a tagref to reference
CommonInst_Tr64ToRef(OpIndex),
/// common inst: converts a tagref to a tag (int<64>)
CommonInst_Tr64ToTag(OpIndex),
/// internal use: move from value to value
Move(OpIndex),
/// internal use: print op as hex value
......@@ -699,6 +723,18 @@ impl Instruction_ {
&Instruction_::CommonInst_Pin(op) => format!("COMMONINST Pin {}", ops[op]),
&Instruction_::CommonInst_Unpin(op) => format!("COMMONINST Unpin {}", ops[op]),
// Tagerf64
&Instruction_::CommonInst_Tr64IsFp (op) => format!("COMMONINST Tr64IsFp {}", ops[op]),
&Instruction_::CommonInst_Tr64IsInt (op) => format!("COMMONINST Tr64IsInt {}", ops[op]),
&Instruction_::CommonInst_Tr64IsRef (op) => format!("COMMONINST Tr64IsRef {}", ops[op]),
&Instruction_::CommonInst_Tr64FromFp (op) => format!("COMMONINST Tr64FromFp {}", ops[op]),
&Instruction_::CommonInst_Tr64FromInt(op) => format!("COMMONINST Tr64FromInt {}", ops[op]),
&Instruction_::CommonInst_Tr64FromRef(op1, op2) => format!("COMMONINST Tr64FromRet {} {}", ops[op1], ops[op2]),
&Instruction_::CommonInst_Tr64ToFp (op) => format!("COMMONINST Tr64ToFp {}", ops[op]),
&Instruction_::CommonInst_Tr64ToInt(op) => format!("COMMONINST Tr64ToInt {}", ops[op]),
&Instruction_::CommonInst_Tr64ToRef(op) => format!("COMMONINST Tr64ToRef {}", ops[op]),
&Instruction_::CommonInst_Tr64ToTag(op) => format!("COMMONINST Tr64ToTag {}", ops[op]),
// move
&Instruction_::Move(from) => format!("MOVE {}", ops[from]),
// print hex
......@@ -710,7 +746,7 @@ impl Instruction_ {
}
/// BinOpStatus represents status flags from a binary operation
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone)]
pub struct BinOpStatus {
/// negative flag
pub flag_n: bool,
......@@ -762,7 +798,7 @@ impl fmt::Debug for BinOpStatus {
}
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug)]
pub enum MemoryOrder {
NotAtomic,
Relaxed,
......@@ -773,18 +809,18 @@ pub enum MemoryOrder {
SeqCst
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug)]
pub enum CallConvention {
Mu,
Foreign(ForeignFFI)
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug)]
pub enum ForeignFFI {
C
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug)]
pub struct CallData {
pub func: OpIndex,
pub args: Vec<OpIndex>,
......@@ -801,7 +837,7 @@ impl CallData {
}
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug)]
pub struct ResumptionData {
pub normal_dest: Destination,
pub exn_dest: Destination
......@@ -813,7 +849,7 @@ impl ResumptionData {
}
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug)]
pub struct Destination {
pub target: MuID,
pub args: Vec<DestArg>
......@@ -856,7 +892,7 @@ impl Destination {
}
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug)]
pub enum DestArg {
/// a normal destination argument is an SSA value (appears in the ops field of the instruction)
Normal(OpIndex),
......
This diff is collapsed.
......@@ -30,11 +30,11 @@
//!
//! Client should not create MuIR via this crate, use API instead.
extern crate log;
#[macro_use]
extern crate rodal;
extern crate simple_logger;
#[macro_use]
extern crate lazy_static;
extern crate rustc_serialize;
extern crate utils;
/// all data structures for MuIR is an *MuEntity*
......
......@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum BinOp {
// BinOp Int(n) Int(n) -> Int(n)
Add,
......@@ -39,7 +39,7 @@ pub enum BinOp {
FRem
}
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum CmpOp {
// for Int comparison
EQ,
......@@ -192,7 +192,7 @@ impl CmpOp {
}
}
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum ConvOp {
TRUNC,
ZEXT,
......@@ -208,7 +208,7 @@ pub enum ConvOp {
PTRCAST
}
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum AtomicRMWOp {
XCHG,
ADD,
......
......@@ -12,16 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::sync::Arc;
/// P<T> is alias type for sharable Mu AST components (such as Value, MuFuncSig, MuType, etc)
......
......@@ -18,8 +18,10 @@ use ir::*;
use utils::POINTER_SIZE;
use utils::vec_utils;
use std;
use rodal;
use std::fmt;
use utils::LinkedHashMap;
use std::collections::HashMap;
use std::sync::RwLock;
// some common types that the compiler may use internally
......@@ -98,12 +100,14 @@ pub fn init_types() {
}
/// MuType represents a Mu type
#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
#[derive(PartialEq, Debug)]
pub struct MuType {
pub hdr: MuEntityHeader,
pub v: MuType_
}
rodal_struct!(MuType{hdr, v});
impl MuType {
/// creates a new Mu type
pub fn new(id: MuID, v: MuType_) -> MuType {
......@@ -376,7 +380,7 @@ pub type StructTag = MuName;
pub type HybridTag = MuName;
/// MuType_ is used for pattern matching for MuType
#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
#[derive(PartialEq, Debug)]
pub enum MuType_ {
/// int <length>
Int (usize),
......@@ -425,6 +429,10 @@ pub enum MuType_ {
UFuncPtr (P<MuFuncSig>),
}
rodal_enum!(MuType_{(Int: size), Float, Double, (Ref: ty), (IRef: ty), (WeakRef: ty), (UPtr: ty),
(Struct: tag), (Array: ty, size), (Hybrid: tag), Void, ThreadRef, StackRef, Tagref64,
(Vector: ty, size), (FuncRef: ty), (UFuncPtr: ty)});
impl fmt::Display for MuType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.v)
......@@ -457,12 +465,15 @@ impl fmt::Display for MuType_ {
lazy_static! {
/// storing a map from MuName to StructType_
pub static ref STRUCT_TAG_MAP : RwLock<LinkedHashMap<StructTag, StructType_>> = RwLock::new(LinkedHashMap::new());
pub static ref STRUCT_TAG_MAP : RwLock<HashMap<StructTag, StructType_>> =
rodal::try_load_asm_name_move("STRUCT_TAG_MAP").unwrap_or(RwLock::new(HashMap::new()));
/// storing a map from MuName to HybridType_
pub static ref HYBRID_TAG_MAP : RwLock<LinkedHashMap<HybridTag, HybridType_>> = RwLock::new(LinkedHashMap::new());
pub static ref HYBRID_TAG_MAP : RwLock<HashMap<HybridTag, HybridType_>> =
rodal::try_load_asm_name_move("HYBRID_TAG_MAP").unwrap_or(RwLock::new(HashMap::new()));
}
#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
rodal_struct!(StructType_{tys});
#[derive(PartialEq, Debug)]
pub struct StructType_ {
tys: Vec<P<MuType>>
}
......@@ -496,7 +507,8 @@ impl StructType_ {
}
}
#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
rodal_struct!(HybridType_{fix_tys, var_ty});
#[derive(PartialEq, Debug)]
pub struct HybridType_ {
fix_tys: Vec<P<MuType>>,
var_ty : P<MuType>
......@@ -673,13 +685,15 @@ impl MuType_ {
}
/// MuFuncSig represents a Mu function signature
#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
#[derive(PartialEq, Debug)]
pub struct MuFuncSig {
pub hdr: MuEntityHeader,
pub ret_tys : Vec<P<MuType>>,
pub arg_tys: Vec<P<MuType>>
}
rodal_struct!(MuFuncSig{hdr, ret_tys, arg_tys});
impl fmt::Display for MuFuncSig {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "[{}] -> [{}]", vec_utils::as_str(&self.arg_tys), vec_utils::as_str(&self.ret_tys))
......
......@@ -30,11 +30,13 @@ use utils::LinkedHashMap;
use ast::ptr::P;
use ast::ir::*;
use ast::types;
use std::str;
use std::usize;
use std::ops;
use std::collections::HashSet;
use std::sync::RwLock;
struct ASMCode {
name: MuName,
......@@ -2732,10 +2734,10 @@ fn write_const_value(f: &mut File, constant: P<Value>) {
&Constant::Int(val) => {
let len = ty.get_int_length().unwrap();
match len {
8 => f.write_fmt(format_args!(".byte {}\n", val as u8 )).unwrap(),
16 => f.write_fmt(format_args!(".word {}\n", val as u16)).unwrap(),
32 => f.write_fmt(format_args!(".long {}\n", val as u32)).unwrap(),
64 => f.write_fmt(format_args!(".quad {}\n", val as u64)).unwrap(),
1 ... 8 => f.write_fmt(format_args!(".byte {}\n", get_unsigned_value(val, len) as u8 )).unwrap(),
9 ... 16 => f.write_fmt(format_args!(".word {}\n", get_unsigned_value(val, len) as u16)).unwrap(),
17 ... 32 => f.write_fmt(format_args!(".long {}\n", get_unsigned_value(val, len) as u32)).unwrap(),
33 ... 64 => f.write_fmt(format_args!(".xword {}\n", get_unsigned_value(val, len) as u64)).unwrap(),
_ => panic!("unimplemented int length: {}", len)
}
}
......@@ -2747,15 +2749,15 @@ fn write_const_value(f: &mut File, constant: P<Value>) {
}
&Constant::Double(val) => {
let bytes: [u8; 8] = unsafe {mem::transmute(val)};
f.write(".quad ".as_bytes()).unwrap();
f.write(".xword ".as_bytes()).unwrap();
f.write(&bytes).unwrap();
f.write("\n".as_bytes()).unwrap();
}
&Constant::NullRef => {
f.write_fmt(format_args!(".quad 0\n")).unwrap()
f.write_fmt(format_args!(".xword 0\n")).unwrap()
}
&Constant::ExternSym(ref name) => {
f.write_fmt(format_args!(".quad {}\n", name)).unwrap()
f.write_fmt(format_args!(".xword {}\n", name)).unwrap()
}
&Constant::List(ref vals) => {
for val in vals {
......@@ -2773,7 +2775,6 @@ pub fn emit_context_with_reloc(vm: &VM,
fields : HashMap<Address, String>) {
use std::path;
use std::io::prelude::*;
use rustc_serialize::json;
debug!("---Emit VM Context---");
create_emit_directory(vm);
......@@ -2787,9 +2788,6 @@ pub fn emit_context_with_reloc(vm: &VM,
Ok(file) => file
};
// bss
file.write_fmt(format_args!(".bss\n")).unwrap();
// data
file.write(".data\n".as_bytes()).unwrap();
......@@ -2860,20 +2858,20 @@ 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(".quad 0\n".as_bytes()).unwrap();
file.write(".xword 0\n".as_bytes()).unwrap();
} else {
let label = match relocatable_refs.get(&load_ref) {
Some(label) => label,
None => panic!("cannot find label for address {}, it is not dumped by GC (why GC didn't trace to it)", load_ref)
};
file.write_fmt(format_args!(".quad {}\n", label.clone())).unwrap();
file.write_fmt(format_args!(".xword {}\n", label.clone())).unwrap();
}
} else if fields.contains_key(&cur_addr) {
// write uptr (or other relocatable value) with label
let label = fields.get(&cur_addr).unwrap();
file.write_fmt(format_args!(".quad {}\n", label.clone())).unwrap();
file.write_fmt(format_args!(".xword {}\n", label.clone())).unwrap();
} else {
// write plain word (as bytes)
let next_word_addr = cur_addr.plus(POINTER_SIZE);
......@@ -2892,15 +2890,21 @@ pub fn emit_context_with_reloc(vm: &VM,
// serialize vm
trace!("start serializing vm");
{
let serialize_vm = json::encode(&vm).unwrap();
use rodal;
let mut dumper = rodal::AsmDumper::new(file);
let vm_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();
}
// Dump an Arc to the vm
let vm_arc = rodal::FakeArc::new(vm);
dumper.dump("vm", &vm_arc);
use std::ops::Deref;
let struct_tag_map: &RwLock<HashMap<types::StructTag, types::StructType_>> = types::STRUCT_TAG_MAP.deref();
dumper.dump("STRUCT_TAG_MAP", struct_tag_map);
let hybrid_tag_map: &RwLock<HashMap<types::HybridTag, types::HybridType_>> = types::HYBRID_TAG_MAP.deref();
dumper.dump("HYBRID_TAG_MAP", hybrid_tag_map);
dumper.finish(); // Dump everything the previously dumped objects referenced
// main_thread
// let primordial = vm.primordial.read().unwrap();
......
This diff is collapsed.
......@@ -33,12 +33,14 @@ use utils::LinkedHashMap;
use ast::ptr::P;
use ast::ir::*;
use ast::types;
use std::str;
use std::usize;
use std::slice::Iter;
use std::ops;
use std::collections::HashSet;
use std::sync::RwLock;
use std::any::Any;
/// ASMCode represents a segment of assembly machine code. Usually it is machine code for
......@@ -3570,7 +3572,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);
......@@ -3700,15 +3701,21 @@ pub fn emit_context_with_reloc(vm: &VM,
// currently using rustc_serialize to persist vm as json string.
// Deserializing from this is extremely slow, we need to fix this. See Issue #41
trace!("start serializing vm");
{
let serialize_vm = json::encode(&vm).unwrap();
use rodal;
let mut dumper = rodal::AsmDumper::new(file);
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();
}
// Dump an Arc to the vm
let vm_arc = rodal::FakeArc::new(vm);
dumper.dump("vm", &vm_arc);
use std::ops::Deref;
let struct_tag_map: &RwLock<HashMap<types::StructTag, types::StructType_>> = types::STRUCT_TAG_MAP.deref();
dumper.dump("STRUCT_TAG_MAP", struct_tag_map);
let hybrid_tag_map: &RwLock<HashMap<types::HybridTag, types::HybridType_>> = types::HYBRID_TAG_MAP.deref();
dumper.dump("HYBRID_TAG_MAP", hybrid_tag_map);
dumper.finish();
debug!("---finish---");
}
......@@ -3731,7 +3738,7 @@ fn write_data_bytes(f: &mut File, from: Address, to: Address) {
let byte = unsafe {cursor.load::<u8>()};
f.write_fmt(format_args!("0x{:x}", byte)).unwrap();
cursor = cursor + 1 as ByteSize;
cursor += 1 as ByteSize;
if cursor != to {
f.write(",".as_bytes()).unwrap();
}
......
......@@ -639,6 +639,7 @@ pub fn estimate_insts_for_ir(inst: &Instruction) -> usize {
Move(_) => 0,
PrintHex(_) => 10,
SetRetval(_) => 10,
ExnInstruction{ref inner, ..} => estimate_insts_for_ir(&inner)
ExnInstruction{ref inner, ..} => estimate_insts_for_ir(&inner),
_ => unimplemented!(),
}
}
......@@ -21,6 +21,7 @@ pub mod peephole_opt;
/// Code emission pass. May as well emit dot graph for IR and generated code.
pub mod code_emission;
use std;
use utils::ByteSize;
use utils::math::align_up;
use runtime::mm;
......@@ -197,7 +198,7 @@ use ast::ir::*;
/// native without extra steps (though they need to be pinned first)
///
// GCType is a temporary design, we will rewrite GC (Issue#12)
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug)]
pub struct BackendType {
pub size: ByteSize,
pub alignment: ByteSize,