/* Finalizable objs falls back to objs with fin when resurrection fallback happens */ static void finalizable_objs_fallback(GC *gc) { Finref_Metadata *metadata = gc->finref_metadata; Pool *finalizable_obj_pool = metadata->finalizable_obj_pool; Pool *obj_with_fin_pool = metadata->obj_with_fin_pool; Vector_Block *obj_with_fin_block = finref_get_free_block(gc); Vector_Block *block = pool_get_entry(finalizable_obj_pool); while(block){ POINTER_SIZE_INT *iter = vector_block_iterator_init(block); for(; !vector_block_iterator_end(block, iter); iter = vector_block_iterator_advance(block, iter)){ REF *p_ref = (REF*)iter; Partial_Reveal_Object *p_obj = read_slot(p_ref); assert(p_obj); /* Perhaps obj has been resurrected by previous resurrections. If the fin-obj was resurrected, we need put it back to obj_with_fin pool. For minor collection, the resurrected obj was forwarded, so we need use the new copy.*/ if(!gc_obj_is_dead(gc, p_obj) && obj_belongs_to_nos(p_obj)){ /* Even in NOS, not all live objects are forwarded due to the partial-forward algortihm */ if(!NOS_PARTIAL_FORWARD || fspace_obj_to_be_forwarded(p_obj)){ write_slot(p_ref , obj_get_fw_in_oi(p_obj)); p_obj = read_slot(p_ref); } } /* Perhaps obj_with_fin_block has been allocated with a new free block if it is full */ obj_with_fin_block = gc_add_finalizer(gc, obj_with_fin_block, p_obj); } block = pool_get_entry(finalizable_obj_pool); } pool_put_entry(obj_with_fin_pool, obj_with_fin_block); metadata->pending_finalizers = FALSE; }
static void dead_weak_refs_fallback(GC *gc, Pool *ref_pool) { Finref_Metadata *metadata = gc->finref_metadata; Pool *free_pool = metadata->free_pool; Pool *fallback_ref_pool = metadata->fallback_ref_pool; Vector_Block *fallback_ref_block = finref_get_free_block(gc); Vector_Block *block = pool_get_entry(ref_pool); while(block){ POINTER_SIZE_INT *iter = vector_block_iterator_init(block); while(!vector_block_iterator_end(block, iter)){ Partial_Reveal_Object *p_obj = read_slot((REF*)iter); /* Perhaps fallback_ref_block has been allocated with a new free block if it is full */ if(p_obj) fallback_ref_block = finref_add_fallback_ref(gc, fallback_ref_block, p_obj); iter = vector_block_iterator_advance(block, iter); } vector_block_clear(block); pool_put_entry(free_pool, block); block = pool_get_entry(ref_pool); } pool_put_entry(fallback_ref_pool, fallback_ref_block); }
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; }