static Boolean mspace_alloc_block(Mspace* mspace, Allocator* allocator) { alloc_context_reset(allocator); /* now try to get a new block */ unsigned int old_free_idx = mspace->free_block_idx; unsigned int new_free_idx = old_free_idx+1; while( old_free_idx <= mspace->ceiling_block_idx ){ unsigned int allocated_idx = atomic_cas32(&mspace->free_block_idx, new_free_idx, old_free_idx); if(allocated_idx != old_free_idx){ old_free_idx = mspace->free_block_idx; new_free_idx = old_free_idx+1; continue; } /* ok, got one */ Block_Header* alloc_block = (Block_Header*)&(mspace->blocks[allocated_idx - mspace->first_block_idx]); allocator_init_free_block(allocator, alloc_block); return TRUE; } /* Mspace is out. If it's caused by mutator, a collection should be triggered. If it's caused by collector, a fallback should be triggered. */ return FALSE; }
void gc_reset_mutator_context(GC* gc) { TRACE2("gc.process", "GC: reset mutator context ...\n"); Mutator *mutator = gc->mutator_list; while (mutator) { alloc_context_reset((Allocator*)mutator); mutator = mutator->next; } return; }
void mutator_destruct(GC* gc, void *unused_gc_information) { Mutator *mutator = (Mutator *)gc_get_tls(); alloc_context_reset((Allocator*)mutator); lock(gc->mutator_list_lock); // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv #ifdef USE_UNIQUE_MARK_SWEEP_GC allocactor_destruct_local_chunks((Allocator*)mutator); #endif mutator_register_new_obj_size(mutator); volatile Mutator *temp = gc->mutator_list; if (temp == mutator) { /* it is at the head of the list */ gc->mutator_list = temp->next; } else { while (temp->next != mutator) { temp = temp->next; assert(temp); } temp->next = mutator->next; } gc->num_mutators--; unlock(gc->mutator_list_lock); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ if(gc_is_gen_mode()){ /* put back the remset when a mutator exits */ pool_put_entry(gc->metadata->mutator_remset_pool, mutator->rem_set); mutator->rem_set = NULL; } if(mutator->obj_with_fin){ pool_put_entry(gc->finref_metadata->obj_with_fin_pool, mutator->obj_with_fin); mutator->obj_with_fin = NULL; } lock(mutator->dirty_set_lock); if( mutator->dirty_set != NULL){ if(vector_block_is_empty(mutator->dirty_set)) pool_put_entry(gc->metadata->free_set_pool, mutator->dirty_set); else{ /* FIXME:: this condition may be released. */ pool_put_entry(gc->metadata->gc_dirty_set_pool, mutator->dirty_set); mutator->dirty_set = NULL; } } unlock(mutator->dirty_set_lock); STD_FREE(mutator); gc_set_tls(NULL); return; }