Skip to content

Commit

Permalink
Stop using Julia's size classes when using MMTk (#108)
Browse files Browse the repository at this point in the history
When allocating an object, we are still allocating the number of bytes
according to Julia's size classes, which may be an overestimation of the
number of bytes an object actually requires. This PR removes this since
this is specific to Julia's stock GC. This affects not only allocation
itself but needs to be reflected in the `get_current_size` function.

Needs to be merged with mmtk/julia#31.

(cherry picked from commit efb9e10)

# Conflicts:
#	mmtk/Cargo.toml
  • Loading branch information
udesou authored and mergify[bot] committed Feb 27, 2024
1 parent e110638 commit de38af4
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 91 deletions.
13 changes: 6 additions & 7 deletions julia/mmtk_julia.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,25 +49,24 @@ JL_DLLEXPORT void (jl_mmtk_harness_end)(void)
mmtk_harness_end();
}

JL_DLLEXPORT jl_value_t *jl_mmtk_gc_alloc_default(jl_ptls_t ptls, int pool_offset,
int osize, void *ty)
JL_DLLEXPORT jl_value_t *jl_mmtk_gc_alloc_default(jl_ptls_t ptls, int osize, size_t align, void *ty)
{
// safepoint
jl_gc_safepoint_(ptls);

jl_value_t *v;
if ((uintptr_t)ty != jl_buff_tag) {
// v needs to be 16 byte aligned, therefore v_tagged needs to be offset accordingly to consider the size of header
jl_taggedvalue_t *v_tagged = (jl_taggedvalue_t *)mmtk_immix_alloc_fast(&ptls->mmtk_mutator, osize, 16, sizeof(jl_taggedvalue_t));
jl_taggedvalue_t *v_tagged = (jl_taggedvalue_t *)mmtk_immix_alloc_fast(&ptls->mmtk_mutator, LLT_ALIGN(osize, align), align, sizeof(jl_taggedvalue_t));
v = jl_valueof(v_tagged);
mmtk_immix_post_alloc_fast(&ptls->mmtk_mutator, v, osize);
mmtk_immix_post_alloc_fast(&ptls->mmtk_mutator, v, LLT_ALIGN(osize, align));
} else {
// allocating an extra word to store the size of buffer objects
jl_taggedvalue_t *v_tagged = (jl_taggedvalue_t *)mmtk_immix_alloc_fast(&ptls->mmtk_mutator, osize + sizeof(jl_taggedvalue_t), 16, 0);
jl_taggedvalue_t *v_tagged = (jl_taggedvalue_t *)mmtk_immix_alloc_fast(&ptls->mmtk_mutator, LLT_ALIGN(osize+sizeof(jl_taggedvalue_t), align), align, 0);
jl_value_t* v_tagged_aligned = ((jl_value_t*)((char*)(v_tagged) + sizeof(jl_taggedvalue_t)));
v = jl_valueof(v_tagged_aligned);
mmtk_store_obj_size_c(v, osize + sizeof(jl_taggedvalue_t));
mmtk_immix_post_alloc_fast(&ptls->mmtk_mutator, v, osize + sizeof(jl_taggedvalue_t));
mmtk_store_obj_size_c(v, LLT_ALIGN(osize+sizeof(jl_taggedvalue_t), align));
mmtk_immix_post_alloc_fast(&ptls->mmtk_mutator, v, LLT_ALIGN(osize+sizeof(jl_taggedvalue_t), align));
}

ptls->gc_num.allocd += osize;
Expand Down
4 changes: 4 additions & 0 deletions mmtk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ edition = "2018"
[package.metadata.julia]
# Our CI matches the following line and extract mmtk/julia. If this line is updated, please check ci yaml files and make sure it works.
julia_repo = "https://github.com/mmtk/julia.git"
<<<<<<< HEAD
julia_version = "75ac661401d8e26e3305dc43c662430814a3076c"
=======
julia_version = "9460689801747623d464024586fe90e635c74fbc"
>>>>>>> efb9e10 (Stop using Julia's size classes when using MMTk (#108))

[lib]
crate-type = ["cdylib"]
Expand Down
95 changes: 11 additions & 84 deletions mmtk/src/object_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,42 +180,6 @@ pub fn is_object_in_los(object: &ObjectReference) -> bool {
&& (*object).to_raw_address().as_usize() < 0x800_0000_0000
}

const JL_GC_SIZECLASSES: [::std::os::raw::c_int; 49] = [
8,
// 16 pools at 8-byte spacing
// the 8-byte aligned pools are only used for Strings
16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, 136,
// 8 pools at 16-byte spacing
144, 160, 176, 192, 208, 224, 240, 256,
// the following tables are computed for maximum packing efficiency via the formula:
// pg = 2^14
// sz = (div.(pg-8, rng).÷16)*16; hcat(sz, (pg-8).÷sz, pg .- (pg-8).÷sz.*sz)'

// rng = 60:-4:32 (8 pools)
272, 288, 304, 336, 368, 400, 448, 496,
// 60, 56, 53, 48, 44, 40, 36, 33, /pool
// 64, 256, 272, 256, 192, 384, 256, 16, bytes lost

// rng = 30:-2:16 (8 pools)
544, 576, 624, 672, 736, 816, 896, 1008,
// 30, 28, 26, 24, 22, 20, 18, 16, /pool
// 64, 256, 160, 256, 192, 64, 256, 256, bytes lost

// rng = 15:-1:8 (8 pools)
1088, 1168, 1248, 1360, 1488, 1632, 1808,
2032, // 15, 14, 13, 12, 11, 10, 9, 8, /pool
// 64, 32, 160, 64, 16, 64, 112, 128, bytes lost
];

const SZCLASS_TABLE: [u8; 128] = [
0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 28, 29, 29, 30,
30, 31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34, 35, 35, 35, 36, 36, 36, 37, 37, 37, 37, 38, 38,
38, 38, 38, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 42, 42, 42, 42,
42, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 46, 46, 46,
46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 48,
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();
Expand Down Expand Up @@ -255,8 +219,7 @@ pub unsafe fn get_so_object_size(object: ObjectReference) -> usize {
dtsz + JULIA_HEADER_SIZE
);

let pool_id = mmtk_jl_gc_szclass(dtsz + JULIA_HEADER_SIZE);
JL_GC_SIZECLASSES[pool_id]
llt_align(dtsz + JULIA_HEADER_SIZE, 16)
}
1 | 2 => {
let a_ndims_words = mmtk_jl_array_ndimwords(mmtk_jl_array_ndims(a));
Expand All @@ -269,8 +232,7 @@ pub unsafe fn get_so_object_size(object: ObjectReference) -> usize {
dtsz + JULIA_HEADER_SIZE
);

let pool_id = mmtk_jl_gc_szclass(dtsz + JULIA_HEADER_SIZE);
JL_GC_SIZECLASSES[pool_id]
llt_align(dtsz + JULIA_HEADER_SIZE, 16)
}
3 => {
let a_ndims_words = mmtk_jl_array_ndimwords(mmtk_jl_array_ndims(a));
Expand All @@ -283,8 +245,7 @@ pub unsafe fn get_so_object_size(object: ObjectReference) -> usize {
dtsz + JULIA_HEADER_SIZE
);

let pool_id = mmtk_jl_gc_szclass(dtsz + JULIA_HEADER_SIZE);
JL_GC_SIZECLASSES[pool_id]
llt_align(dtsz + JULIA_HEADER_SIZE, 16)
}
_ => unreachable!(),
};
Expand All @@ -300,12 +261,7 @@ pub unsafe fn get_so_object_size(object: ObjectReference) -> usize {
dtsz + JULIA_HEADER_SIZE
);

let sz = dtsz + JULIA_HEADER_SIZE;

let pool_id = mmtk_jl_gc_szclass(sz);
let osize = JL_GC_SIZECLASSES[pool_id];

osize as usize
llt_align(dtsz + JULIA_HEADER_SIZE, 16)
} else if obj_type == jl_module_type {
let dtsz = std::mem::size_of::<mmtk_jl_module_t>();
debug_assert!(
Expand All @@ -314,10 +270,7 @@ pub unsafe fn get_so_object_size(object: ObjectReference) -> usize {
dtsz + JULIA_HEADER_SIZE
);

let pool_id = mmtk_jl_gc_szclass(dtsz + JULIA_HEADER_SIZE);
let osize = JL_GC_SIZECLASSES[pool_id];

osize as usize
llt_align(dtsz + JULIA_HEADER_SIZE, 16)
} else if obj_type == jl_task_type {
let dtsz = std::mem::size_of::<mmtk_jl_task_t>();
debug_assert!(
Expand All @@ -326,10 +279,7 @@ pub unsafe fn get_so_object_size(object: ObjectReference) -> usize {
dtsz + JULIA_HEADER_SIZE
);

let pool_id = mmtk_jl_gc_szclass(dtsz + JULIA_HEADER_SIZE);
let osize = JL_GC_SIZECLASSES[pool_id];

osize as usize
llt_align(dtsz + JULIA_HEADER_SIZE, 16)
} else if obj_type == jl_string_type {
let length = object.to_raw_address().load::<usize>();
let dtsz = length + std::mem::size_of::<usize>() + 1;
Expand All @@ -340,10 +290,7 @@ pub unsafe fn get_so_object_size(object: ObjectReference) -> usize {
dtsz + JULIA_HEADER_SIZE
);

let pool_id = mmtk_jl_gc_szclass_align8(dtsz + JULIA_HEADER_SIZE);
let osize = JL_GC_SIZECLASSES[pool_id];

osize as usize
llt_align(dtsz + JULIA_HEADER_SIZE, 16)
} else if obj_type == jl_method_type {
let dtsz = std::mem::size_of::<mmtk_jl_method_t>();
debug_assert!(
Expand All @@ -352,10 +299,7 @@ pub unsafe fn get_so_object_size(object: ObjectReference) -> usize {
dtsz + JULIA_HEADER_SIZE
);

let pool_id = mmtk_jl_gc_szclass(dtsz + JULIA_HEADER_SIZE);
let osize = JL_GC_SIZECLASSES[pool_id];

osize as usize
llt_align(dtsz + JULIA_HEADER_SIZE, 16)
} else {
let layout = (*obj_type).layout;
let dtsz = (*layout).size as usize;
Expand All @@ -365,10 +309,7 @@ pub unsafe fn get_so_object_size(object: ObjectReference) -> usize {
dtsz + JULIA_HEADER_SIZE
);

let pool_id = mmtk_jl_gc_szclass(dtsz + JULIA_HEADER_SIZE);
let osize = JL_GC_SIZECLASSES[pool_id];

osize as usize
llt_align(dtsz + JULIA_HEADER_SIZE, 16)
}
}

Expand All @@ -385,22 +326,8 @@ 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;
}

let klass = SZCLASS_TABLE[(sz + 15) / 16];
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;
}

return mmtk_jl_gc_szclass(sz);
pub unsafe fn llt_align(size: usize, align: usize) -> usize {
((size) + (align) - 1) & !((align) - 1)
}

#[inline(always)]
Expand Down

0 comments on commit de38af4

Please sign in to comment.