Skip to content

Commit

Permalink
Merge pull request mmtk#27 from udesou/feature/rb-roots
Browse files Browse the repository at this point in the history
Changes to support moving immix
  • Loading branch information
udesou committed Feb 13, 2024
1 parent 874179e commit 5a812ad
Show file tree
Hide file tree
Showing 14 changed files with 91 additions and 4 deletions.
15 changes: 15 additions & 0 deletions src/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +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;

// 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;
Expand Down Expand Up @@ -287,6 +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;
// 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);
Expand Down Expand Up @@ -683,6 +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));
}
// 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);
Expand Down
13 changes: 12 additions & 1 deletion src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,9 @@ static uintptr_t type_object_id_(jl_value_t *v, jl_varidx_t *env) JL_NOTSAFEPOIN
i++;
pe = pe->prev;
}
// 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) {
Expand Down Expand Up @@ -358,6 +361,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)) {

// 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
Expand Down Expand Up @@ -414,8 +421,12 @@ static uintptr_t NOINLINE jl_object_id__cold(jl_datatype_t *dt, jl_value_t *v) J
return memhash32_seed(jl_string_data(v), jl_string_len(v), 0xedc3b677);
#endif
}
if (dt->name->mutabl)
if (dt->name->mutabl) {
// 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);
}

Expand Down
6 changes: 6 additions & 0 deletions src/datatype.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ 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;
tn->wrapper = NULL;
Expand Down Expand Up @@ -96,6 +99,9 @@ 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);
t->hash = 0;
t->hasfreetypevars = 0;
t->isdispatchtuple = 0;
Expand Down
2 changes: 2 additions & 0 deletions src/interpreter.c
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,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_typeis(stmts, jl_array_any_type));
s->src = src;
s->module = m;
Expand All @@ -763,6 +764,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;
}

Expand Down
5 changes: 4 additions & 1 deletion src/ircode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1145,12 +1145,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;
Expand Down
16 changes: 16 additions & 0 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,22 @@
#define JULIA_H

#ifdef LIBRARY_EXPORTS

#ifdef __cplusplus
extern "C" {
#endif

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) \
mmtk_pin_object(key); \

#ifdef __cplusplus
}
#endif

// Generated file, needs to be searched in include paths so that the builddir
// retains priority
#include <jl_internal_funcs.inc>
Expand Down
8 changes: 7 additions & 1 deletion src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,13 @@ 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);
// 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;
}

STATIC_INLINE jl_value_t *jl_gc_permobj(size_t sz, void *ty) JL_NOTSAFEPOINT
Expand Down
4 changes: 4 additions & 0 deletions src/mmtk-gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,10 @@ 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)) {
// if the source string was pinned, we also pin the new one
mmtk_pin_object(snew);
}
return snew;
}

Expand Down
2 changes: 2 additions & 0 deletions src/runtime_ccall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,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;
Expand Down
9 changes: 9 additions & 0 deletions src/staticdata.c
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,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);
}

Expand Down Expand Up @@ -2197,6 +2199,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;
Expand Down Expand Up @@ -2442,6 +2446,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);
Expand Down Expand Up @@ -2529,6 +2534,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
Expand Down Expand Up @@ -3083,6 +3089,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;
Expand Down Expand Up @@ -3116,6 +3123,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 {
Expand Down
9 changes: 9 additions & 0 deletions src/staticdata_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -428,6 +429,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);
}
}
Expand Down Expand Up @@ -463,6 +465,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
Expand Down Expand Up @@ -534,6 +538,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;
Expand Down Expand Up @@ -1070,6 +1076,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 {
Expand Down Expand Up @@ -1135,6 +1143,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);
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -1062,6 +1062,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;
Expand Down Expand Up @@ -1101,6 +1102,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();
}
Expand Down
2 changes: 2 additions & 0 deletions src/toplevel.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,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);

Expand Down
2 changes: 1 addition & 1 deletion test/threads.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 5a812ad

Please sign in to comment.