/*<--------all (live and dead) objects scanner begin-------->*/ static FORCE_INLINE void verifier_scan_object_slots(Partial_Reveal_Object *p_obj, Heap_Verifier* heap_verifier) { verifier_allocation_update_info(p_obj, heap_verifier); verify_object_header(p_obj, heap_verifier); if (!object_has_ref_field(p_obj)) return; REF* p_ref; if (object_is_array(p_obj)){ Partial_Reveal_Array* array = (Partial_Reveal_Array*)p_obj; unsigned int array_length = array->array_len; p_ref = (REF*)((POINTER_SIZE_INT)array + (int)array_first_element_offset(array)); for (unsigned int i = 0; i < array_length; i++) { verify_write_barrier(p_ref+i, heap_verifier); if( read_slot(p_ref+i) != NULL) verify_all_object_slot(p_ref+i, heap_verifier); // if(!is_unreachable_obj(p_obj)){ // verify_write_barrier(p_ref+i, heap_verifier); // if( read_slot(p_ref+i) != NULL) verify_live_object_slot(p_ref+i, heap_verifier); // }else{ // if( read_slot(p_ref+i) != NULL) verify_all_object_slot(p_ref+i, heap_verifier); // } } }else{ unsigned int num_refs = object_ref_field_num(p_obj); int* ref_iterator = object_ref_iterator_init(p_obj); for(unsigned int i=0; i<num_refs; i++){ p_ref = object_ref_iterator_get(ref_iterator+i, p_obj); verify_write_barrier(p_ref, heap_verifier); if( read_slot(p_ref) != NULL) verify_all_object_slot(p_ref, heap_verifier); //if(!is_unreachable_obj(p_obj)){ // verify_write_barrier(p_ref, heap_verifier); // if( read_slot(p_ref) != NULL) verify_live_object_slot(p_ref, heap_verifier); //}else{ // if( read_slot(p_ref) != NULL) verify_all_object_slot(p_ref, heap_verifier); //} } #ifndef BUILD_IN_REFERENT WeakReferenceType type = special_reference_type(p_obj); if(type == NOT_REFERENCE) return; //if(type != SOFT_REFERENCE && verifier_collect_is_minor(heap_verifier->gc_verifier)){ { p_ref = obj_get_referent_field(p_obj); verify_write_barrier(p_ref, heap_verifier); if( read_slot(p_ref) != NULL) verify_all_object_slot(p_ref, heap_verifier); //if(!is_unreachable_obj(p_obj)){ // verify_write_barrier(p_ref, heap_verifier); // if( read_slot(p_ref) != NULL) verify_live_object_slot(p_ref, heap_verifier); //}else{ // if( read_slot(p_ref) != NULL) verify_all_object_slot(p_ref, heap_verifier); //} } #endif } return; }
static FORCE_INLINE void scan_object(Collector* collector, Partial_Reveal_Object *p_obj) { vm_notify_obj_alive( (void *)p_obj); assert((((POINTER_SIZE_INT)p_obj) % GC_OBJECT_ALIGNMENT) == 0); Partial_Reveal_VTable *vtable = decode_vt(obj_get_vt(p_obj)); if(TRACE_JLC_VIA_VTABLE) if(vtable->vtmark == VT_UNMARKED) { vtable->vtmark = VT_MARKED; if(obj_mark_in_vt(vtable->jlC)) collector_tracestack_push(collector, vtable->jlC); } if( !object_has_ref_field(p_obj) ) return; REF *p_ref; if (object_is_array(p_obj)) { /* scan array object */ Partial_Reveal_Array* array = (Partial_Reveal_Array*)p_obj; unsigned int array_length = array->array_len; p_ref = (REF *)((POINTER_SIZE_INT)array + (int)array_first_element_offset(array)); for (unsigned int i = 0; i < array_length; i++) { scan_slot(collector, p_ref+i); } }else{ /* scan non-array object */ unsigned int num_refs = object_ref_field_num(p_obj); int* ref_iterator = object_ref_iterator_init(p_obj); for(unsigned int i=0; i<num_refs; i++){ p_ref = object_ref_iterator_get(ref_iterator+i, p_obj); scan_slot(collector, p_ref); } #ifndef BUILD_IN_REFERENT scan_weak_reference(collector, p_obj, scan_slot); #endif } return; }
static FORCE_INLINE void scan_object(Conclctor* marker, Partial_Reveal_Object *p_obj) { assert((((POINTER_SIZE_INT)p_obj) % GC_OBJECT_ALIGNMENT) == 0); if(obj_is_dirty_in_table(p_obj)){ assert(obj_is_mark_black_in_table(p_obj)); return; } if(!object_has_ref_field(p_obj)) return; REF *p_ref; if(object_is_array(p_obj)){ /* scan array object */ Partial_Reveal_Array *array = (Partial_Reveal_Array*)p_obj; unsigned int array_length = array->array_len; p_ref = (REF *)((POINTER_SIZE_INT)array + (int)array_first_element_offset(array)); for (unsigned int i = 0; i < array_length; i++) scan_slot((Collector*)marker, p_ref+i); return; } /* scan non-array object */ unsigned int num_refs = object_ref_field_num(p_obj); int *ref_iterator = object_ref_iterator_init(p_obj); for(unsigned int i=0; i<num_refs; i++){ p_ref = object_ref_iterator_get(ref_iterator+i, p_obj); scan_slot((Collector*)marker, p_ref); } #ifndef BUILD_IN_REFERENT scan_weak_reference_direct((Collector*)marker, p_obj, scan_slot); #endif }
static FORCE_INLINE void scan_object(Heap_Verifier* heap_verifier, Partial_Reveal_Object *p_obj) { GC_Verifier* gc_verifier = heap_verifier->gc_verifier; #if !defined(USE_UNIQUE_MARK_SWEEP_GC) && !defined(USE_UNIQUE_MOVE_COMPACT_GC) if(gc_verifier->is_before_fallback_collection) { if(obj_belongs_to_nos(p_obj) && obj_is_fw_in_oi(p_obj)){ assert(obj_get_vt(p_obj) == obj_get_vt(obj_get_fw_in_oi(p_obj))); p_obj = obj_get_fw_in_oi(p_obj); assert(p_obj); } } #endif if(!obj_mark_in_vt(p_obj)) return; if( !major_is_marksweep() && p_obj >= los_boundary ){ Block_Header* block = GC_BLOCK_HEADER(p_obj); if( heap_verifier->is_before_gc) block->num_live_objs++; /* we can't set block->num_live_objs = 0 if !is_before_gc, because the some blocks may be freed hence not visited after GC. So we should reset it in GC space reset functions. */ } verify_object_header(p_obj, heap_verifier); verifier_update_verify_info(p_obj, heap_verifier); /*FIXME: */ if (!object_has_ref_field(p_obj)) return; REF* p_ref; if (object_is_array(p_obj)) { Partial_Reveal_Array* array = (Partial_Reveal_Array*)p_obj; unsigned int array_length = array->array_len; p_ref = (REF*)((POINTER_SIZE_INT)array + (int)array_first_element_offset(array)); for (unsigned int i = 0; i < array_length; i++) { scan_slot(heap_verifier, p_ref+i); } }else{ unsigned int num_refs = object_ref_field_num(p_obj); int* ref_iterator = object_ref_iterator_init(p_obj); for(unsigned int i=0; i<num_refs; i++){ p_ref = object_ref_iterator_get(ref_iterator+i, p_obj); scan_slot(heap_verifier, p_ref); } #ifndef BUILD_IN_REFERENT WeakReferenceType type = special_reference_type(p_obj); if(type == SOFT_REFERENCE && verifier_collect_is_minor(gc_verifier)){ p_ref = obj_get_referent_field(p_obj); scan_slot(heap_verifier, p_ref); } #endif } return; }
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; }