static inline Partial_Reveal_Object *get_next_first_src_obj(Mspace *mspace) { Partial_Reveal_Object *first_src_obj; while(TRUE) { lock(current_dest_block.lock); Block_Header *next_dest_block = (Block_Header *)current_dest_block.block; if (!next_dest_block || !(first_src_obj = next_dest_block->src)) { next_dest_block = get_next_dest_block(mspace); if(!next_dest_block) { unlock(current_dest_block.lock); return NULL; } else if(next_dest_block == DEST_NOT_EMPTY) { unlock(current_dest_block.lock); while(check_dest_block(mspace)==DEST_NOT_EMPTY); continue; } first_src_obj = next_dest_block->src; if(next_dest_block->status == BLOCK_DEST) { assert(!next_dest_block->dest_counter); current_dest_block.block = next_dest_block; } } Partial_Reveal_Object *next_src_obj = GC_BLOCK_HEADER(first_src_obj)->next_src; if(next_src_obj && GC_BLOCK_HEADER(ref_to_obj_ptr((REF)get_obj_info_raw(next_src_obj))) != next_dest_block) { next_src_obj = NULL; } next_dest_block->src = next_src_obj; unlock(current_dest_block.lock); return first_src_obj; } }
Boolean gc_heap_copy_object_array(Managed_Object_Handle src_array, unsigned int src_start, Managed_Object_Handle dst_array, unsigned int dst_start, unsigned int length) { GC_VTable_Info *src_gcvt = obj_get_gcvt((Partial_Reveal_Object*)src_array); GC_VTable_Info *dst_gcvt = obj_get_gcvt((Partial_Reveal_Object*)dst_array); Class_Handle src_class = src_gcvt->gc_clss; Class_Handle dst_class = dst_gcvt->gc_clss; //element size of src should be same as element size of dst assert(src_gcvt->array_elem_size == dst_gcvt->array_elem_size); unsigned int elem_size = src_gcvt->array_elem_size; unsigned int src_first_elem_offset = array_first_element_offset((Partial_Reveal_Array*)src_array); unsigned int dst_first_elem_offset = array_first_element_offset((Partial_Reveal_Array*)dst_array); /* #ifdef COMPRESS_REFERENCE COMPRESSED_REFERENCE *src_copy_body = (COMPRESSED_REFERENCE *)((POINTER_SIZE_INT)src_array + src_first_elem_offset + elem_size*src_start); COMPRESSED_REFERENCE *dst_copy_body = (COMPRESSED_REFERENCE *)((POINTER_SIZE_INT)dst_array + dst_first_elem_offset + elem_size*dst_start); #else #endif */ REF* src_copy_body = (REF*)((POINTER_SIZE_INT)src_array + src_first_elem_offset + elem_size*src_start); REF* dst_copy_body = (REF*)((POINTER_SIZE_INT)dst_array + dst_first_elem_offset + elem_size*dst_start); if(class_is_instanceof(src_class, dst_class)) { //rem obj before is for OTF GC barriers if(WB_REM_OLD_VAR == write_barrier_function) { for (unsigned int count = 0; count < length; count++) { write_barrier_rem_slot_oldvar((Managed_Object_Handle *)dst_copy_body+count); } } else if(WB_REM_OBJ_SNAPSHOT == write_barrier_function) { write_barrier_rem_obj_snapshot(dst_array); } memmove(dst_copy_body, src_copy_body, length * elem_size); } else { //for the condition src is not the type of dst Class_Handle dst_elem_clss = class_get_array_element_class(dst_class); if(WB_REM_OBJ_SNAPSHOT == write_barrier_function) { write_barrier_rem_obj_snapshot(dst_array); } for (unsigned int count = 0; count < length; count++) { // 1, null elements copy direct if (src_copy_body[count] == NULL) { if(WB_REM_OLD_VAR == write_barrier_function) { write_barrier_rem_slot_oldvar((Managed_Object_Handle *)dst_copy_body+count); } dst_copy_body[count] = NULL; continue; } // 2, For non-null elements check if types are compatible. /* #ifdef COMPRESS_REFERENCE ManagedObject *src_elem = (ManagedObject *)uncompress_compressed_reference(src_elem_offset); Class_Handle src_elem_clss = src_elem->vt()->clss; #else #endif */ Class_Handle src_elem_clss = obj_get_gcvt(ref_to_obj_ptr(src_copy_body[count]))->gc_clss; if (!class_is_instanceof(src_elem_clss, dst_elem_clss)) { if(WB_REM_SOURCE_OBJ == write_barrier_function) { write_barrier_rem_source_obj(dst_array); } return FALSE; } if(WB_REM_OLD_VAR == write_barrier_function) { write_barrier_rem_slot_oldvar((Managed_Object_Handle *)dst_copy_body+count); } dst_copy_body[count] = src_copy_body[count]; } } //rem obj after is for mostly concurrent if(WB_REM_SOURCE_OBJ == write_barrier_function) { write_barrier_rem_source_obj(dst_array); } return TRUE; }