blob: bc9c721ac32a4dcb6b3b8f9ccaf39f813f89c6d0 [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 "../common/gc_common.h"
#ifdef GC_GEN_STATS
#include "gen.h"
#include "gen_stats.h"
Boolean gc_profile = FALSE;
void gc_gen_stats_initialize(GC_Gen* gc)
{
GC_Gen_Stats* stats = (GC_Gen_Stats*)STD_MALLOC(sizeof(GC_Gen_Stats));
memset(stats, 0, sizeof(GC_Gen_Stats));
stats->is_los_collected = FALSE;
gc->stats = stats;
}
void gc_gen_stats_destruct(GC_Gen* gc)
{
STD_FREE(gc->stats);
}
void gc_gen_stats_reset_before_collection(GC_Gen* gc)
{
GC_Gen_Stats* stats = gc->stats;
if(collect_is_minor()){
stats->nos_surviving_obj_num_minor = 0;
stats->nos_surviving_obj_size_minor = 0;
stats->los_suviving_obj_num = 0;
stats->los_suviving_obj_size = 0;
stats->is_los_collected = false;
}else{
stats->nos_mos_suviving_obj_num_major = 0;
stats->nos_mos_suviving_obj_size_major = 0;
stats->los_suviving_obj_num = 0;
stats->los_suviving_obj_size = 0;
stats->is_los_collected = false;
}
}
void gc_gen_stats_update_after_collection(GC_Gen* gc)
{
Collector** collector = gc->collectors;
GC_Gen_Stats* gc_gen_stats = gc->stats;
GC_Gen_Collector_Stats* collector_stats;
Boolean is_los_collected = gc_gen_stats->is_los_collected;
if(collect_is_minor()) {
for (unsigned int i=0; i<gc->num_active_collectors; i++) {
collector_stats = (GC_Gen_Collector_Stats*)collector[i]->stats;
gc_gen_stats->nos_surviving_obj_num_minor += collector_stats->nos_obj_num_moved_minor;
gc_gen_stats->nos_surviving_obj_size_minor += collector_stats->nos_obj_size_moved_minor;
}
gc_gen_stats->nos_surviving_ratio_minor = ((float)gc_gen_stats->nos_surviving_obj_size_minor)/gc->nos->committed_heap_size;
}else{
for (unsigned int i=0; i < gc->num_active_collectors; i++) {
collector_stats = (GC_Gen_Collector_Stats*)collector[i]->stats;
gc_gen_stats->nos_mos_suviving_obj_num_major += collector_stats->nos_mos_obj_num_moved_major;
gc_gen_stats->nos_mos_suviving_obj_size_major += collector_stats->nos_mos_obj_size_moved_major;
/*need to accumulate the los related info if los is collected when major*/
if(is_los_collected) {
gc_gen_stats->los_suviving_obj_num += collector_stats->los_obj_num_moved_major;
gc_gen_stats->los_suviving_obj_size += collector_stats->los_obj_size_moved_major;
}
}
gc_gen_stats->nos_mos_suviving_ratio_major = ((float)gc_gen_stats->nos_mos_suviving_obj_size_major)/(gc->nos->committed_heap_size+gc->mos->committed_heap_size);
}
if (is_los_collected) {
gc_gen_stats->los_surviving_ratio = ((float)gc_gen_stats->los_suviving_obj_size)/gc->los->committed_heap_size;
}
}
void gc_gen_stats_verbose(GC_Gen* gc)
{
GC_Gen_Stats* stats = gc->stats;
Boolean is_los_collected = stats->is_los_collected;
if (collect_is_minor()){
TRACE2("gc.space", "GC: NOS Collection stats: "
<<"\nGC: " << (gc_is_gen_mode()?"generational":"nongenerational")
<<"\nGC: collection algo: " << (minor_is_semispace()?"semi-space":"partial-forward")
<<"\nGC: num surviving objs: " << stats->nos_surviving_obj_num_minor
<<"\nGC: size surviving objs: " << verbose_print_size(stats->nos_surviving_obj_size_minor)
<<"\nGC: surviving ratio: " << (int)(stats->nos_surviving_ratio_minor*100) << "%\n");
}else{
TRACE2("gc.space", "GC: MOS Collection stats: "
<<"\nGC: collection algo: " << (major_is_marksweep()?"mark-sweep":"slide compact")
<<"\nGC: num surviving objs: "<<stats->nos_mos_suviving_obj_num_major
<<"\nGC: size surviving objs: "<<verbose_print_size(stats->nos_mos_suviving_obj_size_major)
<<"\nGC: surviving ratio: "<<(int)(stats->nos_mos_suviving_ratio_major*100)<<"%\n");
}
if(stats->is_los_collected) { /*if los is collected, need to output los related info*/
TRACE2("gc.space", "GC: Lspace Collection stats: "
<<"\nGC: collection algo: "<<(collect_is_major()?"slide compact":"mark sweep")
<<"\nGC: num surviving objs: "<<stats->los_suviving_obj_num
<<"\nGC: size surviving objs: "<<verbose_print_size(stats->los_suviving_obj_size)
<<"\nGC: surviving ratio: "<<(int)(stats->los_surviving_ratio*100)<<"%\n");
}
}
void gc_gen_collector_stats_initialize(Collector* collector)
{
GC_Gen_Collector_Stats* stats = (GC_Gen_Collector_Stats*)STD_MALLOC(sizeof(GC_Gen_Collector_Stats));
memset(stats, 0, sizeof(GC_Gen_Collector_Stats));
collector->stats = (void*)stats;
}
void gc_gen_collector_stats_destruct(Collector* collector)
{
STD_FREE(collector->stats);
}
void gc_gen_collector_stats_reset(GC_Gen* gc)
{
Collector** collector = gc->collectors;
GC_Gen_Collector_Stats* stats;
for (unsigned int i=0; i<gc->num_active_collectors; i++){
stats = (GC_Gen_Collector_Stats*)collector[i]->stats;
memset(stats, 0, sizeof(GC_Gen_Collector_Stats));
}
}
void gc_gen_collector_stats_verbose_minor_collection(GC_Gen* gc)
{
Collector** collector = gc->collectors;
GC_Gen_Collector_Stats* stats;
/*variable used to accumulate each collector's stats when minor collection*/
unsigned int total_process_rootset_ref = 0;
unsigned int total_mark_nos_obj_num = 0;
unsigned int total_mark_non_nos_obj_num = 0;
unsigned int total_forward_obj_num = 0;
POINTER_SIZE_INT total_forward_obj_size = 0;
for (unsigned int i=0; i<gc->num_active_collectors; i++){
stats = (GC_Gen_Collector_Stats*)collector[i]->stats;
total_process_rootset_ref += stats->process_rootset_ref_num;
total_mark_nos_obj_num += stats->nos_obj_num_marked_minor;
total_mark_non_nos_obj_num += stats->nonnos_obj_num_marked_minor;
total_forward_obj_num += stats->nos_obj_num_moved_minor;
total_forward_obj_size += stats->nos_obj_size_moved_minor;
/*output each collector's stats*/
TRACE2("gc.collect", "GC: Collector["<<((POINTER_SIZE_INT)collector[i]->thread_handle)<<"] stats when collection:"
<<"\nGC: process rootset ref num: "<<stats->process_rootset_ref_num
<<"\nGC: mark nos obj num: "<<stats->nos_obj_num_marked_minor
<<"\nGC: mark nonnos obj num: "<<stats->nonnos_obj_num_marked_minor
<<" \nGC: forword obj num: "<<stats->nos_obj_num_moved_minor
<<" \nGC: forward obj size: "<<verbose_print_size(stats->nos_obj_size_moved_minor)<<"\n");
}
/*output accumulated info for all collectors*/
TRACE2("gc.collect", "GC: Total Collector Stats when collection: "
<<"\nGC: process rootset ref num: "<<total_process_rootset_ref
<<"\nGC: mark nos obj num: "<<total_mark_nos_obj_num
<<"\nGC: mark nonnos obj num: "<<total_mark_non_nos_obj_num
<<"\nGC: forword obj num: "<<total_forward_obj_num
<<"\nGC: forward obj size: "<<verbose_print_size(total_forward_obj_size)<<"\n");
}
void gc_gen_collector_stats_verbose_major_collection(GC_Gen* gc)
{
Collector** collector = gc->collectors;
GC_Gen_Collector_Stats* stats;
Boolean is_los_collected = gc->stats->is_los_collected;
/*variable used to accumulate each collector's stats when major collection*/
unsigned int total_process_rootset_ref = 0;
unsigned int total_mark_heap_live_obj_num = 0;
unsigned int total_move_mos_nos_live_obj_num = 0;
POINTER_SIZE_INT total_move_mos_nos_live_obj_size = 0;
unsigned int total_move_los_live_obj_num = 0;
POINTER_SIZE_INT total_move_los_live_obj_size = 0;
for (unsigned int i=0; i<gc->num_active_collectors; i++){
stats = (GC_Gen_Collector_Stats*)collector[i]->stats;
total_process_rootset_ref = stats->process_rootset_ref_num;
total_mark_heap_live_obj_num = stats->num_obj_marked_major;
total_move_mos_nos_live_obj_num = stats->nos_mos_obj_num_moved_major;
total_move_mos_nos_live_obj_size = stats->nos_mos_obj_size_moved_major;
if (is_los_collected){/*if los is collected when major collection happened, need to accumulate los related info*/
total_move_los_live_obj_num = stats->los_obj_num_moved_major;
total_move_los_live_obj_size = stats->los_obj_size_moved_major;
}
if(is_los_collected){
TRACE2("gc.collect", "GC: Collector["<<((POINTER_SIZE_INT)collector[i]->thread_handle)<<"] stats when collection:"
<<"\nGC: process rootset ref num: "<<stats->process_rootset_ref_num
<<"\nGC: mark obj num: "<<stats->num_obj_marked_major
<<"\nGC: move mos and nos obj num: "<<stats->nos_mos_obj_num_moved_major
<<"\nGC: move obj size: "<<verbose_print_size(stats->nos_mos_obj_size_moved_major)
<<"\nGC: move los obj num: "<<stats->los_obj_num_moved_major
<<"\nGC: move obj size: "<<verbose_print_size(stats->los_obj_size_moved_major)<<"\n");
}else{
TRACE2("gc.collect", "GC: Collector["<<((POINTER_SIZE_INT)collector[i]->thread_handle)<<"] stats when collection:"
<<"\nGC: process rootset ref num: "<<stats->process_rootset_ref_num
<<"\nGC: mark obj num: "<<stats->num_obj_marked_major
<<"\nGC: move obj num: "<<stats->nos_mos_obj_num_moved_major
<<"\nGC: move obj size: "<<verbose_print_size(stats->nos_mos_obj_size_moved_major)<<"\n");
}
}
if(is_los_collected){/*if los is collected when major collection happened, need to output los related collector info*/
TRACE2("gc.collect", "GC: Total Collector Stats when collection: "
<<"\nGC: process rootset ref num: "<<total_process_rootset_ref
<<"\nGC: mark obj num: "<<total_mark_heap_live_obj_num
<<"\nGC: move mos and nos obj num: "<<total_move_mos_nos_live_obj_num
<<"\nGC: move obj size: "<<verbose_print_size(total_move_mos_nos_live_obj_size)
<<"\nGC: move los obj num: "<<total_move_los_live_obj_num
<<"\nGC: move obj size: "<<verbose_print_size(total_move_los_live_obj_size)<<"\n");
}else{
TRACE2("gc.collect", "GC: Total Collector Stats when collection: "
<<"\nGC: process rootset ref num: "<<total_process_rootset_ref
<<"\nGC: mark obj num: "<<total_mark_heap_live_obj_num
<<"\nGC: move mos and nos obj num: "<<total_move_mos_nos_live_obj_num
<<"\nGC: move obj size: "<<verbose_print_size(total_move_mos_nos_live_obj_size)<<"\n");
}
}
#endif