Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/object allocation #20

Open
wants to merge 4 commits into
base: v1.8.2+RAI
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 25 additions & 103 deletions julia/mmtk_julia.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,25 +35,20 @@ JL_DLLEXPORT void (jl_mmtk_harness_end)(void)
harness_end();
}

JL_DLLEXPORT jl_value_t *jl_mmtk_gc_alloc_default_llvm(int pool_offset, int osize)
JL_DLLEXPORT jl_value_t *jl_mmtk_gc_alloc_default_llvm(int pool_offset, size_t osize)
{
jl_ptls_t ptls = (jl_ptls_t)jl_get_ptls_states();

// safepoint
if (__unlikely(jl_atomic_load(&jl_gc_running))) {
int8_t old_state = ptls->gc_state;
jl_atomic_store_release(&ptls->gc_state, JL_GC_STATE_WAITING);
jl_safepoint_wait_gc();
jl_atomic_store_release(&ptls->gc_state, old_state);
}
jl_gc_safepoint_(ptls);

jl_value_t *v;
jl_taggedvalue_t *v_tagged;

// v needs to be 16 byte aligned, therefore v_tagged needs to be offset accordingly to consider the size of header
ptls->mmtk_mutator_ptr->allocators.immix[0].cursor = ptls->cursor;

// 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 *) alloc(ptls->mmtk_mutator_ptr, osize, 16, 8, 0);
v_tagged = (jl_taggedvalue_t *) alloc(ptls->mmtk_mutator_ptr, osize, 16, 8, 0);

ptls->cursor = ptls->mmtk_mutator_ptr->allocators.immix[0].cursor;
ptls->limit = ptls->mmtk_mutator_ptr->allocators.immix[0].limit;
Expand Down Expand Up @@ -84,16 +79,10 @@ STATIC_INLINE void* alloc_default_object(jl_ptls_t ptls, size_t size, int offset
}
}

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, size_t osize, void *ty)
{
// safepoint
if (__unlikely(jl_atomic_load(&jl_gc_running))) {
int8_t old_state = ptls->gc_state;
jl_atomic_store_release(&ptls->gc_state, JL_GC_STATE_WAITING);
jl_safepoint_wait_gc();
jl_atomic_store_release(&ptls->gc_state, old_state);
}
jl_gc_safepoint_(ptls);

jl_value_t *v;
if ((uintptr_t)ty != jl_buff_tag) {
Expand All @@ -119,12 +108,7 @@ JL_DLLEXPORT jl_value_t *jl_mmtk_gc_alloc_default(jl_ptls_t ptls, int pool_offse
JL_DLLEXPORT jl_value_t *jl_mmtk_gc_alloc_big(jl_ptls_t ptls, size_t sz)
{
// safepoint
if (__unlikely(jl_atomic_load(&jl_gc_running))) {
int8_t old_state = ptls->gc_state;
jl_atomic_store_release(&ptls->gc_state, JL_GC_STATE_WAITING);
jl_safepoint_wait_gc();
jl_atomic_store_release(&ptls->gc_state, old_state);
}
jl_gc_safepoint_(ptls);

size_t offs = offsetof(bigval_t, header);
assert(sz >= sizeof(jl_taggedvalue_t) && "sz must include tag");
Expand Down Expand Up @@ -326,112 +310,50 @@ size_t get_so_size(void* obj)
jl_array_t* a = (jl_array_t*) obj;
if (a->flags.how == 0) {
int ndimwords = jl_array_ndimwords(jl_array_ndims(a));
int tsz = sizeof(jl_array_t) + ndimwords*sizeof(size_t);
size_t tsz = sizeof(jl_array_t) + ndimwords*sizeof(size_t);
if (object_is_managed_by_mmtk(a->data)) {
size_t pre_data_bytes = ((size_t)a->data - a->offset*a->elsize) - (size_t)a;
if (pre_data_bytes > 0) { // a->data is allocated after a
tsz = ((size_t)a->data - a->offset*a->elsize) - (size_t)a;
tsz += jl_array_nbytes(a);
}
if (tsz + sizeof(jl_taggedvalue_t) > 2032) { // if it's too large to be inlined (a->data and a are disjoint objects)
tsz = sizeof(jl_array_t) + ndimwords*sizeof(size_t); // simply keep the info before data
}
}
if (tsz + sizeof(jl_taggedvalue_t) > 2032) {
printf("size greater than minimum!\n");
runtime_panic();
if (a->flags.pooled && tsz > 2032) { // a->data is actually a separate object and not inlined
tsz = sizeof(jl_array_t) + ndimwords*sizeof(size_t);
}
int pool_id = jl_gc_szclass(tsz + sizeof(jl_taggedvalue_t));
int osize = jl_gc_sizeclasses[pool_id];
return osize;

return tsz + sizeof(jl_taggedvalue_t);
} else if (a->flags.how == 1) {
int ndimwords = jl_array_ndimwords(jl_array_ndims(a));
int tsz = sizeof(jl_array_t) + ndimwords*sizeof(size_t);
if (tsz + sizeof(jl_taggedvalue_t) > 2032) {
printf("size greater than minimum!\n");
runtime_panic();
}
int pool_id = jl_gc_szclass(tsz + sizeof(jl_taggedvalue_t));
int osize = jl_gc_sizeclasses[pool_id];

return osize;
size_t tsz = sizeof(jl_array_t) + ndimwords*sizeof(size_t);
return tsz + sizeof(jl_taggedvalue_t);
} else if (a->flags.how == 2) {
int ndimwords = jl_array_ndimwords(jl_array_ndims(a));
int tsz = sizeof(jl_array_t) + ndimwords*sizeof(size_t);
if (tsz + sizeof(jl_taggedvalue_t) > 2032) {
printf("size greater than minimum!\n");
runtime_panic();
}
int pool_id = jl_gc_szclass(tsz + sizeof(jl_taggedvalue_t));
int osize = jl_gc_sizeclasses[pool_id];

return osize;
size_t tsz = sizeof(jl_array_t) + ndimwords*sizeof(size_t);
return tsz + sizeof(jl_taggedvalue_t);
} else if (a->flags.how == 3) {
int ndimwords = jl_array_ndimwords(jl_array_ndims(a));
int tsz = sizeof(jl_array_t) + ndimwords * sizeof(size_t) + sizeof(void*);
if (tsz + sizeof(jl_taggedvalue_t) > 2032) {
printf("size greater than minimum!\n");
runtime_panic();
}
int pool_id = jl_gc_szclass(tsz + sizeof(jl_taggedvalue_t));
int osize = jl_gc_sizeclasses[pool_id];
return osize;
size_t tsz = sizeof(jl_array_t) + ndimwords * sizeof(size_t) + sizeof(void*);
return tsz + sizeof(jl_taggedvalue_t);
}
} else if (vt == jl_simplevector_type) {
size_t l = jl_svec_len(obj);
if (l * sizeof(void*) + sizeof(jl_svec_t) + sizeof(jl_taggedvalue_t) > 2032) {
printf("size greater than minimum!\n");
runtime_panic();
}
int pool_id = jl_gc_szclass(l * sizeof(void*) + sizeof(jl_svec_t) + sizeof(jl_taggedvalue_t));
int osize = jl_gc_sizeclasses[pool_id];
return osize;
return l * sizeof(void*) + sizeof(jl_svec_t) + sizeof(jl_taggedvalue_t);
} else if (vt == jl_module_type) {
size_t dtsz = sizeof(jl_module_t);
if (dtsz + sizeof(jl_taggedvalue_t) > 2032) {
printf("size greater than minimum!\n");
runtime_panic();
}
int pool_id = jl_gc_szclass(dtsz + sizeof(jl_taggedvalue_t));
int osize = jl_gc_sizeclasses[pool_id];
return osize;
return dtsz + sizeof(jl_taggedvalue_t);
} else if (vt == jl_task_type) {
size_t dtsz = sizeof(jl_task_t);
if (dtsz + sizeof(jl_taggedvalue_t) > 2032) {
printf("size greater than minimum!\n");
runtime_panic();
}
int pool_id = jl_gc_szclass(dtsz + sizeof(jl_taggedvalue_t));
int osize = jl_gc_sizeclasses[pool_id];
return osize;
return dtsz + sizeof(jl_taggedvalue_t);
} else if (vt == jl_string_type) {
size_t dtsz = jl_string_len(obj) + sizeof(size_t) + 1;
if (dtsz + sizeof(jl_taggedvalue_t) > 2032) {
printf("size greater than minimum!\n");
runtime_panic();
}
int pool_id = jl_gc_szclass_align8(dtsz + sizeof(jl_taggedvalue_t));
int osize = jl_gc_sizeclasses[pool_id];
return osize;
return dtsz + sizeof(jl_taggedvalue_t);
} else if (vt == jl_method_type) {
size_t dtsz = sizeof(jl_method_t);
if (dtsz + sizeof(jl_taggedvalue_t) > 2032) {
printf("size greater than minimum!\n");
runtime_panic();
}
int pool_id = jl_gc_szclass(dtsz + sizeof(jl_taggedvalue_t));

int osize = jl_gc_sizeclasses[pool_id];
return osize;
return dtsz + sizeof(jl_taggedvalue_t);
} else {
size_t dtsz = jl_datatype_size(vt);
if (dtsz + sizeof(jl_taggedvalue_t) > 2032) {
printf("size greater than minimum!\n");
runtime_panic();
}
int pool_id = jl_gc_szclass(dtsz + sizeof(jl_taggedvalue_t));
int osize = jl_gc_sizeclasses[pool_id];
return osize;
return dtsz + sizeof(jl_taggedvalue_t);
}
}

Expand Down
1 change: 0 additions & 1 deletion mmtk/julia
Submodule julia deleted from f3792d
56 changes: 49 additions & 7 deletions mmtk/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ use std::ffi::CStr;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::RwLockWriteGuard;

#[cfg(feature = "immix")]
use crate::MAX_STANDARD_OBJECT_SIZE;

#[no_mangle]
pub extern "C" fn gc_init(
min_heap_size: usize,
Expand Down Expand Up @@ -136,6 +139,30 @@ pub extern "C" fn destroy_mutator(mutator: *mut Mutator<JuliaVM>) {
memory_manager::destroy_mutator(unsafe { &mut *mutator })
}

#[cfg(feature = "immix")]
#[no_mangle]
pub extern "C" fn alloc(
mutator: *mut Mutator<JuliaVM>,
size: usize,
align: usize,
offset: isize,
semantics: AllocationSemantics,
) -> Address {
if size >= MAX_STANDARD_OBJECT_SIZE {
// MAX_IMMIX_OBJECT_SIZE
memory_manager::alloc::<JuliaVM>(
unsafe { &mut *mutator },
size,
64,
offset,
AllocationSemantics::Los,
)
} else {
memory_manager::alloc::<JuliaVM>(unsafe { &mut *mutator }, size, align, offset, semantics)
}
}

#[cfg(not(feature = "immix"))]
#[no_mangle]
pub extern "C" fn alloc(
mutator: *mut Mutator<JuliaVM>,
Expand Down Expand Up @@ -163,23 +190,38 @@ pub extern "C" fn alloc_large(
)
}

#[cfg(feature = "immix")]
#[no_mangle]
pub extern "C" fn post_alloc(
mutator: *mut Mutator<JuliaVM>,
refer: ObjectReference,
bytes: usize,
semantics: AllocationSemantics,
) {
match semantics {
AllocationSemantics::Los => {
memory_manager::post_alloc::<JuliaVM>(unsafe { &mut *mutator }, refer, bytes, semantics)
}
_ => {
memory_manager::post_alloc::<JuliaVM>(unsafe { &mut *mutator }, refer, bytes, semantics)
}
if bytes >= MAX_STANDARD_OBJECT_SIZE {
// MAX_IMMIX_OBJECT_SIZE
memory_manager::post_alloc::<JuliaVM>(
unsafe { &mut *mutator },
refer,
bytes,
AllocationSemantics::Los,
)
} else {
memory_manager::post_alloc::<JuliaVM>(unsafe { &mut *mutator }, refer, bytes, semantics)
}
}

#[cfg(not(feature = "immix"))]
#[no_mangle]
pub extern "C" fn post_alloc(
mutator: *mut Mutator<JuliaVM>,
refer: ObjectReference,
bytes: usize,
semantics: AllocationSemantics,
) {
memory_manager::post_alloc::<JuliaVM>(unsafe { &mut *mutator }, refer, bytes, semantics)
}

#[no_mangle]
pub extern "C" fn will_never_move(object: ObjectReference) -> bool {
!object.is_movable()
Expand Down
4 changes: 1 addition & 3 deletions mmtk/src/collection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,18 +181,16 @@ pub extern "C" fn mmtk_run_finalizers(at_exit: bool) {
{
// if the finalizer function triggers GC you don't want the objects to be GC-ed
let mut fin_roots = FINALIZER_ROOTS.write().unwrap();

let inserted = fin_roots.insert(obj);
assert!(inserted);

}
unsafe { ((*UPCALLS).run_finalizer_function)(obj.0, obj.1, obj.2) }
{
let mut fin_roots = FINALIZER_ROOTS.write().unwrap();
let removed = fin_roots.remove(&obj);
assert!(removed);
}

}
None => break,
}
Expand Down
10 changes: 10 additions & 0 deletions mmtk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,16 @@ extern "C" {
pub static BI_METADATA_END_ALIGNED_UP: usize;
}

#[cfg(feature = "immix")]
#[no_mangle]
pub static MAX_STANDARD_OBJECT_SIZE: usize =
mmtk::plan::IMMIX_CONSTRAINTS.max_non_los_default_alloc_bytes;

#[cfg(not(feature = "immix"))]
#[no_mangle]
pub static MAX_STANDARD_OBJECT_SIZE: usize = // default to size of Julia's max size class
2032 - std::mem::size_of::<Address>();

#[no_mangle]
pub static BLOCK_FOR_GC: AtomicBool = AtomicBool::new(false);

Expand Down