1 /*
   2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_GC_SHARED_REFERENCEPROCESSORPHASETIMES_HPP
  26 #define SHARE_VM_GC_SHARED_REFERENCEPROCESSORPHASETIMES_HPP
  27 
  28 #include "gc/shared/referenceProcessorStats.hpp"
  29 #include "gc/shared/workerDataArray.inline.hpp"
  30 
  31 class DiscoveredList;
  32 class GCTimer;
  33 
  34 class ReferenceProcessorPhaseTimes : public CHeapObj<mtGC> {
  35 public:
  36   // For phases that have parallel work.
  37   enum RefProcPhases {
  38     RefPhase1,
  39     RefPhase2,
  40     RefPhase3,
  41     RefEnqueue,
  42     RefPhaseMax
  43   };
  44 
  45 private:
  46   // Records per thread information of each phase.
  47   WorkerDataArray<double>* _worker_time_sec[RefPhaseMax];
  48   // Records elapsed time of each phase.
  49   double                   _phase_time_ms[RefPhaseMax];
  50   double                   _balance_queues_time_ms;
  51   bool                     _processing_is_mt;
  52   const uint               _max_gc_threads;
  53 
  54 public:
  55   ReferenceProcessorPhaseTimes(uint max_gc_threads, bool processing_is_mt);
  56 
  57   static double uninitialized() { return -1.0; }
  58 
  59   WorkerDataArray<double>* worker_time_sec(RefProcPhases phase) const;
  60   double phase_time_ms(RefProcPhases phase) const;
  61   void set_phase_time_ms(RefProcPhases phase, double time);
  62   double balance_queues_time_ms() const { return _balance_queues_time_ms; }
  63   void set_balance_queues_time_ms(double time_ms) { _balance_queues_time_ms = time_ms; }
  64   bool processing_is_mt() const     { return _processing_is_mt; }
  65   void set_processing_is_mt(bool processing_is_mt) { _processing_is_mt = processing_is_mt; }
  66   uint max_gc_threads() const       { return _max_gc_threads; }
  67 
  68   void reset();
  69 };
  70 
  71 // Updates working time of each worker thread.
  72 class RefProcWorkerTimeTracker : public StackObj {
  73 protected:
  74   WorkerDataArray<double>* _worker_time;
  75   double                   _start_time;
  76   uint                     _worker_id;
  77 
  78 public:
  79   RefProcWorkerTimeTracker(WorkerDataArray<double>* worker_time, uint worker_id);
  80   ~RefProcWorkerTimeTracker();
  81 };
  82 
  83 class RefProcPhaseTimeBaseTracker : public StackObj {
  84 protected:
  85   const char*                   _title;
  86   ReferenceProcessorPhaseTimes* _phase_times;
  87   Ticks                         _start_ticks;
  88   Ticks                         _end_ticks;
  89   GCTimer*                      _gc_timer;
  90 
  91   Ticks end_ticks();
  92   double elapsed_time();
  93   ReferenceProcessorPhaseTimes* phase_times() const { return _phase_times; }
  94   // Print phase elapsed time with each worker information if MT processed.
  95   void print_phase(ReferenceProcessorPhaseTimes::RefProcPhases phase, uint indent);
  96 
  97 public:
  98   RefProcPhaseTimeBaseTracker(const char* title,
  99                               ReferenceProcessorPhaseTimes* phase_times,
 100                               GCTimer* gc_timer);
 101   ~RefProcPhaseTimeBaseTracker();
 102 };
 103 
 104 // Updates queue balance time at ReferenceProcessorPhaseTimes and
 105 // save it into GCTimer.
 106 class RefProcBalanceQueuesTimeTracker : public RefProcPhaseTimeBaseTracker {
 107 public:
 108   RefProcBalanceQueuesTimeTracker(ReferenceProcessorPhaseTimes* phase_times,
 109                                   GCTimer* gc_timer);
 110   ~RefProcBalanceQueuesTimeTracker();
 111 };
 112 
 113 // Updates phase time at ReferenceProcessorPhaseTimes and save it into GCTimer.
 114 class RefProcPhaseTimeTracker : public RefProcPhaseTimeBaseTracker {
 115   ReferenceProcessorPhaseTimes::RefProcPhases _phase;
 116 
 117 public:
 118   RefProcPhaseTimeTracker(ReferenceProcessorPhaseTimes::RefProcPhases phase,
 119                           ReferenceProcessorPhaseTimes* phase_times,
 120                           GCTimer* gc_timer);
 121   ~RefProcPhaseTimeTracker();
 122 };
 123 
 124 // Prints phase time log.
 125 // - Each phase processing time, cleared/discovered reference counts and stats for each working threads if MT processed.
 126 // From destructor, ReferenceProcessorPhaseTimes will be reset for next time use.
 127 class RefProcPhaseTimesLogger : public RefProcPhaseTimeBaseTracker {
 128   DiscoveredList* _lists;
 129   size_t          _ref_discovered;
 130 
 131 public:
 132   RefProcPhaseTimesLogger(const char* title,
 133                           ReferenceProcessorPhaseTimes* phase_times,
 134                           DiscoveredList lists[],
 135                           GCTimer* gc_timer);
 136   ~RefProcPhaseTimesLogger();
 137 };
 138 
 139 // Prints enqueue time log.
 140 // - Enqueueing time, enqueued reference count and stats for each working thread if MT processed.
 141 class RefProcEnqueueTimeLogger : public RefProcPhaseTimeBaseTracker {
 142   ReferenceProcessorStats& _stats;
 143 
 144 public:
 145   RefProcEnqueueTimeLogger(ReferenceProcessorPhaseTimes* phase_times,
 146                            ReferenceProcessorStats& stats,
 147                            GCTimer* gc_timer);
 148   ~RefProcEnqueueTimeLogger();
 149 };
 150 
 151 #endif // SHARE_VM_GC_SHARED_REFERENCEPROCESSORPHASETIMES_HPP