/* Caller does not hold allocation lock. */ void GC_init_gcj_malloc(int mp_index, void * /* really GC_mark_proc */mp) { register int i; GC_bool ignore_gcj_info; DCL_LOCK_STATE; GC_init(); /* In case it's not already done. */ DISABLE_SIGNALS(); LOCK(); if (GC_gcj_malloc_initialized) { UNLOCK(); ENABLE_SIGNALS(); return; } GC_gcj_malloc_initialized = TRUE; ignore_gcj_info = (0 != GETENV("GC_IGNORE_GCJ_INFO")); # ifdef CONDPRINT if (GC_print_stats && ignore_gcj_info) { GC_printf0("Gcj-style type information is disabled!\n"); } # endif GC_ASSERT(GC_mark_procs[mp_index] == (GC_mark_proc)0); /* unused */ GC_mark_procs[mp_index] = (GC_mark_proc)mp; if (mp_index >= GC_n_mark_procs) ABORT("GC_init_gcj_malloc: bad index"); /* Set up object kind gcj-style indirect descriptor. */ GC_gcjobjfreelist = (ptr_t *)GC_new_free_list_inner(); if (ignore_gcj_info) { /* Use a simple length-based descriptor, thus forcing a fully */ /* conservative scan. */ GC_gcj_kind = GC_new_kind_inner((void **)GC_gcjobjfreelist, (0 | GC_DS_LENGTH), TRUE, TRUE); } else { GC_gcj_kind = GC_new_kind_inner( (void **)GC_gcjobjfreelist, (((word)(-MARK_DESCR_OFFSET - GC_INDIR_PER_OBJ_BIAS)) | GC_DS_PER_OBJECT), FALSE, TRUE); } /* Set up object kind for objects that require mark proc call. */ if (ignore_gcj_info) { GC_gcj_debug_kind = GC_gcj_kind; GC_gcjdebugobjfreelist = GC_gcjobjfreelist; } else { GC_gcjdebugobjfreelist = (ptr_t *)GC_new_free_list_inner(); GC_gcj_debug_kind = GC_new_kind_inner( (void **)GC_gcjdebugobjfreelist, GC_MAKE_PROC(mp_index, 1 /* allocated with debug info */), FALSE, TRUE); } UNLOCK(); ENABLE_SIGNALS(); }
STATIC void GC_init_explicit_typing(void) { unsigned i; GC_STATIC_ASSERT(sizeof(struct LeafDescriptor) % sizeof(word) == 0); /* Set up object kind with simple indirect descriptor. */ GC_eobjfreelist = (ptr_t *)GC_new_free_list_inner(); GC_explicit_kind = GC_new_kind_inner( (void **)GC_eobjfreelist, (WORDS_TO_BYTES((word)-1) | GC_DS_PER_OBJECT), TRUE, TRUE); /* Descriptors are in the last word of the object. */ GC_typed_mark_proc_index = GC_new_proc_inner(GC_typed_mark_proc); /* Set up object kind with array descriptor. */ GC_array_mark_proc_index = GC_new_proc_inner(GC_array_mark_proc); GC_array_kind = GC_new_kind_inner(GC_new_free_list_inner(), GC_MAKE_PROC(GC_array_mark_proc_index, 0), FALSE, TRUE); GC_bm_table[0] = GC_DS_BITMAP; for (i = 1; i < WORDSZ/2; i++) { GC_bm_table[i] = (((word)-1) << (WORDSZ - i)) | GC_DS_BITMAP; } }
GC_API void GC_CALL GC_init_finalized_malloc(void) { DCL_LOCK_STATE; GC_init(); /* In case it's not already done. */ LOCK(); if (done_init) { UNLOCK(); return; } done_init = TRUE; GC_finalized_objfreelist = (ptr_t *)GC_new_free_list_inner(); 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, TRUE); UNLOCK(); }
GC_API void GC_CALL GC_init_finalized_malloc(void) { DCL_LOCK_STATE; GC_init(); /* In case it's not already done. */ LOCK(); if (done_init) { UNLOCK(); return; } done_init = TRUE; /* The finalizer closure is placed in the first word in order to */ /* use the lower bits to distinguish live objects from objects on */ /* the free list. The downside of this is that we need one-word */ /* offset interior pointers, and that GC_base does not return the */ /* start of the user region. */ GC_register_displacement_inner(sizeof(word)); 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(); }