brutisso@3923: /* tschatzl@7893: * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. brutisso@3923: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. brutisso@3923: * brutisso@3923: * This code is free software; you can redistribute it and/or modify it brutisso@3923: * under the terms of the GNU General Public License version 2 only, as brutisso@3923: * published by the Free Software Foundation. brutisso@3923: * brutisso@3923: * This code is distributed in the hope that it will be useful, but WITHOUT brutisso@3923: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or brutisso@3923: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License brutisso@3923: * version 2 for more details (a copy is included in the LICENSE file that brutisso@3923: * accompanied this code). brutisso@3923: * brutisso@3923: * You should have received a copy of the GNU General Public License version brutisso@3923: * 2 along with this work; if not, write to the Free Software Foundation, brutisso@3923: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. brutisso@3923: * brutisso@3923: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA brutisso@3923: * or visit www.oracle.com if you need additional information or have any brutisso@3923: * questions. brutisso@3923: * brutisso@3923: */ brutisso@3923: brutisso@3923: #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1GCPHASETIMESLOG_HPP brutisso@3923: #define SHARE_VM_GC_IMPLEMENTATION_G1_G1GCPHASETIMESLOG_HPP brutisso@3923: brutisso@3923: #include "memory/allocation.hpp" brutisso@3923: brutisso@7658: class LineBuffer; brutisso@4015: brutisso@7658: template class WorkerDataArray; brutisso@4015: jmasa@3924: class G1GCPhaseTimes : public CHeapObj { brutisso@7658: friend class G1GCParPhasePrinter; brutisso@3923: brutisso@3923: uint _active_gc_threads; brutisso@3923: uint _max_gc_threads; brutisso@3923: brutisso@7658: public: brutisso@7658: enum GCParPhases { brutisso@7658: GCWorkerStart, brutisso@7658: ExtRootScan, brutisso@7660: ThreadRoots, brutisso@7660: StringTableRoots, brutisso@7660: UniverseRoots, brutisso@7660: JNIRoots, brutisso@7660: ObjectSynchronizerRoots, brutisso@7660: FlatProfilerRoots, brutisso@7660: ManagementRoots, brutisso@7660: SystemDictionaryRoots, brutisso@7660: CLDGRoots, brutisso@7660: JVMTIRoots, brutisso@7660: CodeCacheRoots, brutisso@7660: CMRefRoots, brutisso@7660: WaitForStrongCLD, brutisso@7660: WeakCLDRoots, brutisso@7658: SATBFiltering, brutisso@7658: UpdateRS, brutisso@7658: ScanRS, brutisso@7658: CodeRoots, brutisso@7658: ObjCopy, brutisso@7658: Termination, brutisso@7658: Other, brutisso@7658: GCWorkerTotal, brutisso@7658: GCWorkerEnd, brutisso@7658: StringDedupQueueFixup, brutisso@7658: StringDedupTableFixup, brutisso@7658: RedirtyCards, brutisso@7658: GCParPhasesSentinel brutisso@7658: }; brutisso@7658: brutisso@7658: private: brutisso@7658: // Markers for grouping the phases in the GCPhases enum above brutisso@7658: static const int GCMainParPhasesLast = GCWorkerEnd; brutisso@7658: static const int StringDedupPhasesFirst = StringDedupQueueFixup; brutisso@7658: static const int StringDedupPhasesLast = StringDedupTableFixup; brutisso@7658: brutisso@7658: WorkerDataArray* _gc_par_phases[GCParPhasesSentinel]; brutisso@7658: WorkerDataArray* _update_rs_processed_buffers; brutisso@7658: WorkerDataArray* _termination_attempts; brutisso@7658: WorkerDataArray* _redirtied_cards; brutisso@3923: brutisso@3923: double _cur_collection_par_time_ms; brutisso@3923: double _cur_collection_code_root_fixup_time_ms; tschatzl@6402: double _cur_strong_code_root_purge_time_ms; brutisso@3923: tschatzl@6406: double _cur_evac_fail_recalc_used; tschatzl@6406: double _cur_evac_fail_restore_remsets; tschatzl@6406: double _cur_evac_fail_remove_self_forwards; tschatzl@6406: brutisso@7658: double _cur_string_dedup_fixup_time_ms; pliden@6413: brutisso@3923: double _cur_clear_ct_time_ms; brutisso@3923: double _cur_ref_proc_time_ms; brutisso@3923: double _cur_ref_enq_time_ms; brutisso@3923: brutisso@3923: double _cur_collection_start_sec; brutisso@3923: double _root_region_scan_wait_time_ms; brutisso@3923: brutisso@3923: double _recorded_young_cset_choice_time_ms; brutisso@3923: double _recorded_non_young_cset_choice_time_ms; brutisso@3923: tschatzl@6405: double _recorded_redirty_logged_cards_time_ms; tschatzl@6405: brutisso@3923: double _recorded_young_free_cset_time_ms; brutisso@3923: double _recorded_non_young_free_cset_time_ms; brutisso@3923: tschatzl@7010: double _cur_fast_reclaim_humongous_time_ms; tschatzl@7828: double _cur_fast_reclaim_humongous_register_time_ms; tschatzl@7010: size_t _cur_fast_reclaim_humongous_total; tschatzl@7010: size_t _cur_fast_reclaim_humongous_candidates; tschatzl@7010: size_t _cur_fast_reclaim_humongous_reclaimed; tschatzl@7010: brutisso@4015: double _cur_verify_before_time_ms; brutisso@4015: double _cur_verify_after_time_ms; brutisso@4015: brutisso@4015: // Helper methods for detailed logging brutisso@4015: void print_stats(int level, const char* str, double value); tschatzl@7010: void print_stats(int level, const char* str, size_t value); vkempik@6552: void print_stats(int level, const char* str, double value, uint workers); brutisso@3923: brutisso@3923: public: brutisso@3923: G1GCPhaseTimes(uint max_gc_threads); brutisso@7658: void note_gc_start(uint active_gc_threads, bool mark_in_progress); brutisso@4015: void note_gc_end(); brutisso@4015: void print(double pause_time_sec); brutisso@3923: brutisso@7658: // record the time a phase took in seconds brutisso@7658: void record_time_secs(GCParPhases phase, uint worker_i, double secs); brutisso@3923: brutisso@7658: // add a number of seconds to a phase brutisso@7658: void add_time_secs(GCParPhases phase, uint worker_i, double secs); brutisso@3923: brutisso@7658: void record_thread_work_item(GCParPhases phase, uint worker_i, size_t count); brutisso@3923: brutisso@7658: // return the average time for a phase in milliseconds brutisso@7658: double average_time_ms(GCParPhases phase); brutisso@3923: brutisso@7658: size_t sum_thread_work_items(GCParPhases phase); brutisso@3923: brutisso@7658: private: brutisso@7658: double get_time_ms(GCParPhases phase, uint worker_i); brutisso@7658: double sum_time_ms(GCParPhases phase); brutisso@7658: double min_time_ms(GCParPhases phase); brutisso@7658: double max_time_ms(GCParPhases phase); brutisso@7658: size_t get_thread_work_item(GCParPhases phase, uint worker_i); brutisso@7658: double average_thread_work_items(GCParPhases phase); brutisso@7658: size_t min_thread_work_items(GCParPhases phase); brutisso@7658: size_t max_thread_work_items(GCParPhases phase); brutisso@3923: brutisso@7658: public: brutisso@3923: brutisso@3923: void record_clear_ct_time(double ms) { brutisso@3923: _cur_clear_ct_time_ms = ms; brutisso@3923: } brutisso@3923: brutisso@3923: void record_par_time(double ms) { brutisso@3923: _cur_collection_par_time_ms = ms; brutisso@3923: } brutisso@3923: brutisso@3923: void record_code_root_fixup_time(double ms) { brutisso@3923: _cur_collection_code_root_fixup_time_ms = ms; brutisso@3923: } brutisso@3923: tschatzl@6402: void record_strong_code_root_purge_time(double ms) { tschatzl@6402: _cur_strong_code_root_purge_time_ms = ms; tschatzl@6402: } tschatzl@6402: tschatzl@6406: void record_evac_fail_recalc_used_time(double ms) { tschatzl@6406: _cur_evac_fail_recalc_used = ms; tschatzl@6406: } tschatzl@6406: tschatzl@6406: void record_evac_fail_restore_remsets(double ms) { tschatzl@6406: _cur_evac_fail_restore_remsets = ms; tschatzl@6406: } tschatzl@6406: tschatzl@6406: void record_evac_fail_remove_self_forwards(double ms) { tschatzl@6406: _cur_evac_fail_remove_self_forwards = ms; tschatzl@6406: } tschatzl@6406: pliden@6413: void record_string_dedup_fixup_time(double ms) { pliden@6413: _cur_string_dedup_fixup_time_ms = ms; pliden@6413: } pliden@6413: brutisso@3923: void record_ref_proc_time(double ms) { brutisso@3923: _cur_ref_proc_time_ms = ms; brutisso@3923: } brutisso@3923: brutisso@3923: void record_ref_enq_time(double ms) { brutisso@3923: _cur_ref_enq_time_ms = ms; brutisso@3923: } brutisso@3923: brutisso@3923: void record_root_region_scan_wait_time(double time_ms) { brutisso@3923: _root_region_scan_wait_time_ms = time_ms; brutisso@3923: } brutisso@3923: brutisso@3923: void record_young_free_cset_time_ms(double time_ms) { brutisso@3923: _recorded_young_free_cset_time_ms = time_ms; brutisso@3923: } brutisso@3923: brutisso@3923: void record_non_young_free_cset_time_ms(double time_ms) { brutisso@3923: _recorded_non_young_free_cset_time_ms = time_ms; brutisso@3923: } brutisso@4015: tschatzl@7828: void record_fast_reclaim_humongous_stats(double time_ms, size_t total, size_t candidates) { tschatzl@7828: _cur_fast_reclaim_humongous_register_time_ms = time_ms; tschatzl@7010: _cur_fast_reclaim_humongous_total = total; tschatzl@7010: _cur_fast_reclaim_humongous_candidates = candidates; tschatzl@7010: } tschatzl@7010: tschatzl@7010: void record_fast_reclaim_humongous_time_ms(double value, size_t reclaimed) { tschatzl@7010: _cur_fast_reclaim_humongous_time_ms = value; tschatzl@7010: _cur_fast_reclaim_humongous_reclaimed = reclaimed; tschatzl@7010: } tschatzl@7010: brutisso@4015: void record_young_cset_choice_time_ms(double time_ms) { brutisso@4015: _recorded_young_cset_choice_time_ms = time_ms; brutisso@4015: } brutisso@4015: brutisso@4015: void record_non_young_cset_choice_time_ms(double time_ms) { brutisso@4015: _recorded_non_young_cset_choice_time_ms = time_ms; brutisso@4015: } brutisso@4015: tschatzl@6405: void record_redirty_logged_cards_time_ms(double time_ms) { tschatzl@6405: _recorded_redirty_logged_cards_time_ms = time_ms; tschatzl@6405: } tschatzl@6405: brutisso@4015: void record_cur_collection_start_sec(double time_ms) { brutisso@4015: _cur_collection_start_sec = time_ms; brutisso@4015: } brutisso@4015: brutisso@4015: void record_verify_before_time_ms(double time_ms) { brutisso@4015: _cur_verify_before_time_ms = time_ms; brutisso@4015: } brutisso@4015: brutisso@4015: void record_verify_after_time_ms(double time_ms) { brutisso@4015: _cur_verify_after_time_ms = time_ms; brutisso@4015: } brutisso@4015: brutisso@4015: double accounted_time_ms(); brutisso@4015: brutisso@4015: double cur_collection_start_sec() { brutisso@4015: return _cur_collection_start_sec; brutisso@4015: } brutisso@4015: brutisso@4015: double cur_collection_par_time_ms() { brutisso@4015: return _cur_collection_par_time_ms; brutisso@4015: } brutisso@4015: brutisso@4015: double cur_clear_ct_time_ms() { brutisso@4015: return _cur_clear_ct_time_ms; brutisso@4015: } brutisso@4015: brutisso@4015: double root_region_scan_wait_time_ms() { brutisso@4015: return _root_region_scan_wait_time_ms; brutisso@4015: } brutisso@4015: brutisso@4015: double young_cset_choice_time_ms() { brutisso@4015: return _recorded_young_cset_choice_time_ms; brutisso@4015: } brutisso@4015: brutisso@4015: double young_free_cset_time_ms() { brutisso@4015: return _recorded_young_free_cset_time_ms; brutisso@4015: } brutisso@4015: brutisso@4015: double non_young_cset_choice_time_ms() { brutisso@4015: return _recorded_non_young_cset_choice_time_ms; brutisso@4015: } brutisso@4015: brutisso@4015: double non_young_free_cset_time_ms() { brutisso@4015: return _recorded_non_young_free_cset_time_ms; brutisso@4015: } brutisso@4015: tschatzl@7010: double fast_reclaim_humongous_time_ms() { tschatzl@7010: return _cur_fast_reclaim_humongous_time_ms; tschatzl@7010: } brutisso@7658: }; tschatzl@7010: brutisso@7658: class G1GCParPhaseTimesTracker : public StackObj { brutisso@7658: double _start_time; brutisso@7658: G1GCPhaseTimes::GCParPhases _phase; brutisso@7658: G1GCPhaseTimes* _phase_times; brutisso@7658: uint _worker_id; brutisso@7658: public: brutisso@7658: G1GCParPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCPhaseTimes::GCParPhases phase, uint worker_id); brutisso@7658: ~G1GCParPhaseTimesTracker(); brutisso@3923: }; brutisso@3923: brutisso@3923: #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1GCPHASETIMESLOG_HPP