--- old/src/share/vm/gc/shared/gcTimer.hpp 2015-12-14 21:50:30.414701556 -0800 +++ new/src/share/vm/gc/shared/gcTimer.hpp 2015-12-14 21:50:30.322701560 -0800 @@ -39,15 +39,21 @@ class PhaseVisitor { public: virtual void visit(GCPhase* phase) = 0; - virtual void visit(PausePhase* phase) { visit((GCPhase*)phase); } - virtual void visit(ConcurrentPhase* phase) { visit((GCPhase*)phase); } }; class GCPhase { + public: + enum PhaseType { + PausePhaseType = 0, + ConcurrentPhaseType = 1 + }; + + private: const char* _name; int _level; Ticks _start; Ticks _end; + PhaseType _type; public: void set_name(const char* name) { _name = name; } @@ -62,17 +68,9 @@ const Ticks end() const { return _end; } void set_end(const Ticks& time) { _end = time; } - virtual void accept(PhaseVisitor* visitor) = 0; -}; - -class PausePhase : public GCPhase { - public: - void accept(PhaseVisitor* visitor) { - visitor->visit(this); - } -}; + PhaseType type() const { return _type; } + void set_type(PhaseType type) { _type = type; } -class ConcurrentPhase : public GCPhase { void accept(PhaseVisitor* visitor) { visitor->visit(this); } @@ -80,7 +78,7 @@ class PhasesStack { public: - // FIXME: Temporary set to 5 (used to be 4), since Reference processing needs it. + // Set to 5, since Reference processing needs it. static const int PHASE_LEVELS = 5; private: @@ -99,8 +97,7 @@ class TimePartitions { static const int INITIAL_CAPACITY = 10; - // Currently we only support pause phases. - GrowableArray* _phases; + GrowableArray* _phases; PhasesStack _active_phases; Tickspan _sum_of_pauses; @@ -111,8 +108,8 @@ ~TimePartitions(); void clear(); - void report_gc_phase_start(const char* name, const Ticks& time); - void report_gc_phase_end(const Ticks& time); + void report_gc_phase_start(const char* name, const Ticks& time, GCPhase::PhaseType type=GCPhase::PausePhaseType); + void report_gc_phase_end(const Ticks& time, GCPhase::PhaseType type=GCPhase::PausePhaseType); int num_phases() const; GCPhase* phase_at(int index) const; @@ -121,6 +118,7 @@ const Tickspan longest_pause() const { return _longest_pause; } bool has_active_phases(); + private: void update_statistics(GCPhase* phase); }; @@ -162,9 +160,20 @@ }; class ConcurrentGCTimer : public GCTimer { + // ConcurrentGCTimer can't be used if there is an overlap between a pause phase and a concurrent phase. + // _is_concurrent_phase_active is used to find above case. + NOT_PRODUCT(volatile bool _is_concurrent_phase_active;) + public: +#ifndef PRODUCT + ConcurrentGCTimer(): GCTimer(), _is_concurrent_phase_active(false) {}; +#endif + void register_gc_pause_start(const char* name); void register_gc_pause_end(); + + void register_gc_concurrent_start(const char* name, const Ticks& time = Ticks::now()); + void register_gc_concurrent_end(const Ticks& time = Ticks::now()); }; class TimePartitionPhasesIterator {