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

Updating the binding to support MMTk with upstream Julia #180

Merged
merged 32 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
ea27258
Changes to make the binding compatible with the latest version of Jul…
udesou Sep 2, 2024
f19ffd6
Update julia_repo and julia_version
udesou Sep 2, 2024
63e6b50
Add check so that we don't try to scan a null object
udesou Sep 2, 2024
641d748
Skip test about heap snapshot
udesou Sep 3, 2024
aeb224b
Updating julia_version
udesou Sep 23, 2024
d24f52e
Adding changes to support getter for jl_gc_disable_counter and using …
udesou Sep 25, 2024
7873163
Updating julia_version
udesou Sep 25, 2024
8f0ceed
Updating julia_version
udesou Sep 25, 2024
552883a
Updating rust version to 1.77.0
udesou Oct 8, 2024
7793910
Merging refactor-pre-mmtk branch from julia and reflecting those chan…
udesou Oct 9, 2024
56b2542
Updating julia_version
udesou Oct 9, 2024
a41dadd
Only run tests for non-moving immix
udesou Oct 10, 2024
91d43ec
Update julia_version and ci.yml
udesou Oct 10, 2024
7690691
Updating julia_version
udesou Oct 10, 2024
da9ff0d
Skipping tests that check the reasons for a full sweep and are specif…
udesou Oct 10, 2024
61e1cfd
Adding comments on new functions
udesou Oct 13, 2024
60c3d58
Removing julia folder and using build.rs to generate bindings
udesou Oct 16, 2024
4791a62
This file will be generated by build.rs
udesou Oct 16, 2024
9798604
Updating julia_version
udesou Oct 16, 2024
48c82a0
Adding build.rs
udesou Oct 16, 2024
10fbc83
Exporting JULIA_PATH
udesou Oct 16, 2024
0862d06
Adding architecture to see if it removes bindgen issues
udesou Oct 16, 2024
b1fd11e
One more try with --target=x86_64-pc-linux-gnu
udesou Oct 16, 2024
ee4911e
Trying to set up tmate session to debug bingen issue
udesou Oct 16, 2024
b0b6d7e
Typo
udesou Oct 16, 2024
8888772
Adding tmate session before building Julia?
udesou Oct 16, 2024
efbd912
Removing with sudo false
udesou Oct 16, 2024
d6c6bbe
Disable action-tmate and rm llvm-* before building mmtk (?)
udesou Oct 17, 2024
2ea5669
Trying again
udesou Oct 17, 2024
7affec8
Applying cargo fmt
udesou Oct 17, 2024
480834e
Remove commented code
udesou Oct 17, 2024
3a397c9
Updating emails
udesou Oct 18, 2024
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
8 changes: 7 additions & 1 deletion .github/scripts/ci-test-patching.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,17 @@ declare -a tests_to_skip=(
'@test !live_bytes_has_grown_too_much' "$JULIA_PATH/test/gc.jl"
'@test any(page_utilization .> 0)' "$JULIA_PATH/test/gc.jl"

# Tests that check the reasons for a full sweep and are specific to stock Julia
'@test reasons\[:FULL_SWEEP_REASON_FORCED_FULL_SWEEP\] >= 1' "$JULIA_PATH/test/gc.jl"
'@test keys(reasons) == Set(Base.FULL_SWEEP_REASONS)' "$JULIA_PATH/test/gc.jl"

# Allocation profiler tests that fail when we inline fastpath allocation
'@test length(\[a for a in prof.allocs if a.type == MyType\]) >= 1' "$JULIA_PATH/stdlib/Profile/test/allocs.jl"
'@test length(prof.allocs) >= 1' "$JULIA_PATH/stdlib/Profile/test/allocs.jl"
'@test length(filter(a->a.type <: type, profile.allocs)) >= NUM_TASKS' "$JULIA_PATH/stdlib/Profile/test/allocs.jl"


# Test that expects information from heap snapshot which is currently not available in MMTk
'@test contains(sshot, "redact_this")' "$JULIA_PATH/stdlib/Profile/test/runtests.jl"

# This test checks GC logging
'@test occursin("GC: pause", read(tmppath, String))' "$JULIA_PATH/test/misc.jl"
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:
- master
- v1.8.2\+RAI
- v1.9.2\+RAI
- upstream-ready/immix

concurrency:
# Cancels pending runs when a PR gets updated.
Expand All @@ -17,8 +18,8 @@ jobs:
strategy:
fail-fast: false
matrix:
gc_plan: [Immix, StickyImmix]
moving: [Default, Non_Moving]
gc_plan: [Immix]
moving: [Non_Moving]
uses: ./.github/workflows/binding-tests.yml
with:
gc_plan: ${{ matrix.gc_plan }}
Expand Down
111 changes: 34 additions & 77 deletions julia/mmtk_julia.c
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
#include "mmtk_julia.h"
#include "mmtk.h"
#include "gc-mmtk.h"
#include "mmtk_julia_types.h"
#include <stdbool.h>
#include <stddef.h>
#include "gc.h"
#include "gc-common.h"
#include "threading.h"

extern int64_t perm_scanned_bytes;
extern gc_heapstatus_t gc_heap_stats;
extern void run_finalizer(jl_task_t *ct, void *o, void *ff);
extern int gc_n_threads;
extern jl_ptls_t* gc_all_tls_states;
extern jl_value_t *cmpswap_names JL_GLOBALLY_ROOTED;
extern jl_genericmemory_t *jl_global_roots_list JL_GLOBALLY_ROOTED;
extern jl_genericmemory_t *jl_global_roots_keyset JL_GLOBALLY_ROOTED;
extern jl_typename_t *jl_array_typename JL_GLOBALLY_ROOTED;
extern void jl_gc_free_memory(jl_value_t *v, int isaligned);
extern long BI_METADATA_START_ALIGNED_DOWN;
extern long BI_METADATA_END_ALIGNED_UP;
extern uint64_t finalizer_rngState[JL_RNG_SIZE];
extern const unsigned pool_sizes[];
extern void mmtk_store_obj_size_c(void* obj, size_t size);
extern void jl_gc_free_array(jl_array_t *a);
extern size_t mmtk_get_obj_size(void* obj);
extern void jl_rng_split(uint64_t to[JL_RNG_SIZE], uint64_t from[JL_RNG_SIZE]);
extern void _jl_free_stack(jl_ptls_t ptls, void *stkbuf, size_t bufsz);
Expand All @@ -29,6 +27,8 @@ extern jl_mutex_t finalizers_lock;
extern void jl_gc_wait_for_the_world(jl_ptls_t* gc_all_tls_states, int gc_n_threads);
extern void mmtk_block_thread_for_gc(void);
extern int64_t live_bytes;
extern void jl_throw_out_of_memory_error(void);
extern uint32_t jl_get_gc_disable_counter(void);


extern void* new_mutator_iterator(void);
Expand All @@ -46,73 +46,29 @@ 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 osize, size_t align, void *ty)
static void jl_gc_free_memory(jl_value_t *v, int isaligned) JL_NOTSAFEPOINT
udesou marked this conversation as resolved.
Show resolved Hide resolved
{
// 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, LLT_ALIGN(osize, align), align, sizeof(jl_taggedvalue_t));
v = jl_valueof(v_tagged);
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, 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, 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_tls.gc_num.allocd += osize;
ptls->gc_tls.gc_num.poolalloc++;

return v;
}

JL_DLLEXPORT jl_value_t *jl_mmtk_gc_alloc_big(jl_ptls_t ptls, size_t sz)
{
// safepoint
jl_gc_safepoint_(ptls);

size_t offs = offsetof(bigval_t, header);
assert(sz >= sizeof(jl_taggedvalue_t) && "sz must include tag");
static_assert(offsetof(bigval_t, header) >= sizeof(void*), "Empty bigval header?");
static_assert(sizeof(bigval_t) % JL_HEAP_ALIGNMENT == 0, "");
size_t allocsz = LLT_ALIGN(sz + offs, JL_CACHE_BYTE_ALIGNMENT);
if (allocsz < sz) { // overflow in adding offs, size was "negative"
assert(0 && "Error when allocating big object");
jl_throw(jl_memory_exception);
}

bigval_t *v = (bigval_t*)mmtk_alloc_large(&ptls->mmtk_mutator, allocsz, JL_CACHE_BYTE_ALIGNMENT, 0, 2);

if (v == NULL) {
assert(0 && "Allocation failed");
jl_throw(jl_memory_exception);
}
v->sz = allocsz;

ptls->gc_tls.gc_num.allocd += allocsz;
ptls->gc_tls.gc_num.bigalloc++;

jl_value_t *result = jl_valueof(&v->header);
mmtk_post_alloc(&ptls->mmtk_mutator, result, allocsz, 2);

return result;
assert(jl_is_genericmemory(v));
jl_genericmemory_t *m = (jl_genericmemory_t*)v;
assert(jl_genericmemory_how(m) == 1 || jl_genericmemory_how(m) == 2);
char *d = (char*)m->ptr;
if (isaligned)
jl_free_aligned(d);
else
free(d);
gc_num.freed += jl_genericmemory_nbytes(m);
gc_num.freecall++;
}

static void mmtk_sweep_malloced_memory(void) JL_NOTSAFEPOINT
{
void* iter = new_mutator_iterator();
jl_ptls_t ptls2 = get_next_mutator_tls(iter);
while(ptls2 != NULL) {
mallocarray_t *ma = ptls2->gc_tls.heap.mallocarrays;
mallocarray_t **pma = &ptls2->gc_tls.heap.mallocarrays;
mallocmemory_t *ma = ptls2->gc_tls_common.heap.mallocarrays;
mallocmemory_t **pma = &ptls2->gc_tls_common.heap.mallocarrays;
while (ma != NULL) {
mallocarray_t *nxt = ma->next;
mallocmemory_t *nxt = ma->next;
jl_value_t *a = (jl_value_t*)((uintptr_t)ma->a & ~1);
if (!mmtk_object_is_managed_by_mmtk(a)) {
pma = &ma->next;
Expand All @@ -121,16 +77,16 @@ static void mmtk_sweep_malloced_memory(void) JL_NOTSAFEPOINT
}
if (mmtk_is_live_object(a)) {
// if the array has been forwarded, the reference needs to be updated
jl_value_t *maybe_forwarded = (jl_value_t*)mmtk_get_possibly_forwared(ma->a);
jl_genericmemory_t *maybe_forwarded = (jl_genericmemory_t*)mmtk_get_possibly_forwared(ma->a);
ma->a = maybe_forwarded;
pma = &ma->next;
}
else {
*pma = nxt;
int isaligned = (uintptr_t)ma->a & 1;
jl_gc_free_memory(a, isaligned);
ma->next = ptls2->gc_tls.heap.mafreelist;
ptls2->gc_tls.heap.mafreelist = ma;
ma->next = ptls2->gc_tls_common.heap.mafreelist;
ptls2->gc_tls_common.heap.mafreelist = ma;
}
ma = nxt;
}
Expand Down Expand Up @@ -160,8 +116,8 @@ JL_DLLEXPORT void jl_gc_prepare_to_collect(void)
jl_task_t *ct = jl_current_task;
jl_ptls_t ptls = ct->ptls;
if (jl_atomic_load_acquire(&jl_gc_disable_counter)) {
size_t localbytes = jl_atomic_load_relaxed(&ptls->gc_tls.gc_num.allocd) + gc_num.interval;
jl_atomic_store_relaxed(&ptls->gc_tls.gc_num.allocd, -(int64_t)gc_num.interval);
size_t localbytes = jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.allocd) + gc_num.interval;
jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.allocd, -(int64_t)gc_num.interval);
static_assert(sizeof(_Atomic(uint64_t)) == sizeof(gc_num.deferred_alloc), "");
jl_atomic_fetch_add_relaxed((_Atomic(uint64_t)*)&gc_num.deferred_alloc, localbytes);
return;
Expand Down Expand Up @@ -417,7 +373,7 @@ void mmtk_sweep_stack_pools(void)

// free half of stacks that remain unused since last sweep
for (int p = 0; p < JL_N_STACK_POOLS; p++) {
small_arraylist_t *al = &ptls2->gc_tls.heap.free_stacks[p];
small_arraylist_t *al = &ptls2->gc_tls_common.heap.free_stacks[p];
size_t n_to_free;
if (jl_atomic_load_relaxed(&ptls2->current_task) == NULL) {
n_to_free = al->len; // not alive yet or dead, so it does not need these anymore
Expand All @@ -439,10 +395,10 @@ void mmtk_sweep_stack_pools(void)
}
}
if (jl_atomic_load_relaxed(&ptls2->current_task) == NULL) {
small_arraylist_free(ptls2->gc_tls.heap.free_stacks);
small_arraylist_free(ptls2->gc_tls_common.heap.free_stacks);
}

small_arraylist_t *live_tasks = &ptls2->gc_tls.heap.live_tasks;
small_arraylist_t *live_tasks = &ptls2->gc_tls_common.heap.live_tasks;
size_t n = 0;
size_t ndel = 0;
size_t l = live_tasks->len;
Expand All @@ -456,16 +412,16 @@ void mmtk_sweep_stack_pools(void)
live_tasks->items[n] = maybe_forwarded;
t = maybe_forwarded;
assert(jl_is_task(t));
if (t->stkbuf == NULL)
if (t->ctx.stkbuf == NULL)
ndel++; // jl_release_task_stack called
else
n++;
} else {
ndel++;
void *stkbuf = t->stkbuf;
size_t bufsz = t->bufsz;
void *stkbuf = t->ctx.stkbuf;
size_t bufsz = t->ctx.bufsz;
if (stkbuf) {
t->stkbuf = NULL;
t->ctx.stkbuf = NULL;
_jl_free_stack(ptls2, stkbuf, bufsz);
}
#ifdef _COMPILER_TSAN_ENABLED_
Expand Down Expand Up @@ -577,14 +533,15 @@ uintptr_t get_abi_structs_checksum_c(void) {
^ print_sizeof(mmtk_jl_task_t)
^ print_sizeof(mmtk_jl_weakref_t)
^ print_sizeof(mmtk_jl_tls_states_t)
^ print_sizeof(mmtk_jl_thread_heap_t)
^ print_sizeof(mmtk_jl_thread_gc_num_t);
^ print_sizeof(mmtk_jl_thread_heap_common_t)
^ print_sizeof(mmtk_jl_thread_gc_num_common_t);
}

Julia_Upcalls mmtk_upcalls = (Julia_Upcalls) {
.scan_julia_exc_obj = scan_julia_exc_obj,
.get_stackbase = get_stackbase,
.jl_throw_out_of_memory_error = jl_throw_out_of_memory_error,
.jl_get_gc_disable_counter = jl_get_gc_disable_counter,
.sweep_malloced_memory = mmtk_sweep_malloced_memory,
.sweep_stack_pools = mmtk_sweep_stack_pools,
.wait_in_a_safepoint = mmtk_wait_in_a_safepoint,
Expand Down
2 changes: 1 addition & 1 deletion julia/mmtk_julia.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include "mmtk.h"
#include "gc.h"
#include "gc-common.h"

extern Julia_Upcalls mmtk_upcalls;

Expand Down
Loading
Loading