From b76c7c73ec4f8c6294e1982749460b92ffe40e74 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Mon, 27 Mar 2017 15:28:26 -0400 Subject: [PATCH] enable GC sooner when loading precompiled modules part of #20671 --- src/dump.c | 35 +++++++++++++++++++++++++++++++++-- src/gc.c | 8 ++++++++ src/gc.h | 1 + src/julia_internal.h | 1 + 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/dump.c b/src/dump.c index 64d21ee2e04a0..865108718a42c 100644 --- a/src/dump.c +++ b/src/dump.c @@ -2123,6 +2123,18 @@ static void jl_insert_methods(linkedlist_t *list) } } +static void linkedlist_to_array(jl_array_t *a, linkedlist_t *list) +{ + while (list) { + size_t i; + for (i = 0; i < list->count; i++) { + jl_array_ptr_1d_push(a, (jl_value_t*)list->def[i].meth); + jl_array_ptr_1d_push(a, (jl_value_t*)list->def[i].simpletype); + } + list = list->next; + } +} + static void jl_insert_backedges(linkedlist_t *list) { while (list) { @@ -3047,6 +3059,20 @@ static int trace_method(jl_typemap_entry_t *entry, void *closure) return 1; } +void jl_gc_mark_deserializer_state(jl_ptls_t ptls) +{ + size_t i; + for (i=0; i < flagref_list.len; ) { + jl_value_t **loc = (jl_value_t**)flagref_list.items[i]; + if (loc) + jl_gc_push_root(ptls, *loc); + i += 2; + } + for (i=0; i < backref_list.len; i++) { + jl_gc_push_root(ptls, (jl_value_t*)backref_list.items[i]); + } +} + static jl_value_t *_jl_restore_incremental(ios_t *f) { if (ios_eof(f) || !jl_read_verify_header(f)) { @@ -3100,14 +3126,19 @@ static jl_value_t *_jl_restore_incremental(ios_t *f) // now all of the interconnects will be created jl_recache_types(); // make all of the types identities correct init_order = jl_finalize_deserializer(&s, tracee_list); // done with f and s (needs to be after recache types) + + jl_array_t *extmeths = jl_alloc_vec_any(0); // make array of references for GC + linkedlist_to_array(extmeths, &external_methods); + + JL_GC_PUSH3(&init_order, &restored, &extmeths); + jl_gc_enable(en); + jl_insert_methods(&external_methods); // hook up methods of external generic functions (needs to be after recache types) jl_recache_other(); // make all of the other objects identities correct (needs to be after insert methods) jl_insert_backedges(&external_methods); // restore external backedges (needs to be after recache other) free_linkedlist(external_methods.next); serializer_worklist = NULL; - JL_GC_PUSH2(&init_order, &restored); - jl_gc_enable(en); arraylist_free(&flagref_list); arraylist_free(&backref_list); ios_close(f); diff --git a/src/gc.c b/src/gc.c index 411510710d7ca..8181e2906f336 100644 --- a/src/gc.c +++ b/src/gc.c @@ -1321,6 +1321,11 @@ NOINLINE static int gc_mark_module(jl_ptls_t ptls, jl_module_t *m, return refyoung; } +void jl_gc_push_root(jl_ptls_t ptls, jl_value_t *v) +{ + gc_push_root(ptls, v, 0); +} + // Handle the case where the stack is only partially copied. STATIC_INLINE uintptr_t gc_get_stack_addr(void *_addr, uintptr_t offset, uintptr_t lb, uintptr_t ub) @@ -1674,6 +1679,9 @@ static void mark_roots(jl_ptls_t ptls) // constants gc_push_root(ptls, jl_typetype_type, 0); gc_push_root(ptls, jl_emptytuple_type, 0); + + // deserializer state during module reload + jl_gc_mark_deserializer_state(ptls); } // find unmarked objects that need to be finalized from the finalizer list "list". diff --git a/src/gc.h b/src/gc.h index f49bc4f13be87..d2a7e21b1070e 100644 --- a/src/gc.h +++ b/src/gc.h @@ -281,6 +281,7 @@ void gc_mark_object_list(jl_ptls_t ptls, arraylist_t *list, size_t start); void visit_mark_stack(jl_ptls_t ptls); void gc_debug_init(void); void jl_mark_box_caches(jl_ptls_t ptls); +void jl_gc_mark_deserializer_state(jl_ptls_t ptls); // GC pages diff --git a/src/julia_internal.h b/src/julia_internal.h index b5d5139bcced4..a7cf872ac5fda 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -350,6 +350,7 @@ jl_tupletype_t *jl_argtype_with_function(jl_function_t *f, jl_tupletype_t *types JL_DLLEXPORT jl_value_t *jl_apply_2va(jl_value_t *f, jl_value_t **args, uint32_t nargs); void jl_gc_setmark(jl_ptls_t ptls, jl_value_t *v); +void jl_gc_push_root(jl_ptls_t ptls, jl_value_t *v); void jl_gc_sync_total_bytes(void); void jl_gc_track_malloced_array(jl_ptls_t ptls, jl_array_t *a); void jl_gc_count_allocd(size_t sz);