From 8320da593dcc8fa9e99e63bc9c6d4857fc4367ae Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Wed, 19 Aug 2015 10:23:36 +0300 Subject: [PATCH] Mark fo_head, finalize_now with a single GC_push_all call (code refactoring) * finalize.c (GC_fnlz_roots): New static variable. * finalize.c (GC_fo_head, GC_finalize_now): Move into GC_fnlz_roots (remove "GC_" prefix for field names). * finalize.c (GC_push_finalizer_structures): Replace GC_ASSERT and GC_PUSH_ALL_SYM for GC_fo_head, GC_finalize_now with a single GC_ASSERT and GC_PUSH_ALL_SYM for GC_fnlz_roots. * finalize.c (GC_register_finalizer_inner, GC_register_finalizer_unreachable, GC_finalize, GC_should_invoke_finalizers, GC_invoke_finalizers, GC_notify_or_invoke_finalizers): Replace access to GC_fo_head, GC_finalize_now with access to the corresponding field of GC_fnlz_roots. --- finalize.c | 103 +++++++++++++++++++++++++++-------------------------- 1 file changed, 52 insertions(+), 51 deletions(-) diff --git a/finalize.c b/finalize.c index beb0d613..dc5022ba 100644 --- a/finalize.c +++ b/finalize.c @@ -55,7 +55,7 @@ STATIC struct dl_hashtbl_s GC_dl_hashtbl = { STATIC struct dl_hashtbl_s GC_ll_hashtbl = { NULL, -1, 0 }; #endif -STATIC struct finalizable_object { +struct finalizable_object { struct hash_chain_entry prolog; # define fo_hidden_base prolog.hidden_key /* Pointer to object base. */ @@ -67,25 +67,26 @@ STATIC struct finalizable_object { ptr_t fo_client_data; word fo_object_size; /* In bytes. */ finalization_mark_proc fo_mark_proc; /* Mark-through procedure */ -} **GC_fo_head = 0; - -STATIC struct finalizable_object * GC_finalize_now = 0; - /* List of objects that should be finalized now. */ +}; static signed_word log_fo_table_size = -1; +STATIC struct { + struct finalizable_object **fo_head; + /* List of objects that should be finalized now: */ + struct finalizable_object *finalize_now; +} GC_fnlz_roots = { NULL, NULL }; + GC_API void GC_CALL GC_push_finalizer_structures(void) { GC_ASSERT((word)&GC_dl_hashtbl.head % sizeof(word) == 0); - GC_ASSERT((word)&GC_fo_head % sizeof(word) == 0); - GC_ASSERT((word)&GC_finalize_now % sizeof(word) == 0); + GC_ASSERT((word)&GC_fnlz_roots % sizeof(word) == 0); # ifndef GC_LONG_REFS_NOT_NEEDED GC_ASSERT((word)&GC_ll_hashtbl.head % sizeof(word) == 0); GC_PUSH_ALL_SYM(GC_ll_hashtbl.head); # endif GC_PUSH_ALL_SYM(GC_dl_hashtbl.head); - GC_PUSH_ALL_SYM(GC_fo_head); - GC_PUSH_ALL_SYM(GC_finalize_now); + GC_PUSH_ALL_SYM(GC_fnlz_roots); } /* Double the size of a hash table. *size_ptr is the log of its current */ @@ -466,7 +467,7 @@ STATIC void GC_register_finalizer_inner(void * obj, LOCK(); if (log_fo_table_size == -1 || GC_fo_entries > ((word)1 << log_fo_table_size)) { - GC_grow_table((struct hash_chain_entry ***)&GC_fo_head, + GC_grow_table((struct hash_chain_entry ***)&GC_fnlz_roots.fo_head, &log_fo_table_size); GC_COND_LOG_PRINTF("Grew fo table to %u entries\n", 1 << (unsigned)log_fo_table_size); @@ -476,7 +477,7 @@ STATIC void GC_register_finalizer_inner(void * obj, for (;;) { index = HASH2(base, log_fo_table_size); prev_fo = 0; - curr_fo = GC_fo_head[index]; + curr_fo = GC_fnlz_roots.fo_head[index]; while (curr_fo != 0) { GC_ASSERT(GC_size(curr_fo) >= sizeof(struct finalizable_object)); if (curr_fo -> fo_hidden_base == GC_HIDE_POINTER(base)) { @@ -487,7 +488,7 @@ STATIC void GC_register_finalizer_inner(void * obj, if (ofn) *ofn = curr_fo -> fo_fn; /* Delete the structure for base. */ if (prev_fo == 0) { - GC_fo_head[index] = fo_next(curr_fo); + GC_fnlz_roots.fo_head[index] = fo_next(curr_fo); } else { fo_set_next(prev_fo, fo_next(curr_fo)); } @@ -506,7 +507,7 @@ STATIC void GC_register_finalizer_inner(void * obj, /* Reinsert it. We deleted it first to maintain */ /* consistency in the event of a signal. */ if (prev_fo == 0) { - GC_fo_head[index] = curr_fo; + GC_fnlz_roots.fo_head[index] = curr_fo; } else { fo_set_next(prev_fo, curr_fo); } @@ -566,9 +567,9 @@ STATIC void GC_register_finalizer_inner(void * obj, new_fo -> fo_client_data = (ptr_t)cd; new_fo -> fo_object_size = hhdr -> hb_sz; new_fo -> fo_mark_proc = mp; - fo_set_next(new_fo, GC_fo_head[index]); + fo_set_next(new_fo, GC_fnlz_roots.fo_head[index]); GC_fo_entries++; - GC_fo_head[index] = new_fo; + GC_fnlz_roots.fo_head[index] = new_fo; UNLOCK(); } @@ -644,8 +645,8 @@ GC_API void GC_CALL GC_register_finalizer_unreachable(void * obj, # endif GC_printf("Finalizers:\n"); for (i = 0; i < fo_size; i++) { - for (curr_fo = GC_fo_head[i]; curr_fo != 0; - curr_fo = fo_next(curr_fo)) { + for (curr_fo = GC_fnlz_roots.fo_head[i]; + curr_fo != NULL; curr_fo = fo_next(curr_fo)) { real_ptr = GC_REVEAL_POINTER(curr_fo -> fo_hidden_base); GC_printf("Finalizable object: %p\n", real_ptr); } @@ -775,8 +776,8 @@ GC_INNER void GC_finalize(void) /* from finalizable objects. */ GC_ASSERT(GC_mark_state == MS_NONE); for (i = 0; i < fo_size; i++) { - for (curr_fo = GC_fo_head[i]; curr_fo != 0; - curr_fo = fo_next(curr_fo)) { + for (curr_fo = GC_fnlz_roots.fo_head[i]; + curr_fo != NULL; curr_fo = fo_next(curr_fo)) { GC_ASSERT(GC_size(curr_fo) >= sizeof(struct finalizable_object)); real_ptr = GC_REVEAL_POINTER(curr_fo -> fo_hidden_base); if (!GC_is_marked(real_ptr)) { @@ -792,7 +793,7 @@ GC_INNER void GC_finalize(void) /* unreachable. */ GC_bytes_finalized = 0; for (i = 0; i < fo_size; i++) { - curr_fo = GC_fo_head[i]; + curr_fo = GC_fnlz_roots.fo_head[i]; prev_fo = 0; while (curr_fo != 0) { real_ptr = GC_REVEAL_POINTER(curr_fo -> fo_hidden_base); @@ -802,8 +803,8 @@ GC_INNER void GC_finalize(void) } /* Delete from hash table */ next_fo = fo_next(curr_fo); - if (prev_fo == 0) { - GC_fo_head[i] = next_fo; + if (NULL == prev_fo) { + GC_fnlz_roots.fo_head[i] = next_fo; } else { fo_set_next(prev_fo, next_fo); } @@ -812,8 +813,8 @@ GC_INNER void GC_finalize(void) GC_object_finalized_proc(real_ptr); /* Add to list of objects awaiting finalization. */ - fo_set_next(curr_fo, GC_finalize_now); - GC_finalize_now = curr_fo; + fo_set_next(curr_fo, GC_fnlz_roots.finalize_now); + GC_fnlz_roots.finalize_now = curr_fo; /* unhide object pointer so any future collections will */ /* see it. */ curr_fo -> fo_hidden_base = @@ -833,8 +834,8 @@ GC_INNER void GC_finalize(void) if (GC_java_finalization) { /* make sure we mark everything reachable from objects finalized using the no_order mark_proc */ - for (curr_fo = GC_finalize_now; - curr_fo != NULL; curr_fo = fo_next(curr_fo)) { + for (curr_fo = GC_fnlz_roots.finalize_now; + curr_fo != NULL; curr_fo = fo_next(curr_fo)) { real_ptr = (ptr_t)curr_fo -> fo_hidden_base; if (!GC_is_marked(real_ptr)) { if (curr_fo -> fo_mark_proc == GC_null_finalize_mark_proc) { @@ -849,29 +850,29 @@ GC_INNER void GC_finalize(void) /* now revive finalize-when-unreachable objects reachable from other finalizable objects */ if (need_unreachable_finalization) { - curr_fo = GC_finalize_now; - prev_fo = 0; - while (curr_fo != 0) { + curr_fo = GC_fnlz_roots.finalize_now; + prev_fo = NULL; + while (curr_fo != NULL) { next_fo = fo_next(curr_fo); if (curr_fo -> fo_mark_proc == GC_unreachable_finalize_mark_proc) { real_ptr = (ptr_t)curr_fo -> fo_hidden_base; if (!GC_is_marked(real_ptr)) { GC_set_mark_bit(real_ptr); } else { - if (prev_fo == 0) - GC_finalize_now = next_fo; - else + if (NULL == prev_fo) { + GC_fnlz_roots.finalize_now = next_fo; + } else { fo_set_next(prev_fo, next_fo); - + } curr_fo -> fo_hidden_base = GC_HIDE_POINTER(curr_fo -> fo_hidden_base); GC_bytes_finalized -= curr_fo->fo_object_size + sizeof(struct finalizable_object); i = HASH2(real_ptr, log_fo_table_size); - fo_set_next (curr_fo, GC_fo_head[i]); + fo_set_next(curr_fo, GC_fnlz_roots.fo_head[i]); GC_fo_entries++; - GC_fo_head[i] = curr_fo; + GC_fnlz_roots.fo_head[i] = curr_fo; curr_fo = prev_fo; } } @@ -911,9 +912,9 @@ GC_INNER void GC_finalize(void) fo_size = log_fo_table_size == -1 ? 0 : 1 << log_fo_table_size; GC_bytes_finalized = 0; for (i = 0; i < fo_size; i++) { - curr_fo = GC_fo_head[i]; - prev_fo = 0; - while (curr_fo != 0) { + curr_fo = GC_fnlz_roots.fo_head[i]; + prev_fo = NULL; + while (curr_fo != NULL) { real_ptr = GC_REVEAL_POINTER(curr_fo -> fo_hidden_base); GC_MARK_FO(real_ptr, GC_normal_finalize_mark_proc); GC_set_mark_bit(real_ptr); @@ -921,15 +922,15 @@ GC_INNER void GC_finalize(void) /* Delete from hash table */ next_fo = fo_next(curr_fo); if (prev_fo == 0) { - GC_fo_head[i] = next_fo; + GC_fnlz_roots.fo_head[i] = next_fo; } else { - fo_set_next(prev_fo, next_fo); + fo_set_next(prev_fo, next_fo); } GC_fo_entries--; /* Add to list of objects awaiting finalization. */ - fo_set_next(curr_fo, GC_finalize_now); - GC_finalize_now = curr_fo; + fo_set_next(curr_fo, GC_fnlz_roots.finalize_now); + GC_fnlz_roots.finalize_now = curr_fo; /* unhide object pointer so any future collections will */ /* see it. */ @@ -981,7 +982,7 @@ GC_INNER void GC_finalize(void) /* getting into that safe state is expensive.) */ GC_API int GC_CALL GC_should_invoke_finalizers(void) { - return GC_finalize_now != 0; + return GC_fnlz_roots.finalize_now != NULL; } /* Invoke finalizers for all objects that are ready to be finalized. */ @@ -993,7 +994,7 @@ GC_API int GC_CALL GC_invoke_finalizers(void) word bytes_freed_before = 0; /* initialized to prevent warning. */ DCL_LOCK_STATE; - while (GC_finalize_now != 0) { + while (GC_fnlz_roots.finalize_now != NULL) { # ifdef THREADS LOCK(); # endif @@ -1001,13 +1002,13 @@ GC_API int GC_CALL GC_invoke_finalizers(void) bytes_freed_before = GC_bytes_freed; /* Don't do this outside, since we need the lock. */ } - curr_fo = GC_finalize_now; + curr_fo = GC_fnlz_roots.finalize_now; # ifdef THREADS - if (curr_fo != 0) GC_finalize_now = fo_next(curr_fo); + if (curr_fo != 0) GC_fnlz_roots.finalize_now = fo_next(curr_fo); UNLOCK(); if (curr_fo == 0) break; # else - GC_finalize_now = fo_next(curr_fo); + GC_fnlz_roots.finalize_now = fo_next(curr_fo); # endif fo_set_next(curr_fo, 0); (*(curr_fo -> fo_fn))((ptr_t)(curr_fo -> fo_hidden_base), @@ -1043,7 +1044,7 @@ GC_INNER void GC_notify_or_invoke_finalizers(void) # if defined(THREADS) && !defined(KEEP_BACK_PTRS) \ && !defined(MAKE_BACK_GRAPH) /* Quick check (while unlocked) for an empty finalization queue. */ - if (GC_finalize_now == 0) return; + if (NULL == GC_fnlz_roots.finalize_now) return; # endif LOCK(); @@ -1075,7 +1076,7 @@ GC_INNER void GC_notify_or_invoke_finalizers(void) # endif } # endif - if (GC_finalize_now == 0) { + if (NULL == GC_fnlz_roots.finalize_now) { UNLOCK(); return; } @@ -1088,7 +1089,7 @@ GC_INNER void GC_notify_or_invoke_finalizers(void) (void) GC_invoke_finalizers(); *pnested = 0; /* Reset since no more finalizers. */ # ifndef THREADS - GC_ASSERT(GC_finalize_now == 0); + GC_ASSERT(NULL == GC_fnlz_roots.finalize_now); # endif /* Otherwise GC can run concurrently and add more */ } return; @@ -1123,7 +1124,7 @@ GC_INNER void GC_notify_or_invoke_finalizers(void) (unsigned long)IF_LONG_REFS_PRESENT_ELSE( GC_ll_hashtbl.entries, 0)); - for (fo = GC_finalize_now; 0 != fo; fo = fo_next(fo)) + for (fo = GC_fnlz_roots.finalize_now; fo != NULL; fo = fo_next(fo)) ++ready; GC_log_printf("%lu finalization-ready objects;" " %ld/%ld short/long links cleared\n", -- 2.40.0