1 /*
   2  * Copyright (c) 2005, 2010, 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_IMPLEMENTATION_SHARED_VMGCOPERATIONS_HPP
  26 #define SHARE_VM_GC_IMPLEMENTATION_SHARED_VMGCOPERATIONS_HPP
  27 
  28 #include "memory/heapInspection.hpp"
  29 #include "runtime/handles.hpp"
  30 #include "runtime/jniHandles.hpp"
  31 #include "runtime/synchronizer.hpp"
  32 #include "runtime/vm_operations.hpp"
  33 
  34 // The following class hierarchy represents
  35 // a set of operations (VM_Operation) related to GC.
  36 //
  37 //  VM_Operation
  38 //      VM_GC_Operation
  39 //          VM_GC_HeapInspection
  40 //          VM_GenCollectForAllocation
  41 //          VM_GenCollectFull
  42 //          VM_GenCollectFullConcurrent
  43 //          VM_ParallelGCFailedAllocation
  44 //          VM_ParallelGCFailedPermanentAllocation
  45 //          VM_ParallelGCSystemGC
  46 //  VM_GC_Operation
  47 //   - implements methods common to all classes in the hierarchy:
  48 //     prevents multiple gc requests and manages lock on heap;
  49 //
  50 //  VM_GC_HeapInspection
  51 //   - prints class histogram on SIGBREAK if PrintClassHistogram
  52 //     is specified; and also the attach "inspectheap" operation
  53 //
  54 //  VM_GenCollectForAllocation
  55 //  VM_GenCollectForPermanentAllocation
  56 //  VM_ParallelGCFailedAllocation
  57 //  VM_ParallelGCFailedPermanentAllocation
  58 //   - this operation is invoked when allocation is failed;
  59 //     operation performs garbage collection and tries to
  60 //     allocate afterwards;
  61 //
  62 //  VM_GenCollectFull
  63 //  VM_GenCollectFullConcurrent
  64 //  VM_ParallelGCSystemGC
  65 //   - these operations preform full collection of heaps of
  66 //     different kind
  67 //
  68 
  69 class VM_GC_Operation: public VM_Operation {
  70  protected:
  71   BasicLock     _pending_list_basic_lock; // for refs pending list notification (PLL)
  72   unsigned int  _gc_count_before;         // gc count before acquiring PLL
  73   unsigned int  _full_gc_count_before;    // full gc count before acquiring PLL
  74   bool          _full;                    // whether a "full" collection
  75   bool          _prologue_succeeded;      // whether doit_prologue succeeded
  76   GCCause::Cause _gc_cause;                // the putative cause for this gc op
  77   bool          _gc_locked;               // will be set if gc was locked
  78 
  79   virtual bool skip_operation() const;
  80 
  81   // java.lang.ref.Reference support
  82   void acquire_pending_list_lock();
  83   void release_and_notify_pending_list_lock();
  84 
  85  public:
  86   VM_GC_Operation(unsigned int gc_count_before,
  87                   unsigned int full_gc_count_before = 0,
  88                   bool full = false) {
  89     _full = full;
  90     _prologue_succeeded = false;
  91     _gc_count_before    = gc_count_before;
  92 
  93     // A subclass constructor will likely overwrite the following
  94     _gc_cause           = GCCause::_no_cause_specified;
  95 
  96     _gc_locked = false;
  97 
  98     _full_gc_count_before = full_gc_count_before;
  99     // In ParallelScavengeHeap::mem_allocate() collections can be
 100     // executed within a loop and _all_soft_refs_clear can be set
 101     // true after they have been cleared by a collection and another
 102     // collection started so that _all_soft_refs_clear can be true
 103     // when this collection is started.  Don't assert that
 104     // _all_soft_refs_clear have to be false here even though
 105     // mutators have run.  Soft refs will be cleared again in this
 106     // collection.
 107   }
 108   ~VM_GC_Operation() {
 109     CollectedHeap* ch = Universe::heap();
 110     ch->collector_policy()->set_all_soft_refs_clear(false);
 111   }
 112 
 113   // Acquire the reference synchronization lock
 114   virtual bool doit_prologue();
 115   // Do notifyAll (if needed) and release held lock
 116   virtual void doit_epilogue();
 117 
 118   virtual bool allow_nested_vm_operations() const  { return true; }
 119   bool prologue_succeeded() const { return _prologue_succeeded; }
 120 
 121   void set_gc_locked() { _gc_locked = true; }
 122   bool gc_locked() const  { return _gc_locked; }
 123 
 124   static void notify_gc_begin(bool full = false);
 125   static void notify_gc_end();
 126 };
 127 
 128 
 129 class VM_GC_HeapInspection: public VM_GC_Operation {
 130  private:
 131   outputStream* _out;
 132   bool _full_gc;
 133   bool _need_prologue;
 134  public:
 135   VM_GC_HeapInspection(outputStream* out, bool request_full_gc,
 136                        bool need_prologue) :
 137     VM_GC_Operation(0 /* total collections,      dummy, ignored */,
 138                     0 /* total full collections, dummy, ignored */,
 139                     request_full_gc) {
 140     _out = out;
 141     _full_gc = request_full_gc;
 142     _need_prologue = need_prologue;
 143   }
 144 
 145   ~VM_GC_HeapInspection() {}
 146   virtual VMOp_Type type() const { return VMOp_GC_HeapInspection; }
 147   virtual bool skip_operation() const;
 148   virtual bool doit_prologue();
 149   virtual void doit();
 150 };
 151 
 152 
 153 class VM_GenCollectForAllocation: public VM_GC_Operation {
 154  private:
 155   HeapWord*   _res;
 156   size_t      _size;                       // size of object to be allocated.
 157   bool        _tlab;                       // alloc is of a tlab.
 158  public:
 159   VM_GenCollectForAllocation(size_t size,
 160                              bool tlab,
 161                              unsigned int gc_count_before)
 162     : VM_GC_Operation(gc_count_before),
 163       _size(size),
 164       _tlab(tlab) {
 165     _res = NULL;
 166   }
 167   ~VM_GenCollectForAllocation()  {}
 168   virtual VMOp_Type type() const { return VMOp_GenCollectForAllocation; }
 169   virtual void doit();
 170   HeapWord* result() const       { return _res; }
 171 };
 172 
 173 
 174 // VM operation to invoke a collection of the heap as a
 175 // GenCollectedHeap heap.
 176 class VM_GenCollectFull: public VM_GC_Operation {
 177  private:
 178   int _max_level;
 179  public:
 180   VM_GenCollectFull(unsigned int gc_count_before,
 181                     unsigned int full_gc_count_before,
 182                     GCCause::Cause gc_cause,
 183                       int max_level)
 184     : VM_GC_Operation(gc_count_before, full_gc_count_before, true /* full */),
 185       _max_level(max_level)
 186   { _gc_cause = gc_cause; }
 187   ~VM_GenCollectFull() {}
 188   virtual VMOp_Type type() const { return VMOp_GenCollectFull; }
 189   virtual void doit();
 190 };
 191 
 192 class VM_GenCollectForPermanentAllocation: public VM_GC_Operation {
 193  private:
 194   HeapWord*   _res;
 195   size_t      _size;                       // size of object to be allocated
 196  public:
 197   VM_GenCollectForPermanentAllocation(size_t size,
 198                                       unsigned int gc_count_before,
 199                                       unsigned int full_gc_count_before,
 200                                       GCCause::Cause gc_cause)
 201     : VM_GC_Operation(gc_count_before, full_gc_count_before, true),
 202       _size(size) {
 203     _res = NULL;
 204     _gc_cause = gc_cause;
 205   }
 206   ~VM_GenCollectForPermanentAllocation()  {}
 207   virtual VMOp_Type type() const { return VMOp_GenCollectForPermanentAllocation; }
 208   virtual void doit();
 209   HeapWord* result() const       { return _res; }
 210 };
 211 
 212 #endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_VMGCOPERATIONS_HPP