GC_INNER void GC_bl_init_no_interiors(void) { if (GC_incomplete_normal_bl == 0) { GC_old_normal_bl = (word *)GC_scratch_alloc(sizeof(page_hash_table)); GC_incomplete_normal_bl = (word *)GC_scratch_alloc( sizeof(page_hash_table)); if (GC_old_normal_bl == 0 || GC_incomplete_normal_bl == 0) { GC_err_printf("Insufficient memory for black list\n"); EXIT(); } GC_clear_bl(GC_old_normal_bl); GC_clear_bl(GC_incomplete_normal_bl); } }
GC_INNER void GC_bl_init(void) { if (!GC_all_interior_pointers) { GC_bl_init_no_interiors(); } GC_ASSERT(NULL == GC_old_stack_bl && NULL == GC_incomplete_stack_bl); GC_old_stack_bl = (word *)GC_scratch_alloc(sizeof(page_hash_table)); GC_incomplete_stack_bl = (word *)GC_scratch_alloc(sizeof(page_hash_table)); if (GC_old_stack_bl == 0 || GC_incomplete_stack_bl == 0) { GC_err_printf("Insufficient memory for black list\n"); EXIT(); } GC_clear_bl(GC_old_stack_bl); GC_clear_bl(GC_incomplete_stack_bl); }
/* A size of 0 granules is used for large objects. */ GC_INNER GC_bool GC_add_map_entry(size_t granules) { unsigned displ; unsigned short * new_map; if (granules > BYTES_TO_GRANULES(MAXOBJBYTES)) granules = 0; if (GC_obj_map[granules] != 0) { return(TRUE); } new_map = (unsigned short *)GC_scratch_alloc(MAP_LEN * sizeof(short)); if (new_map == 0) return(FALSE); GC_COND_LOG_PRINTF( "Adding block map for size of %u granules (%u bytes)\n", (unsigned)granules, (unsigned)GRANULES_TO_BYTES(granules)); if (granules == 0) { for (displ = 0; displ < BYTES_TO_GRANULES(HBLKSIZE); displ++) { new_map[displ] = 1; /* Nonzero to get us out of marker fast path. */ } } else { for (displ = 0; displ < BYTES_TO_GRANULES(HBLKSIZE); displ++) { new_map[displ] = (unsigned short)(displ % granules); } } GC_obj_map[granules] = new_map; return(TRUE); }
/* Return TRUE on success */ STATIC GC_bool GC_alloc_reclaim_list(struct obj_kind *kind) { struct hblk ** result = (struct hblk **) GC_scratch_alloc((MAXOBJGRANULES+1) * sizeof(struct hblk *)); if (result == 0) return(FALSE); BZERO(result, (MAXOBJGRANULES+1)*sizeof(struct hblk *)); kind -> ok_reclaim_list = result; return(TRUE); }
GC_INNER void GC_init_headers(void) { register unsigned i; GC_all_nils = (bottom_index *)GC_scratch_alloc((word)sizeof(bottom_index)); BZERO(GC_all_nils, sizeof(bottom_index)); for (i = 0; i < TOP_SZ; i++) { GC_top_index[i] = GC_all_nils; } }
/* Return an uninitialized header */ static hdr * alloc_hdr(void) { register hdr * result; if (hdr_free_list == 0) { result = (hdr *) GC_scratch_alloc((word)(sizeof(hdr))); } else { result = hdr_free_list; hdr_free_list = (hdr *) (result -> hb_next); } return(result); }
GC_INNER ptr_t GC_scratch_alloc(size_t bytes) { register ptr_t result = scratch_free_ptr; bytes += GRANULE_BYTES-1; bytes &= ~(GRANULE_BYTES-1); scratch_free_ptr += bytes; if (scratch_free_ptr <= GC_scratch_end_ptr) { return(result); } { word bytes_to_get = MINHINCR * HBLKSIZE; if (bytes_to_get <= bytes) { /* Undo the damage, and get memory directly */ bytes_to_get = bytes; # ifdef USE_MMAP bytes_to_get += GC_page_size - 1; bytes_to_get &= ~(GC_page_size - 1); # endif result = (ptr_t)GET_MEM(bytes_to_get); GC_add_to_our_memory(result, bytes_to_get); scratch_free_ptr -= bytes; GC_scratch_last_end_ptr = result + bytes; return(result); } result = (ptr_t)GET_MEM(bytes_to_get); GC_add_to_our_memory(result, bytes_to_get); if (result == 0) { if (GC_print_stats) GC_printf("Out of memory - trying to allocate less\n"); scratch_free_ptr -= bytes; bytes_to_get = bytes; # ifdef USE_MMAP bytes_to_get += GC_page_size - 1; bytes_to_get &= ~(GC_page_size - 1); # endif result = (ptr_t)GET_MEM(bytes_to_get); GC_add_to_our_memory(result, bytes_to_get); return result; } scratch_free_ptr = result; GC_scratch_end_ptr = scratch_free_ptr + bytes_to_get; GC_scratch_last_end_ptr = GC_scratch_end_ptr; return(GC_scratch_alloc(bytes)); } }