From: Ivan Maidanski Date: Wed, 20 Jul 2016 22:26:58 +0000 (+0300) Subject: Re-implement GC_finalized_malloc using GC_malloc_kind X-Git-Tag: gc7_6_0~17 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0ce1a71ec28c4d07dba09c5f32e4937708492cf2;p=gc Re-implement GC_finalized_malloc using GC_malloc_kind (code refactoring) * fnlz_mlc.c: Do not test THREAD_LOCAL_ALLOC; do not include thread_local_alloc.h. * fnlz_mlc.c (GC_finalized_objfreelist, GC_core_finalized_malloc): Remove. * fnlz_mlc.c [ENABLE_DISCLAIM]: Include gc_inline.h (to declare GC_malloc_kind). * fnlz_mlc.c [ENABLE_DISCLAIM] (GC_init_finalized_malloc): Do not use GC_finalized_objfreelist. * fnlz_mlc.c [ENABLE_DISCLAIM] (GC_finalized_malloc): Call GC_malloc_kind (instead of own implementation mostly duplicating the algorithm of GC_malloc_kind[_global]); change type of "op" local variable from ptr_t to word*. * include/private/thread_local_alloc.h [ENABLE_DISCLAIM] (THREAD_FREELISTS_KINDS): Increase value by 1. * include/private/thread_local_alloc.h (thread_local_freelists.finalized_freelists, GC_finalized_objfreelist): Remove. * thread_local_alloc.c (GC_finalized_objfreelist): Remove. * thread_local_alloc.c (GC_init_thread_local, GC_destroy_thread_local, GC_mark_thread_local_fls_for, GC_check_tls_for): Do not access finalized_freelists. --- diff --git a/fnlz_mlc.c b/fnlz_mlc.c index 1b168874..15b234b9 100644 --- a/fnlz_mlc.c +++ b/fnlz_mlc.c @@ -17,12 +17,7 @@ #ifdef ENABLE_DISCLAIM #include "gc_disclaim.h" - -#ifdef THREAD_LOCAL_ALLOC -# include "private/thread_local_alloc.h" -#else - STATIC ptr_t * GC_finalized_objfreelist = NULL; -#endif /* !THREAD_LOCAL_ALLOC */ +#include "gc_inline.h" /* for GC_malloc_kind */ STATIC int GC_finalized_kind = 0; @@ -66,8 +61,7 @@ GC_API void GC_CALL GC_init_finalized_malloc(void) /* start of the user region. */ GC_register_displacement_inner(sizeof(word)); - GC_finalized_objfreelist = (ptr_t *)GC_new_free_list_inner(); - GC_finalized_kind = GC_new_kind_inner((void **)GC_finalized_objfreelist, + GC_finalized_kind = GC_new_kind_inner(GC_new_free_list_inner(), GC_DS_LENGTH, TRUE, TRUE); GC_register_disclaim_proc(GC_finalized_kind, GC_finalized_disclaim, TRUE); UNLOCK(); @@ -81,90 +75,17 @@ GC_API void GC_CALL GC_register_disclaim_proc(int kind, GC_disclaim_proc proc, GC_obj_kinds[kind].ok_mark_unconditionally = (GC_bool)mark_unconditionally; } -#ifdef THREAD_LOCAL_ALLOC - STATIC void * GC_core_finalized_malloc(size_t lb, - const struct GC_finalizer_closure *fclos) -#else - GC_API GC_ATTR_MALLOC void * GC_CALL GC_finalized_malloc(size_t lb, +GC_API GC_ATTR_MALLOC void * GC_CALL GC_finalized_malloc(size_t lb, const struct GC_finalizer_closure *fclos) -#endif { - ptr_t op; - word lg; - DCL_LOCK_STATE; + word *op; - lb += sizeof(word); GC_ASSERT(done_init); - if (SMALL_OBJ(lb)) { - GC_DBG_COLLECT_AT_MALLOC(lb); - lg = GC_size_map[lb]; - LOCK(); - op = GC_finalized_objfreelist[lg]; - if (EXPECT(0 == op, FALSE)) { - UNLOCK(); - op = GC_generic_malloc(lb, GC_finalized_kind); - if (NULL == op) - return NULL; - /* GC_generic_malloc has extended the size map for us. */ - lg = GC_size_map[lb]; - } else { - GC_finalized_objfreelist[lg] = obj_link(op); - obj_link(op) = 0; - GC_bytes_allocd += GRANULES_TO_BYTES(lg); - UNLOCK(); - } - GC_ASSERT(lg > 0); - } else { - op = GC_generic_malloc(lb, GC_finalized_kind); - if (NULL == op) - return NULL; - GC_ASSERT(GC_size(op) >= lb); - } - *(word *)op = (word)fclos | 1; - return GC_clear_stack((word *)op + 1); + op = GC_malloc_kind(lb + sizeof(word), GC_finalized_kind); + if (EXPECT(NULL == op, FALSE)) + return NULL; + *op = (word)fclos | 1; + return op + 1; } -#ifdef THREAD_LOCAL_ALLOC - GC_API GC_ATTR_MALLOC void * GC_CALL GC_finalized_malloc(size_t client_lb, - const struct GC_finalizer_closure *fclos) - { - size_t lb = client_lb + sizeof(word); - size_t lg = ROUNDED_UP_GRANULES(lb); - GC_tlfs tsd; - void *result; - void **tiny_fl, **my_fl, *my_entry; - void *next; - - if (EXPECT(lg >= GC_TINY_FREELISTS, FALSE)) - return GC_core_finalized_malloc(client_lb, fclos); - - tsd = GC_getspecific(GC_thread_key); - tiny_fl = tsd->finalized_freelists; - my_fl = tiny_fl + lg; - my_entry = *my_fl; - while (EXPECT((word)my_entry - <= DIRECT_GRANULES + GC_TINY_FREELISTS + 1, FALSE)) { - if ((word)my_entry - 1 < DIRECT_GRANULES) { - *my_fl = (ptr_t)my_entry + lg + 1; - return GC_core_finalized_malloc(client_lb, fclos); - } else { - GC_generic_malloc_many(GC_RAW_BYTES_FROM_INDEX(lg), - GC_finalized_kind, my_fl); - my_entry = *my_fl; - if (my_entry == 0) { - return (*GC_get_oom_fn())(lb); - } - } - } - - next = obj_link(my_entry); - result = (void *)my_entry; - *my_fl = next; - obj_link(result) = 0; - *(word *)result = (word)fclos | 1; - GC_PREFETCH_FOR_WRITE(next); - return (word *)result + 1; - } -#endif /* THREAD_LOCAL_ALLOC */ - #endif /* ENABLE_DISCLAIM */ diff --git a/include/private/thread_local_alloc.h b/include/private/thread_local_alloc.h index d273350e..3b44a1e6 100644 --- a/include/private/thread_local_alloc.h +++ b/include/private/thread_local_alloc.h @@ -76,8 +76,12 @@ #include #ifndef THREAD_FREELISTS_KINDS -# define THREAD_FREELISTS_KINDS (NORMAL+1) -#endif +# ifdef ENABLE_DISCLAIM +# define THREAD_FREELISTS_KINDS (NORMAL+2) +# else +# define THREAD_FREELISTS_KINDS (NORMAL+1) +# endif +#endif /* !THREAD_FREELISTS_KINDS */ /* One of these should be declared as the tlfs field in the */ /* structure pointed to by a GC_thread. */ @@ -91,9 +95,6 @@ typedef struct thread_local_freelists { # define ERROR_FL ((void *)(word)-1) /* Value used for gcj_freelists[-1]; allocation is */ /* erroneous. */ -# endif -# ifdef ENABLE_DISCLAIM - void * finalized_freelists[TINY_FREELISTS]; # endif /* Free lists contain either a pointer or a small count */ /* reflecting the number of granules allocated at that */ @@ -164,10 +165,6 @@ GC_INNER void GC_destroy_thread_local(GC_tlfs p); /* we take care of an individual thread freelist structure. */ GC_INNER void GC_mark_thread_local_fls_for(GC_tlfs p); -#ifdef ENABLE_DISCLAIM - GC_EXTERN ptr_t * GC_finalized_objfreelist; -#endif - #ifndef GC_ATTR_TLS_FAST # define GC_ATTR_TLS_FAST /* empty */ #endif diff --git a/thread_local_alloc.c b/thread_local_alloc.c index 1e000794..951a5df2 100644 --- a/thread_local_alloc.c +++ b/thread_local_alloc.c @@ -32,12 +32,6 @@ GC_key_t GC_thread_key; static GC_bool keys_initialized; -#ifdef ENABLE_DISCLAIM - GC_INNER ptr_t * GC_finalized_objfreelist = NULL; - /* This variable is declared here to prevent linking of */ - /* fnlz_mlc module unless the client uses the latter one. */ -#endif - /* Return a single nonempty freelist fl to the global one pointed to */ /* by gfl. */ @@ -118,9 +112,6 @@ GC_INNER void GC_init_thread_local(GC_tlfs p) } # ifdef GC_GCJ_SUPPORT p -> gcj_freelists[j] = (void *)(word)1; -# endif -# ifdef ENABLE_DISCLAIM - p -> finalized_freelists[j] = (void *)(word)1; # endif } /* The size 0 free lists are handled like the regular free lists, */ @@ -147,10 +138,6 @@ GC_INNER void GC_destroy_thread_local(GC_tlfs p) # ifdef GC_GCJ_SUPPORT return_freelists(p -> gcj_freelists, (void **)GC_gcjobjfreelist); # endif -# ifdef ENABLE_DISCLAIM - return_freelists(p -> finalized_freelists, - (void **)GC_finalized_objfreelist); -# endif } #ifdef GC_ASSERTIONS @@ -289,11 +276,6 @@ GC_INNER void GC_mark_thread_local_fls_for(GC_tlfs p) if ((word)q > HBLKSIZE) GC_set_fl_marks(q); } -# endif -# ifdef ENABLE_DISCLAIM - q = p -> finalized_freelists[j]; - if ((word)q > HBLKSIZE) - GC_set_fl_marks(q); # endif } } @@ -310,9 +292,6 @@ GC_INNER void GC_mark_thread_local_fls_for(GC_tlfs p) } # ifdef GC_GCJ_SUPPORT GC_check_fl_marks(&p->gcj_freelists[j]); -# endif -# ifdef ENABLE_DISCLAIM - GC_check_fl_marks(&p->finalized_freelists[j]); # endif } }