Commit 19ddbf50 authored by qinsoon's avatar qinsoon

[wip] cannot link (cannot find global symbol)

parent 339bb523
......@@ -2722,7 +2722,7 @@ pub fn emit_context(vm: &VM) {
// file.write_fmt(format_args!("\t{}\n", directive_globl(symbol(global.name().unwrap())))).unwrap();
// file.write_fmt(format_args!("\t{}\n", directive_comm(symbol(global.name().unwrap()), size, align))).unwrap();
// file.write("\n".as_bytes()).unwrap();
}
// }
}
// data
......@@ -2734,44 +2734,46 @@ pub fn emit_context(vm: &VM) {
// presist globals
let global_locs_lock = vm.global_locations.read().unwrap();
let global_lock = vm.globals.read().unwrap();
let global_lock = vm.globals().read().unwrap();
// dump heap from globals
let global_addrs : Vec<Address> = global_locs_lock.values().map(|x| x.to_address()).collect();
debug!("going to dump these globals: {:?}", global_addrs);
let global_dump = mm::persist_heap(global_addrs);
debug!("Heap Dump from GC: {:?}", global_dump);
for id in global_locs_lock.keys() {
let global_value = global_lock.get(id).unwrap();
let global_addr = global_locs_lock.get(id).unwrap();
let global_addr = global_locs_lock.get(id).unwrap().to_address();
let obj_dump = global_dump.objects.get(&global_addr).unwrap();
// .bytes xx,xx,xx,xx (between mem_start to reference_addr)
write_data_bytes(file, obj_dump.mem_start, obj_dump.reference_addr);
write_data_bytes(&mut file, obj_dump.mem_start, obj_dump.reference_addr);
// .globl global_cell_name
// .globl dump_label
file.write_fmt(format_args!("\t{}\n", directive_globl(symbol(global_value.name().unwrap())))).unwrap();
file.write_fmt(format_args!("\t.quad {}\n", directive_globl(symbol(global_dump.relocatable_refs.get(&obj_dump.reference_start).unwrap())))).unwrap();
file.write_fmt(format_args!("\t{}\n", directive_globl(symbol(global_dump.relocatable_refs.get(&obj_dump.reference_addr).unwrap().clone())))).unwrap();
let base = obj_dump.reference_start;
let mut cursor = obj_dump.reference_start;
for ref_offset in obj_dump.reference_offsets {
let cur_ref_addr = base.plus(ref_offset);
let base = obj_dump.reference_addr;
let mut cursor = obj_dump.reference_addr;
for ref_offset in obj_dump.reference_offsets.iter() {
let cur_ref_addr = base.plus(*ref_offset);
if cursor < cur_ref_addr {
// write all non-ref data
write_data_bytes(file, cursor, cur_ref_addr);
write_data_bytes(&mut file, cursor, cur_ref_addr);
}
// write ref with label
file.write_fmt(format_args!("\t.quad {}\n", directive_globl(symbol(global_dump.relocatable_refs.get(&cur_ref_addr).unwrap())))).unwrap();
file.write_fmt(format_args!("\t.quad {}\n", symbol(global_dump.relocatable_refs.get(&cur_ref_addr).unwrap().clone()))).unwrap();
cursor = cur_ref_addr.plus(POINTER_SIZE);
}
// write whatever is after the last ref
write_data_bytes(file, cursor, obj_dump.mem_start.plus(obj_dump.mem_size));
write_data_bytes(&mut file, cursor, obj_dump.mem_start.plus(obj_dump.mem_size));
}
}
......@@ -2796,12 +2798,25 @@ pub fn emit_context(vm: &VM) {
debug!("---finish---");
}
fn write_data_bytes(f: &mut File, from: Address, to: Address) -> String {
fn write_data_bytes(f: &mut File, from: Address, to: Address) {
use std::io::Write;
if from < to {
f.write("\t.byte ".as_bytes()).unwrap();
let mut cursor = from;
unimplemented!()
} else {
String::from("")
while cursor < to {
let byte = unsafe {cursor.load::<u8>()};
f.write_fmt(format_args!("0x{:x}", byte)).unwrap();
cursor = cursor.plus(1);
if cursor != to {
f.write(",".as_bytes()).unwrap();
}
}
f.write("\n".as_bytes()).unwrap();
}
}
......
......@@ -173,5 +173,14 @@ mod tests {
assert_eq!(vec[0].gen_ref_offsets(), vec![0]);
assert_eq!(vec[1].gen_ref_offsets(), vec![0, 16, 32, 48, 64, 80, 96, 112, 128, 144]);
assert_eq!(vec[2].gen_ref_offsets(), (0..100).map(|x| x * 16).collect::<Vec<ByteSize>>());
let int = GCType {
id: 3,
size: 8,
non_repeat_refs: None,
repeat_refs: None
};
assert_eq!(int.gen_ref_offsets(), vec![]);
}
}
......@@ -24,6 +24,7 @@ pub struct ObjectDump {
impl HeapDump {
pub fn from_roots(roots: Vec<Address>) -> HeapDump {
trace!("dump heap from {:?}", roots);
let mut work_queue : Vec<Address> = roots;
let mut heap : HeapDump = HeapDump {
objects: HashMap::new(),
......@@ -48,6 +49,7 @@ impl HeapDump {
}
fn persist_object(&self, obj: Address) -> ObjectDump {
trace!("dump object: {}", obj);
let hdr_addr = obj.offset(objectmodel::OBJECT_HEADER_OFFSET);
let hdr = unsafe {hdr_addr.load::<u64>()};
......@@ -57,6 +59,8 @@ impl HeapDump {
// has ref map
let ref_map = objectmodel::header_get_ref_map(hdr);
trace!("fix sized, ref map as {:b}", ref_map);
let mut offsets = vec![];
let mut i = 0;
while i < objectmodel::REF_MAP_LENGTH {
......@@ -79,13 +83,15 @@ impl HeapDump {
// by type ID
let gctype_id = objectmodel::header_get_gctype_id(hdr);
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();
ObjectDump {
reference_addr: obj,
mem_start : hdr_addr,
mem_size : gctype.size,
mem_size : gctype.size + objectmodel::OBJECT_HEADER_SIZE,
reference_offsets: gctype.gen_ref_offsets()
}
}
......@@ -93,13 +99,15 @@ impl HeapDump {
// hybrids - same as above
let gctype_id = objectmodel::header_get_gctype_id(hdr);
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();
ObjectDump {
reference_addr: obj,
mem_start : hdr_addr,
mem_size : gctype.size,
mem_size : gctype.size + objectmodel::OBJECT_HEADER_SIZE,
reference_offsets: gctype.gen_ref_offsets()
}
}
......
......@@ -11,21 +11,35 @@ use vm::VM;
use runtime::ValueLocation;
use runtime::thread::MuThread;
fn allocate(size: ByteSize, align: ByteSize) -> ObjectReference {
fn allocate(size: ByteSize, align: ByteSize, encode: u64) -> ObjectReference {
let allocator = (&mut MuThread::current_mut().allocator) as *mut Mutator;
if size > LARGE_OBJECT_THRESHOLD {
let ret = if size > LARGE_OBJECT_THRESHOLD {
muentry_alloc_large(allocator, size, align)
} else {
alloc(allocator, size, align)
}
};
muentry_init_object(allocator, ret, encode);
ret
}
pub fn allocate_value(value: P<Value>, vm: &VM) -> ValueLocation {
pub fn allocate_global(value: P<Value>, vm: &VM) -> ValueLocation {
let tyid = value.ty.id();
let backend_ty = vm.get_backend_type_info(tyid);
let addr = allocate(backend_ty.size, backend_ty.alignment).to_address();
let referenced_type = match value.ty.get_referenced_ty() {
Some(ty) => ty,
None => panic!("expected global to be an iref type, found {}", value.ty)
};
let backendtype = vm.get_backend_type_info(referenced_type.id());
let gctype = backendtype.gc_type.clone();
let gctype_id = gctype.id;
let encode = get_gc_type_encode(gctype_id);
trace!("allocating global as gctype {:?}", gctype);
let addr = allocate(backendtype.size, backendtype.alignment, encode).to_address();
ValueLocation::Direct(RegGroup::GPR, addr)
}
......@@ -588,11 +588,13 @@ impl <'a> VM {
});
let mut globals = self.globals.write().unwrap();
trace!("declare global #{} = {}", id, global);
globals.insert(id, global.clone());
// allocate global
let loc = gc::allocate_value(global.clone(), self);
let loc = gc::allocate_global(global.clone(), self);
let mut global_locs = self.global_locations.write().unwrap();
trace!("allocate global #{} as {}", id, loc);
global_locs.insert(id, loc);
global
......
......@@ -71,6 +71,7 @@ fn test_set_global_by_api() {
let uint64_1_handle = vm.handle_from_uint64(1, 64);
debug!("write {:?} to location {:?}", uint64_1_handle, global_handle);
handle::store(MemoryOrder::Relaxed, global_handle, uint64_1_handle);
}
......
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