void wspace_compact(Collector *collector, Wspace *wspace) { Chunk_Header *least_free_chunk, *most_free_chunk; Pool *pfc_pool = wspace_grab_next_pfc_pool(wspace); for(; pfc_pool; pfc_pool = wspace_grab_next_pfc_pool(wspace)){ if(pool_is_empty(pfc_pool)) continue; Boolean pfc_pool_need_compact = pfc_pool_roughly_sort(pfc_pool, &least_free_chunk, &most_free_chunk); if(!pfc_pool_need_compact) continue; Chunk_Header *dest = get_least_free_chunk(&least_free_chunk, &most_free_chunk); Chunk_Header *src = get_most_free_chunk(&least_free_chunk, &most_free_chunk); Boolean src_is_new = TRUE; while(dest && src){ if(src_is_new) src->slot_index = 0; //chunk_depad_last_index_word(src); move_obj_between_chunks(wspace, &dest, src); if(!dest) dest = get_least_free_chunk(&least_free_chunk, &most_free_chunk); if(!src->alloc_num){ collector_add_free_chunk(collector, (Free_Chunk*)src); src = get_most_free_chunk(&least_free_chunk, &most_free_chunk); src_is_new = TRUE; } else { src_is_new = FALSE; } } /* Rebuild the pfc_pool */ if(dest) wspace_put_pfc(wspace, dest); if(src){ //chunk_pad_last_index_word(src, cur_alloc_mask); pfc_reset_slot_index(src); wspace_put_pfc(wspace, src); } } }
static void *wspace_alloc_normal_obj(Wspace *wspace, unsigned size, Allocator *allocator) { Size_Segment *size_seg = wspace_get_size_seg(wspace, size); unsigned int seg_index = size_seg->seg_index; size = (unsigned int)NORMAL_SIZE_ROUNDUP(size, size_seg); unsigned int index = NORMAL_SIZE_TO_INDEX(size, size_seg); Chunk_Header *chunk = NULL; void *p_obj = NULL; if(size_seg->local_alloc){ Chunk_Header **chunks = allocator->local_chunks[seg_index]; chunk = chunks[index]; if(!chunk){ mutator_post_signal((Mutator*) allocator,HSIG_DISABLE_SWEEP_LOCAL_CHUNKS); chunk = wspace_get_pfc(wspace, seg_index, index); if(!chunk){ chunk = (Chunk_Header*)wspace_get_normal_free_chunk(wspace); if(chunk) normal_chunk_init(chunk, size); } //if(!chunk) chunk = wspace_steal_pfc(wspace, seg_index, index); if(!chunk){ mutator_post_signal((Mutator*) allocator,HSIG_MUTATOR_SAFE); //INFO2("gc.wspace", "[Local Alloc Failed] alloc obj with size" << size << " bytes" ); return NULL; } chunk->status |= CHUNK_IN_USE; chunks[index] = chunk; mutator_post_signal((Mutator*) allocator,HSIG_MUTATOR_SAFE); } mutator_post_signal((Mutator*) allocator,HSIG_MUTATOR_ENTER_ALLOC_MARK); p_obj = alloc_in_chunk(chunks[index]); mutator_post_signal((Mutator*) allocator,HSIG_MUTATOR_SAFE); if(chunk->slot_index == MAX_SLOT_INDEX){ chunk->status = CHUNK_USED | CHUNK_NORMAL; /*register to used chunk list.*/ wspace_reg_used_chunk(wspace,chunk); chunks[index] = NULL; } } else { mutator_post_signal((Mutator*) allocator,HSIG_DISABLE_SWEEP_GLOBAL_CHUNKS); if(gc_is_specify_con_sweep()){ while(gc_is_sweep_global_normal_chunk()){ mutator_post_signal((Mutator*) allocator,HSIG_MUTATOR_SAFE); } } chunk = wspace_get_pfc(wspace, seg_index, index); if(!chunk){ chunk = (Chunk_Header*)wspace_get_normal_free_chunk(wspace); if(chunk) normal_chunk_init(chunk, size); } //if(!chunk) chunk = wspace_steal_pfc(wspace, seg_index, index); if(!chunk) { mutator_post_signal((Mutator*) allocator,HSIG_MUTATOR_SAFE); //INFO2("gc.wspace", "[Non-Local Alloc Failed] alloc obj with size" << size << " bytes" ); return NULL; } p_obj = alloc_in_chunk(chunk); if(chunk->slot_index == MAX_SLOT_INDEX){ chunk->status = CHUNK_USED | CHUNK_NORMAL; /*register to used chunk list.*/ wspace_reg_used_chunk(wspace,chunk); chunk = NULL; } if(chunk){ wspace_put_pfc(wspace, chunk); } mutator_post_signal((Mutator*) allocator,HSIG_MUTATOR_SAFE); } if(p_obj) { ((Mutator*)allocator)->new_obj_occupied_size+=size; } return p_obj; }