Index: src/common/gc_common.cpp =================================================================== --- src/common/gc_common.cpp (revision 542506) +++ src/common/gc_common.cpp (working copy) @@ -46,7 +46,7 @@ extern unsigned int MAJOR_COLLECTORS; POINTER_SIZE_INT HEAP_SIZE_DEFAULT = 256 * MB; -POINTER_SIZE_INT min_heap_size_bytes = 32 * MB; +POINTER_SIZE_INT min_heap_size_bytes = 16 * MB; POINTER_SIZE_INT max_heap_size_bytes = 0; extern Boolean JVMTI_HEAP_ITERATION ; @@ -326,18 +326,12 @@ #endif } - //For_LOS_extend! gc_space_tuner_reset(gc); - + gc_assign_free_area_to_mutators(gc); vm_reclaim_native_objs(); - vm_resume_threads_after(); return; } - - - - Index: src/common/gc_common.h =================================================================== --- src/common/gc_common.h (revision 542506) +++ src/common/gc_common.h (working copy) @@ -69,7 +69,7 @@ #define BYTES_OF_POINTER_SIZE_INT (sizeof(POINTER_SIZE_INT)) #define BIT_SHIFT_TO_BYTES_OF_POINTER_SIZE_INT ((sizeof(POINTER_SIZE_INT)==4)? 2: 3) -#define GC_OBJ_SIZE_THRESHOLD (4*KB) +#define GC_OBJ_SIZE_THRESHOLD (5*KB) #define USE_32BITS_HASHCODE Index: src/common/gc_for_vm.cpp =================================================================== --- src/common/gc_for_vm.cpp (revision 542506) +++ src/common/gc_for_vm.cpp (working copy) @@ -222,7 +222,7 @@ if(!hash) hash = (0x173 & GCGEN_HASH_MASK); unsigned int new_info = (unsigned int)(info | hash); while (true) { - unsigned int temp = atomic_cas32(&obj->obj_info, new_info, info); + unsigned int temp = atomic_cas32((volatile unsigned int*)(&obj->obj_info), new_info, info); if (temp == info) break; info = get_obj_info_raw(obj); new_info = (unsigned int)(info | hash); @@ -253,7 +253,7 @@ case HASHCODE_UNSET: new_info = (unsigned int)(info | HASHCODE_SET_BIT); while (true) { - unsigned int temp = atomic_cas32(&p_obj->obj_info, new_info, info); + unsigned int temp = atomic_cas32((volatile unsigned int*)(&p_obj->obj_info), new_info, info); if (temp == info) break; info = get_obj_info_raw(p_obj); new_info = (unsigned int)(info | HASHCODE_SET_BIT); Index: src/common/space_tuner.cpp =================================================================== --- src/common/space_tuner.cpp (revision 542506) +++ src/common/space_tuner.cpp (working copy) @@ -138,7 +138,9 @@ lspace->move_object = 0; } - /*If los or non-los is already the smallest size, there is no need to tune anymore.*/ + /*If los or non-los is already the smallest size, there is no need to tune anymore. + *But we give "force tune" a chance to extend the whole heap size down there. + */ if(((lspace->committed_heap_size <= min_los_size_bytes) && (tuner->kind == TRANS_FROM_LOS_TO_MOS)) || ((fspace->committed_heap_size + mspace->committed_heap_size <= min_none_los_size_bytes) && (tuner->kind == TRANS_FROM_MOS_TO_LOS))){ assert((lspace->committed_heap_size == min_los_size_bytes) || (fspace->committed_heap_size + mspace->committed_heap_size == min_none_los_size_bytes)); @@ -173,10 +175,10 @@ non_los_live_obj_size += collector->non_los_live_obj_size; los_live_obj_size += collector->los_live_obj_size; } + + POINTER_SIZE_INT additional_non_los_size = ((collector_num * 2) << GC_BLOCK_SHIFT_COUNT) + (non_los_live_obj_size >> GC_BLOCK_SHIFT_COUNT) * (GC_OBJ_SIZE_THRESHOLD/4); + non_los_live_obj_size = round_up_to_size(non_los_live_obj_size + additional_non_los_size, GC_BLOCK_SIZE_BYTES); - non_los_live_obj_size += ((collector_num << 2) << GC_BLOCK_SHIFT_COUNT); - non_los_live_obj_size = round_up_to_size(non_los_live_obj_size, GC_BLOCK_SIZE_BYTES); - los_live_obj_size += ((collector_num << 2) << GC_BLOCK_SHIFT_COUNT); los_live_obj_size = round_up_to_size(los_live_obj_size, GC_BLOCK_SIZE_BYTES); @@ -210,50 +212,63 @@ /*If force tune*/ if( (tuner->force_tune) && (doforce) ){ + POINTER_SIZE_INT lspace_free_size = + ( (lspace->committed_heap_size > los_live_obj_size) ? (lspace->committed_heap_size - los_live_obj_size) : (0) ); + //debug_adjust + assert(!(lspace_free_size % KB)); + assert(!(failure_size % KB)); - tuner->tuning_size = failure_size; - - /*We should assure that the tuning size is no more than the free space of non_los area*/ - if( gc->committed_heap_size > lspace->committed_heap_size + non_los_live_obj_size ) - max_tuning_size = gc->committed_heap_size - lspace->committed_heap_size - non_los_live_obj_size; + if(lspace_free_size >= failure_size){ + tuner->tuning_size = 0; + tuner->kind = TRANS_NOTHING; + lspace->move_object = 1; + return; + }else{ + tuner->tuning_size = failure_size -lspace_free_size; + + /*We should assure that the tuning size is no more than the free space of non_los area*/ + if( gc->committed_heap_size > lspace->committed_heap_size + non_los_live_obj_size ) + max_tuning_size = gc->committed_heap_size - lspace->committed_heap_size - non_los_live_obj_size; - if(max_tuning_size > max_tune_for_min_non_los) - max_tuning_size = max_tune_for_min_non_los; + if(max_tuning_size > max_tune_for_min_non_los) + max_tuning_size = max_tune_for_min_non_los; - /*Round up to satisfy LOS alloc demand.*/ - tuner->tuning_size = round_up_to_size(tuner->tuning_size, GC_BLOCK_SIZE_BYTES); - max_tuning_size = round_down_to_size(max_tuning_size, GC_BLOCK_SIZE_BYTES); + /*Round up to satisfy LOS alloc demand.*/ + tuner->tuning_size = round_up_to_size(tuner->tuning_size, GC_BLOCK_SIZE_BYTES); + max_tuning_size = round_down_to_size(max_tuning_size, GC_BLOCK_SIZE_BYTES); - /*If the tuning size is too large, we did nothing and wait for the OOM of JVM*/ - /*Fixme: if the heap size is not mx, we can extend the whole heap size*/ - if(tuner->tuning_size > max_tuning_size){ - tuner->tuning_size = round_up_to_size(tuner->tuning_size, SPACE_ALLOC_UNIT); - max_tuning_size = round_down_to_size(max_tuning_size, SPACE_ALLOC_UNIT); + /*If the tuning size is too large, we did nothing and wait for the OOM of JVM*/ + /*Fixme: if the heap size is not mx, we can extend the whole heap size*/ + if(tuner->tuning_size > max_tuning_size){ + tuner->tuning_size = round_up_to_size(tuner->tuning_size, SPACE_ALLOC_UNIT); + max_tuning_size = round_down_to_size(max_tuning_size, SPACE_ALLOC_UNIT); + //debug_adjust + assert(max_heap_size_bytes >= gc->committed_heap_size); + POINTER_SIZE_INT extend_heap_size = 0; + POINTER_SIZE_INT potential_max_tuning_size = max_tuning_size + max_heap_size_bytes - gc->committed_heap_size; + potential_max_tuning_size -= LOS_HEAD_RESERVE_FOR_HEAP_NULL; + //debug_adjust - assert(max_heap_size_bytes >= gc->committed_heap_size); - POINTER_SIZE_INT extend_heap_size = 0; - POINTER_SIZE_INT potential_max_heap_size = max_tuning_size + max_heap_size_bytes - gc->committed_heap_size; - potential_max_heap_size -= LOS_HEAD_RESERVE_FOR_HEAP_NULL; - - //debug_adjust - assert(!(potential_max_heap_size % SPACE_ALLOC_UNIT)); - if(tuner->tuning_size > potential_max_heap_size){ - tuner->tuning_size = 0; - tuner->kind = TRANS_NOTHING; - lspace->move_object = 0; - }else{ - extend_heap_size = tuner->tuning_size - max_tuning_size; - blocked_space_extend(fspace, (unsigned int)extend_heap_size); - gc->committed_heap_size += extend_heap_size; + assert(!(potential_max_tuning_size % SPACE_ALLOC_UNIT)); + if(tuner->tuning_size > potential_max_tuning_size){ + tuner->tuning_size = 0; + tuner->kind = TRANS_NOTHING; + lspace->move_object = 0; + }else{ + //We have tuner->tuning_size > max_tuning_size up there. + extend_heap_size = tuner->tuning_size - max_tuning_size; + blocked_space_extend(fspace, (unsigned int)extend_heap_size); + gc->committed_heap_size += extend_heap_size; + tuner->kind = TRANS_FROM_MOS_TO_LOS; + lspace->move_object = 1; + } + } + else + { tuner->kind = TRANS_FROM_MOS_TO_LOS; - lspace->move_object = 0; + lspace->move_object = 1; } } - else - { - tuner->kind = TRANS_FROM_MOS_TO_LOS; - lspace->move_object = 0; - } } /*No force tune, LOS_Extend:*/ else if(tuner->kind == TRANS_FROM_MOS_TO_LOS) Index: src/gen/gen.cpp =================================================================== --- src/gen/gen.cpp (revision 542506) +++ src/gen/gen.cpp (working copy) @@ -394,7 +394,8 @@ if(new_heap_total_size <= heap_total_size) return; - if(new_heap_total_size > max_heap_size_bytes - LOS_HEAD_RESERVE_FOR_HEAP_NULL) + /*If there is only small piece of area left not committed, we just merge it into the heap at once*/ + if(new_heap_total_size + (max_heap_size_bytes >> 5) > max_heap_size_bytes - LOS_HEAD_RESERVE_FOR_HEAP_NULL) new_heap_total_size = max_heap_size_bytes - LOS_HEAD_RESERVE_FOR_HEAP_NULL; adjust_size = new_heap_total_size - heap_total_size; Index: src/mark_sweep/lspace.h =================================================================== --- src/mark_sweep/lspace.h (revision 542506) +++ src/mark_sweep/lspace.h (working copy) @@ -49,7 +49,7 @@ /*LOS_Shrink:This field stands for sliding compact to lspace */ Boolean move_object; /*For_statistic: size allocated science last time collect los, ie. last major*/ - POINTER_SIZE_INT alloced_size; + volatile POINTER_SIZE_INT alloced_size; /*For_statistic: size survived after lspace_sweep*/ POINTER_SIZE_INT surviving_size; /* END of Space --> */ Index: src/mark_sweep/lspace_alloc_collect.cpp =================================================================== --- src/mark_sweep/lspace_alloc_collect.cpp (revision 542506) +++ src/mark_sweep/lspace_alloc_collect.cpp (working copy) @@ -321,22 +321,24 @@ switch(tuner->kind){ case TRANS_FROM_MOS_TO_LOS:{ - assert(!lspace->move_object); - void* origin_end = lspace->heap_end; - lspace->heap_end = (void*)(((GC_Gen*)gc)->mos->blocks); - /*The assumption that the first word of one KB must be zero when iterating lspace in - that function lspace_get_next_marked_object is not true*/ - Free_Area* trans_fa = free_area_new(origin_end, trans_size); - free_pool_add_area(lspace->free_pool, trans_fa); + if(lspace->move_object){ + assert(tuner->force_tune); + Block* mos_first_block = ((GC_Gen*)gc)->mos->blocks; + lspace->heap_end = (void*)mos_first_block; + assert(!(tuner->tuning_size % GC_BLOCK_SIZE_BYTES)); + new_fa_size = (POINTER_SIZE_INT)lspace->scompact_fa_end - (POINTER_SIZE_INT)lspace->scompact_fa_start + tuner->tuning_size; + Free_Area* fa = free_area_new(lspace->scompact_fa_start, new_fa_size); + if(new_fa_size >= GC_OBJ_SIZE_THRESHOLD) free_pool_add_area(lspace->free_pool, fa); + }else{ + void* origin_end = lspace->heap_end; + lspace->heap_end = (void*)(((GC_Gen*)gc)->mos->blocks); + /*The assumption that the first word of one KB must be zero when iterating lspace in + that function lspace_get_next_marked_object is not true*/ + Free_Area* trans_fa = free_area_new(origin_end, trans_size); + if(trans_size >= GC_OBJ_SIZE_THRESHOLD) free_pool_add_area(lspace->free_pool, trans_fa); + } lspace->committed_heap_size += trans_size; lspace->reserved_heap_size += trans_size; - if(lspace->move_object){ - Block* mos_first_block = ((GC_Gen*)gc)->mos->blocks; - lspace->heap_end = (void*)mos_first_block; - new_fa_size = (POINTER_SIZE_INT)lspace->scompact_fa_end - (POINTER_SIZE_INT)lspace->scompact_fa_start; - Free_Area* fa = free_area_new(lspace->scompact_fa_start, new_fa_size); - if(new_fa_size >= GC_OBJ_SIZE_THRESHOLD) free_pool_add_area(lspace->free_pool, fa); - } break; } case TRANS_FROM_LOS_TO_MOS:{ @@ -351,7 +353,7 @@ assert((POINTER_SIZE_INT)lspace->scompact_fa_end > (POINTER_SIZE_INT)lspace->scompact_fa_start + tuner->tuning_size); new_fa_size = (POINTER_SIZE_INT)lspace->scompact_fa_end - (POINTER_SIZE_INT)lspace->scompact_fa_start - tuner->tuning_size; Free_Area* fa = free_area_new(lspace->scompact_fa_start, new_fa_size); - free_pool_add_area(lspace->free_pool, fa); + if(new_fa_size >= GC_OBJ_SIZE_THRESHOLD) free_pool_add_area(lspace->free_pool, fa); break; } default:{ @@ -360,7 +362,7 @@ assert(!tuner->tuning_size); new_fa_size = (POINTER_SIZE_INT)lspace->scompact_fa_end - (POINTER_SIZE_INT)lspace->scompact_fa_start; Free_Area* fa = free_area_new(lspace->scompact_fa_start, new_fa_size); - free_pool_add_area(lspace->free_pool, fa); + if(new_fa_size >= GC_OBJ_SIZE_THRESHOLD) free_pool_add_area(lspace->free_pool, fa); } break; } Index: src/thread/collector_alloc.h =================================================================== --- src/thread/collector_alloc.h (revision 542506) +++ src/thread/collector_alloc.h (working copy) @@ -61,7 +61,7 @@ /* else, take the obj by setting the forwarding flag atomically we don't put a simple bit in vt because we need compute obj size later. */ REF target = obj_ptr_to_ref(p_targ_obj); - if (oi != (Obj_Info_Type)atomic_cas32(get_obj_info_addr(p_obj), ( ( (unsigned int)target |FORWARD_BIT)), oi)) { + if (oi != (Obj_Info_Type)atomic_cas32((volatile unsigned int*)get_obj_info_addr(p_obj), ( ( (unsigned int)target |FORWARD_BIT)), oi)) { /* forwarded by other, we need unalloc the allocated obj. We may waste some space if the allocation switched block. The remaining part of the switched block cannot be revivied for next allocation of object that has smaller size than this one. */ Index: src/utils/bit_ops.h =================================================================== --- src/utils/bit_ops.h (revision 542506) +++ src/utils/bit_ops.h (working copy) @@ -1,129 +1,129 @@ -/* - * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @author Ji, Qi, 2006/10/25 - */ - -#ifndef _BIT_OPS_H_ -#define _BIT_OPS_H_ - -#include "../common/gc_common.h" - -inline unsigned int word_get_first_set_lsb(POINTER_SIZE_INT target_word) -{ - assert(target_word != 0); - POINTER_SIZE_INT bit_offset = 0; - -#if defined(_IPF_) || defined(_WIN64) - while( ! (target_word & ((POINTER_SIZE_INT)1 << bit_offset)) ){ - bit_offset++; - } -#else /* !_IPF_ && !_WIN64 */ -#ifdef PLATFORM_POSIX /* linux X86 32/64 */ - __asm__ __volatile__( - "bsf %1,%0\n" - :"=r"(bit_offset) - :"m"(target_word) - ); -#else /* !PLATFORM_POSIX */ -#ifdef WIN32 - __asm{ - bsf eax, target_word - mov bit_offset, eax - } -#endif /* WIN32 */ -#endif /* !PLATFORM_POSIX */ -#endif /* !_IPF_ && !_WIN64 */ - - assert(bit_offset < BITS_PER_WORD); - return (unsigned int)bit_offset; - -} - -inline unsigned int words_get_next_set_lsb(POINTER_SIZE_INT* words, unsigned int count, unsigned int start_idx) -{ - unsigned int bit_offset; - - assert(start_idx < 128); - - unsigned int start_word_index = start_idx >> BIT_SHIFT_TO_BITS_PER_WORD; - unsigned int start_bit_offset = start_idx & BIT_MASK_TO_BITS_PER_WORD; - - bit_offset = start_idx - start_bit_offset; - for(unsigned int i = start_word_index; i < count; i ++ ){ - POINTER_SIZE_INT cur_word = *(words + i); - - if(start_word_index == i){ - POINTER_SIZE_INT mask = ~(((POINTER_SIZE_INT)1 << start_bit_offset) - 1); - cur_word = cur_word & mask; - } - - if(cur_word != 0){ - bit_offset += word_get_first_set_lsb(cur_word); - return bit_offset; - } - - bit_offset += BITS_PER_WORD; - } - - return bit_offset; -} - -inline void words_set_bit(POINTER_SIZE_INT* words, unsigned int count, unsigned int start_idx) -{ - assert(start_idx < 128); - - unsigned int word_index = start_idx >> BIT_SHIFT_TO_BITS_PER_WORD; - unsigned int bit_offset = start_idx & BIT_MASK_TO_BITS_PER_WORD; - - if(word_index >= count) return; - - POINTER_SIZE_INT* p_word = words + word_index; - POINTER_SIZE_INT old_value = *p_word; - POINTER_SIZE_INT mask = (POINTER_SIZE_INT)1 << bit_offset; - POINTER_SIZE_INT new_value = old_value|mask; - while (true) { - POINTER_SIZE_INT temp = atomic_casptrsz(p_word, new_value, old_value); - if (temp == old_value) break; - old_value = *p_word; - new_value = old_value|mask; - } - return; -} - -inline void words_clear_bit(POINTER_SIZE_INT* words, unsigned int count, unsigned int start_idx) -{ - assert(start_idx < 128); - - unsigned int word_index = start_idx >> BIT_SHIFT_TO_BITS_PER_WORD; - unsigned int bit_offset = start_idx & BIT_MASK_TO_BITS_PER_WORD; - - if(word_index >= count) return; - - POINTER_SIZE_INT* p_word = words + word_index; - POINTER_SIZE_INT old_value = *p_word; - POINTER_SIZE_INT mask = ~((POINTER_SIZE_INT)1 << bit_offset); - POINTER_SIZE_INT new_value = old_value & mask; - while (true) { - POINTER_SIZE_INT temp = atomic_casptrsz(p_word, new_value, old_value); - if (temp == old_value) break; - old_value = *p_word; - new_value = old_value & mask; - } - return; -} -#endif +/* + * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Ji, Qi, 2006/10/25 + */ + +#ifndef _BIT_OPS_H_ +#define _BIT_OPS_H_ + +#include "../common/gc_common.h" + +inline unsigned int word_get_first_set_lsb(POINTER_SIZE_INT target_word) +{ + assert(target_word != 0); + POINTER_SIZE_INT bit_offset = 0; + +#if defined(_IPF_) || defined(_WIN64) + while( ! (target_word & ((POINTER_SIZE_INT)1 << bit_offset)) ){ + bit_offset++; + } +#else /* !_IPF_ && !_WIN64 */ +#ifdef PLATFORM_POSIX /* linux X86 32/64 */ + __asm__ __volatile__( + "bsf %1,%0\n" + :"=r"(bit_offset) + :"m"(target_word) + ); +#else /* !PLATFORM_POSIX */ +#ifdef WIN32 + __asm{ + bsf eax, target_word + mov bit_offset, eax + } +#endif /* WIN32 */ +#endif /* !PLATFORM_POSIX */ +#endif /* !_IPF_ && !_WIN64 */ + + assert(bit_offset < BITS_PER_WORD); + return (unsigned int)bit_offset; + +} + +inline unsigned int words_get_next_set_lsb(POINTER_SIZE_INT* words, unsigned int count, unsigned int start_idx) +{ + unsigned int bit_offset; + + assert(start_idx < 128); + + unsigned int start_word_index = start_idx >> BIT_SHIFT_TO_BITS_PER_WORD; + unsigned int start_bit_offset = start_idx & BIT_MASK_TO_BITS_PER_WORD; + + bit_offset = start_idx - start_bit_offset; + for(unsigned int i = start_word_index; i < count; i ++ ){ + POINTER_SIZE_INT cur_word = *(words + i); + + if(start_word_index == i){ + POINTER_SIZE_INT mask = ~(((POINTER_SIZE_INT)1 << start_bit_offset) - 1); + cur_word = cur_word & mask; + } + + if(cur_word != 0){ + bit_offset += word_get_first_set_lsb(cur_word); + return bit_offset; + } + + bit_offset += BITS_PER_WORD; + } + + return bit_offset; +} + +inline void words_set_bit(POINTER_SIZE_INT* words, unsigned int count, unsigned int start_idx) +{ + assert(start_idx < 128); + + unsigned int word_index = start_idx >> BIT_SHIFT_TO_BITS_PER_WORD; + unsigned int bit_offset = start_idx & BIT_MASK_TO_BITS_PER_WORD; + + if(word_index >= count) return; + + volatile POINTER_SIZE_INT* p_word = words + word_index; + POINTER_SIZE_INT old_value = *p_word; + POINTER_SIZE_INT mask = (POINTER_SIZE_INT)1 << bit_offset; + POINTER_SIZE_INT new_value = old_value|mask; + while (true) { + POINTER_SIZE_INT temp = atomic_casptrsz(p_word, new_value, old_value); + if (temp == old_value) break; + old_value = *p_word; + new_value = old_value|mask; + } + return; +} + +inline void words_clear_bit(POINTER_SIZE_INT* words, unsigned int count, unsigned int start_idx) +{ + assert(start_idx < 128); + + unsigned int word_index = start_idx >> BIT_SHIFT_TO_BITS_PER_WORD; + unsigned int bit_offset = start_idx & BIT_MASK_TO_BITS_PER_WORD; + + if(word_index >= count) return; + + volatile POINTER_SIZE_INT* p_word = words + word_index; + POINTER_SIZE_INT old_value = *p_word; + POINTER_SIZE_INT mask = ~((POINTER_SIZE_INT)1 << bit_offset); + POINTER_SIZE_INT new_value = old_value & mask; + while (true) { + POINTER_SIZE_INT temp = atomic_casptrsz(p_word, new_value, old_value); + if (temp == old_value) break; + old_value = *p_word; + new_value = old_value & mask; + } + return; +} +#endif Index: src/verify/verifier_common.cpp =================================================================== --- src/verify/verifier_common.cpp (revision 542506) +++ src/verify/verifier_common.cpp (working copy) @@ -1,6 +1,7 @@ #include "verifier_common.h" #include "verify_gc_effect.h" #include "verify_mutator_effect.h" + Boolean verifier_compare_objs_pools(Pool* objs_pool_before_gc, Pool* objs_pool_after_gc, Pool* free_pool ,Object_Comparator object_comparator) { Vector_Block* objs_set_before_gc = pool_get_entry(objs_pool_before_gc); @@ -12,7 +13,7 @@ && !vector_block_iterator_end(objs_set_after_gc, iter_2) ){ if(!(*object_comparator)(iter_1, iter_2)){ assert(0); - printf("ERROR\n"); + printf("\nERROR: objs pools compare error!!!\n"); return FALSE; } iter_1 = vector_block_iterator_advance(objs_set_before_gc, iter_1); @@ -29,10 +30,12 @@ objs_set_before_gc = pool_get_entry(objs_pool_before_gc); objs_set_after_gc = pool_get_entry(objs_pool_after_gc); } - if(pool_is_empty(objs_pool_before_gc)&&pool_is_empty(objs_pool_before_gc)) + if(pool_is_empty(objs_pool_before_gc)&&pool_is_empty(objs_pool_before_gc)){ return TRUE; - else + }else{ + assert(0); return FALSE; + } } Boolean verifier_copy_rootsets(GC* gc, Heap_Verifier* heap_verifier) @@ -51,7 +54,7 @@ REF* p_ref = (REF* )*iter; iter = vector_block_iterator_advance(root_set,iter); if( read_slot(p_ref) == NULL) continue; - verifier_rootset_push(p_ref,gc_verifier->root_set); + verifier_set_push(p_ref,gc_verifier->root_set,verifier_metadata->root_set_pool); } root_set = pool_iterator_next(gc_metadata->gc_rootset_pool); } @@ -79,7 +82,8 @@ if(!heap_verifier->gc_is_gen_mode){ assert(!address_belongs_to_gc_heap(p_ref, heap_verifier->gc)); if(address_belongs_to_gc_heap(p_ref, heap_verifier->gc)){ - printf("ERROR\n"); + printf("\nERROR: rootset address is inside gc heap\n"); + assert(0); return FALSE; } } @@ -87,21 +91,23 @@ if(heap_verifier->is_before_gc){ //if(!address_belongs_to_gc_heap(p_ref) && address_belongs_to_gc_heap(p_obj)){ if(!address_belongs_to_gc_heap(p_obj, heap_verifier->gc)){ - printf("error!\n"); + printf("\nERROR: obj referenced by rootset is outside the heap error!\n"); + assert(0); return FALSE; } }else{ if(heap_verifier->gc_verifier->is_before_fallback_collection){ if(!address_belongs_to_gc_heap(p_obj, heap_verifier->gc)){ - printf("error!\n"); + printf("\nERROR: obj referenced by rootset is outside the heap error!\n"); assert(0); return FALSE; } return TRUE; } - assert(address_belongs_to_space(p_obj, mspace) || address_belongs_to_space(p_obj, lspace)); - if(!address_belongs_to_space(p_obj, mspace) && !address_belongs_to_space(p_obj, lspace)){ - printf("Error\n"); + + if(!address_belongs_to_space(p_obj, mspace) && !address_belongs_to_space(p_obj, lspace) && !NOS_PARTIAL_FORWARD){ + assert(0); + printf("\nERROR: obj referenced by rootset is in nos after GC!\n"); return FALSE; } } @@ -145,50 +151,89 @@ Allocation_Verifier* alloc_verifier = heap_verifier->allocation_verifier; WriteBarrier_Verifier* wb_verifier = heap_verifier->writebarrier_verifier; RootSet_Verifier* rootset_verifier = heap_verifier->rootset_verifier; - - printf("before gc:\n"); - + printf("\n\n"); + verifier_log_start(" Begin of GC "); + printf(" collection number: %4d \n", heap_verifier->gc->num_collections); + if(heap_verifier->need_verify_allocation){ - printf(" Allocation Verify: %s , ", alloc_verifier->is_verification_passed?"passed":"failed"); - printf(" new nos: %d : %d , ", alloc_verifier->num_nos_newobjs, alloc_verifier->num_nos_objs); - printf(" new los: %d : %d \n", alloc_verifier->num_los_newobjs, + printf(" .......................................................................... \n"); + printf(" Allocation Verify: %s , ", alloc_verifier->is_verification_passed?"passed":"failed"); + printf("new nos: %d : %d , ", alloc_verifier->num_nos_newobjs, alloc_verifier->num_nos_objs); + printf("new los: %d : %d \n", alloc_verifier->num_los_newobjs, alloc_verifier->num_los_objs-alloc_verifier->last_num_los_objs); } if(heap_verifier->need_verify_rootset){ - printf(" RootSet Verify: %s , ", rootset_verifier->is_verification_passed?"passed":"failed"); - printf(" num: %d , ", rootset_verifier->num_slots_in_rootset); - printf(" error num: %d \n", rootset_verifier->num_error_slots); + printf(" .......................................................................... \n"); + printf(" RootSet Verify: %s, ", rootset_verifier->is_verification_passed?"passed":"failed"); + printf("num: %d, ", rootset_verifier->num_slots_in_rootset); + printf("error num: %d \n", rootset_verifier->num_error_slots); } if(heap_verifier->need_verify_writebarrier){ - printf(" WriteBarrier Verify: %s , ", wb_verifier->is_verification_passed?"passed":"failed"); - printf(" num cached: %d , ", wb_verifier->num_ref_wb_in_remset); - printf(" num real : %d \n", wb_verifier->num_ref_wb_after_scanning); + printf(" .......................................................................... \n"); + printf(" WriteBarrier Verify: %s, ", wb_verifier->is_verification_passed?"passed":"failed"); + printf("cached: %d, ", wb_verifier->num_ref_wb_in_remset); + printf("real : %d \n", wb_verifier->num_ref_wb_after_scanning); } - printf("===============================================\n"); +} +void verifier_log_start(char* message) +{ + printf("------------------------------%-16s------------------------------\n", message); } -void verifier_log_start() +void verifier_collect_kind_log(Heap_Verifier* heap_verifier) { - printf("\n===============================================\n"); + GC* gc = heap_verifier->gc; + char* gc_kind; + if(gc_match_kind(gc, MINOR_COLLECTION)){ + gc_kind = " minor collection."; + }else if(gc_match_kind(gc, FALLBACK_COLLECTION)){ + gc_kind = " fallback collection."; + }else if(gc_match_kind(gc, EXTEND_COLLECTION)){ + gc_kind = " extend collection."; + }else if(gc_match_kind(gc, MAJOR_COLLECTION)){ + if(gc->tuner->kind == TRANS_NOTHING) gc_kind = "major collection (normal)"; + else if(gc->tuner->kind == TRANS_FROM_LOS_TO_MOS) gc_kind = "major collection (LOS shrink)"; + else if(gc->tuner->kind == TRANS_FROM_MOS_TO_LOS) gc_kind = "major collection (LOS extend)"; + } + printf(" GC_kind: %s\n", gc_kind); } +void verifier_hashcode_log(GC_Verifier* gc_verifier); void verifier_log_after_gc(Heap_Verifier* heap_verifier) { GC_Verifier* gc_verifier = heap_verifier->gc_verifier; - printf("after gc:\n"); if(heap_verifier->need_verify_gc){ - printf(" GC Verify: %s \n", gc_verifier->is_verification_passed?"passed":"failed"); - printf(" live obj : NUM before %d , after %d \n", gc_verifier->num_live_objects_before_gc, gc_verifier->num_live_objects_after_gc); - printf(" live obj : SIZE before %d MB, after %d MB \n", gc_verifier->size_live_objects_before_gc>>20, gc_verifier->size_live_objects_after_gc>>20); - printf(" resurrect obj: NUM before %d , after %d \n", gc_verifier->num_resurrect_objects_before_gc, gc_verifier->num_resurrect_objects_after_gc); - printf(" resurrect obj : SIZE before %d MB, after %d MB\n", gc_verifier->size_resurrect_objects_before_gc>>20, gc_verifier->size_resurrect_objects_after_gc>>20); + printf(" .......................................................................... \n"); + verifier_collect_kind_log(heap_verifier); + printf(" GC Verify Result: %s \n", gc_verifier->is_verification_passed?"Passed":"Failed*"); + printf(" .......................................................................... \n"); + printf(" %-14s: %-7s | Before %10d | After %10d |\n", "live obj", "NUM" ,gc_verifier->num_live_objects_before_gc, gc_verifier->num_live_objects_after_gc); + printf(" %-14s: %-7s | Before %7d MB | After %7d MB |\n","live obj", "SIZE", gc_verifier->size_live_objects_before_gc>>20, gc_verifier->size_live_objects_after_gc>>20); + printf(" %-14s: %-7s | Before %10d | After %10d |\n", "resurrect obj", "NUM",gc_verifier->num_resurrect_objects_before_gc, gc_verifier->num_resurrect_objects_after_gc); + if(gc_verifier->size_resurrect_objects_before_gc>>20 == 0 && gc_verifier->size_resurrect_objects_before_gc != 0){ + if(gc_verifier->size_resurrect_objects_before_gc>>10 == 0 ){ + printf(" %-14s: %-7s | Before %7d B | After %7d B |\n", "resurrect obj", "SIZE", gc_verifier->size_resurrect_objects_before_gc, gc_verifier->size_resurrect_objects_after_gc); + }else{ + printf(" %-14s: %-7s | Before %7d KB | After %7d KB |\n", "resurrect obj", "SIZE", gc_verifier->size_resurrect_objects_before_gc>>10, gc_verifier->size_resurrect_objects_after_gc>>10); + } + }else{ + printf(" %-14s: %-7s | Before %7d MB | After %7d MB |\n", "resurrect obj", "SIZE", gc_verifier->size_resurrect_objects_before_gc>>20, gc_verifier->size_resurrect_objects_after_gc>>20); + } + verifier_hashcode_log(gc_verifier); } - printf("===============================================\n"); + if(!heap_verifier->gc_verifier->is_before_fallback_collection) + verifier_log_start(" End of GC "); + else + verifier_log_start(" failed GC end "); } +void verifier_hashcode_log(GC_Verifier* gc_verifier) +{ + printf(" %-14s: %-7s | Before %10d | After %10d |\n", "hashcode", "NUM", gc_verifier->num_hash_before_gc, gc_verifier->num_hash_after_gc); +} Index: src/verify/verifier_common.h =================================================================== --- src/verify/verifier_common.h (revision 542506) +++ src/verify/verifier_common.h (working copy) @@ -5,6 +5,10 @@ #include "../common/gc_common.h" #include "../common/gc_space.h" #include "../gen/gen.h" +#include "../common/space_tuner.h" +#ifdef USE_32BITS_HASHCODE +#include "../common/hashcode.h" +#endif struct Heap_Verifier; struct Allocation_Verifier; @@ -50,7 +54,7 @@ Boolean verifier_parse_options(Heap_Verifier* heap_verifier, char* options); void verifier_log_before_gc(Heap_Verifier* heap_verifier); void verifier_log_after_gc(Heap_Verifier* heap_verifier); -void verifier_log_start(); +void verifier_log_start(char* message); Boolean verify_rootset_slot(REF* p_ref, Heap_Verifier* heap_verifier); @@ -90,7 +94,7 @@ assert(address_belongs_to_gc_heap(read_slot(p_ref), (GC*)heap_verifier->gc)); Partial_Reveal_Object* UNUSED p_obj = read_slot(p_ref); assert(p_obj); - assert(obj_get_vt(p_obj)); + assert(uncompress_vt(obj_get_vt(p_obj))); assert(!address_belongs_to_gc_heap(uncompress_vt(obj_get_vt(p_obj)), (GC*)heap_verifier->gc)); } @@ -138,19 +142,17 @@ REF ref = *p_ref; return (REF)((POINTER_SIZE_INT)ref | VERIFY_WB_MARK_BIT); } - - +/* #define UNREACHABLE_OBJ_MARK_IN_VT 0x02 inline void tag_unreachable_obj(Partial_Reveal_Object* p_obj) { - Partial_Reveal_VTable* vt = uncompress_vt(obj_get_vt_raw(p_obj)); - obj_set_vt(p_obj, compress_vt((Partial_Reveal_VTable*)((POINTER_SIZE_INT)vt | UNREACHABLE_OBJ_MARK_IN_VT))); + VT vt = obj_get_vt_raw(p_obj); + obj_set_vt(p_obj, (VT)((POINTER_SIZE_INT)vt | UNREACHABLE_OBJ_MARK_IN_VT)); } inline Boolean is_unreachable_obj(Partial_Reveal_Object* p_obj) { return (Boolean)((POINTER_SIZE_INT)obj_get_vt_raw(p_obj) & UNREACHABLE_OBJ_MARK_IN_VT); -} - +}*/ #endif Index: src/verify/verifier_metadata.cpp =================================================================== --- src/verify/verifier_metadata.cpp (revision 542506) +++ src/verify/verifier_metadata.cpp (working copy) @@ -29,33 +29,29 @@ vector_block_init(block, GC_VERIFIER_METADATA_BLOCK_SIZE_BYTES); } - unsigned num_tasks = num_blocks>>2; + unsigned num_tasks = num_blocks>>1; heap_verifier_metadata->free_task_pool = sync_pool_create(); for(i=0; ifree_task_pool, (void*)block); } - heap_verifier_metadata->mark_task_pool = sync_pool_create(); - unsigned num_sets = num_blocks>>2; heap_verifier_metadata->free_set_pool = sync_pool_create(); - for(; i<(num_sets + num_tasks); i++){ + for(; ifree_set_pool, (void*)block); } + + heap_verifier_metadata->mark_task_pool = sync_pool_create(); heap_verifier_metadata->root_set_pool = sync_pool_create(); - - heap_verifier_metadata->free_objects_pool = sync_pool_create(); - for(; ifree_objects_pool, (void*)block); - } heap_verifier_metadata->objects_pool_before_gc = sync_pool_create(); heap_verifier_metadata->objects_pool_after_gc = sync_pool_create(); heap_verifier_metadata->resurrect_objects_pool_before_gc = sync_pool_create(); heap_verifier_metadata->resurrect_objects_pool_after_gc = sync_pool_create(); heap_verifier_metadata->new_objects_pool = sync_pool_create(); + heap_verifier_metadata->hashcode_pool_before_gc = sync_pool_create(); + heap_verifier_metadata->hashcode_pool_after_gc = sync_pool_create(); verifier_metadata = heap_verifier_metadata; heap_verifier->heap_verifier_metadata = heap_verifier_metadata; @@ -67,17 +63,17 @@ Heap_Verifier_Metadata* metadata = heap_verifier->heap_verifier_metadata; sync_pool_destruct(metadata->free_task_pool); + sync_pool_destruct(metadata->free_set_pool); + sync_pool_destruct(metadata->mark_task_pool); - - sync_pool_destruct(metadata->free_set_pool); sync_pool_destruct(metadata->root_set_pool); - - sync_pool_destruct(metadata->free_objects_pool); sync_pool_destruct(metadata->objects_pool_before_gc); sync_pool_destruct(metadata->objects_pool_after_gc); sync_pool_destruct(metadata->resurrect_objects_pool_before_gc); sync_pool_destruct(metadata->resurrect_objects_pool_after_gc); sync_pool_destruct(metadata->new_objects_pool); + sync_pool_destruct(metadata->hashcode_pool_before_gc); + sync_pool_destruct(metadata->hashcode_pool_after_gc); for(unsigned int i=0; inum_alloc_segs; i++){ assert(metadata->segments[i]); @@ -134,7 +130,6 @@ block = pool_get_entry(pool); unlock(verifier_metadata->alloc_lock); - printf("extend metadata\n"); return block; } @@ -148,3 +143,22 @@ working_block = pool_get_entry(working_pool); } } + +Pool* verifier_copy_pool_reverse_order(Pool* source_pool) +{ + Pool* dest_pool = sync_pool_create(); + pool_iterator_init(source_pool); + Vector_Block* dest_set = verifier_free_set_pool_get_entry(verifier_metadata->free_set_pool); + + while(Vector_Block *source_set = pool_iterator_next(source_pool)){ + POINTER_SIZE_INT *iter = vector_block_iterator_init(source_set); + while( !vector_block_iterator_end(source_set, iter)){ + assert(!vector_block_is_full(dest_set)); + vector_block_add_entry(dest_set, *iter); + iter = vector_block_iterator_advance(source_set, iter); + } + pool_put_entry(dest_pool, dest_set); + dest_set = verifier_free_set_pool_get_entry(verifier_metadata->free_set_pool); + } + return dest_pool; +} Index: src/verify/verifier_metadata.h =================================================================== --- src/verify/verifier_metadata.h (revision 542506) +++ src/verify/verifier_metadata.h (working copy) @@ -20,14 +20,15 @@ Pool* root_set_pool; Pool* mark_task_pool; - Pool* free_objects_pool; - Pool* objects_pool_before_gc; Pool* objects_pool_after_gc; Pool* resurrect_objects_pool_before_gc; Pool* resurrect_objects_pool_after_gc; - + + Pool* hashcode_pool_before_gc; + Pool* hashcode_pool_after_gc; + Pool* new_objects_pool; } Heap_Verifier_Metadata; @@ -39,6 +40,7 @@ Vector_Block* gc_verifier_metadata_extend(Pool* pool, Boolean is_set_pool); void verifier_clear_pool(Pool* working_pool, Pool* free_pool, Boolean is_vector_stack); +Pool* verifier_copy_pool_reverse_order(Pool* source_pool); inline Vector_Block* verifier_free_set_pool_get_entry(Pool* free_pool) { @@ -64,8 +66,6 @@ return block; } - - inline void verifier_tracestack_push(void* p_task, Vector_Block_Ptr& trace_task) { vector_stack_push(trace_task, (POINTER_SIZE_INT)p_task); @@ -77,17 +77,6 @@ assert(trace_task); } -inline void verifier_rootset_push(void* p_task, Vector_Block_Ptr& root_set) -{ - vector_block_add_entry(root_set, (POINTER_SIZE_INT)p_task); - - if( !vector_block_is_full(root_set)) return; - - pool_put_entry(verifier_metadata->root_set_pool, root_set); - root_set = verifier_free_set_pool_get_entry(verifier_metadata->free_set_pool); - assert(root_set); -} - inline void verifier_set_push(void* p_data, Vector_Block_Ptr& set_block, Pool* pool) { vector_block_add_entry(set_block, (POINTER_SIZE_INT)p_data); @@ -95,7 +84,7 @@ if( !vector_block_is_full(set_block) ) return; pool_put_entry(pool, set_block); - set_block = verifier_free_set_pool_get_entry(verifier_metadata->free_objects_pool); + set_block = verifier_free_set_pool_get_entry(verifier_metadata->free_set_pool); assert(set_block); } Index: src/verify/verifier_scanner.cpp =================================================================== --- src/verify/verifier_scanner.cpp (revision 542506) +++ src/verify/verifier_scanner.cpp (working copy) @@ -85,8 +85,9 @@ { Heap_Verifier_Metadata* verifier_metadata = heap_verifier->heap_verifier_metadata; GC_Verifier* gc_verifier = heap_verifier->gc_verifier; - gc_verifier->objects_set = verifier_free_task_pool_get_entry(verifier_metadata->free_objects_pool); + gc_verifier->objects_set = verifier_free_set_pool_get_entry(verifier_metadata->free_set_pool); gc_verifier->trace_stack = verifier_free_task_pool_get_entry(verifier_metadata->free_task_pool); + gc_verifier->hashcode_set = verifier_free_set_pool_get_entry(verifier_metadata->free_set_pool); pool_iterator_init(root_set_pool); Vector_Block* root_set = pool_iterator_next(root_set_pool); @@ -145,7 +146,6 @@ gc_verifier->trace_stack = verifier_free_task_pool_get_entry(verifier_metadata->free_task_pool); pool_iterator_init(obj_set_pool); Vector_Block* obj_set = pool_iterator_next(obj_set_pool); - /* first step: copy all root objects to trace tasks. */ while(obj_set){ POINTER_SIZE_INT* iter = vector_block_iterator_init(obj_set); @@ -193,9 +193,12 @@ if(heap_verifier->is_before_gc){ verifier_trace_objsets(heap_verifier, gc->finref_metadata->obj_with_fin_pool); }else{ - if(!heap_verifier->gc_verifier->is_before_fallback_collection){ + if(!heap_verifier->gc_verifier->is_before_fallback_collection){ verify_live_finalizable_obj(heap_verifier, gc->finref_metadata->obj_with_fin_pool); - verifier_trace_objsets(heap_verifier, gc->finref_metadata->finalizable_obj_pool); + Pool* finalizable_obj_pool = verifier_copy_pool_reverse_order(gc->finref_metadata->finalizable_obj_pool); + verifier_trace_objsets(heap_verifier, finalizable_obj_pool); + verifier_clear_pool(finalizable_obj_pool, heap_verifier->heap_verifier_metadata->free_set_pool, FALSE); + sync_pool_destruct(finalizable_obj_pool); }else{ verifier_trace_objsets(heap_verifier, gc->finref_metadata->obj_with_fin_pool); } @@ -231,12 +234,14 @@ p_ref = (REF*)((POINTER_SIZE_INT)array + (int)array_first_element_offset(array)); for (unsigned int i = 0; i < array_length; i++) { - 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); - } + 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); @@ -244,12 +249,14 @@ for(unsigned int i=0; ibase; while( cur_obj < block->free ){ verify_object_header(cur_obj, heap_verifier); - if(!obj_is_marked_in_vt(cur_obj)) tag_unreachable_obj(cur_obj); + // if(!obj_is_marked_in_vt(cur_obj)) tag_unreachable_obj(cur_obj); cur_obj = obj_end(cur_obj); } } @@ -365,7 +374,7 @@ while(p_los_obj){ verify_object_header(p_los_obj, heap_verifier); - if(!obj_is_marked_in_vt(p_los_obj)) tag_unreachable_obj(p_los_obj); + //if(!obj_is_marked_in_vt(p_los_obj)) tag_unreachable_obj(p_los_obj); p_los_obj = lspace_get_next_object(lspace, interator); } } @@ -393,4 +402,3 @@ - Index: src/verify/verify_gc_effect.cpp =================================================================== --- src/verify/verify_gc_effect.cpp (revision 542506) +++ src/verify/verify_gc_effect.cpp (working copy) @@ -1,6 +1,8 @@ #include "verifier_common.h" #include "verify_gc_effect.h" +static POINTER_SIZE_INT hash_obj_distance = 0; + void verifier_init_GC_verifier(Heap_Verifier* heap_verifier) { GC_Verifier* gc_verifier = (GC_Verifier*)STD_MALLOC(sizeof(GC_Verifier)); @@ -9,10 +11,6 @@ gc_verifier->trace_stack = gc_verifier->objects_set = gc_verifier->root_set = NULL; gc_verifier->is_tracing_resurrect_obj = FALSE; - gc_verifier->num_live_objects_after_gc = gc_verifier->num_live_objects_before_gc = 0; - gc_verifier->size_live_objects_after_gc = gc_verifier->size_live_objects_before_gc = 0; - gc_verifier->num_resurrect_objects_after_gc = gc_verifier->num_resurrect_objects_before_gc = 0; - gc_verifier->size_resurrect_objects_after_gc = gc_verifier->size_resurrect_objects_before_gc = 0; heap_verifier->gc_verifier = gc_verifier; } void verifier_destruct_GC_verifier(Heap_Verifier* heap_verifier) @@ -28,11 +26,11 @@ void verifier_clear_objsets(Heap_Verifier* heap_verifier) { Heap_Verifier_Metadata* verifier_metadata = heap_verifier->heap_verifier_metadata; - verifier_clear_pool(verifier_metadata->objects_pool_before_gc, verifier_metadata->free_objects_pool, FALSE); - verifier_clear_pool(verifier_metadata->objects_pool_after_gc, verifier_metadata->free_objects_pool, FALSE); + verifier_clear_pool(verifier_metadata->objects_pool_before_gc, verifier_metadata->free_set_pool, FALSE); + verifier_clear_pool(verifier_metadata->objects_pool_after_gc, verifier_metadata->free_set_pool, FALSE); #ifndef BUILD_IN_REFERENT - verifier_clear_pool(verifier_metadata->resurrect_objects_pool_before_gc, verifier_metadata->free_objects_pool, FALSE); - verifier_clear_pool(verifier_metadata->resurrect_objects_pool_after_gc, verifier_metadata->free_objects_pool, FALSE); + verifier_clear_pool(verifier_metadata->resurrect_objects_pool_before_gc, verifier_metadata->free_set_pool, FALSE); + verifier_clear_pool(verifier_metadata->resurrect_objects_pool_after_gc, verifier_metadata->free_set_pool, FALSE); #endif } @@ -44,6 +42,10 @@ gc_verifier->is_tracing_resurrect_obj = FALSE; gc_verifier->num_live_objects_after_gc = gc_verifier->num_live_objects_before_gc = 0; gc_verifier->size_live_objects_after_gc = gc_verifier->size_live_objects_before_gc = 0; + gc_verifier->num_hash_after_gc = gc_verifier->num_hash_before_gc = 0; + gc_verifier->num_hash_attached_after_gc = gc_verifier->num_hash_attached_before_gc = 0; + gc_verifier->num_hash_buffered_after_gc = gc_verifier->num_hash_buffered_before_gc = 0; + gc_verifier->num_hash_set_unalloc_after_gc = gc_verifier->num_hash_set_unalloc_before_gc = 0; #ifndef BUILD_IN_REFERENT gc_verifier->num_resurrect_objects_after_gc = gc_verifier->num_resurrect_objects_before_gc = 0; gc_verifier->size_resurrect_objects_after_gc = gc_verifier->size_resurrect_objects_before_gc = 0; @@ -65,7 +67,8 @@ if(p_fin_obj==NULL) continue; assert(obj_is_marked_in_vt(p_fin_obj)); if(!obj_is_marked_in_vt(p_fin_obj)){ - printf("ERROR\n"); + printf("\nERROR: live finalizable obj is not marked.\n"); + assert(0); } } live_fin_objs = pool_iterator_next(live_finalizable_objs_pool); @@ -102,13 +105,21 @@ if(heap_verifier->is_before_gc){ pool_put_entry(verifier_metadata->objects_pool_before_gc, gc_verifier->objects_set); - gc_verifier->objects_set = verifier_free_set_pool_get_entry(verifier_metadata->free_objects_pool); + gc_verifier->objects_set = verifier_free_set_pool_get_entry(verifier_metadata->free_set_pool); assert(gc_verifier->objects_set); + + pool_put_entry(verifier_metadata->hashcode_pool_before_gc, gc_verifier->hashcode_set); + gc_verifier->hashcode_set = verifier_free_set_pool_get_entry(verifier_metadata->free_set_pool); + assert(gc_verifier->hashcode_set); return; }else{ pool_put_entry(verifier_metadata->objects_pool_after_gc, gc_verifier->objects_set); - gc_verifier->objects_set = verifier_free_set_pool_get_entry(verifier_metadata->free_objects_pool); + gc_verifier->objects_set = verifier_free_set_pool_get_entry(verifier_metadata->free_set_pool); assert(gc_verifier->objects_set); + + pool_put_entry(verifier_metadata->hashcode_pool_after_gc, gc_verifier->hashcode_set); + gc_verifier->hashcode_set = verifier_free_set_pool_get_entry(verifier_metadata->free_set_pool); + assert(gc_verifier->hashcode_set); return; } @@ -120,21 +131,105 @@ GC_Verifier* gc_verifier = heap_verifier->gc_verifier; Heap_Verifier_Metadata* verifier_metadata = heap_verifier->heap_verifier_metadata; + hash_obj_distance = 0; + if(heap_verifier->is_before_gc){ pool_put_entry(verifier_metadata->resurrect_objects_pool_before_gc, gc_verifier->objects_set); gc_verifier->objects_set = NULL; assert(!gc_verifier->objects_set); + + pool_put_entry(verifier_metadata->hashcode_pool_before_gc, gc_verifier->hashcode_set); + gc_verifier->hashcode_set = verifier_free_set_pool_get_entry(verifier_metadata->free_set_pool); + assert(gc_verifier->hashcode_set); return; }else{ pool_put_entry(verifier_metadata->resurrect_objects_pool_after_gc, gc_verifier->objects_set); gc_verifier->objects_set = NULL; assert(!gc_verifier->objects_set); + + pool_put_entry(verifier_metadata->hashcode_pool_after_gc, gc_verifier->hashcode_set); + gc_verifier->hashcode_set = verifier_free_set_pool_get_entry(verifier_metadata->free_set_pool); + assert(gc_verifier->hashcode_set); return; } } +#ifdef USE_32BITS_HASHCODE +inline Object_Hashcode_Inform* verifier_copy_hashcode(Partial_Reveal_Object* p_obj, Heap_Verifier* heap_verifier, Boolean is_before_gc) +{ + hash_obj_distance ++; + + if(!hashcode_is_set(p_obj)) return NULL; + GC_Verifier* gc_verifier = heap_verifier->gc_verifier; + if(is_before_gc) gc_verifier->num_hash_before_gc++; + else gc_verifier->num_hash_after_gc++; + + Obj_Info_Type info = get_obj_info_raw(p_obj); + int hash = 0; + switch(info & HASHCODE_MASK){ + case HASHCODE_SET_UNALLOCATED: + if(is_before_gc) gc_verifier->num_hash_set_unalloc_before_gc++; + else gc_verifier->num_hash_set_unalloc_after_gc++; + hash = hashcode_gen((void*)p_obj); + break; + case HASHCODE_SET_ATTACHED: + if(is_before_gc) gc_verifier->num_hash_attached_before_gc++; + else gc_verifier->num_hash_attached_after_gc++; + hash = hashcode_lookup(p_obj,info); + break; + case HASHCODE_SET_BUFFERED: + if(is_before_gc) gc_verifier->num_hash_buffered_before_gc++; + else gc_verifier->num_hash_buffered_after_gc++; + hash = hashcode_lookup(p_obj,info); + break; + default: + assert(0); + } + + unsigned int size = sizeof(Object_Hashcode_Inform); + Object_Hashcode_Inform* obj_hash_info = (Object_Hashcode_Inform*) STD_MALLOC(size); + assert(obj_hash_info); + memset(obj_hash_info, 0, size); + + obj_hash_info->address = p_obj; + obj_hash_info->hashcode = hash; + obj_hash_info->hash_obj_distance = hash_obj_distance - 1; + + hash_obj_distance = 0; + + return obj_hash_info; +} +#else +inline Object_Hashcode_Inform* verifier_copy_hashcode(Partial_Reveal_Object* p_obj, Heap_Verifier* heap_verifier, Boolean is_before_gc) +{ + hash_obj_distance ++; + + if(!hashcode_is_set(p_obj)) return NULL; + + GC_Verifier* gc_verifier = heap_verifier->gc_verifier; + if(is_before_gc) gc_verifier->num_hash_before_gc++; + else gc_verifier->num_hash_after_gc++; + + Obj_Info_Type info = get_obj_info_raw(p_obj); + + int hash = info & GCGEN_HASH_MASK; + unsigned int size = sizeof(Object_Hashcode_Inform); + Object_Hashcode_Inform* obj_hash_info = (Object_Hashcode_Inform*) STD_MALLOC(size); + assert(obj_hash_info); + memset(obj_hash_info, 0, size); + + obj_hash_info->address = p_obj; + obj_hash_info->hashcode = hash; + obj_hash_info->hash_obj_distance = hash_obj_distance - 1; + + hash_obj_distance = 0; + + return obj_hash_info; +} +#endif //USE_32BIT_HASHCODE + void verifier_update_verify_info(Partial_Reveal_Object* p_obj, Heap_Verifier* heap_verifier) { if(!heap_verifier->need_verify_gc) return; @@ -163,6 +258,7 @@ } /*store the object information*/ void* p_obj_information = verifier_copy_obj_information(p_obj); + void* obj_hash_info = verifier_copy_hashcode(p_obj, heap_verifier, heap_verifier->is_before_gc); #ifndef BUILD_IN_REFERENT if(!gc_verifier->is_tracing_resurrect_obj){ @@ -170,10 +266,12 @@ /*size and number*/ if(heap_verifier->is_before_gc){ verifier_set_push(p_obj_information, gc_verifier->objects_set, verifier_metadata->objects_pool_before_gc); + if(obj_hash_info != NULL) verifier_set_push(obj_hash_info, gc_verifier->hashcode_set, verifier_metadata->hashcode_pool_before_gc); gc_verifier->num_live_objects_before_gc ++; gc_verifier->size_live_objects_before_gc += vm_object_size(p_obj); }else{ verifier_set_push(p_obj_information, gc_verifier->objects_set, verifier_metadata->objects_pool_after_gc); + if(obj_hash_info != NULL) verifier_set_push(obj_hash_info, gc_verifier->hashcode_set, verifier_metadata->hashcode_pool_after_gc); gc_verifier->num_live_objects_after_gc ++; gc_verifier->size_live_objects_after_gc += vm_object_size(p_obj); } @@ -184,10 +282,12 @@ if(heap_verifier->is_before_gc){ verifier_set_push(p_obj_information, gc_verifier->objects_set, verifier_metadata->resurrect_objects_pool_before_gc); + if(obj_hash_info != NULL) verifier_set_push(obj_hash_info, gc_verifier->hashcode_set, verifier_metadata->hashcode_pool_before_gc); gc_verifier->num_resurrect_objects_before_gc ++; gc_verifier->size_resurrect_objects_before_gc += vm_object_size(p_obj); }else{ verifier_set_push(p_obj_information, gc_verifier->objects_set, verifier_metadata->resurrect_objects_pool_after_gc); + if(obj_hash_info != NULL) verifier_set_push(obj_hash_info, gc_verifier->hashcode_set, verifier_metadata->hashcode_pool_after_gc); gc_verifier->num_resurrect_objects_after_gc ++; gc_verifier->size_resurrect_objects_after_gc += vm_object_size(p_obj); } @@ -208,12 +308,28 @@ STD_FREE(obj_inform_2); return TRUE; }else{ + assert(0); STD_FREE(obj_inform_1); STD_FREE(obj_inform_2); return FALSE; } } +Boolean compare_obj_hash_inform(POINTER_SIZE_INT* container1,POINTER_SIZE_INT* container2) +{ + Object_Hashcode_Inform* obj_hash_1 = (Object_Hashcode_Inform*) *container1; + Object_Hashcode_Inform* obj_hash_2 = (Object_Hashcode_Inform*) *container2; + if(obj_hash_1->hashcode == obj_hash_2->hashcode && obj_hash_1->hash_obj_distance== obj_hash_2->hash_obj_distance){ + STD_FREE(obj_hash_1); + STD_FREE(obj_hash_2); + return TRUE; + }else{ + assert(0); + STD_FREE(obj_hash_1); + STD_FREE(obj_hash_2); + return FALSE; + } +} void verify_gc_effect(Heap_Verifier* heap_verifier) { @@ -221,38 +337,50 @@ if(gc_verifier->num_live_objects_before_gc != gc_verifier->num_live_objects_after_gc){ gc_verifier->is_verification_passed = FALSE; - printf("ERROR"); + printf("\nERROR: live objects number error!\n"); + assert(0); } if(gc_verifier->size_live_objects_before_gc != gc_verifier->size_live_objects_after_gc){ - printf("ERROR"); + printf("\nERROR: live objects size error!\n"); + assert(0); gc_verifier->is_verification_passed = FALSE; } #ifndef BUILD_IN_REFERENT if(gc_verifier->num_resurrect_objects_before_gc != gc_verifier->num_resurrect_objects_after_gc){ - printf("ERROR"); + printf("\nERROR: resurrect objects number error!\n"); + assert(0); gc_verifier->is_verification_passed = FALSE; } if(gc_verifier->size_resurrect_objects_before_gc != gc_verifier->size_resurrect_objects_after_gc){ - printf("ERROR"); + printf("\nERROR: resurrect objects size error!\n"); + assert(0); gc_verifier->is_verification_passed = FALSE; } #endif - + + if(gc_verifier->num_hash_before_gc != gc_verifier->num_hash_after_gc){ + printf("\nERROR: hashcode number error\n"); + assert(0); + gc_verifier->is_verification_passed = FALSE; + } + Heap_Verifier_Metadata* verifier_metadata = heap_verifier->heap_verifier_metadata; - Pool* free_pool = verifier_metadata->free_objects_pool; + Pool* free_pool = verifier_metadata->free_set_pool; - Object_Comparator object_comparator = compare_live_obj_inform; Boolean passed = verifier_compare_objs_pools(verifier_metadata->objects_pool_before_gc, - verifier_metadata->objects_pool_after_gc , free_pool, object_comparator); + verifier_metadata->objects_pool_after_gc , free_pool, compare_live_obj_inform); if(!passed) gc_verifier->is_verification_passed = FALSE; #ifndef BUILD_IN_REFERENT passed = verifier_compare_objs_pools(verifier_metadata->resurrect_objects_pool_before_gc, - verifier_metadata->resurrect_objects_pool_after_gc , free_pool, object_comparator); + verifier_metadata->resurrect_objects_pool_after_gc , free_pool, compare_live_obj_inform); if(!passed) gc_verifier->is_verification_passed = FALSE; #endif + passed = verifier_compare_objs_pools(verifier_metadata->hashcode_pool_before_gc, + verifier_metadata->hashcode_pool_after_gc , free_pool, compare_obj_hash_inform); + if(!passed) gc_verifier->is_verification_passed = FALSE; } Index: src/verify/verify_gc_effect.h =================================================================== --- src/verify/verify_gc_effect.h (revision 542506) +++ src/verify/verify_gc_effect.h (working copy) @@ -7,6 +7,7 @@ Vector_Block* trace_stack; Vector_Block* root_set; Vector_Block* objects_set; + Vector_Block* hashcode_set; Boolean is_tracing_resurrect_obj; unsigned int gc_collect_kind; @@ -21,7 +22,18 @@ POINTER_SIZE_INT num_resurrect_objects_after_gc; POINTER_SIZE_INT size_resurrect_objects_before_gc; POINTER_SIZE_INT size_resurrect_objects_after_gc; - + + POINTER_SIZE_INT num_hash_buffered_before_gc; + POINTER_SIZE_INT num_hash_buffered_after_gc; + POINTER_SIZE_INT num_hash_attached_before_gc; + POINTER_SIZE_INT num_hash_attached_after_gc; + POINTER_SIZE_INT num_hash_set_unalloc_before_gc; + POINTER_SIZE_INT num_hash_set_unalloc_after_gc; + + POINTER_SIZE_INT num_hash_before_gc; + POINTER_SIZE_INT num_hash_after_gc; + + Boolean is_verification_passed; }GC_Verifier; @@ -30,6 +42,12 @@ Partial_Reveal_Object* address; } Live_Object_Inform; +typedef struct Object_Hashcode_Inform_struct{ + int hashcode; + Partial_Reveal_Object* address; + POINTER_SIZE_INT hash_obj_distance; +}Object_Hashcode_Inform; + void verifier_init_GC_verifier(Heap_Verifier* heap_verifier); void verifier_destruct_GC_verifier(Heap_Verifier* heap_verifier); void verifier_reset_gc_verification(Heap_Verifier* heap_verifier); Index: src/verify/verify_live_heap.cpp =================================================================== --- src/verify/verify_live_heap.cpp (revision 542506) +++ src/verify/verify_live_heap.cpp (working copy) @@ -31,7 +31,7 @@ = heap_verifier->need_verify_allocation = heap_verifier->need_verify_writebarrier = FALSE; if(!verifier_parse_options(heap_verifier, GC_VERIFY)){ - printf("GC Verify options error, verifier will not start.\n"); + printf("GC Verify options error, verifier will not be started.\n"); gc_terminate_heap_verification(gc); return; } @@ -52,7 +52,6 @@ void verify_heap_before_gc(GC* gc) { - verifier_log_start(); verifier_set_gc_collect_kind(heap_verifier->gc_verifier, gc->collect_kind); verifier_set_gen_mode(heap_verifier); verifier_reset_mutator_verification(heap_verifier); @@ -74,7 +73,6 @@ void verify_heap_after_gc(GC* gc) { - verifier_log_start(); if(need_scan_live_objs(heap_verifier)) (*heap_verifier->live_obj_scanner)(heap_verifier); if(need_verify_gc_effect(heap_verifier)) @@ -103,16 +101,15 @@ assert(gc->collect_kind == FALLBACK_COLLECTION); if(!heap_verifier->need_verify_gc) return; - verifier_log_start(); /*finish the fallbacked gc verify*/ heap_verifier->is_before_gc = FALSE; verifier_set_fallback_collection(heap_verifier->gc_verifier, TRUE); (*heap_verifier->live_obj_scanner)(heap_verifier); verify_gc_effect(heap_verifier); - printf("GC Fall Back, GC end.\n"); verifier_log_after_gc(heap_verifier); verifier_clear_gc_verification(heap_verifier); + verifier_log_start("GC start"); /*start fallback major gc verify */ heap_verifier->is_before_gc = TRUE; verifier_set_fallback_collection(heap_verifier->gc_verifier, TRUE); @@ -134,4 +131,3 @@ - Index: src/verify/verify_mutator_effect.cpp =================================================================== --- src/verify/verify_mutator_effect.cpp (revision 542506) +++ src/verify/verify_mutator_effect.cpp (working copy) @@ -14,7 +14,7 @@ allocation_verifier->last_size_los_objs = allocation_verifier->last_num_los_objs = 0; allocation_verifier->new_objects_set = NULL; allocation_verifier->new_objects_set - = verifier_free_set_pool_get_entry(heap_verifier->heap_verifier_metadata->free_objects_pool); + = verifier_free_set_pool_get_entry(heap_verifier->heap_verifier_metadata->free_set_pool); heap_verifier->allocation_verifier = allocation_verifier; } @@ -44,7 +44,7 @@ alloc_verifier->size_los_objs = alloc_verifier->num_los_objs = 0; assert(alloc_verifier->new_objects_set == NULL); - alloc_verifier->new_objects_set = verifier_free_set_pool_get_entry(verifier_metadata->free_objects_pool); + alloc_verifier->new_objects_set = verifier_free_set_pool_get_entry(verifier_metadata->free_set_pool); assert(alloc_verifier->new_objects_set); } @@ -135,7 +135,7 @@ STD_FREE(p_newobj); } vector_block_clear(new_objects); - pool_put_entry(verifier_metadata->free_objects_pool, new_objects); + pool_put_entry(verifier_metadata->free_set_pool, new_objects); new_objects = pool_get_entry(verifier_metadata->new_objects_pool); } } @@ -216,7 +216,7 @@ /*The rootset set verifier is placed here, so the rootset verifier verifys the rootset that vm enumerated before GC. The rootset verifying processes before and after gc will be integrated in gc verifying pass, - the rootset verifying is considered as slot verifying while verifying gc. */ + the rootset verifying is considered as slot verifying while verifying heap. */ void verifier_init_rootset_verifier( Heap_Verifier* heap_verifier) { RootSet_Verifier* rs_verifier = (RootSet_Verifier*)STD_MALLOC(sizeof(RootSet_Verifier)); @@ -237,6 +237,12 @@ heap_verifier->rootset_verifier = NULL; } +void verifier_reset_rootset_verifier( Heap_Verifier* heap_verifier) +{ + RootSet_Verifier* rootset_verifier = heap_verifier->rootset_verifier; + rootset_verifier->num_slots_in_rootset = 0; + rootset_verifier->num_error_slots = 0; +} void verify_root_set(Heap_Verifier* heap_verifier) { @@ -296,6 +302,13 @@ heap_verifier->writebarrier_verifier = NULL; } +void verifier_reset_wb_verifier(Heap_Verifier* heap_verifier) +{ + WriteBarrier_Verifier* wb_verifier = heap_verifier->writebarrier_verifier; + wb_verifier->num_ref_wb_after_scanning = 0; + wb_verifier->num_ref_wb_in_remset = 0; + wb_verifier->num_slots_in_remset = 0; +} void verifier_mark_wb_slots(Heap_Verifier* heap_verifier) { @@ -344,12 +357,19 @@ if(!address_belongs_to_space((void*)p_ref, nspace) && address_belongs_to_space(read_slot(p_ref), nspace)){ if(!wb_is_marked_in_slot(p_ref)){ assert(0); - printf("GC Verify ==> Verify Write Barrier: error!!!\n"); + printf("GC Verify ==> Verify Write Barrier: unbuffered error!!!\n"); wb_verifier->is_verification_passed = FALSE; }else{ wb_unmark_in_slot(p_ref); wb_verifier->num_ref_wb_after_scanning ++; } + return; + }else{ + if(wb_is_marked_in_slot(p_ref)){ + assert(0); + printf("GC Verify ==>Verify Write Barrier: buffered error!!!\n"); + } + return; } } @@ -375,7 +395,8 @@ heap_verifier->allocation_verifier->is_verification_passed = TRUE; heap_verifier->writebarrier_verifier->is_verification_passed = TRUE; heap_verifier->rootset_verifier->is_verification_passed = TRUE; - + verifier_reset_wb_verifier(heap_verifier); + verifier_reset_rootset_verifier(heap_verifier); if(heap_verifier->need_verify_writebarrier && heap_verifier->gc_is_gen_mode) verifier_mark_wb_slots(heap_verifier);