blob: 9d823a5be3f86a3525264a88128d0aa7c97a1fc9 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
#include "verify_live_heap.h"
#include "verifier_common.h"
#include "verify_gc_effect.h"
#include "verify_mutator_effect.h"
char* GC_VERIFY = NULL;
Boolean verify_live_heap;
Heap_Verifier* heap_verifier;
void gc_init_heap_verification(GC* gc)
{
if(GC_VERIFY == NULL){
verify_live_heap = FALSE;
return;
}
heap_verifier = (Heap_Verifier*) STD_MALLOC(sizeof(Heap_Verifier));
assert(heap_verifier);
memset(heap_verifier, 0, sizeof(Heap_Verifier));
heap_verifier->gc = gc;
verifier_metadata_initialize(heap_verifier);
verifier_init_mutator_verifiers(heap_verifier);
verifier_init_GC_verifier(heap_verifier);
verifier_init_object_scanner(heap_verifier);
heap_verifier->is_before_gc = heap_verifier->gc_is_gen_mode = FALSE;
heap_verifier->need_verify_gc = heap_verifier->need_verify_rootset
= 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 be started.\n");
gc_terminate_heap_verification(gc);
return;
}
verify_live_heap = TRUE;
return;
}
void gc_terminate_heap_verification(GC* gc)
{
gc_verifier_metadata_destruct(heap_verifier);
verifier_destruct_mutator_verifiers(heap_verifier);
verifier_destruct_GC_verifier(heap_verifier);
STD_FREE(heap_verifier);
heap_verifier = NULL;
return;
}
void verify_heap_before_gc(GC* gc)
{
verifier_set_gc_collect_kind(heap_verifier->gc_verifier, GC_PROP);
verifier_set_gen_mode(heap_verifier);
verifier_reset_mutator_verification(heap_verifier);
verifier_reset_gc_verification(heap_verifier);
if(need_scan_all_objs(heap_verifier))
(*heap_verifier->all_obj_scanner)(heap_verifier);
/*verify mutator side effect before gc after scanning all objs.*/
if(need_verify_mutator_effect(heap_verifier))
verify_mutator_effect(heap_verifier);
if(need_scan_live_objs(heap_verifier))
(*heap_verifier->live_obj_scanner)(heap_verifier);
verifier_log_before_gc(heap_verifier);
}
void verifier_cleanup_block_info(GC* gc);
void verify_heap_after_gc(GC* gc)
{
if(!major_is_marksweep())
verifier_cleanup_block_info(gc);
if(need_scan_live_objs(heap_verifier))
(*heap_verifier->live_obj_scanner)(heap_verifier);
if(need_verify_gc_effect(heap_verifier))
verify_gc_effect(heap_verifier);
verifier_log_after_gc(heap_verifier);
verifier_clear_mutator_verification(heap_verifier);
verifier_clear_gc_verification(heap_verifier);
}
void gc_verify_heap(GC* gc, Boolean is_before_gc)
{
heap_verifier->is_before_gc = is_before_gc;
if(is_before_gc){
verify_heap_before_gc(gc);
}else{
verify_heap_after_gc(gc);
}
}
void event_gc_collect_kind_changed(GC* gc)
{
/*GC collection kind were changed from normal MINOR or MAJOR to FALLBACK MAJOR*/
assert(collect_is_fallback());
if(!heap_verifier->need_verify_gc) return;
if(!major_is_marksweep())
verifier_cleanup_block_info(gc);
/*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);
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);
verifier_set_gc_collect_kind(heap_verifier->gc_verifier, GC_PROP);
verifier_set_gen_mode(heap_verifier);
verifier_reset_gc_verification(heap_verifier);
(*heap_verifier->live_obj_scanner)(heap_verifier);
verifier_set_fallback_collection(heap_verifier->gc_verifier, FALSE);
}
void event_mutator_allocate_newobj(Partial_Reveal_Object* p_newobj, POINTER_SIZE_INT size, VT vt_raw)
{
verifier_event_mutator_allocate_newobj(p_newobj, size, vt_raw);
}
Heap_Verifier* get_heap_verifier()
{ return heap_verifier; }