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; }
Vector_Block* gc_verifier_metadata_extend(Pool* pool, Boolean is_set_pool) { /*add a slot to pool point back to verifier_metadata, then we do not need the global var verifer_metadata*/ lock(verifier_metadata->alloc_lock); Vector_Block* block = pool_get_entry(pool); if( block ){ unlock(verifier_metadata->alloc_lock); return block; } unsigned int num_alloced = verifier_metadata->num_alloc_segs; if(num_alloced == METADATA_SEGMENT_NUM){ printf("Run out GC metadata, please give it more segments!\n"); exit(0); } unsigned int seg_size = GC_VERIFIER_METADATA_EXTEND_SIZE_BYTES + GC_VERIFIER_METADATA_BLOCK_SIZE_BYTES; void *new_segment = STD_MALLOC(seg_size); assert(new_segment); memset(new_segment, 0, seg_size); verifier_metadata->segments[num_alloced] = new_segment; new_segment = (void*)round_up_to_size((POINTER_SIZE_INT)new_segment, GC_VERIFIER_METADATA_BLOCK_SIZE_BYTES); verifier_metadata->num_alloc_segs = num_alloced + 1; unsigned int num_blocks = GC_VERIFIER_METADATA_EXTEND_SIZE_BYTES/GC_VERIFIER_METADATA_BLOCK_SIZE_BYTES; unsigned int i=0; for(i=0; i<num_blocks; i++){ Vector_Block* block = (Vector_Block*)((POINTER_SIZE_INT)new_segment + i*GC_VERIFIER_METADATA_BLOCK_SIZE_BYTES); vector_block_init(block, GC_VERIFIER_METADATA_BLOCK_SIZE_BYTES); assert(vector_block_is_empty(block)); } if(is_set_pool){ for(i=0; i<num_blocks; i++){ POINTER_SIZE_INT block = (POINTER_SIZE_INT)new_segment + i*GC_VERIFIER_METADATA_BLOCK_SIZE_BYTES; pool_put_entry(pool, (void*)block); } }else{ for(i=0; i<num_blocks; i++){ Vector_Block *block = (Vector_Block *)((POINTER_SIZE_INT)new_segment + i*GC_VERIFIER_METADATA_BLOCK_SIZE_BYTES); vector_stack_init(block); pool_put_entry(pool, (void*)block); } } block = pool_get_entry(pool); unlock(verifier_metadata->alloc_lock); return block; }
Vector_Block* gc_get_local_dirty_set(GC* gc, unsigned int shared_id) { lock(gc->mutator_list_lock); Mutator *mutator = gc->mutator_list; while (mutator) { Vector_Block* local_dirty_set = mutator->dirty_set; if(!vector_block_is_empty(local_dirty_set) && vector_block_set_shared(local_dirty_set,shared_id)){ unlock(gc->mutator_list_lock); return local_dirty_set; } mutator = mutator->next; } unlock(gc->mutator_list_lock); return NULL; }
Boolean gc_local_dirtyset_is_empty(GC* gc) { lock(gc->mutator_list_lock); Mutator *mutator = gc->mutator_list; while (mutator) { Vector_Block* local_dirty_set = mutator->dirty_set; if(!vector_block_is_empty(local_dirty_set)){ unlock(gc->mutator_list_lock); return FALSE; } mutator = mutator->next; } unlock(gc->mutator_list_lock); return TRUE; }
static Boolean dirty_set_is_empty(GC *gc) { lock(gc->mutator_list_lock); Mutator *mutator = gc->mutator_list; while (mutator) { Vector_Block* local_dirty_set = mutator->dirty_set; if(!vector_block_is_empty(local_dirty_set)){ unlock(gc->mutator_list_lock); return FALSE; } mutator = mutator->next; } GC_Metadata *metadata = gc->metadata; Boolean is_empty = pool_is_empty(metadata->gc_dirty_set_pool); unlock(gc->mutator_list_lock); //unlock put here to prevent creating new mutators before checking global dirty set return is_empty; }
void mutator_initialize(GC* gc, void *unused_gc_information) { /* FIXME:: make sure gc_info is cleared */ Mutator *mutator = (Mutator *)STD_MALLOC(sizeof(Mutator)); memset(mutator, 0, sizeof(Mutator)); mutator->alloc_space = gc_get_nos((GC_Gen*)gc); mutator->gc = gc; if(gc_is_gen_mode()){ mutator->rem_set = free_set_pool_get_entry(gc->metadata); assert(vector_block_is_empty(mutator->rem_set)); } mutator->dirty_set = free_set_pool_get_entry(gc->metadata); if(!IGNORE_FINREF ) mutator->obj_with_fin = finref_get_free_block(gc); else mutator->obj_with_fin = NULL; #ifdef USE_UNIQUE_MARK_SWEEP_GC allocator_init_local_chunks((Allocator*)mutator); #endif lock(gc->mutator_list_lock); // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv mutator->next = (Mutator *)gc->mutator_list; gc->mutator_list = mutator; gc->num_mutators++; /*Begin to measure the mutator thread execution time. */ mutator->time_measurement_start = time_now(); unlock(gc->mutator_list_lock); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ gc_set_tls(mutator); return; }