From 9cd4c2f2d3bf68a98210024dfd573c8b50ff41d6 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Thu, 30 Jun 2016 10:20:53 +0300 Subject: [PATCH] Revert "Refactoring of GC_Xobjfreelist" partially This reverts commit 41871b970c8fd9704835c1a221a8f9f1deea707a partially (GC_malloc_kind_global, GC_generic_malloc_uncollectable, GC_destroy_thread_local are not reverted). --- alloc.c | 4 +-- checksums.c | 2 +- include/private/gc_priv.h | 71 ++++++++++++++++++++++++--------------- malloc.c | 5 ++- mallocx.c | 8 ++--- mark.c | 10 +++--- misc.c | 4 +-- thread_local_alloc.c | 4 +-- 8 files changed, 62 insertions(+), 46 deletions(-) diff --git a/alloc.c b/alloc.c index d7a381dc..4a2cf3c7 100644 --- a/alloc.c +++ b/alloc.c @@ -35,11 +35,11 @@ * an object of (small) size lb as follows: * * lg = GC_size_map[lb]; - * op = GC_freelists[NORMAL][lg]; + * op = GC_objfreelist[lg]; * if (NULL == op) { * op = GENERAL_MALLOC(lb, NORMAL); * } else { - * GC_freelists[NORMAL][lg] = obj_link(op); + * GC_objfreelist[lg] = obj_link(op); * } * * Note that this is very fast if the free list is non-empty; it should diff --git a/checksums.c b/checksums.c index 7be3e518..f0f902a3 100644 --- a/checksums.c +++ b/checksums.c @@ -80,7 +80,7 @@ STATIC word GC_checksum(struct hblk *h) ptr_t p; if (sz > MAXOBJWORDS) return(FALSE); - for (p = GC_freelists[STUBBORN][sz]; p != 0; p = obj_link(p)) { + for (p = GC_sobjfreelist[sz]; p != 0; p = obj_link(p)) { if (HBLKPTR(p) == h) return(TRUE); } return(FALSE); diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index a84536e7..75f4b058 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -1098,19 +1098,6 @@ 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 */ @@ -1221,23 +1208,32 @@ 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_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. */ +# 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 */ # 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]; @@ -1339,6 +1335,7 @@ 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)) @@ -1391,10 +1388,30 @@ GC_EXTERN struct obj_kind { #ifdef SEPARATE_GLOBALS extern word GC_bytes_allocd; /* Number of bytes allocated during this collection cycle. */ - extern void *GC_freelists[PREDEFINED_KINDS][MAXOBJGRANULES + 1]; - /* Array of free lists for objects of predefined kinds. */ + 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)) #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 */ diff --git a/malloc.c b/malloc.c index 8df86cf5..f8495e7f 100644 --- a/malloc.c +++ b/malloc.c @@ -240,8 +240,7 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_malloc_kind_global(size_t lb, int k) size_t lg; DCL_LOCK_STATE; - GC_STATIC_ASSERT(MAXOBJKINDS >= PREDEFINED_KINDS); - GC_ASSERT(k < PREDEFINED_KINDS); + GC_ASSERT(k < MAXOBJKINDS); if (SMALL_OBJ(lb)) { GC_DBG_COLLECT_AT_MALLOC(lb); lg = GC_size_map[lb]; @@ -296,7 +295,7 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_generic_malloc_uncollectable( size_t lg; DCL_LOCK_STATE; - GC_ASSERT(k < PREDEFINED_KINDS); + GC_ASSERT(k < MAXOBJKINDS); if (SMALL_OBJ(lb)) { GC_DBG_COLLECT_AT_MALLOC(lb); if (EXTRA_BYTES != 0 && lb != 0) lb--; diff --git a/mallocx.c b/mallocx.c index 75147486..cb830ce2 100644 --- a/mallocx.c +++ b/mallocx.c @@ -40,11 +40,11 @@ /* 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_freelists[NORMAL]; -void ** const GC_aobjfreelist_ptr = GC_freelists[PTRFREE]; -void ** const GC_uobjfreelist_ptr = GC_freelists[UNCOLLECTABLE]; +void ** const GC_objfreelist_ptr = GC_objfreelist; +void ** const GC_aobjfreelist_ptr = GC_aobjfreelist; +void ** const GC_uobjfreelist_ptr = GC_uobjfreelist; # ifdef GC_ATOMIC_UNCOLLECTABLE - void ** const GC_auobjfreelist_ptr = GC_freelists[AUNCOLLECTABLE]; + void ** const GC_auobjfreelist_ptr = GC_auobjfreelist; # endif GC_API int GC_CALL GC_get_kind_and_size(const void * p, size_t * psize) diff --git a/mark.c b/mark.c index fb4740a0..9c382078 100644 --- 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_freelists[PTRFREE][0], 0 /* filled in dynamically */, +/* PTRFREE */ { &GC_aobjfreelist[0], 0 /* filled in dynamically */, 0 | GC_DS_LENGTH, FALSE, FALSE /*, */ OK_DISCLAIM_INITZ }, -/* NORMAL */ { &GC_freelists[NORMAL][0], 0, +/* NORMAL */ { &GC_objfreelist[0], 0, 0 | GC_DS_LENGTH, /* Adjusted in GC_init for EXTRA_BYTES */ TRUE /* add length to descr */, TRUE /*, */ OK_DISCLAIM_INITZ }, /* UNCOLLECTABLE */ - { &GC_freelists[UNCOLLECTABLE][0], 0, + { &GC_uobjfreelist[0], 0, 0 | GC_DS_LENGTH, TRUE /* add length to descr */, TRUE /*, */ OK_DISCLAIM_INITZ }, # ifdef GC_ATOMIC_UNCOLLECTABLE /* AUNCOLLECTABLE */ - { &GC_freelists[AUNCOLLECTABLE][0], 0, + { &GC_auobjfreelist[0], 0, 0 | GC_DS_LENGTH, FALSE /* add length to descr */, FALSE /*, */ OK_DISCLAIM_INITZ }, # endif # ifdef STUBBORN_ALLOC -/*STUBBORN*/ { (void **)&GC_freelists[STUBBORN][0], 0, +/*STUBBORN*/ { (void **)&GC_sobjfreelist[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 d2455dd9..adfa2f59 100644 --- 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((ptr_t)GC_freelists, - (ptr_t)GC_freelists + sizeof(GC_freelists)); + GC_exclude_static_roots_inner(beginGC_objfreelist, endGC_objfreelist); + GC_exclude_static_roots_inner(beginGC_aobjfreelist, endGC_aobjfreelist); # endif # if defined(USE_PROC_FOR_LIBRARIES) && defined(GC_LINUX_THREADS) WARN("USE_PROC_FOR_LIBRARIES + GC_LINUX_THREADS performs poorly.\n", 0); diff --git a/thread_local_alloc.c b/thread_local_alloc.c index ab4382b6..1e000794 100644 --- a/thread_local_alloc.c +++ b/thread_local_alloc.c @@ -138,7 +138,7 @@ 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. */ - GC_STATIC_ASSERT(PREDEFINED_KINDS >= THREAD_FREELISTS_KINDS); + GC_STATIC_ASSERT(THREAD_FREELISTS_KINDS <= MAXOBJKINDS); for (k = 0; k < THREAD_FREELISTS_KINDS; ++k) { if (k == (int)GC_n_kinds) break; /* kind is not created */ @@ -164,7 +164,7 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_malloc_kind(size_t bytes, int knd) void *tsd; void *result; -# if PREDEFINED_KINDS > THREAD_FREELISTS_KINDS +# if MAXOBJKINDS > THREAD_FREELISTS_KINDS if (EXPECT(knd >= THREAD_FREELISTS_KINDS, FALSE)) { return GC_malloc_kind_global(bytes, knd); } -- 2.40.0