Mark fo_head, finalize_now with a single GC_push_all call
authorIvan Maidanski <ivmai@mail.ru>
Wed, 19 Aug 2015 07:23:36 +0000 (10:23 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Wed, 26 Aug 2015 08:47:48 +0000 (11:47 +0300)
(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

index beb0d61..dc5022b 100644 (file)
@@ -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",