static void add_block(int index) { header *h = find_block(pool_block(index), pool_size(index)); insert(block_pool[index], h); pool_total += pool_block(index); free_ptr[index] = h->h_memory; free_count[index] = pool_count(index); }
static void* pool_get(size_t index) { #ifdef USE_VALGRIND VALGRIND_DISABLE_ERROR_REPORTING; #endif pool_local_t* thread = &pool_local[index]; pool_global_t* global = &pool_global[index]; pool_item_t* p = thread->pool; if(p != NULL) { thread->pool = p->next; thread->length--; } else { p = pool_block(thread, global); if(p == NULL) { p = pool_pull(thread, global); if(p == NULL) p = pool_pages(thread, global); } } #ifdef USE_VALGRIND VALGRIND_ENABLE_ERROR_REPORTING; #endif return p; }
void *gc_alloc(value *desc, unsigned size, value *sp) { unsigned alloc_size; word *p = NULL; header *h; if (debug['z']) gc_collect(sp); size = round_up(size+4, BYTES_PER_WORD); if (size <= MAX_SMALL_BYTES) { /* Try to allocate from the appropriate pool */ unsigned index = pool_map(size); alloc_size = pool_size(index); ASSERT(alloc_size >= size); if (free_count[index] == 0) { while (pool_total + pool_block(index) > heap_size && free_count[index] == 0) scavenge(sp, pool_block(index)); if (free_count[index] == 0) add_block(index); } p = (word *) free_ptr[index]; free_ptr[index] += alloc_size; free_count[index]--; } else { /* Allocate whole pages */ alloc_size = round_up(size, GC_PAGESIZE); while (pool_total + alloc_size > heap_size) scavenge(sp, alloc_size); h = find_block(alloc_size, alloc_size); insert(block_pool[n_sizes], h); pool_total += alloc_size; p = (word *) h->h_memory; } alloc_since_gc += alloc_size; DEBUG_PRINT('c', ("[Alloc %d %p]", size, p)); *p = (word) desc; return p+1; }