/* allocated as a small object. */ void * GC_gcj_fast_malloc(size_t lw, void * ptr_to_struct_containing_descr) { ptr_t op; ptr_t * opp; DCL_LOCK_STATE; opp = &(GC_gcjobjfreelist[lw]); LOCK(); op = *opp; if( EXPECT(op == 0, 0) ) { maybe_finalize(); op = (ptr_t)GC_clear_stack( GC_generic_malloc_words_small_inner(lw, GC_gcj_kind)); if (0 == op) { UNLOCK(); return GC_oom_fn(WORDS_TO_BYTES(lw)); } } else { *opp = obj_link(op); GC_words_allocd += lw; } *(void **)op = ptr_to_struct_containing_descr; UNLOCK(); return((GC_PTR) op); }
GC_API void * GC_CALL GC_finalized_malloc(size_t lb, const struct GC_finalizer_closure *fclos) #endif { ptr_t op; word lg; DCL_LOCK_STATE; lb += sizeof(void *); 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); ((const void **)op)[GRANULES_TO_WORDS(lg) - 1] = fclos; } else { size_t op_sz; op = GC_generic_malloc(lb, GC_finalized_kind); if (NULL == op) return NULL; op_sz = GC_size(op); GC_ASSERT(op_sz >= lb); ((const void **)op)[op_sz / sizeof(void *) - 1] = fclos; } return GC_clear_stack(op); }