WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

Commit b0467947 authored by qinsoon's avatar qinsoon
Browse files

BackendTypeInfo includes GCType, generating GCType during resolving type

info
parent 3ed935e1
......@@ -394,6 +394,26 @@ pub fn is_ptr(ty: &MuType) -> bool {
}
}
/// this a type reference type (located in heap)?
pub fn is_reference(ty: &MuType) -> bool {
match ty.v {
MuType_::Ref(_)
| MuType_::IRef(_)
| MuType_::WeakRef(_) => true,
_ => false
}
}
/// this is a aggregated type (consited of other types)
pub fn is_aggregate(ty: &MuType) -> bool {
match ty.v {
MuType_::Struct(_)
| MuType_::Hybrid(_)
| MuType_::Array(_, _) => true,
_ => false
}
}
/// is a type scalar type?
pub fn is_scalar(ty: &MuType) -> bool {
match ty.v {
......
......@@ -3,7 +3,10 @@ pub mod reg_alloc;
pub mod peephole_opt;
pub mod code_emission;
use ast::types;
use utils::ByteSize;
use runtime::mm;
use runtime::mm::common::gctype::{GCType, GCTYPE_INIT_ID, RefPattern, RepeatingRefPattern};
pub type Word = usize;
pub const WORD_SIZE : ByteSize = 8;
......@@ -64,35 +67,77 @@ use ast::ptr::*;
use ast::ir::*;
pub fn resolve_backend_type_info (ty: &MuType, vm: &VM) -> BackendTypeInfo {
match ty.v {
// integral
// integer
MuType_::Int(size_in_bit) => {
match size_in_bit {
1 => BackendTypeInfo{size: 1, alignment: 1, struct_layout: None},
8 => BackendTypeInfo{size: 1, alignment: 1, struct_layout: None},
16 => BackendTypeInfo{size: 2, alignment: 2, struct_layout: None},
32 => BackendTypeInfo{size: 4, alignment: 4, struct_layout: None},
64 => BackendTypeInfo{size: 8, alignment: 8, struct_layout: None},
1 => BackendTypeInfo{
size: 1, alignment: 1, struct_layout: None,
gc_type: mm::add_gc_type(GCType::new_noreftype(1))
},
8 => BackendTypeInfo{
size: 1, alignment: 1, struct_layout: None,
gc_type: mm::add_gc_type(GCType::new_noreftype(1))
},
16 => BackendTypeInfo{
size: 2, alignment: 2, struct_layout: None,
gc_type: mm::add_gc_type(GCType::new_noreftype(2))
},
32 => BackendTypeInfo{
size: 4, alignment: 4, struct_layout: None,
gc_type: mm::add_gc_type(GCType::new_noreftype(4))
},
64 => BackendTypeInfo{
size: 8, alignment: 8, struct_layout: None,
gc_type: mm::add_gc_type(GCType::new_noreftype(8))
},
_ => unimplemented!()
}
},
// pointer of any type
// reference of any type
MuType_::Ref(_)
| MuType_::IRef(_)
| MuType_::WeakRef(_)
| MuType_::UPtr(_)
| MuType_::FuncRef(_)
| MuType_::WeakRef(_) => BackendTypeInfo{
size: 8, alignment: 8, struct_layout: None,
gc_type: mm::add_gc_type(GCType::new_reftype())
},
// pointer
MuType_::UPtr(_)
| MuType_::UFuncPtr(_)
| MuType_::Tagref64
| MuType_::FuncRef(_)
| MuType_::ThreadRef
| MuType_::StackRef => BackendTypeInfo{size: 8, alignment: 8, struct_layout: None},
| MuType_::StackRef => BackendTypeInfo{
size: 8, alignment: 8, struct_layout: None,
gc_type: mm::add_gc_type(GCType::new_noreftype(8))
},
// tagref
MuType_::Tagref64 => unimplemented!(),
// floating point
MuType_::Float => BackendTypeInfo{size: 4, alignment: 4, struct_layout: None},
MuType_::Double => BackendTypeInfo{size: 8, alignment: 8, struct_layout: None},
MuType_::Float => BackendTypeInfo{
size: 4, alignment: 4, struct_layout: None,
gc_type: mm::add_gc_type(GCType::new_noreftype(4))
},
MuType_::Double => BackendTypeInfo {
size: 8, alignment: 8, struct_layout: None,
gc_type: mm::add_gc_type(GCType::new_noreftype(8))
},
// array
MuType_::Array(ref ty, len) => {
let ele_ty = vm.get_backend_type_info(ty.id());
BackendTypeInfo{size: ele_ty.size * len, alignment: ele_ty.alignment, struct_layout: None}
BackendTypeInfo{
size : ele_ty.size * len,
alignment : ele_ty.alignment,
struct_layout: None,
gc_type : mm::add_gc_type(GCType {
id : GCTYPE_INIT_ID,
size : ele_ty.size * len,
non_repeat_refs: None,
repeat_refs : Some(RepeatingRefPattern{
pattern: RefPattern::NestedType(vec![ele_ty.gc_type]),
count : len
})
})
}
}
// struct
MuType_::Struct(ref name) => {
......@@ -118,16 +163,29 @@ pub fn resolve_backend_type_info (ty: &MuType, vm: &VM) -> BackendTypeInfo {
let mut ret = layout_struct(fix_tys, vm);
// treat var_ty as array (getting its alignment)
let var_align = vm.get_backend_type_info(var_ty.id()).alignment;
let var_ele_ty = vm.get_backend_type_info(var_ty.id());
let var_align = var_ele_ty.alignment;
// fix type info as hybrid
// 1. check alignment
if ret.alignment < var_align {
ret.alignment = var_align;
}
// 2. fix gc type
let mut gctype = ret.gc_type.as_ref().clone();
gctype.repeat_refs = Some(RepeatingRefPattern {
pattern: RefPattern::NestedType(vec![var_ele_ty.gc_type.clone()]),
count : 0
});
ret.gc_type = mm::add_gc_type(gctype);
ret
}
// void
MuType_::Void => BackendTypeInfo{size: 0, alignment: 8, struct_layout: None},
MuType_::Void => BackendTypeInfo{
size: 0, alignment: 8, struct_layout: None,
gc_type: mm::add_gc_type(GCType::new_noreftype(0))
},
// vector
MuType_::Vector(_, _) => unimplemented!()
}
......@@ -137,6 +195,11 @@ fn layout_struct(tys: &Vec<P<MuType>>, vm: &VM) -> BackendTypeInfo {
let mut offsets : Vec<ByteSize> = vec![];
let mut cur : ByteSize = 0;
let mut struct_align : ByteSize = 1;
// for gc type
let mut use_ref_offsets = true;
let mut ref_offsets = vec![];
let mut gc_types = vec![];
for ty in tys.iter() {
let ty_info = vm.get_backend_type_info(ty.id());
......@@ -154,19 +217,48 @@ fn layout_struct(tys: &Vec<P<MuType>>, vm: &VM) -> BackendTypeInfo {
offsets.push(cur);
trace!("aligned to {}", cur);
// for convenience, if the struct contains other struct/array
// we do not use reference map
if types::is_aggregate(ty) {
use_ref_offsets = false;
}
// if this type is reference type, we store its offsets
// we may not use this ref map though
if types::is_reference(ty) {
ref_offsets.push(cur);
}
// always store its gc type (we may not use it as well)
gc_types.push(ty_info.gc_type.clone());
cur += ty_info.size;
}
// if we need padding at the end
if cur % struct_align != 0 {
cur = (cur / struct_align + 1) * struct_align;
}
let size = if cur % struct_align != 0 {
(cur / struct_align + 1) * struct_align
} else {
cur
};
BackendTypeInfo {
size: cur,
alignment: struct_align,
struct_layout: Some(offsets)
size : size,
alignment : struct_align,
struct_layout: Some(offsets),
gc_type : mm::add_gc_type(GCType {
id : GCTYPE_INIT_ID,
size : size,
non_repeat_refs: Some(if use_ref_offsets {
RefPattern::Map {
offsets: ref_offsets,
size: size
}
} else {
RefPattern::NestedType(gc_types)
}),
repeat_refs : None
})
}
}
......@@ -180,7 +272,9 @@ pub fn sequetial_layout(tys: &Vec<P<MuType>>, vm: &VM) -> (ByteSize, ByteSize, V
pub struct BackendTypeInfo {
pub size: ByteSize,
pub alignment: ByteSize,
pub struct_layout: Option<Vec<ByteSize>>
pub struct_layout: Option<Vec<ByteSize>>,
pub gc_type: P<GCType>
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
......
......@@ -19,4 +19,5 @@ log = "0.3.5"
simple_logger = "0.4.0"
aligned_alloc = "0.1.2"
crossbeam = "0.2.8"
doubly = "1.1.1"
\ No newline at end of file
doubly = "1.1.1"
rustc-serialize = "*"
\ No newline at end of file
#![allow(dead_code)]
use std::sync::Arc;
use utils::POINTER_SIZE;
use utils::ByteSize;
#[derive(Clone, Debug)]
use std::usize;
pub const GCTYPE_INIT_ID: usize = usize::MAX;
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct GCType {
pub id: usize,
pub size: ByteSize,
......@@ -11,6 +16,27 @@ pub struct GCType {
}
impl GCType {
pub fn new_noreftype(size: ByteSize) -> GCType {
GCType {
id: GCTYPE_INIT_ID,
size: size,
non_repeat_refs: None,
repeat_refs : None
}
}
pub fn new_reftype() -> GCType {
GCType {
id: GCTYPE_INIT_ID,
size: POINTER_SIZE,
non_repeat_refs: Some(RefPattern::Map{
offsets: vec![0],
size: POINTER_SIZE
}),
repeat_refs: None
}
}
#[allow(unused_assignments)]
pub fn gen_ref_offsets(&self) -> Vec<ByteSize> {
let mut ret = vec![];
......@@ -34,13 +60,13 @@ impl GCType {
}
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub enum RefPattern {
Map{
offsets: Vec<ByteSize>,
size : usize
},
NestedType(Vec<GCType>)
NestedType(Vec<Arc<GCType>>)
}
impl RefPattern {
......@@ -71,7 +97,7 @@ impl RefPattern {
}
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct RepeatingRefPattern {
pub pattern: RefPattern,
pub count: usize
......@@ -92,6 +118,7 @@ impl RepeatingRefPattern {
#[cfg(test)]
mod tests {
use super::*;
use std::sync::Arc;
use utils::ByteSize;
fn create_types() -> Vec<GCType> {
......@@ -126,7 +153,7 @@ mod tests {
size: 1600,
non_repeat_refs: None,
repeat_refs : Some(RepeatingRefPattern {
pattern: RefPattern::NestedType(vec![b.clone()]),
pattern: RefPattern::NestedType(vec![Arc::new(b.clone()).clone()]),
count : 10
})
};
......
......@@ -6,6 +6,7 @@ extern crate log;
extern crate simple_logger;
extern crate aligned_alloc;
extern crate crossbeam;
extern crate rustc_serialize;
use std::sync::atomic::Ordering;
......@@ -36,7 +37,7 @@ pub struct GC {
immix_space: Arc<ImmixSpace>,
lo_space : Arc<FreeListSpace>,
gc_types : Vec<GCType>
gc_types : Vec<Arc<GCType>>
}
impl fmt::Debug for GC {
......@@ -66,16 +67,18 @@ pub extern fn get_spaces() -> (Arc<ImmixSpace>, Arc<FreeListSpace>) {
}
#[no_mangle]
pub extern fn add_gc_type(mut ty: GCType) -> usize {
pub extern fn add_gc_type(mut ty: GCType) -> Arc<GCType> {
let mut gc_guard = MY_GC.write().unwrap();
let mut gc = gc_guard.as_mut().unwrap();
let index = gc.gc_types.len();
ty.id = index;
gc.gc_types.push(ty);
let ty = Arc::new(ty);
index
gc.gc_types.push(ty.clone());
ty
}
#[no_mangle]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment