From de38af4095bbed7e9d921f32aec998ec9c045256 Mon Sep 17 00:00:00 2001 From: Eduardo Souza Date: Wed, 28 Feb 2024 09:29:23 +1100 Subject: [PATCH] Stop using Julia's size classes when using MMTk (#108) 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 https://github.com/mmtk/julia/pull/31. (cherry picked from commit efb9e105f830c1644b735b6fd24774914408075e) # Conflicts: # mmtk/Cargo.toml --- julia/mmtk_julia.c | 13 +++--- mmtk/Cargo.toml | 4 ++ mmtk/src/object_model.rs | 95 +++++----------------------------------- 3 files changed, 21 insertions(+), 91 deletions(-) diff --git a/julia/mmtk_julia.c b/julia/mmtk_julia.c index 8faf1779..618100a3 100644 --- a/julia/mmtk_julia.c +++ b/julia/mmtk_julia.c @@ -49,8 +49,7 @@ 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); @@ -58,16 +57,16 @@ JL_DLLEXPORT jl_value_t *jl_mmtk_gc_alloc_default(jl_ptls_t ptls, int pool_offse 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; diff --git a/mmtk/Cargo.toml b/mmtk/Cargo.toml index 605a252d..8839f034 100644 --- a/mmtk/Cargo.toml +++ b/mmtk/Cargo.toml @@ -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"] diff --git a/mmtk/src/object_model.rs b/mmtk/src/object_model.rs index 00fdb425..f955971b 100644 --- a/mmtk/src/object_model.rs +++ b/mmtk/src/object_model.rs @@ -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(); @@ -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)); @@ -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)); @@ -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!(), }; @@ -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::(); debug_assert!( @@ -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::(); debug_assert!( @@ -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::(); let dtsz = length + std::mem::size_of::() + 1; @@ -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::(); debug_assert!( @@ -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; @@ -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) } } @@ -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)]