]> granicus.if.org Git - gc/commitdiff
Refactoring of GC_Xobjfreelist
authorAlessandro Bruni <alessandro.bruni@gmail.com>
Tue, 5 Jan 2016 07:51:52 +0000 (10:51 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 5 Jan 2016 07:51:52 +0000 (10:51 +0300)
(use single array to keep free lists of all kinds)

* alloc.c: Update comment (replace GC_objfreelist with
GC_freelists[NORMAL]).
* checksums.c (GC_on_free_list): Replace GC_sobjfreelist with
GC_freelists[STUBBORN].
* mark.c (GC_obj_kinds): Likewise.
* include/private/gc_priv.h (PTRFREE, NORMAL, UNCOLLECTABLE,
AUNCOLLECTABLE, STUBBORN, IS_UNCOLLECTABLE): Move definition upper to
be before _GC_arrays declaration.
* include/private/gc_priv.h (PREDEFINED_KINDS): New macro.
* include/private/gc_priv.h (GC_freelists): New macro (of global
variable if SEPARATE_GLOBALS).
* include/private/gc_priv.h (_GC_arrays): Replace _objfreelist,
_aobjfreelist, _uobjfreelist, _auobjfreelist, _sobjfreelist fields
with single _freelists[] field.
* include/private/gc_priv.h (GC_objfreelist, GC_aobjfreelist,
GC_auobjfreelist, GC_sobjfreelist, GC_uobjfreelist,
beginGC_objfreelist, endGC_objfreelist, beginGC_aobjfreelist,
endGC_aobjfreelist): Remove macro.
* include/private/gc_priv.h (GC_objfreelist, GC_aobjfreelist): Replace
variable declarations with single GC_freelists[] one (if
SEPARATE_GLOBALS).
* malloc.c (GC_malloc_atomic): Replace GC_aobjfreelist with
GC_freelists[PTRFREE].
* mallocx.c (GC_aobjfreelist_ptr): Likewise.
* mark.c (GC_obj_kinds): Likewise.
* thread_local_alloc.c (GC_destroy_thread_local): Likewise.
* malloc.c (GC_malloc): Replace GC_objfreelist with
GC_freelists[NORMAL].
* mallocx.c (GC_objfreelist_ptr): Likewise.
* mark.c (GC_obj_kinds): Likewise.
* thread_local_alloc.c (GC_destroy_thread_local): Likewise.
* malloc.c (GC_malloc_uncollectable): Replace GC_uobjfreelist with
GC_freelists[UNCOLLECTABLE].
* mallocx.c (GC_uobjfreelist_ptr): Likewise.
* mark.c (GC_obj_kinds): Likewise.
* mallocx.c (GC_auobjfreelist_ptr, GC_malloc_atomic_uncollectable):
Replace GC_auobjfreelist with GC_freelists[AUNCOLLECTABLE].
* mark.c (GC_obj_kinds): Likewise.
* misc.c (GC_init): Exclude whole GC_freelists from scanning instead
of beginGC_objfreelist and beginGC_aobjfreelist (if SEPARATE_GLOBALS).

alloc.c
checksums.c
include/private/gc_priv.h
malloc.c
mallocx.c
mark.c
misc.c
thread_local_alloc.c

diff --git a/alloc.c b/alloc.c
index 4a2cf3c784c165d024bde4dbeca6c0dcd3b17a1c..d7a381dc9464b8a99147b3f28a252ca2c70ff00c 100644 (file)
--- a/alloc.c
+++ b/alloc.c
  * an object of (small) size lb as follows:
  *
  *   lg = GC_size_map[lb];
- *   op = GC_objfreelist[lg];
+ *   op = GC_freelists[NORMAL][lg];
  *   if (NULL == op) {
  *     op = GENERAL_MALLOC(lb, NORMAL);
  *   } else {
- *     GC_objfreelist[lg] = obj_link(op);
+ *     GC_freelists[NORMAL][lg] = obj_link(op);
  *   }
  *
  * Note that this is very fast if the free list is non-empty; it should
index f0f902a3374aa00c0352d2c86c3bb4c4b35be40e..7be3e51818ff96f8ed8640e46a51bf7d2849cb76 100644 (file)
@@ -80,7 +80,7 @@ STATIC word GC_checksum(struct hblk *h)
     ptr_t p;
 
     if (sz > MAXOBJWORDS) return(FALSE);
-    for (p = GC_sobjfreelist[sz]; p != 0; p = obj_link(p)) {
+    for (p = GC_freelists[STUBBORN][sz]; p != 0; p = obj_link(p)) {
         if (HBLKPTR(p) == h) return(TRUE);
     }
     return(FALSE);
index 9efbe688f2b572d0437c4b5ee3bb321460134e7f..7c61384654413ed3c67144baa27d6d57171de33c 100644 (file)
@@ -1098,6 +1098,19 @@ typedef struct GC_ms_entry {
                         /* as described in gc_mark.h.                   */
 } mse;
 
+/* Predefined kinds: */
+#define PTRFREE 0
+#define NORMAL  1
+#define UNCOLLECTABLE 2
+#ifdef GC_ATOMIC_UNCOLLECTABLE
+# define AUNCOLLECTABLE 3
+# define STUBBORN 4
+# define IS_UNCOLLECTABLE(k) (((k) & ~1) == UNCOLLECTABLE)
+#else
+# define STUBBORN 3
+# define IS_UNCOLLECTABLE(k) ((k) == UNCOLLECTABLE)
+#endif
+
 /* Lists of all heap blocks and free lists      */
 /* as well as other random data structures      */
 /* that should not be scanned by the            */
@@ -1208,32 +1221,23 @@ struct _GC_arrays {
                 /* multi-threaded case, we currently only save the      */
                 /* calling stack.                                       */
 # endif
+# ifndef PREDEFINED_KINDS
+#   ifdef STUBBORN_ALLOC
+#     define PREDEFINED_KINDS (STUBBORN+1)
+#   else
+#     define PREDEFINED_KINDS STUBBORN
+#   endif
+# endif
 # ifndef SEPARATE_GLOBALS
-#   define GC_objfreelist GC_arrays._objfreelist
-    void *_objfreelist[MAXOBJGRANULES+1];
-                          /* free list for objects */
-#   define GC_aobjfreelist GC_arrays._aobjfreelist
-    void *_aobjfreelist[MAXOBJGRANULES+1];
-                          /* free list for atomic objs  */
-# endif
-  void *_uobjfreelist[MAXOBJGRANULES+1];
-                          /* Uncollectible but traced objs      */
-                          /* objects on this and auobjfreelist  */
-                          /* are always marked, except during   */
-                          /* garbage collections.               */
-# ifdef GC_ATOMIC_UNCOLLECTABLE
-#   define GC_auobjfreelist GC_arrays._auobjfreelist
-    void *_auobjfreelist[MAXOBJGRANULES+1];
-                        /* Atomic uncollectible but traced objs */
+#   define GC_freelists GC_arrays._freelists
+    void *_freelists[PREDEFINED_KINDS][MAXOBJGRANULES + 1];
+                /* Array of free lists for objects of predefined kinds: */
+                /* normal, atomic, uncollectible, atomic uncollectible  */
+                /* and immutable.                                       */
 # endif
   size_t _size_map[MAXOBJBYTES+1];
         /* Number of granules to allocate when asked for a certain      */
         /* number of bytes.                                             */
-# ifdef STUBBORN_ALLOC
-#   define GC_sobjfreelist GC_arrays._sobjfreelist
-    ptr_t _sobjfreelist[MAXOBJGRANULES+1];
-                          /* Free list for immutable objects.   */
-# endif
 # ifdef MARK_BIT_PER_GRANULE
 #   define GC_obj_map GC_arrays._obj_map
     short * _obj_map[MAXOBJGRANULES+1];
@@ -1335,7 +1339,6 @@ GC_API_PRIV GC_FAR struct _GC_arrays GC_arrays;
 #define GC_size_map GC_arrays._size_map
 #define GC_static_roots GC_arrays._static_roots
 #define GC_top_index GC_arrays._top_index
-#define GC_uobjfreelist GC_arrays._uobjfreelist
 #define GC_valid_offsets GC_arrays._valid_offsets
 
 #define beginGC_arrays ((ptr_t)(&GC_arrays))
@@ -1387,30 +1390,10 @@ GC_EXTERN struct obj_kind {
 #ifdef SEPARATE_GLOBALS
   extern word GC_bytes_allocd;
         /* Number of bytes allocated during this collection cycle.      */
-  extern ptr_t GC_objfreelist[MAXOBJGRANULES+1];
-                          /* free list for NORMAL objects */
-# define beginGC_objfreelist ((ptr_t)(&GC_objfreelist))
-# define endGC_objfreelist (beginGC_objfreelist + sizeof(GC_objfreelist))
-
-  extern ptr_t GC_aobjfreelist[MAXOBJGRANULES+1];
-                          /* free list for atomic (PTRFREE) objs        */
-# define beginGC_aobjfreelist ((ptr_t)(&GC_aobjfreelist))
-# define endGC_aobjfreelist (beginGC_aobjfreelist + sizeof(GC_aobjfreelist))
+  extern void *GC_freelists[PREDEFINED_KINDS][MAXOBJGRANULES + 1];
+        /* Array of free lists for objects of predefined kinds.         */
 #endif /* SEPARATE_GLOBALS */
 
-/* Predefined kinds: */
-#define PTRFREE 0
-#define NORMAL  1
-#define UNCOLLECTABLE 2
-#ifdef GC_ATOMIC_UNCOLLECTABLE
-# define AUNCOLLECTABLE 3
-# define STUBBORN 4
-# define IS_UNCOLLECTABLE(k) (((k) & ~1) == UNCOLLECTABLE)
-#else
-# define STUBBORN 3
-# define IS_UNCOLLECTABLE(k) ((k) == UNCOLLECTABLE)
-#endif
-
 GC_EXTERN unsigned GC_n_kinds;
 
 GC_EXTERN word GC_n_heap_sects; /* Number of separately added heap      */
index 1627bdb55b4ab9b68c1383c369353d717fa80137..0255d908da2ede5e21926b0cebd48036d25c72bb 100644 (file)
--- a/malloc.c
+++ b/malloc.c
@@ -244,12 +244,12 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_generic_malloc(size_t lb, int k)
         GC_DBG_COLLECT_AT_MALLOC(lb);
         lg = GC_size_map[lb];
         LOCK();
-        op = GC_aobjfreelist[lg];
+        op = GC_freelists[PTRFREE][lg];
         if (EXPECT(0 == op, FALSE)) {
             UNLOCK();
             return(GENERAL_MALLOC((word)lb, PTRFREE));
         }
-        GC_aobjfreelist[lg] = obj_link(op);
+        GC_freelists[PTRFREE][lg] = obj_link(op);
         GC_bytes_allocd += GRANULES_TO_BYTES(lg);
         UNLOCK();
         return((void *) op);
@@ -273,7 +273,7 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_generic_malloc(size_t lb, int k)
         GC_DBG_COLLECT_AT_MALLOC(lb);
         lg = GC_size_map[lb];
         LOCK();
-        op = GC_objfreelist[lg];
+        op = GC_freelists[NORMAL][lg];
         if (EXPECT(0 == op, FALSE)) {
             UNLOCK();
             return (GENERAL_MALLOC((word)lb, NORMAL));
@@ -283,7 +283,7 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_generic_malloc(size_t lb, int k)
                         <= (word)GC_greatest_plausible_heap_addr
                      && (word)obj_link(op)
                         >= (word)GC_least_plausible_heap_addr));
-        GC_objfreelist[lg] = obj_link(op);
+        GC_freelists[NORMAL][lg] = obj_link(op);
         obj_link(op) = 0;
         GC_bytes_allocd += GRANULES_TO_BYTES(lg);
         UNLOCK();
@@ -307,9 +307,9 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_malloc_uncollectable(size_t lb)
                   /* collected anyway.                                  */
         lg = GC_size_map[lb];
         LOCK();
-        op = GC_uobjfreelist[lg];
+        op = GC_freelists[UNCOLLECTABLE][lg];
         if (EXPECT(op != 0, TRUE)) {
-            GC_uobjfreelist[lg] = obj_link(op);
+            GC_freelists[UNCOLLECTABLE][lg] = obj_link(op);
             obj_link(op) = 0;
             GC_bytes_allocd += GRANULES_TO_BYTES(lg);
             /* Mark bit ws already set on free list.  It will be        */
index 5a370609aaaedb836d7d9e9349690625cb86dab1..a8827b9e9a82cc1443522d387d517b23713239a4 100644 (file)
--- a/mallocx.c
+++ b/mallocx.c
 /* Some externally visible but unadvertised variables to allow access to */
 /* free lists from inlined allocators without including gc_priv.h        */
 /* or introducing dependencies on internal data structure layouts.       */
-void ** const GC_objfreelist_ptr = GC_objfreelist;
-void ** const GC_aobjfreelist_ptr = GC_aobjfreelist;
-void ** const GC_uobjfreelist_ptr = GC_uobjfreelist;
+void ** const GC_objfreelist_ptr = GC_freelists[NORMAL];
+void ** const GC_aobjfreelist_ptr = GC_freelists[PTRFREE];
+void ** const GC_uobjfreelist_ptr = GC_freelists[UNCOLLECTABLE];
 # ifdef GC_ATOMIC_UNCOLLECTABLE
-    void ** const GC_auobjfreelist_ptr = GC_auobjfreelist;
+    void ** const GC_auobjfreelist_ptr = GC_freelists[AUNCOLLECTABLE];
 # endif
 
 GC_API int GC_CALL GC_get_kind_and_size(const void * p, size_t * psize)
@@ -533,9 +533,9 @@ GC_API int GC_CALL GC_posix_memalign(void **memptr, size_t align, size_t lb)
                   /* collected anyway.                                  */
         lg = GC_size_map[lb];
         LOCK();
-        op = GC_auobjfreelist[lg];
+        op = GC_freelists[AUNCOLLECTABLE][lg];
         if (EXPECT(op != 0, TRUE)) {
-            GC_auobjfreelist[lg] = obj_link(op);
+            GC_freelists[AUNCOLLECTABLE][lg] = obj_link(op);
             obj_link(op) = 0;
             GC_bytes_allocd += GRANULES_TO_BYTES(lg);
             /* Mark bit was already set while object was on free list. */
diff --git a/mark.c b/mark.c
index 9c3820780a1e8566ddedd209975e579831129b33..fb4740a02c294073a687e63f0a0103ac964990f7 100644 (file)
--- a/mark.c
+++ b/mark.c
@@ -47,25 +47,25 @@ GC_INNER unsigned GC_n_mark_procs = GC_RESERVED_MARK_PROCS;
 /* GC_init is called.                                                   */
 /* It's done here, since we need to deal with mark descriptors.         */
 GC_INNER struct obj_kind GC_obj_kinds[MAXOBJKINDS] = {
-/* PTRFREE */ { &GC_aobjfreelist[0], 0 /* filled in dynamically */,
+/* PTRFREE */ { &GC_freelists[PTRFREE][0], 0 /* filled in dynamically */,
                 0 | GC_DS_LENGTH, FALSE, FALSE
                 /*, */ OK_DISCLAIM_INITZ },
-/* NORMAL  */ { &GC_objfreelist[0], 0,
+/* NORMAL  */ { &GC_freelists[NORMAL][0], 0,
                 0 | GC_DS_LENGTH,  /* Adjusted in GC_init for EXTRA_BYTES */
                 TRUE /* add length to descr */, TRUE
                 /*, */ OK_DISCLAIM_INITZ },
 /* UNCOLLECTABLE */
-              { &GC_uobjfreelist[0], 0,
+              { &GC_freelists[UNCOLLECTABLE][0], 0,
                 0 | GC_DS_LENGTH, TRUE /* add length to descr */, TRUE
                 /*, */ OK_DISCLAIM_INITZ },
 # ifdef GC_ATOMIC_UNCOLLECTABLE
    /* AUNCOLLECTABLE */
-              { &GC_auobjfreelist[0], 0,
+              { &GC_freelists[AUNCOLLECTABLE][0], 0,
                 0 | GC_DS_LENGTH, FALSE /* add length to descr */, FALSE
                 /*, */ OK_DISCLAIM_INITZ },
 # endif
 # ifdef STUBBORN_ALLOC
-/*STUBBORN*/ { (void **)&GC_sobjfreelist[0], 0,
+/*STUBBORN*/ { (void **)&GC_freelists[STUBBORN][0], 0,
                 0 | GC_DS_LENGTH, TRUE /* add length to descr */, TRUE
                 /*, */ OK_DISCLAIM_INITZ },
 # endif
diff --git a/misc.c b/misc.c
index 99f65f08c6b04797d801c546ddd08977ba352c5a..d28d3d818bf75974ea6fc59dafa44f4d7b220169 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -1146,8 +1146,8 @@ GC_API void GC_CALL GC_init(void)
     GC_exclude_static_roots_inner(beginGC_arrays, endGC_arrays);
     GC_exclude_static_roots_inner(beginGC_obj_kinds, endGC_obj_kinds);
 #   ifdef SEPARATE_GLOBALS
-      GC_exclude_static_roots_inner(beginGC_objfreelist, endGC_objfreelist);
-      GC_exclude_static_roots_inner(beginGC_aobjfreelist, endGC_aobjfreelist);
+      GC_exclude_static_roots_inner((ptr_t)GC_freelists,
+                                (ptr_t)GC_freelists + sizeof(GC_freelists));
 #   endif
 #   if defined(USE_PROC_FOR_LIBRARIES) && defined(GC_LINUX_THREADS)
         WARN("USE_PROC_FOR_LIBRARIES + GC_LINUX_THREADS performs poorly.\n", 0);
index 9db324ebb33db2621e439e39967ef8b152f1dc1f..038e56f04324bc46ad5e4ad98b8488f0e4de78bc 100644 (file)
@@ -141,8 +141,8 @@ GC_INNER void GC_destroy_thread_local(GC_tlfs p)
 {
     /* We currently only do this from the thread itself or from */
     /* the fork handler for a child process.                    */
-    return_freelists(p -> ptrfree_freelists, GC_aobjfreelist);
-    return_freelists(p -> normal_freelists, GC_objfreelist);
+    return_freelists(p -> ptrfree_freelists, GC_freelists[PTRFREE]);
+    return_freelists(p -> normal_freelists, GC_freelists[NORMAL]);
 #   ifdef GC_GCJ_SUPPORT
         return_freelists(p -> gcj_freelists, (void **)GC_gcjobjfreelist);
 #   endif