< prev index next >

src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp

Print this page

        

*** 23,145 **** */ #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1GCPHASETIMESLOG_HPP #define SHARE_VM_GC_IMPLEMENTATION_G1_G1GCPHASETIMESLOG_HPP - #include "memory/allocation.hpp" #include "gc_interface/gcCause.hpp" template <class T> class WorkerDataArray : public CHeapObj<mtGC> { T* _data; uint _length; ! const char* _print_format; bool _print_sum; ! NOT_PRODUCT(static const T _uninitialized;) // We are caching the sum and average to only have to calculate them once. // This is not done in an MT-safe way. It is intended to allow single // threaded code to call sum() and average() multiple times in any order // without having to worry about the cost. bool _has_new_data; T _sum; double _average; public: ! WorkerDataArray(uint length, const char* print_format, bool print_sum = true) : ! _length(length), _print_format(print_format), _print_sum(print_sum), _has_new_data(true) { ! assert(length > 0, "Must have some workers to store data for"); ! _data = NEW_C_HEAP_ARRAY(T, _length, mtGC); ! } ! ~WorkerDataArray() { ! FREE_C_HEAP_ARRAY(T, _data); } void set(uint worker_i, T value) { assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length)); ! assert(_data[worker_i] == (T)-1, err_msg("Overwriting data for worker %d", worker_i)); _data[worker_i] = value; _has_new_data = true; } T get(uint worker_i) { assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length)); ! assert(_data[worker_i] != (T)-1, err_msg("No data to add to for worker %d", worker_i)); return _data[worker_i]; } void add(uint worker_i, T value) { assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length)); ! assert(_data[worker_i] != (T)-1, err_msg("No data to add to for worker %d", worker_i)); _data[worker_i] += value; _has_new_data = true; } double average(){ - if (_has_new_data) { calculate_totals(); - } return _average; } T sum() { - if (_has_new_data) { calculate_totals(); - } return _sum; } ! void print(int level, const char* title); void reset() PRODUCT_RETURN; void verify() PRODUCT_RETURN; private: void calculate_totals(){ _sum = (T)0; for (uint i = 0; i < _length; ++i) { ! _sum += _data[i]; } _average = (double)_sum / (double)_length; _has_new_data = false; } }; class G1GCPhaseTimes : public CHeapObj<mtGC> { - private: uint _active_gc_threads; uint _max_gc_threads; ! WorkerDataArray<double> _last_gc_worker_start_times_ms; ! WorkerDataArray<double> _last_ext_root_scan_times_ms; ! WorkerDataArray<double> _last_satb_filtering_times_ms; ! WorkerDataArray<double> _last_update_rs_times_ms; ! WorkerDataArray<int> _last_update_rs_processed_buffers; ! WorkerDataArray<double> _last_scan_rs_times_ms; ! WorkerDataArray<double> _last_strong_code_root_scan_times_ms; ! WorkerDataArray<double> _last_obj_copy_times_ms; ! WorkerDataArray<double> _last_termination_times_ms; ! WorkerDataArray<size_t> _last_termination_attempts; ! WorkerDataArray<double> _last_gc_worker_end_times_ms; ! WorkerDataArray<double> _last_gc_worker_times_ms; ! WorkerDataArray<double> _last_gc_worker_other_times_ms; double _cur_collection_par_time_ms; double _cur_collection_code_root_fixup_time_ms; double _cur_strong_code_root_purge_time_ms; double _cur_evac_fail_recalc_used; double _cur_evac_fail_restore_remsets; double _cur_evac_fail_remove_self_forwards; double _cur_string_dedup_fixup_time_ms; - WorkerDataArray<double> _cur_string_dedup_queue_fixup_worker_times_ms; - WorkerDataArray<double> _cur_string_dedup_table_fixup_worker_times_ms; double _cur_clear_ct_time_ms; double _cur_ref_proc_time_ms; double _cur_ref_enq_time_ms; --- 23,190 ---- */ #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1GCPHASETIMESLOG_HPP #define SHARE_VM_GC_IMPLEMENTATION_G1_G1GCPHASETIMESLOG_HPP #include "gc_interface/gcCause.hpp" + class LineBuffer; + template <class T> class WorkerDataArray : public CHeapObj<mtGC> { + friend class G1GCPhasePrinter; T* _data; uint _length; ! const char* _title; bool _print_sum; + int _log_level; + uint _indent_level; + bool _enabled; + + WorkerDataArray<size_t>* _sub_count; ! NOT_PRODUCT(T uninitialized();) // We are caching the sum and average to only have to calculate them once. // This is not done in an MT-safe way. It is intended to allow single // threaded code to call sum() and average() multiple times in any order // without having to worry about the cost. bool _has_new_data; T _sum; + T _min; + T _max; double _average; public: ! WorkerDataArray(uint length, const char* title, bool print_sum, int log_level, uint indent_level); ! ! ~WorkerDataArray(); ! void link_sub_count_array(WorkerDataArray<size_t>* sub_count) { ! _sub_count = sub_count; } + WorkerDataArray<size_t>* sub_count() { return _sub_count; } + void set(uint worker_i, T value) { assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length)); ! assert(_data[worker_i] == WorkerDataArray<T>::uninitialized(), err_msg("Overwriting data for worker %d in %s", worker_i, _title)); _data[worker_i] = value; _has_new_data = true; } + void set_sub_count(uint worker_i, size_t value) { + assert(_sub_count != NULL, "No sub count"); + _sub_count->set(worker_i, value); + } + T get(uint worker_i) { assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length)); ! assert(_data[worker_i] != WorkerDataArray<T>::uninitialized(), err_msg("No data to add to for worker %d", worker_i)); return _data[worker_i]; } void add(uint worker_i, T value) { assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length)); ! assert(_data[worker_i] != WorkerDataArray<T>::uninitialized(), err_msg("No data to add to for worker %d", worker_i)); _data[worker_i] += value; _has_new_data = true; } double average(){ calculate_totals(); return _average; } T sum() { calculate_totals(); return _sum; } ! T minimum() { ! calculate_totals(); ! return _min; ! } ! ! T maximum() { ! calculate_totals(); ! return _max; ! } void reset() PRODUCT_RETURN; void verify() PRODUCT_RETURN; + void set_enabled(bool enabled) { _enabled = enabled; } + + int log_level() { return _log_level; } + private: void calculate_totals(){ + if (!_has_new_data) { + return; + } + _sum = (T)0; + _min = _data[0]; + _max = _min; for (uint i = 0; i < _length; ++i) { ! T val = _data[i]; ! _sum += val; ! _min = MIN2(_min, val); ! _max = MAX2(_max, val); } _average = (double)_sum / (double)_length; _has_new_data = false; } }; class G1GCPhaseTimes : public CHeapObj<mtGC> { + friend class G1GCPhasePrinter; uint _active_gc_threads; uint _max_gc_threads; ! public: ! enum GCPhases { ! GCWorkerStart, ! ExtRootScan, ! SATBFiltering, ! UpdateRS, ! ScanRS, ! CodeRoots, ! ObjCopy, ! Termination, ! Other, ! GCWorkerTotal, ! GCWorkerEnd, ! StringDedupQueueFixup, ! StringDedupTableFixup, ! RedirtyCards, ! Sentinel ! }; ! ! private: ! // Markers for grouping the phases in the GCPhases enum above ! static const int GCMainPhasesLast = GCWorkerEnd; ! static const int StringDedupPhasesFirst = StringDedupQueueFixup; ! static const int StringDedupPhasesLast = StringDedupTableFixup; ! ! WorkerDataArray<double>* _gc_phases[Sentinel]; ! WorkerDataArray<size_t>* _update_rs_processed_buffers; ! WorkerDataArray<size_t>* _termination_attempts; ! WorkerDataArray<size_t>* _redirtied_cards; double _cur_collection_par_time_ms; double _cur_collection_code_root_fixup_time_ms; double _cur_strong_code_root_purge_time_ms; double _cur_evac_fail_recalc_used; double _cur_evac_fail_restore_remsets; double _cur_evac_fail_remove_self_forwards; double _cur_string_dedup_fixup_time_ms; double _cur_clear_ct_time_ms; double _cur_ref_proc_time_ms; double _cur_ref_enq_time_ms;
*** 147,158 **** double _root_region_scan_wait_time_ms; double _recorded_young_cset_choice_time_ms; double _recorded_non_young_cset_choice_time_ms; - WorkerDataArray<double> _last_redirty_logged_cards_time_ms; - WorkerDataArray<size_t> _last_redirty_logged_cards_processed_cards; double _recorded_redirty_logged_cards_time_ms; double _recorded_young_free_cset_time_ms; double _recorded_non_young_free_cset_time_ms; --- 192,201 ----
*** 170,228 **** void print_stats(int level, const char* str, size_t value); void print_stats(int level, const char* str, double value, uint workers); public: G1GCPhaseTimes(uint max_gc_threads); ! void note_gc_start(uint active_gc_threads); void note_gc_end(); void print(double pause_time_sec); ! void record_gc_worker_start_time(uint worker_i, double ms) { ! _last_gc_worker_start_times_ms.set(worker_i, ms); } ! void record_ext_root_scan_time(uint worker_i, double ms) { ! _last_ext_root_scan_times_ms.set(worker_i, ms); } ! void record_satb_filtering_time(uint worker_i, double ms) { ! _last_satb_filtering_times_ms.set(worker_i, ms); } ! void record_update_rs_time(uint worker_i, double ms) { ! _last_update_rs_times_ms.set(worker_i, ms); } ! void record_update_rs_processed_buffers(uint worker_i, int processed_buffers) { ! _last_update_rs_processed_buffers.set(worker_i, processed_buffers); } ! void record_scan_rs_time(uint worker_i, double ms) { ! _last_scan_rs_times_ms.set(worker_i, ms); } ! void record_strong_code_root_scan_time(uint worker_i, double ms) { ! _last_strong_code_root_scan_times_ms.set(worker_i, ms); } ! void record_obj_copy_time(uint worker_i, double ms) { ! _last_obj_copy_times_ms.set(worker_i, ms); } ! void add_obj_copy_time(uint worker_i, double ms) { ! _last_obj_copy_times_ms.add(worker_i, ms); } ! void record_termination(uint worker_i, double ms, size_t attempts) { ! _last_termination_times_ms.set(worker_i, ms); ! _last_termination_attempts.set(worker_i, attempts); } ! void record_gc_worker_end_time(uint worker_i, double ms) { ! _last_gc_worker_end_times_ms.set(worker_i, ms); } void record_clear_ct_time(double ms) { _cur_clear_ct_time_ms = ms; } void record_par_time(double ms) { --- 213,295 ---- void print_stats(int level, const char* str, size_t value); void print_stats(int level, const char* str, double value, uint workers); public: G1GCPhaseTimes(uint max_gc_threads); ! void note_gc_start(uint active_gc_threads, bool mark_in_progress); void note_gc_end(); void print(double pause_time_sec); ! // record the time a phase took in seconds ! void record_time_secs(GCPhases phase, uint worker_i, double secs) { ! _gc_phases[phase]->set(worker_i, secs); } ! // add a number of seconds to a phase ! void add_time_secs(GCPhases phase, uint worker_i, double secs) { ! _gc_phases[phase]->add(worker_i, secs); } ! void record_sub_count(GCPhases phase, uint worker_i, size_t count) { ! _gc_phases[phase]->set_sub_count(worker_i, count); ! } ! ! // return the average time for a phase in milliseconds ! double average_time_ms(GCPhases phase) { ! return _gc_phases[phase]->average() * 1000.0; ! } ! ! size_t sub_count_sum(GCPhases phase) { ! assert(_gc_phases[phase]->sub_count() != NULL, "No sub count"); ! return _gc_phases[phase]->sub_count()->sum(); ! } ! ! private: ! ! double get_time_ms(GCPhases phase, uint worker_i) { ! return _gc_phases[phase]->get(worker_i) * 1000.0; } ! double sum_time_ms(GCPhases phase) { ! return _gc_phases[phase]->sum() * 1000.0; } ! double min_time_ms(GCPhases phase) { ! return _gc_phases[phase]->minimum() * 1000.0; } ! double max_time_ms(GCPhases phase) { ! return _gc_phases[phase]->maximum() * 1000.0; } ! size_t get_sub_count(GCPhases phase, uint worker_i) { ! assert(_gc_phases[phase]->sub_count() != NULL, "No sub count"); ! return _gc_phases[phase]->sub_count()->get(worker_i); } ! size_t sum_sub_count(GCPhases phase) { ! assert(_gc_phases[phase]->sub_count() != NULL, "No sub count"); ! return _gc_phases[phase]->sub_count()->sum(); } ! double average_sub_count(GCPhases phase) { ! assert(_gc_phases[phase]->sub_count() != NULL, "No sub count"); ! return _gc_phases[phase]->sub_count()->average(); } ! size_t min_sub_count(GCPhases phase) { ! assert(_gc_phases[phase]->sub_count() != NULL, "No sub count"); ! return _gc_phases[phase]->sub_count()->minimum(); } ! size_t max_sub_count(GCPhases phase) { ! assert(_gc_phases[phase]->sub_count() != NULL, "No sub count"); ! return _gc_phases[phase]->sub_count()->maximum(); } + public: + void record_clear_ct_time(double ms) { _cur_clear_ct_time_ms = ms; } void record_par_time(double ms) {
*** 247,271 **** void record_evac_fail_remove_self_forwards(double ms) { _cur_evac_fail_remove_self_forwards = ms; } - void note_string_dedup_fixup_start(); - void note_string_dedup_fixup_end(); - void record_string_dedup_fixup_time(double ms) { _cur_string_dedup_fixup_time_ms = ms; } - void record_string_dedup_queue_fixup_worker_time(uint worker_id, double ms) { - _cur_string_dedup_queue_fixup_worker_times_ms.set(worker_id, ms); - } - - void record_string_dedup_table_fixup_worker_time(uint worker_id, double ms) { - _cur_string_dedup_table_fixup_worker_times_ms.set(worker_id, ms); - } - void record_ref_proc_time(double ms) { _cur_ref_proc_time_ms = ms; } void record_ref_enq_time(double ms) { --- 314,327 ----
*** 301,318 **** void record_non_young_cset_choice_time_ms(double time_ms) { _recorded_non_young_cset_choice_time_ms = time_ms; } - void record_redirty_logged_cards_time_ms(uint worker_i, double time_ms) { - _last_redirty_logged_cards_time_ms.set(worker_i, time_ms); - } - - void record_redirty_logged_cards_processed_cards(uint worker_i, size_t processed_buffers) { - _last_redirty_logged_cards_processed_cards.set(worker_i, processed_buffers); - } - void record_redirty_logged_cards_time_ms(double time_ms) { _recorded_redirty_logged_cards_time_ms = time_ms; } void record_cur_collection_start_sec(double time_ms) { --- 357,366 ----
*** 362,401 **** } double fast_reclaim_humongous_time_ms() { return _cur_fast_reclaim_humongous_time_ms; } ! double average_last_update_rs_time() { ! return _last_update_rs_times_ms.average(); ! } ! ! int sum_last_update_rs_processed_buffers() { ! return _last_update_rs_processed_buffers.sum(); ! } ! ! double average_last_scan_rs_time(){ ! return _last_scan_rs_times_ms.average(); ! } ! ! double average_last_strong_code_root_scan_time(){ ! return _last_strong_code_root_scan_times_ms.average(); ! } ! ! double average_last_obj_copy_time() { ! return _last_obj_copy_times_ms.average(); ! } ! ! double average_last_termination_time() { ! return _last_termination_times_ms.average(); ! } ! ! double average_last_ext_root_scan_time() { ! return _last_ext_root_scan_times_ms.average(); ! } ! double average_last_satb_filtering_times_ms() { ! return _last_satb_filtering_times_ms.average(); ! } }; #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1GCPHASETIMESLOG_HPP --- 410,439 ---- } double fast_reclaim_humongous_time_ms() { return _cur_fast_reclaim_humongous_time_ms; } + }; ! class G1GCPhaseTimesTracker : public StackObj { ! double _start_time; ! G1GCPhaseTimes::GCPhases _phase; ! G1GCPhaseTimes* _phase_times; ! uint _worker_id; ! public: ! G1GCPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCPhaseTimes::GCPhases phase, uint worker_id); ! ~G1GCPhaseTimesTracker(); ! }; ! class G1GCPhasePrinter : public StackObj { ! G1GCPhaseTimes* _phase_times; ! void print_single_length(G1GCPhaseTimes::GCPhases phase_id, WorkerDataArray<double>* phase); ! void print_multi_length(G1GCPhaseTimes::GCPhases phase_id, WorkerDataArray<double>* phase); ! void print_sub_count(G1GCPhaseTimes::GCPhases phase_id, WorkerDataArray<size_t>* sub_count); ! void print_time_values(LineBuffer& buf, G1GCPhaseTimes::GCPhases phase_id, WorkerDataArray<double>* phase); ! void print_count_values(LineBuffer& buf, G1GCPhaseTimes::GCPhases phase_id, WorkerDataArray<size_t>* phase); ! public: ! G1GCPhasePrinter(G1GCPhaseTimes* phase_times) : _phase_times(phase_times) {} ! void print(G1GCPhaseTimes::GCPhases phase_id); }; #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1GCPHASETIMESLOG_HPP
< prev index next >