# ifndef MARK_BIT_PER_OBJ
size_t granules;
# endif
+
# ifdef ENABLE_DISCLAIM
if (GC_obj_kinds[kind].ok_disclaim_proc)
flags |= HAS_DISCLAIM;
#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);
}
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();
}
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();
#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);
return GC_oom_fn(lb);
}
}
+
next = obj_link(my_entry);
result = (void *)my_entry;
*my_fl = next;
#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 */
/* 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 {
/* 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
/* 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 */
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;
}
}
#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)
{
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);
/* 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) {
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) {
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)
{
q = p -> finalized_freelists[j];
if ((word)q > HBLKSIZE)
GC_set_fl_marks(q);
-# endif /* ENABLE_DISCLAIM */
+# endif
}
}
# 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 */