diff options
-rw-r--r-- | allchblk.c | 1 | ||||
-rw-r--r-- | finalized_mlc.c | 43 | ||||
-rw-r--r-- | include/gc_disclaim.h | 21 | ||||
-rw-r--r-- | include/private/gc_priv.h | 2 | ||||
-rw-r--r-- | misc.c | 19 | ||||
-rw-r--r-- | reclaim.c | 13 | ||||
-rw-r--r-- | thread_local_alloc.c | 8 |
7 files changed, 57 insertions, 50 deletions
@@ -225,6 +225,7 @@ static GC_bool setup_header(hdr * hhdr, struct hblk *block, size_t byte_sz, # ifndef MARK_BIT_PER_OBJ size_t granules; # endif + # ifdef ENABLE_DISCLAIM if (GC_obj_kinds[kind].ok_disclaim_proc) flags |= HAS_DISCLAIM; diff --git a/finalized_mlc.c b/finalized_mlc.c index 41ca9cdb..da529b4e 100644 --- a/finalized_mlc.c +++ b/finalized_mlc.c @@ -17,27 +17,27 @@ #ifdef ENABLE_DISCLAIM #ifdef THREAD_LOCAL_ALLOC -# include "private/thread_local_alloc.h" +# include "private/thread_local_alloc.h" #endif #include "gc_disclaim.h" -STATIC int GC_finalized_kind; - -ptr_t * GC_finalized_objfreelist = NULL; +STATIC int GC_finalized_kind = 0; +GC_INNER ptr_t * GC_finalized_objfreelist = NULL; STATIC int GC_CALLBACK GC_finalized_disclaim(void *obj, void *cd) { struct GC_finalizer_closure *fc = *(void **)obj; if (((word)fc & 1) != 0) { - /* The disclaim function may be passed fragments from the free-list, on - * which it should not run finalization. To recognize this case, we use - * the fact that the first word on such fragments are always even (a link - * to the next fragment, or NULL). If it is desirable to have a finalizer - * which does not use the first word for storing finalization info, - * GC_reclaim_with_finalization must be extended to clear fragments so - * that the assumption holds for the selected word. */ + /* [1] The disclaim function may be passed fragments from the */ + /* free-list, on which it should not run finalization. */ + /* To recognize this case, we use the fact that the first word */ + /* on such fragments are always even (a link to the next */ + /* fragment, or NULL). If it is desirable to have a finalizer */ + /* which does not use the first word for storing finalization */ + /* info, GC_reclaim_with_finalization must be extended to clear */ + /* fragments so that the assumption holds for the selected word. */ fc = (void *)((word)fc & ~(word)1); (*fc->proc)((void **)obj + 1, fc->cd); } @@ -60,12 +60,10 @@ GC_API void GC_CALL GC_init_finalized_malloc(void) done_init = 1; GC_finalized_objfreelist = (ptr_t *)GC_new_free_list_inner(); - GC_finalized_kind = - GC_new_kind_inner((void **)GC_finalized_objfreelist, - 0 | GC_DS_LENGTH, - TRUE, TRUE); - GC_register_disclaim_proc(GC_finalized_kind, GC_finalized_disclaim, 0, 1); - + GC_finalized_kind = GC_new_kind_inner((void **)GC_finalized_objfreelist, + GC_DS_LENGTH, TRUE, TRUE); + GC_register_disclaim_proc(GC_finalized_kind, GC_finalized_disclaim, + NULL, TRUE); UNLOCK(); } @@ -74,17 +72,17 @@ GC_API void GC_CALL GC_init_finalized_malloc(void) struct GC_finalizer_closure *fclos) #else GC_API void * GC_CALL GC_finalized_malloc(size_t lb, - struct GC_finalizer_closure *fclos) + struct GC_finalizer_closure *fclos) #endif { - register ptr_t op; - register ptr_t *opp; + ptr_t op; + ptr_t *opp; + word lg; DCL_LOCK_STATE; lb += sizeof(void *); GC_ASSERT(done_init); if (EXPECT(SMALL_OBJ(lb), 1)) { - register word lg; lg = GC_size_map[lb]; opp = &GC_finalized_objfreelist[lg]; LOCK(); @@ -106,7 +104,7 @@ GC_API void GC_CALL GC_init_finalized_malloc(void) #ifdef THREAD_LOCAL_ALLOC GC_API void * GC_CALL GC_finalized_malloc(size_t client_lb, - struct GC_finalizer_closure *fclos) + struct GC_finalizer_closure *fclos) { size_t lb = client_lb + sizeof(void *); size_t lg = ROUNDED_UP_GRANULES(lb); @@ -135,6 +133,7 @@ GC_API void GC_CALL GC_init_finalized_malloc(void) return GC_oom_fn(lb); } } + next = obj_link(my_entry); result = (void *)my_entry; *my_fl = next; diff --git a/include/gc_disclaim.h b/include/gc_disclaim.h index 098a73ed..f09bc9d6 100644 --- a/include/gc_disclaim.h +++ b/include/gc_disclaim.h @@ -17,9 +17,12 @@ #include "gc.h" +/* This API is defined only if the library has been suitably compiled */ +/* (i.e. with ENABLE_DISCLAIM defined). */ + /* Type of a disclaim call-back, always stored along with closure data */ /* passed as the second argument. */ -typedef int (GC_CALLBACK * GC_disclaim_proc)(void *obj, void *cd); +typedef int (GC_CALLBACK * GC_disclaim_proc)(void * /*obj*/, void * /*cd*/); /* Register "proc" to be called on each object of "kind" ready to be */ /* reclaimed. If "proc" returns non-zero, the collector will not */ @@ -27,9 +30,10 @@ typedef int (GC_CALLBACK * GC_disclaim_proc)(void *obj, void *cd); /* will be protected from collection if "mark_from_all" is non-zero, */ /* but at the expense that long chains of objects will take many cycles */ /* to reclaim. */ -GC_API void GC_register_disclaim_proc(int /* kind */, - GC_disclaim_proc /*proc*/, void * /*cd*/, - int /* mark_from_all */); +GC_API void GC_CALL GC_register_disclaim_proc(int /*kind*/, + GC_disclaim_proc /*proc*/, + void * /*cd*/, + int /*mark_from_all*/); /* The finalizer closure used by GC_finalized_malloc. */ struct GC_finalizer_closure { @@ -41,12 +45,11 @@ struct GC_finalizer_closure { /* dedicated object kind with a disclaim procedure, and is more */ /* efficient than GC_register_finalizer and friends. You need to call */ /* GC_init_finalized_malloc before using this. */ -GC_API void *GC_finalized_malloc(size_t size, struct GC_finalizer_closure *fc); +GC_API void *GC_CALL GC_finalized_malloc(size_t /*size*/, + struct GC_finalizer_closure * /*fc*/); /* Prepare the object kind used for GC_finalized_malloc. */ -GC_API void GC_init_finalized_malloc(void); - -// FIXME: Use GC_CALL and GC_API -// FIXME: GC_init_finalized_malloc: replace with +GC_API void GC_CALL GC_init_finalized_malloc(void); + // FIXME: replace init with enable? #endif diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index fce894ac..1273b65f 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -1237,7 +1237,7 @@ GC_EXTERN struct obj_kind { /* Mark from all, including unmarked, objects */ /* in block. Used to protect objects reachable */ /* from reclaim notifiers. */ - int (GC_CALLBACK *ok_disclaim_proc)(void *obj, void *cd); + int (GC_CALLBACK *ok_disclaim_proc)(void * /*obj*/, void * /*cd*/); void *ok_disclaim_cd; /* The disclaim procedure is called before obj */ /* is reclaimed, but must also tolerate being */ @@ -1479,11 +1479,11 @@ GC_API unsigned GC_CALL GC_new_kind_inner(void **fl, GC_word descr, GC_obj_kinds[result].ok_relocate_descr = adjust; GC_obj_kinds[result].ok_init = clear; # ifdef MARK_UNCONDITIONALLY - GC_obj_kinds[result].ok_mark_unconditionally = 0; + GC_obj_kinds[result].ok_mark_unconditionally = FALSE; # endif # ifdef ENABLE_DISCLAIM GC_obj_kinds[result].ok_disclaim_proc = 0; - GC_obj_kinds[result].ok_disclaim_cd = 0; + GC_obj_kinds[result].ok_disclaim_cd = NULL; # endif return result; } @@ -1519,15 +1519,16 @@ GC_API unsigned GC_CALL GC_new_proc(GC_mark_proc proc) } #ifdef ENABLE_DISCLAIM -GC_API void GC_CALL GC_register_disclaim_proc(int kind, - GC_disclaim_proc proc, void *cd, - int mark_unconditionally) -{ + GC_API void GC_CALL GC_register_disclaim_proc(int kind, + GC_disclaim_proc proc, + void *cd, + int mark_unconditionally) + { GC_obj_kinds[kind].ok_disclaim_proc = proc; GC_obj_kinds[kind].ok_disclaim_cd = cd; - GC_obj_kinds[kind].ok_mark_unconditionally = mark_unconditionally; -} -#endif + GC_obj_kinds[kind].ok_mark_unconditionally = (GC_bool)mark_unconditionally; + } +#endif /* ENABLE_DISCLAIM */ GC_API void * GC_CALL GC_call_with_stack_base(GC_stack_base_func fn, void *arg) { @@ -224,7 +224,7 @@ STATIC ptr_t GC_reclaim_uninit(struct hblk *hbp, hdr *hhdr, size_t sz, word *p, *q, *plim; signed_word n_bytes_found = 0; struct obj_kind *ok = &GC_obj_kinds[hhdr->hb_obj_kind]; - int (*proc)(void *, void *) = ok -> ok_disclaim_proc; + int (GC_CALLBACK *proc)(void *, void *) = ok->ok_disclaim_proc; void *cd = ok -> ok_disclaim_cd; GC_ASSERT(sz == hhdr -> hb_sz); @@ -247,8 +247,8 @@ STATIC ptr_t GC_reclaim_uninit(struct hblk *hbp, hdr *hhdr, size_t sz, /* Clear object, advance p to next object in the process */ q = (word *)((ptr_t)p + sz); # ifdef USE_MARK_BYTES - GC_ASSERT(!(sz & 1) - && !((word)p & (2 * sizeof(word) - 1))); + GC_ASSERT((sz & 1) == 0); + GC_ASSERT(((word)p & (2 * sizeof(word) - 1)) == 0); p[1] = 0; p += 2; while (p < q) { @@ -752,11 +752,14 @@ void GC_reclaim_unconditionally_marked(void) struct obj_kind * ok; struct hblk ** rlp; struct hblk ** rlh; + for (kind = 0; kind < GC_n_kinds; kind++) { ok = &(GC_obj_kinds[kind]); - if (!ok->ok_mark_unconditionally) continue; + if (!ok->ok_mark_unconditionally) + continue; rlp = ok->ok_reclaim_list; - if (rlp == 0) continue; + if (rlp == 0) + continue; for (sz = 1; sz <= MAXOBJGRANULES; sz++) { rlh = rlp + sz; while ((hbp = *rlh) != 0) { diff --git a/thread_local_alloc.c b/thread_local_alloc.c index c5e8f66d..6122c885 100644 --- a/thread_local_alloc.c +++ b/thread_local_alloc.c @@ -33,7 +33,7 @@ GC_key_t GC_thread_key; static GC_bool keys_initialized; /* Return a single nonempty freelist fl to the global one pointed to */ -/* by gfl. */ +/* by gfl. */ static void return_single_freelist(void *fl, void **gfl) { @@ -294,7 +294,7 @@ GC_INNER void GC_mark_thread_local_fls_for(GC_tlfs p) q = p -> finalized_freelists[j]; if ((word)q > HBLKSIZE) GC_set_fl_marks(q); -# endif /* ENABLE_DISCLAIM */ +# endif } } @@ -313,12 +313,12 @@ GC_INNER void GC_mark_thread_local_fls_for(GC_tlfs p) # ifdef GC_GCJ_SUPPORT q = p -> gcj_freelists[j]; if ((word)q > HBLKSIZE) GC_check_fl_marks(q); -# endif /* GC_GCJ_SUPPORT */ +# endif # ifdef ENABLE_DISCLAIM q = p -> finalized_freelists[j]; if ((word)q > HBLKSIZE) GC_check_fl_marks(q); -# endif /* ENABLE_DISCLAIM */ +# endif } } #endif /* GC_ASSERTIONS */ |