From ae2fa58013b841600cc416b65056813054dce3d5 Mon Sep 17 00:00:00 2001 From: Eduardo Souza Date: Thu, 3 Aug 2023 09:44:13 +0000 Subject: [PATCH 1/8] Supporting moving immix (wip) --- src/builtins.c | 12 +++++++++++- src/datatype.c | 2 ++ src/interpreter.c | 2 ++ src/ircode.c | 5 ++++- src/julia.h | 13 +++++++++++++ src/julia_internal.h | 4 +++- src/runtime_ccall.cpp | 2 ++ src/staticdata.c | 9 +++++++++ src/staticdata_utils.c | 9 +++++++++ src/toplevel.c | 2 ++ 10 files changed, 57 insertions(+), 3 deletions(-) diff --git a/src/builtins.c b/src/builtins.c index a6c904c851c95..f3fa4248b3fa4 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -344,6 +344,9 @@ static uintptr_t type_object_id_(jl_value_t *v, jl_varidx_t *env) JL_NOTSAFEPOIN i++; pe = pe->prev; } + if(mmtk_object_is_managed_by_mmtk(v)) { + mmtk_pin_object(v); + } return inthash((uintptr_t)v); } if (tv == jl_uniontype_type) { @@ -392,6 +395,9 @@ static uintptr_t immut_id_(jl_datatype_t *dt, jl_value_t *v, uintptr_t h) JL_NOT return ~h; size_t f, nf = jl_datatype_nfields(dt); if (nf == 0 || (!dt->layout->haspadding && dt->layout->npointers == 0)) { + if(mmtk_object_is_managed_by_mmtk(v)) { + mmtk_pin_object(v); + } // operate element-wise if there are unused bits inside, // otherwise just take the whole data block at once // a few select pointers (notably symbol) also have special hash values @@ -452,8 +458,12 @@ static uintptr_t NOINLINE jl_object_id__cold(jl_datatype_t *dt, jl_value_t *v) J jl_module_t *m = (jl_module_t*)v; return m->hash; } - if (dt->name->mutabl) + if (dt->name->mutabl) { + if(mmtk_object_is_managed_by_mmtk(v)) { + mmtk_pin_object(v); + } return inthash((uintptr_t)v); + } return immut_id_(dt, v, dt->hash); } diff --git a/src/datatype.c b/src/datatype.c index 95c3b11c9abdc..20c3af1555675 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -65,6 +65,7 @@ JL_DLLEXPORT jl_typename_t *jl_new_typename_in(jl_sym_t *name, jl_module_t *modu jl_typename_t *tn = (jl_typename_t*)jl_gc_alloc(ct->ptls, sizeof(jl_typename_t), jl_typename_type); + mmtk_pin_object(tn); tn->name = name; tn->module = module; tn->wrapper = NULL; @@ -96,6 +97,7 @@ jl_datatype_t *jl_new_uninitialized_datatype(void) { jl_task_t *ct = jl_current_task; jl_datatype_t *t = (jl_datatype_t*)jl_gc_alloc(ct->ptls, sizeof(jl_datatype_t), jl_datatype_type); + mmtk_pin_object(t); jl_set_typetagof(t, jl_datatype_tag, 0); t->hash = 0; t->hasfreetypevars = 0; diff --git a/src/interpreter.c b/src/interpreter.c index c08496f72ce04..cdc2a5a96beef 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -748,6 +748,7 @@ jl_value_t *NOINLINE jl_interpret_toplevel_thunk(jl_module_t *m, jl_code_info_t unsigned nroots = jl_source_nslots(src) + jl_source_nssavalues(src); JL_GC_PUSHFRAME(s, s->locals, nroots); jl_array_t *stmts = src->code; + JL_GC_PUSH1(&stmts); assert(jl_typetagis(stmts, jl_array_any_type)); s->src = src; s->module = m; @@ -760,6 +761,7 @@ jl_value_t *NOINLINE jl_interpret_toplevel_thunk(jl_module_t *m, jl_code_info_t jl_value_t *r = eval_body(stmts, s, 0, 1); ct->world_age = last_age; JL_GC_POP(); + JL_GC_POP(); return r; } diff --git a/src/ircode.c b/src/ircode.c index 4121d6691aa5b..69a5ed9a05a80 100644 --- a/src/ircode.c +++ b/src/ircode.c @@ -1162,12 +1162,15 @@ void jl_init_serializer(void) assert(LAST_TAG+1+i < 256); for (i = 2; i < 256; i++) { - if (deser_tag[i]) + if (deser_tag[i]) { + PTRHASH_PIN(deser_tag[i]) ptrhash_put(&ser_tag, deser_tag[i], (void*)i); + } } i = 2; while (common_symbols[i-2] != NULL) { + PTRHASH_PIN(common_symbols[i-2]) ptrhash_put(&common_symbol_tag, common_symbols[i-2], (void*)i); deser_symbols[i] = (jl_value_t*)common_symbols[i-2]; i += 1; diff --git a/src/julia.h b/src/julia.h index 77a95bf625b80..9d3e177544af4 100644 --- a/src/julia.h +++ b/src/julia.h @@ -3,6 +3,19 @@ #ifndef JULIA_H #define JULIA_H +#ifdef __cplusplus +extern "C" { +#endif + +extern int mmtk_object_is_managed_by_mmtk(void* addr); +extern unsigned char mmtk_pin_object(void* obj); +#define PTRHASH_PIN(key) \ + mmtk_pin_object(key); \ + +#ifdef __cplusplus +} +#endif + #if defined(JL_LIBRARY_EXPORTS_INTERNAL) || defined(JL_LIBRARY_EXPORTS_CODEGEN) #define JL_LIBRARY_EXPORTS #endif diff --git a/src/julia_internal.h b/src/julia_internal.h index cbd0bf7750251..c3588b6518816 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -535,7 +535,9 @@ JL_DLLEXPORT uintptr_t jl_get_buff_tag(void); typedef void jl_gc_tracked_buffer_t; // For the benefit of the static analyzer STATIC_INLINE jl_gc_tracked_buffer_t *jl_gc_alloc_buf(jl_ptls_t ptls, size_t sz) { - return jl_gc_alloc(ptls, sz, (void*)jl_buff_tag); + jl_gc_tracked_buffer_t *buf = jl_gc_alloc(ptls, sz, (void*)jl_buff_tag); + mmtk_pin_object(buf); + return buf; } STATIC_INLINE jl_value_t *jl_gc_permobj(size_t sz, void *ty) JL_NOTSAFEPOINT diff --git a/src/runtime_ccall.cpp b/src/runtime_ccall.cpp index 23793254c205d..cac9270c72556 100644 --- a/src/runtime_ccall.cpp +++ b/src/runtime_ccall.cpp @@ -352,6 +352,8 @@ jl_value_t *jl_get_cfunction_trampoline( tramp = trampoline_alloc(); ((void**)result)[0] = tramp; tramp = init_trampoline(tramp, nval); + PTRHASH_PIN((void*)fobj) + PTRHASH_PIN(result) ptrhash_put(cache, (void*)fobj, result); uv_mutex_unlock(&trampoline_lock); return result; diff --git a/src/staticdata.c b/src/staticdata.c index 49b97480b5165..fba106ad632d3 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -655,6 +655,8 @@ static int needs_uniquing(jl_value_t *v) JL_NOTSAFEPOINT static void record_field_change(jl_value_t **addr, jl_value_t *newval) JL_NOTSAFEPOINT { + PTRHASH_PIN((void*)addr) + PTRHASH_PIN((void*)newval) ptrhash_put(&field_replace, (void*)addr, newval); } @@ -2137,6 +2139,8 @@ static jl_svec_t *jl_prune_type_cache_hash(jl_svec_t *cache) JL_GC_DISABLED assert(serialization_queue.items[(char*)idx - 1 - (char*)HT_NOTFOUND] == cache); cache = cache_rehash_set(cache, l); // redirect all references to the old cache to relocate to the new cache object + PTRHASH_PIN((void*)cache) + PTRHASH_PIN((void*)idx) ptrhash_put(&serialization_order, cache, idx); serialization_queue.items[(char*)idx - 1 - (char*)HT_NOTFOUND] = cache; return cache; @@ -2387,6 +2391,7 @@ static void jl_save_system_image_to_stream(ios_t *f, jl_array_t *mod_array, htable_new(&fptr_to_id, sizeof(id_to_fptrs) / sizeof(*id_to_fptrs)); uintptr_t i; for (i = 0; id_to_fptrs[i] != NULL; i++) { + PTRHASH_PIN((void*)(uintptr_t)id_to_fptrs[i]) ptrhash_put(&fptr_to_id, (void*)(uintptr_t)id_to_fptrs[i], (void*)(i + 2)); } htable_new(&serialization_order, 25000); @@ -2473,6 +2478,7 @@ static void jl_save_system_image_to_stream(ios_t *f, jl_array_t *mod_array, htable_new(&external_objects, NUM_TAGS); for (size_t i = 0; tags[i] != NULL; i++) { jl_value_t *tag = *tags[i]; + PTRHASH_PIN(tag) ptrhash_put(&external_objects, tag, tag); } // Queue the worklist itself as the first item we serialize @@ -3044,6 +3050,7 @@ static void jl_restore_system_image_from_stream_(ios_t *f, jl_image_t *image, jl assert(tag == 0); arraylist_push(&delay_list, pfld); arraylist_push(&delay_list, obj); + PTRHASH_PIN(obj) ptrhash_put(&new_dt_objs, (void*)obj, obj); // mark obj as invalid *pfld = (uintptr_t)NULL; continue; @@ -3077,6 +3084,8 @@ static void jl_restore_system_image_from_stream_(ios_t *f, jl_image_t *image, jl } static_assert(offsetof(jl_datatype_t, name) == 0, ""); newdt->name = dt->name; + PTRHASH_PIN(newdt) + PTRHASH_PIN(dt) ptrhash_put(&new_dt_objs, (void*)newdt, dt); } else { diff --git a/src/staticdata_utils.c b/src/staticdata_utils.c index bf1a830b608de..bc6502c134672 100644 --- a/src/staticdata_utils.c +++ b/src/staticdata_utils.c @@ -272,6 +272,7 @@ static void jl_collect_new_roots(jl_array_t *roots, jl_array_t *new_specializati assert(jl_is_code_instance(ci)); jl_method_t *m = ci->def->def.method; assert(jl_is_method(m)); + PTRHASH_PIN(m) ptrhash_put(&mset, (void*)m, (void*)m); } int nwithkey; @@ -434,6 +435,7 @@ static void jl_collect_edges(jl_array_t *edges, jl_array_t *ext_targets, jl_arra for (size_t i = 0; i < jl_array_len(external_cis); i++) { jl_code_instance_t *ci = (jl_code_instance_t*)jl_array_ptr_ref(external_cis, i); jl_method_instance_t *mi = ci->def; + PTRHASH_PIN(mi) ptrhash_put(&external_mis, (void*)mi, (void*)mi); } } @@ -469,6 +471,8 @@ static void jl_collect_edges(jl_array_t *edges, jl_array_t *ext_targets, jl_arra for (size_t i = 0; i < l / 2; i++) { jl_method_instance_t *caller = (jl_method_instance_t*)jl_array_ptr_ref(edges, i * 2); void *target = (void*)((char*)HT_NOTFOUND + i + 1); + PTRHASH_PIN(caller) + PTRHASH_PIN(target) ptrhash_put(&edges_ids, (void*)caller, target); } // process target list to turn it into a memoized validity table @@ -545,6 +549,8 @@ static void jl_collect_edges(jl_array_t *edges, jl_array_t *ext_targets, jl_arra jl_array_ptr_1d_push(ext_targets, callee); jl_array_ptr_1d_push(ext_targets, matches); target = (void*)((char*)HT_NOTFOUND + jl_array_len(ext_targets) / 3); + PTRHASH_PIN(callee) + PTRHASH_PIN(target) ptrhash_put(&edges_map2, (void*)callee, target); } idxs[++nt] = (char*)target - (char*)HT_NOTFOUND - 1; @@ -1090,6 +1096,8 @@ static void jl_insert_backedges(jl_array_t *edges, jl_array_t *ext_targets, jl_a jl_code_instance_t *ci = (jl_code_instance_t*)jl_array_ptr_ref(ci_list, i); assert(ci->min_world == minworld); if (ci->max_world == 1) { // sentinel value: has edges to external callables + PTRHASH_PIN((void*)ci->def) + PTRHASH_PIN((void*)ci) ptrhash_put(&visited, (void*)ci->def, (void*)ci); } else { @@ -1155,6 +1163,7 @@ static void classify_callers(htable_t *callers_with_edges, jl_array_t *edges) size_t l = edges ? jl_array_len(edges) / 2 : 0; for (size_t i = 0; i < l; i++) { jl_method_instance_t *caller = (jl_method_instance_t*)jl_array_ptr_ref(edges, 2 * i); + PTRHASH_PIN((void*)caller) ptrhash_put(callers_with_edges, (void*)caller, (void*)caller); } } diff --git a/src/toplevel.c b/src/toplevel.c index 200d0ad220231..8a72ce8e6c2e6 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -140,6 +140,8 @@ static jl_value_t *jl_eval_module_expr(jl_module_t *parent_module, jl_expr_t *ex jl_value_t *form = (jl_value_t*)newm; JL_GC_PUSH1(&form); JL_LOCK(&jl_modules_mutex); + PTRHASH_PIN(newm) + PTRHASH_PIN((void*)((uintptr_t)HT_NOTFOUND + 1)) ptrhash_put(&jl_current_modules, (void*)newm, (void*)((uintptr_t)HT_NOTFOUND + 1)); JL_UNLOCK(&jl_modules_mutex); From 2f21eecf4c9a9156022fb4ebd18e774a3a293c57 Mon Sep 17 00:00:00 2001 From: Eduardo Souza Date: Mon, 7 Aug 2023 01:06:17 +0000 Subject: [PATCH 2/8] Pushing current task into the stack to set as red root; pin string when realloc-ing if pinned; removing static from functions needed to sweep live_tasks array --- src/gc-stacks.c | 4 ++-- src/mmtk-gc.c | 3 +++ src/task.c | 2 ++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/gc-stacks.c b/src/gc-stacks.c index b35c1722c82ff..9e8b71ac442fc 100644 --- a/src/gc-stacks.c +++ b/src/gc-stacks.c @@ -66,7 +66,7 @@ static void *malloc_stack(size_t bufsz) JL_NOTSAFEPOINT return stk; } -static void free_stack(void *stkbuf, size_t bufsz) +void free_stack(void *stkbuf, size_t bufsz) { munmap(stkbuf, bufsz); jl_atomic_fetch_add(&num_stack_mappings, -1); @@ -104,7 +104,7 @@ static unsigned select_pool(size_t nb) JL_NOTSAFEPOINT } -static void _jl_free_stack(jl_ptls_t ptls, void *stkbuf, size_t bufsz) +void _jl_free_stack(jl_ptls_t ptls, void *stkbuf, size_t bufsz) { #ifdef _COMPILER_ASAN_ENABLED_ __asan_unpoison_stack_memory((uintptr_t)stkbuf, bufsz); diff --git a/src/mmtk-gc.c b/src/mmtk-gc.c index baa5d6642721d..d8bae88fc56a1 100644 --- a/src/mmtk-gc.c +++ b/src/mmtk-gc.c @@ -428,6 +428,9 @@ jl_value_t *jl_gc_realloc_string(jl_value_t *s, size_t sz) size_t len = jl_string_len(s); jl_value_t *snew = jl_alloc_string(sz); memcpy(jl_string_data(snew), jl_string_data(s), sz <= len ? sz : len); + if(mmtk_is_pinned(s)) { + mmtk_pin_object(snew); + } return snew; } diff --git a/src/task.c b/src/task.c index 477ae481071a0..267f7448fa52a 100644 --- a/src/task.c +++ b/src/task.c @@ -1207,6 +1207,7 @@ CFI_NORETURN jl_task_t *ct = jl_get_current_task(); #else jl_task_t *ct = jl_current_task; + JL_GC_PUSH1(&ct); #endif jl_ptls_t ptls = ct->ptls; jl_value_t *res; @@ -1247,6 +1248,7 @@ skip_pop_exception:; ct->result = res; jl_gc_wb(ct, ct->result); jl_finish_task(ct); + JL_GC_POP(); jl_gc_debug_critical_error(); abort(); } From 5fe96d76427b48cc07df3165b339bc0db9522dd7 Mon Sep 17 00:00:00 2001 From: Eduardo Souza Date: Wed, 9 Aug 2023 01:15:56 +0000 Subject: [PATCH 3/8] Fixing issue that prevented building Julia or running tests with Julia's debug build --- Makefile | 2 +- src/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 3e4dbef73bb52..cfa5af6052db9 100644 --- a/Makefile +++ b/Makefile @@ -119,7 +119,7 @@ check-whitespace: ifneq ($(NO_GIT), 1) @# Append the directory containing the julia we just built to the end of `PATH`, @# to give us the best chance of being able to run this check. - @PATH="$(PATH):$(dir $(JULIA_EXECUTABLE))" julia $(call cygpath_w,$(JULIAHOME)/contrib/check-whitespace.jl) + @PATH="$(PATH):$(dir $(JULIA_EXECUTABLE))" $(JULIA_EXECUTABLE) $(call cygpath_w,$(JULIAHOME)/contrib/check-whitespace.jl) else $(warn "Skipping whitespace check because git is unavailable") endif diff --git a/src/Makefile b/src/Makefile index ff5f4ce8b99d6..63654f35026e9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -176,7 +176,7 @@ DOBJS := $(SRCS:%=$(BUILDDIR)/%.dbg.obj) ifeq ($(WITH_MMTK), 1) MMTK_SRCS := mmtk_julia MMTK_OBJS := $(MMTK_SRCS:%=$(MMTK_JULIA_INC)/%.o) $(MMTK_LIB_DST) -MMTK_DOBJS := $(MMTK_SRCS:%=$(MMTK_JULIA_INC)/%.dbg.obj) +MMTK_DOBJS := $(MMTK_SRCS:%=$(MMTK_JULIA_INC)/%.dbg.obj) $(MMTK_LIB_DST) else MMTK_OBJS := MMTK_DOBJS := From 7985bb2f37817a5ec29a34da7f2a140a5c9192d9 Mon Sep 17 00:00:00 2001 From: Eduardo Souza Date: Tue, 22 Aug 2023 01:40:26 +0000 Subject: [PATCH 4/8] Fixing issue when setting up the number of stock GC threads - it should be 0 when using MMTk --- src/mmtk-gc.c | 5 +++-- src/threading.c | 11 ++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/mmtk-gc.c b/src/mmtk-gc.c index d8bae88fc56a1..db2ce338529b5 100644 --- a/src/mmtk-gc.c +++ b/src/mmtk-gc.c @@ -350,8 +350,9 @@ void jl_gc_init(void) max_heap_size = uv_get_free_memory() * 70 / 100; } - // If the two values are the same, we can use either. Otherwise, we need to be careful. - assert(jl_n_gcthreads == jl_options.ngcthreads); + // when using mmtk, we don't spawn any stock GC thread + // and mmtk should use jl_options.ngcthreads to set the number of workers + assert(jl_n_gcthreads == 0); // Check that the julia_copy_stack rust feature has been defined when the COPY_STACK has been defined int copy_stacks; diff --git a/src/threading.c b/src/threading.c index d58528fa183be..ddb4850aa074c 100644 --- a/src/threading.c +++ b/src/threading.c @@ -667,6 +667,12 @@ void jl_init_threading(void) } } +#ifdef MMTK_GC + // MMTk gets the number of GC threads from jl_options.ngcthreads, and spawn its GC threads. + // So we just set ngcthreads to 0 here to avoid spawning any GC threads in Julia. + ngcthreads = 0; +#endif + jl_all_tls_states_size = nthreads + nthreadsi + ngcthreads; jl_n_threads_per_pool = (int*)malloc_s(2 * sizeof(int)); jl_n_threads_per_pool[0] = nthreadsi; @@ -684,11 +690,6 @@ void jl_start_threads(void) { int nthreads = jl_atomic_load_relaxed(&jl_n_threads); int ngcthreads = jl_n_gcthreads; -#ifdef MMTK_GC - // MMTk gets the number of GC threads from jl_options.ngcthreads, and spawn its GC threads. - // So we just set ngcthreads to 0 here to avoid spawning any GC threads in Julia. - ngcthreads = 0; -#endif int cpumasksize = uv_cpumask_size(); char *cp; int i, exclusive; From f9da153bddb2b494feb3cd1840021ea574aa7f36 Mon Sep 17 00:00:00 2001 From: Luis Eduardo de Souza Amorim Date: Fri, 15 Sep 2023 06:49:02 +0000 Subject: [PATCH 5/8] Checking if object is managed by mmtk before calling pin function; Pinning owner to avoid introspecting it during scanning --- src/array.c | 9 +++++++++ src/julia.h | 2 ++ 2 files changed, 11 insertions(+) diff --git a/src/array.c b/src/array.c index 8a064583bbc9e..7c49889ee4662 100644 --- a/src/array.c +++ b/src/array.c @@ -239,6 +239,9 @@ JL_DLLEXPORT jl_array_t *jl_reshape_array(jl_value_t *atype, jl_array_t *data, jl_array_t *owner = (jl_array_t*)jl_array_owner(data); jl_array_data_owner(a) = (jl_value_t*)owner; + if(mmtk_object_is_managed_by_mmtk(owner)) { + mmtk_pin_object(owner); + } a->flags.how = 3; a->data = data->data; a->flags.isshared = 1; @@ -287,6 +290,9 @@ JL_DLLEXPORT jl_array_t *jl_string_to_array(jl_value_t *str) a->flags.ptrarray = 0; a->flags.hasptr = 0; jl_array_data_owner(a) = str; + if(mmtk_object_is_managed_by_mmtk(str)) { + mmtk_pin_object(str); + } a->flags.how = 3; a->flags.isshared = 1; size_t l = jl_string_len(str); @@ -683,6 +689,9 @@ static int NOINLINE array_resize_buffer(jl_array_t *a, size_t newlen) else { s = jl_gc_realloc_string(jl_array_data_owner(a), nbytes - (elsz == 1)); } + if(mmtk_object_is_managed_by_mmtk(s)) { + mmtk_pin_object(s); + } jl_array_data_owner(a) = s; jl_gc_wb(a, s); a->data = jl_string_data(s); diff --git a/src/julia.h b/src/julia.h index 87e965bdae621..337e5131eeee7 100644 --- a/src/julia.h +++ b/src/julia.h @@ -10,7 +10,9 @@ extern "C" { extern int mmtk_object_is_managed_by_mmtk(void* addr); extern unsigned char mmtk_pin_object(void* obj); #define PTRHASH_PIN(key) \ + if (mmtk_object_is_managed_by_mmtk(key)) { \ mmtk_pin_object(key); \ + } \ #ifdef __cplusplus } From cfb6d90e1fcba32a088f073ebf71ac6a98f2cf1d Mon Sep 17 00:00:00 2001 From: Luis Eduardo de Souza Amorim Date: Fri, 15 Sep 2023 06:54:26 +0000 Subject: [PATCH 6/8] Fixing duplicate code from merging mistake --- src/threading.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/threading.c b/src/threading.c index 8d13788fe657c..d1157a02dada0 100644 --- a/src/threading.c +++ b/src/threading.c @@ -694,12 +694,6 @@ void jl_init_threading(void) } int16_t ngcthreads = jl_n_markthreads + jl_n_sweepthreads; -#ifdef MMTK_GC - // MMTk gets the number of GC threads from jl_options.ngcthreads, and spawn its GC threads. - // So we just set ngcthreads to 0 here to avoid spawning any GC threads in Julia. - ngcthreads = 0; -#endif - #ifdef MMTK_GC // MMTk gets the number of GC threads from jl_options.ngcthreads, and spawn its GC threads. // So we just set ngcthreads to 0 here to avoid spawning any GC threads in Julia. From a0c895ee0ff25b751475c3015ed82cd84c058b0e Mon Sep 17 00:00:00 2001 From: Eduardo Souza Date: Fri, 9 Feb 2024 01:41:50 +0000 Subject: [PATCH 7/8] Increasing the timeout just in case it's caused by the github runner specs --- test/threads.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/threads.jl b/test/threads.jl index 8189311739e31..376c77347e15f 100644 --- a/test/threads.jl +++ b/test/threads.jl @@ -288,7 +288,7 @@ close(proc.in) proc = run(cmd; wait = false) done = Threads.Atomic{Bool}(false) timeout = false - timer = Timer(100) do _ + timer = Timer(150) do _ timeout = true for sig in [Base.SIGTERM, Base.SIGHUP, Base.SIGKILL] for _ in 1:1000 From 3b4ae537216b59ccaded4f7b946dc7faf2a27bb5 Mon Sep 17 00:00:00 2001 From: Eduardo Souza Date: Mon, 12 Feb 2024 02:52:56 +0000 Subject: [PATCH 8/8] Refactoring pinning functions and adding comments --- src/array.c | 24 +++++++++++++++--------- src/builtins.c | 19 ++++++++++--------- src/datatype.c | 4 ++++ src/julia.h | 4 ++-- src/julia_internal.h | 4 ++++ src/mmtk-gc.c | 1 + 6 files changed, 36 insertions(+), 20 deletions(-) diff --git a/src/array.c b/src/array.c index 7c49889ee4662..73ba4cc0e8214 100644 --- a/src/array.c +++ b/src/array.c @@ -239,9 +239,11 @@ JL_DLLEXPORT jl_array_t *jl_reshape_array(jl_value_t *atype, jl_array_t *data, jl_array_t *owner = (jl_array_t*)jl_array_owner(data); jl_array_data_owner(a) = (jl_value_t*)owner; - if(mmtk_object_is_managed_by_mmtk(owner)) { - mmtk_pin_object(owner); - } + // For array objects with an owner point (a->flags.how == 3), we would need to + // introspect the object to update the a->data field. To avoid doing that and + // making scan_object much more complex we simply enforce that both owner and + // buffers are always pinned + mmtk_pin_object(owner); a->flags.how = 3; a->data = data->data; a->flags.isshared = 1; @@ -290,9 +292,11 @@ JL_DLLEXPORT jl_array_t *jl_string_to_array(jl_value_t *str) a->flags.ptrarray = 0; a->flags.hasptr = 0; jl_array_data_owner(a) = str; - if(mmtk_object_is_managed_by_mmtk(str)) { - mmtk_pin_object(str); - } + // For array objects with an owner point (a->flags.how == 3), we would need to + // introspect the object to update the a->data field. To avoid doing that and + // making scan_object much more complex we simply enforce that both owner and + // buffers are always pinned + mmtk_pin_object(str); a->flags.how = 3; a->flags.isshared = 1; size_t l = jl_string_len(str); @@ -689,9 +693,11 @@ static int NOINLINE array_resize_buffer(jl_array_t *a, size_t newlen) else { s = jl_gc_realloc_string(jl_array_data_owner(a), nbytes - (elsz == 1)); } - if(mmtk_object_is_managed_by_mmtk(s)) { - mmtk_pin_object(s); - } + // For array objects with an owner point (a->flags.how == 3), we would need to + // introspect the object to update the a->data field. To avoid doing that and + // making scan_object much more complex we simply enforce that both owner and + // buffers are always pinned + mmtk_pin_object(s); jl_array_data_owner(a) = s; jl_gc_wb(a, s); a->data = jl_string_data(s); diff --git a/src/builtins.c b/src/builtins.c index 0094f4e5a2141..0a2cc9cd42729 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -344,9 +344,9 @@ static uintptr_t type_object_id_(jl_value_t *v, jl_varidx_t *env) JL_NOTSAFEPOIN i++; pe = pe->prev; } - if(mmtk_object_is_managed_by_mmtk(v)) { - mmtk_pin_object(v); - } + // FIXME: Pinning objects that get hashed + // until we implement address space hashing. + mmtk_pin_object(v); return inthash((uintptr_t)v); } if (tv == jl_uniontype_type) { @@ -395,9 +395,10 @@ static uintptr_t immut_id_(jl_datatype_t *dt, jl_value_t *v, uintptr_t h) JL_NOT return ~h; size_t f, nf = jl_datatype_nfields(dt); if (nf == 0 || (!dt->layout->haspadding && dt->layout->npointers == 0)) { - if(mmtk_object_is_managed_by_mmtk(v)) { - mmtk_pin_object(v); - } + + // FIXME: Pinning objects that get hashed + // until we implement address space hashing. + mmtk_pin_object(v); // operate element-wise if there are unused bits inside, // otherwise just take the whole data block at once // a few select pointers (notably symbol) also have special hash values @@ -459,9 +460,9 @@ static uintptr_t NOINLINE jl_object_id__cold(jl_datatype_t *dt, jl_value_t *v) J return m->hash; } if (dt->name->mutabl) { - if(mmtk_object_is_managed_by_mmtk(v)) { - mmtk_pin_object(v); - } + // FIXME: Pinning objects that get hashed + // until we implement address space hashing. + mmtk_pin_object(v); return inthash((uintptr_t)v); } return immut_id_(dt, v, dt->hash); diff --git a/src/datatype.c b/src/datatype.c index 20c3af1555675..9e6d480985c69 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -65,6 +65,8 @@ JL_DLLEXPORT jl_typename_t *jl_new_typename_in(jl_sym_t *name, jl_module_t *modu jl_typename_t *tn = (jl_typename_t*)jl_gc_alloc(ct->ptls, sizeof(jl_typename_t), jl_typename_type); + // Typenames should be pinned since they are used as metadata, and are + // read during scan_object mmtk_pin_object(tn); tn->name = name; tn->module = module; @@ -97,6 +99,8 @@ jl_datatype_t *jl_new_uninitialized_datatype(void) { jl_task_t *ct = jl_current_task; jl_datatype_t *t = (jl_datatype_t*)jl_gc_alloc(ct->ptls, sizeof(jl_datatype_t), jl_datatype_type); + // Types should be pinned since they are used as metadata, and are + // read during scan_object mmtk_pin_object(t); jl_set_typetagof(t, jl_datatype_tag, 0); t->hash = 0; diff --git a/src/julia.h b/src/julia.h index 337e5131eeee7..3a33e59e3835a 100644 --- a/src/julia.h +++ b/src/julia.h @@ -9,10 +9,10 @@ extern "C" { extern int mmtk_object_is_managed_by_mmtk(void* addr); extern unsigned char mmtk_pin_object(void* obj); +// FIXME: Pinning objects that get hashed in the ptrhash table +// until we implement address space hashing. #define PTRHASH_PIN(key) \ - if (mmtk_object_is_managed_by_mmtk(key)) { \ mmtk_pin_object(key); \ - } \ #ifdef __cplusplus } diff --git a/src/julia_internal.h b/src/julia_internal.h index 4f90b44c80887..90e6dd6ce1ec1 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -533,6 +533,10 @@ typedef void jl_gc_tracked_buffer_t; // For the benefit of the static analyzer STATIC_INLINE jl_gc_tracked_buffer_t *jl_gc_alloc_buf(jl_ptls_t ptls, size_t sz) { jl_gc_tracked_buffer_t *buf = jl_gc_alloc(ptls, sz, (void*)jl_buff_tag); + // For array objects with an owner point (a->flags.how == 3), we would need to + // introspect the object to update the a->data field. To avoid doing that and + // making scan_object much more complex we simply enforce that both owner and + // buffers are always pinned mmtk_pin_object(buf); return buf; } diff --git a/src/mmtk-gc.c b/src/mmtk-gc.c index 9d8b0f049e11d..05989a6ac335d 100644 --- a/src/mmtk-gc.c +++ b/src/mmtk-gc.c @@ -432,6 +432,7 @@ jl_value_t *jl_gc_realloc_string(jl_value_t *s, size_t sz) jl_value_t *snew = jl_alloc_string(sz); memcpy(jl_string_data(snew), jl_string_data(s), sz <= len ? sz : len); if(mmtk_is_pinned(s)) { + // if the source string was pinned, we also pin the new one mmtk_pin_object(snew); } return snew;