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

Mon, 18 Mar 2013 11:05:27 -0700

author
johnc
date
Mon, 18 Mar 2013 11:05:27 -0700
changeset 4787
fa08949fe0cb
parent 4153
b9a9ed0f8eeb
child 6876
710a3c8b516e
permissions
-rw-r--r--

8009536: G1: Apache Lucene hang during reference processing
Summary: In CMTask::do_marking_step(), Skip offering termination and entering the first and second synchronization barriers if called from a serial context, i.e. the VM thread.
Reviewed-by: brutisso, tschatzl

     1 /*
     2  * Copyright (c) 2001, 2012, 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  */
    25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1MMUTRACKER_HPP
    26 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1MMUTRACKER_HPP
    28 #include "memory/allocation.hpp"
    29 #include "utilities/debug.hpp"
    31 // Keeps track of the GC work and decides when it is OK to do GC work
    32 // and for how long so that the MMU invariants are maintained.
    34 /***** ALL TIMES ARE IN SECS!!!!!!! *****/
    36 // this is the "interface"
    37 class G1MMUTracker: public CHeapObj<mtGC> {
    38 protected:
    39   double          _time_slice;
    40   double          _max_gc_time; // this is per time slice
    42 public:
    43   G1MMUTracker(double time_slice, double max_gc_time);
    45   virtual void add_pause(double start, double end, bool gc_thread) = 0;
    46   virtual double longest_pause(double current_time) = 0;
    47   virtual double when_sec(double current_time, double pause_time) = 0;
    49   double max_gc_time() {
    50     return _max_gc_time;
    51   }
    53   inline bool now_max_gc(double current_time) {
    54     return when_sec(current_time, max_gc_time()) < 0.00001;
    55   }
    57   inline double when_max_gc_sec(double current_time) {
    58     return when_sec(current_time, max_gc_time());
    59   }
    61   inline jlong when_max_gc_ms(double current_time) {
    62     double when = when_max_gc_sec(current_time);
    63     return (jlong) (when * 1000.0);
    64   }
    66   inline jlong when_ms(double current_time, double pause_time) {
    67     double when = when_sec(current_time, pause_time);
    68     return (jlong) (when * 1000.0);
    69   }
    70 };
    72 class G1MMUTrackerQueueElem VALUE_OBJ_CLASS_SPEC {
    73 private:
    74   double _start_time;
    75   double _end_time;
    77 public:
    78   inline double start_time() { return _start_time; }
    79   inline double end_time()   { return _end_time; }
    80   inline double duration()   { return _end_time - _start_time; }
    82   G1MMUTrackerQueueElem() {
    83     _start_time = 0.0;
    84     _end_time   = 0.0;
    85   }
    87   G1MMUTrackerQueueElem(double start_time, double end_time) {
    88     _start_time = start_time;
    89     _end_time   = end_time;
    90   }
    91 };
    93 // this is an implementation of the MMUTracker using a (fixed-size) queue
    94 // that keeps track of all the recent pause times
    95 class G1MMUTrackerQueue: public G1MMUTracker {
    96 private:
    97   enum PrivateConstants {
    98     QueueLength = 64
    99   };
   101   // The array keeps track of all the pauses that fall within a time
   102   // slice (the last time slice during which pauses took place).
   103   // The data structure implemented is a circular queue.
   104   // Head "points" to the most recent addition, tail to the oldest one.
   105   // The array is of fixed size and I don't think we'll need more than
   106   // two or three entries with the current behaviour of G1 pauses.
   107   // If the array is full, an easy fix is to look for the pauses with
   108   // the shortest gap between them and consolidate them.
   109   // For now, we have taken the expedient alternative of forgetting
   110   // the oldest entry in the event that +G1UseFixedWindowMMUTracker, thus
   111   // potentially violating MMU specs for some time thereafter.
   113   G1MMUTrackerQueueElem _array[QueueLength];
   114   int                   _head_index;
   115   int                   _tail_index;
   116   int                   _no_entries;
   118   inline int trim_index(int index) {
   119     return (index + QueueLength) % QueueLength;
   120   }
   122   void remove_expired_entries(double current_time);
   123   double calculate_gc_time(double current_time);
   125   double longest_pause_internal(double current_time);
   126   double when_internal(double current_time, double pause_time);
   128 public:
   129   G1MMUTrackerQueue(double time_slice, double max_gc_time);
   131   virtual void add_pause(double start, double end, bool gc_thread);
   133   virtual double longest_pause(double current_time);
   134   virtual double when_sec(double current_time, double pause_time);
   135 };
   137 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1MMUTRACKER_HPP

mercurial