Skip to content

Commit

Permalink
Updating our dev branches (#182)
Browse files Browse the repository at this point in the history
This PR updates our dev branch to keep it on track with the changes from
its `dev` counterpart from
[`mmtk/julia`](https://github.com/mmtk/julia/tree/dev). The latter has
been updated to account for the changes in
[upstream](https://github.com/JuliaLang/julia) (including the changes
that we want to add from
[`upstream-ready/immix`](https://github.com/mmtk/julia/tree/upstream-ready/immix)
since it is already up to date with upstream).
  • Loading branch information
udesou authored Oct 15, 2024
1 parent 5d07e8f commit 7c4f844
Show file tree
Hide file tree
Showing 15 changed files with 1,472 additions and 5,556 deletions.
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
1 change: 1 addition & 0 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
- dev

concurrency:
# Cancels pending runs when a PR gets updated.
Expand Down
114 changes: 37 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,32 @@ 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)
// This is used in mmtk_sweep_malloced_memory and it is slightly different
// from jl_gc_free_memory from gc-stock.c as the stock GC updates the
// information in the global variable gc_heap_stats (which is specific to the stock GC)
static void jl_gc_free_memory(jl_value_t *v, int isaligned) JL_NOTSAFEPOINT
{
// 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 +80,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 +119,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 +376,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 +398,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 +415,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 +536,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

0 comments on commit 7c4f844

Please sign in to comment.