Skip to content

Commit

Permalink
Cleanup; fixed bug when checking if array is union type
Browse files Browse the repository at this point in the history
  • Loading branch information
udesou committed Jul 26, 2023
1 parent 541289d commit ce8d819
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 101 deletions.
17 changes: 6 additions & 11 deletions mmtk/src/julia_scanning.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::edges::JuliaVMEdge;
use crate::edges::OffsetEdge;
use crate::julia_types::*;
use crate::object_model::mmtk_jl_array_ndims;
use crate::JULIA_BUFF_TAG;
use crate::UPCALLS;
use mmtk::util::Address;
Expand Down Expand Up @@ -94,7 +95,7 @@ pub unsafe fn scan_julia_object<EV: EdgeVisitor<JuliaVMEdge>>(obj: Address, clos
// should be processed below if it contains pointers
} else if flags.how_custom() == 3 {
// has a pointer to the object that owns the data
let owner_addr = mmtk_jl_array_data_owner_addr(obj);
let owner_addr = mmtk_jl_array_data_owner_addr(array);
process_edge(closure, owner_addr);
return;
}
Expand Down Expand Up @@ -467,7 +468,7 @@ pub fn process_offset_edge<EV: EdgeVisitor<JuliaVMEdge>>(
}

#[inline(always)]
pub fn mmtk_jl_array_ndimwords(ndims: u16) -> usize {
pub fn mmtk_jl_array_ndimwords(ndims: u32) -> usize {
if ndims < 3 {
return 0;
}
Expand All @@ -491,18 +492,12 @@ pub unsafe fn mmtk_jl_array_len(a: *const mmtk_jl_array_t) -> usize {
}

#[inline(always)]
pub unsafe fn mmtk_jl_array_data_owner_addr(array: Address) -> Address {
array + mmtk_jl_array_data_owner_offset(mmtk_jl_array_ndims(array))
pub unsafe fn mmtk_jl_array_data_owner_addr(array: *const mmtk_jl_array_t) -> Address {
Address::from_ptr(array) + mmtk_jl_array_data_owner_offset(mmtk_jl_array_ndims(array))
}

#[inline(always)]
pub unsafe fn mmtk_jl_array_ndims(array: Address) -> u16 {
let a = array.to_ptr::<mmtk_jl_array_t>();
(*a).flags.ndims_custom()
}

#[inline(always)]
pub unsafe fn mmtk_jl_array_data_owner_offset(ndims: u16) -> usize {
pub unsafe fn mmtk_jl_array_data_owner_offset(ndims: u32) -> usize {
// (offsetof(jl_array_t,ncols)
#[allow(deref_nullptr)]
let offset_ncols =
Expand Down
188 changes: 98 additions & 90 deletions mmtk/src/object_model.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::api::{mmtk_get_obj_size, mmtk_object_is_managed_by_mmtk};
use crate::julia_scanning::{
jl_array_typename, jl_method_type, jl_module_type, jl_simplevector_type, jl_string_type,
jl_task_type, mmtk_jl_array_ndimwords, mmtk_jl_typeof,
jl_task_type, mmtk_jl_array_len, mmtk_jl_array_ndimwords, mmtk_jl_tparam0, mmtk_jl_typeof,
mmtk_jl_typetagof,
};
use crate::julia_types::*;
use crate::{JuliaVM, JULIA_BUFF_TAG, JULIA_HEADER_SIZE};
Expand Down Expand Up @@ -110,6 +111,7 @@ impl ObjectModel<JuliaVM> for VMObjectModel {
}
}

#[inline(always)]
pub fn is_object_in_los(object: &ObjectReference) -> bool {
// FIXME: get the range from MMTk. Or at least assert at boot time to make sure those constants are correct.
(*object).to_raw_address().as_usize() >= 0x600_0000_0000
Expand Down Expand Up @@ -152,12 +154,80 @@ const SZCLASS_TABLE: [u8; 128] = [
48, 48, 48, 48, 48, 48, 48,
];

#[inline(always)]
pub unsafe fn get_so_object_size(object: ObjectReference) -> usize {
let obj_address = object.to_raw_address();
let obj_type = mmtk_jl_typeof(obj_address);

if obj_type as usize == JULIA_BUFF_TAG {
return mmtk_get_obj_size(object);
mmtk_get_obj_size(object)
} else if (*obj_type).name == jl_array_typename {
let a = obj_address.to_ptr::<mmtk_jl_array_t>();
let osize = match (*a).flags.how_custom() {
0 => {
let a_ndims_words = mmtk_jl_array_ndimwords(mmtk_jl_array_ndims(a));
let mut dtsz = std::mem::size_of::<mmtk_jl_array_t>()
+ a_ndims_words * std::mem::size_of::<usize>();
let data = (*a).data;
let data_addr = Address::from_mut_ptr(data);

if mmtk_object_is_managed_by_mmtk(data_addr.as_usize()) {
let pre_data_bytes = (data_addr.as_usize()
- (*a).offset as usize * (*a).elsize as usize)
- a as usize;

if pre_data_bytes > 0 {
// a->data is allocated after a
dtsz = pre_data_bytes;
dtsz += mmtk_jl_array_nbytes(a);
}
if dtsz + JULIA_HEADER_SIZE > 2032 {
// if it's too large to be inlined (a->data and a are disjoint objects)
dtsz = std::mem::size_of::<mmtk_jl_array_t>()
+ a_ndims_words * std::mem::size_of::<usize>();
}
}
debug_assert!(
dtsz + JULIA_HEADER_SIZE <= 2032,
"size {} greater than minimum!",
dtsz + JULIA_HEADER_SIZE
);

let pool_id = mmtk_jl_gc_szclass(dtsz + JULIA_HEADER_SIZE);
JL_GC_SIZECLASSES[pool_id]
}
1 | 2 => {
let a_ndims_words = mmtk_jl_array_ndimwords(mmtk_jl_array_ndims(a));
let dtsz = std::mem::size_of::<mmtk_jl_array_t>()
+ a_ndims_words * std::mem::size_of::<usize>();

debug_assert!(
dtsz + JULIA_HEADER_SIZE <= 2032,
"size {} greater than minimum!",
dtsz + JULIA_HEADER_SIZE
);

let pool_id = mmtk_jl_gc_szclass(dtsz + JULIA_HEADER_SIZE);
JL_GC_SIZECLASSES[pool_id]
}
3 => {
let a_ndims_words = mmtk_jl_array_ndimwords(mmtk_jl_array_ndims(a));
let dtsz = std::mem::size_of::<mmtk_jl_array_t>()
+ a_ndims_words * std::mem::size_of::<usize>()
+ std::mem::size_of::<Address>();
debug_assert!(
dtsz + JULIA_HEADER_SIZE <= 2032,
"size {} greater than minimum!",
dtsz + JULIA_HEADER_SIZE
);

let pool_id = mmtk_jl_gc_szclass(dtsz + JULIA_HEADER_SIZE);
JL_GC_SIZECLASSES[pool_id]
}
_ => unreachable!(),
};

osize as usize
} else if obj_type == jl_simplevector_type {
let length = (*obj_address.to_ptr::<mmtk_jl_svec_t>()).length as usize;
let dtsz = length * std::mem::size_of::<Address>() + std::mem::size_of::<mmtk_jl_svec_t>();
Expand Down Expand Up @@ -223,77 +293,6 @@ pub unsafe fn get_so_object_size(object: ObjectReference) -> usize {
let pool_id = mmtk_jl_gc_szclass(dtsz + JULIA_HEADER_SIZE);
let osize = JL_GC_SIZECLASSES[pool_id];

osize as usize
} else if (*obj_type).name == jl_array_typename {
let flags = &(*obj_address.to_ptr::<mmtk_jl_array_t>()).flags;

let osize = match flags.how_custom() {
0 => {
let a_ndims = flags.ndims_custom();
let a_ndims_words = mmtk_jl_array_ndimwords(a_ndims);
let mut dtsz = std::mem::size_of::<mmtk_jl_array_t>()
+ a_ndims_words * std::mem::size_of::<usize>();
let data = (*obj_address.to_ptr::<mmtk_jl_array_t>()).data;
let data_addr = Address::from_mut_ptr(data);
if mmtk_object_is_managed_by_mmtk(data_addr.as_usize()) {
let a_offset = (*obj_address.to_ptr::<mmtk_jl_array_t>()).offset;
let a_elsize = (*obj_address.to_ptr::<mmtk_jl_array_t>()).elsize;
let pre_data_bytes = (data_addr.as_usize()
- a_offset as usize * a_elsize as usize)
- obj_address.as_usize();
if pre_data_bytes > 0 {
// a->data is allocated after a
dtsz = pre_data_bytes;
dtsz += mmtk_jl_array_nbytes(obj_address, obj_type, a_ndims);
}
if dtsz + JULIA_HEADER_SIZE > 2032 {
// if it's too large to be inlined (a->data and a are disjoint objects)
dtsz = std::mem::size_of::<mmtk_jl_array_t>()
+ a_ndims_words * std::mem::size_of::<usize>();
}
}
debug_assert!(
dtsz + JULIA_HEADER_SIZE <= 2032,
"size {} greater than minimum!",
dtsz + JULIA_HEADER_SIZE
);

let pool_id = mmtk_jl_gc_szclass(dtsz + JULIA_HEADER_SIZE);
JL_GC_SIZECLASSES[pool_id] as usize
}
1 | 2 => {
let a_ndims = flags.ndims_custom();
let a_ndims_words = mmtk_jl_array_ndimwords(a_ndims);
let dtsz = std::mem::size_of::<mmtk_jl_array_t>()
+ a_ndims_words * std::mem::size_of::<usize>();

debug_assert!(
dtsz + JULIA_HEADER_SIZE <= 2032,
"size {} greater than minimum!",
dtsz + JULIA_HEADER_SIZE
);

let pool_id = mmtk_jl_gc_szclass(dtsz + JULIA_HEADER_SIZE);
JL_GC_SIZECLASSES[pool_id] as usize
}
3 => {
let a_ndims = flags.ndims_custom();
let a_ndims_words = mmtk_jl_array_ndimwords(a_ndims);
let dtsz = std::mem::size_of::<mmtk_jl_array_t>()
+ a_ndims_words * std::mem::size_of::<usize>()
+ std::mem::size_of::<Address>();
debug_assert!(
dtsz + JULIA_HEADER_SIZE <= 2032,
"size {} greater than minimum!",
dtsz + JULIA_HEADER_SIZE
);

let pool_id = mmtk_jl_gc_szclass(dtsz + JULIA_HEADER_SIZE);
JL_GC_SIZECLASSES[pool_id] as usize
}
_ => unreachable!(),
};

osize as usize
} else {
let layout = (*obj_type).layout;
Expand All @@ -311,6 +310,7 @@ pub unsafe fn get_so_object_size(object: ObjectReference) -> usize {
}
}

#[inline(always)]
pub unsafe fn get_object_start_ref(object: ObjectReference) -> Address {
let obj_address = object.to_raw_address();
let obj_type = mmtk_jl_typeof(obj_address);
Expand All @@ -322,6 +322,7 @@ pub unsafe fn get_object_start_ref(object: ObjectReference) -> Address {
}
}

#[inline(always)]
pub unsafe fn mmtk_jl_gc_szclass(sz: usize) -> usize {
if sz <= 8 {
return 0;
Expand All @@ -331,6 +332,7 @@ pub unsafe fn mmtk_jl_gc_szclass(sz: usize) -> usize {
return klass as usize;
}

#[inline(always)]
pub unsafe fn mmtk_jl_gc_szclass_align8(sz: usize) -> usize {
if sz >= 16 && sz <= 152 {
return (sz + 7) / 8 - 1;
Expand All @@ -339,24 +341,13 @@ pub unsafe fn mmtk_jl_gc_szclass_align8(sz: usize) -> usize {
return mmtk_jl_gc_szclass(sz);
}

pub unsafe fn mmtk_jl_array_nbytes(
array: Address,
array_type: *const mmtk_jl_datatype_t,
array_ndims: u16,
) -> usize {
let a = array.to_ptr::<mmtk_jl_array_t>();
let mut sz: usize;
let ptr_array = !(*a).flags.ptrarray_custom();

let elem_type =
Address::from_mut_ptr((*array_type).parameters) + std::mem::size_of::<mmtk_jl_svec_t>();
#[inline(always)]
pub unsafe fn mmtk_jl_array_nbytes(a: *const mmtk_jl_array_t) -> usize {
let mut sz;

// FIXME: This is hardcoded with jl_is_uniontype(v) jl_typetagis(v,jl_uniontype_tag<<4) from julia.h
let union_type = (elem_type.as_usize()) == (4 << 4);
let isbitsunion = mmtk_jl_array_isbitunion(a);

let isbitsunion = (ptr_array != 0) && union_type;

if array_ndims == 1 {
if mmtk_jl_array_ndims(a) == 1 {
let elsize_is_one = if (*a).elsize == 1 && !isbitsunion {
1
} else {
Expand All @@ -368,8 +359,25 @@ pub unsafe fn mmtk_jl_array_nbytes(
}

if isbitsunion {
sz += (*a).length;
sz += mmtk_jl_array_len(a);
}

sz
}

#[inline(always)]
pub unsafe fn mmtk_jl_array_ndims(a: *const mmtk_jl_array_t) -> u32 {
(*a).flags.ndims_custom() as u32
}

#[inline(always)]
pub unsafe fn mmtk_jl_array_isbitunion(a: *const mmtk_jl_array_t) -> bool {
((*a).flags.ptrarray_custom()) == 0
&& mmtk_jl_is_uniontype(mmtk_jl_tparam0(mmtk_jl_typeof(Address::from_ptr(a))))
}

#[inline(always)]
pub unsafe fn mmtk_jl_is_uniontype(t: *const mmtk_jl_datatype_t) -> bool {
mmtk_jl_typetagof(Address::from_ptr(t)).as_usize()
== (mmtk_jlsmall_typeof_tags_mmtk_jl_uniontype_tag << 4) as usize
}

0 comments on commit ce8d819

Please sign in to comment.