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

Fri, 29 Apr 2011 14:59:04 -0400

author
tonyp
date
Fri, 29 Apr 2011 14:59:04 -0400
changeset 2849
063382f9b575
parent 2314
f95d63e2154a
child 2962
ae5b2f1dcf12
permissions
-rw-r--r--

7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
Summary: We should only undirty cards after we decide that they are not on a young region, not before. The fix also includes improvements to the verify_dirty_region() method which print out which cards were not found dirty.
Reviewed-by: johnc, brutisso

     1 /*
     2  * Copyright (c) 2001, 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  */
    25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1OOPCLOSURES_HPP
    26 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1OOPCLOSURES_HPP
    28 class HeapRegion;
    29 class G1CollectedHeap;
    30 class G1RemSet;
    31 class ConcurrentMark;
    32 class DirtyCardToOopClosure;
    33 class CMBitMap;
    34 class CMMarkStack;
    35 class G1ParScanThreadState;
    37 // A class that scans oops in a given heap region (much as OopsInGenClosure
    38 // scans oops in a generation.)
    39 class OopsInHeapRegionClosure: public OopsInGenClosure {
    40 protected:
    41   HeapRegion* _from;
    42 public:
    43   virtual void set_region(HeapRegion* from) { _from = from; }
    44 };
    46 class G1ParClosureSuper : public OopsInHeapRegionClosure {
    47 protected:
    48   G1CollectedHeap* _g1;
    49   G1RemSet* _g1_rem;
    50   ConcurrentMark* _cm;
    51   G1ParScanThreadState* _par_scan_state;
    52 public:
    53   G1ParClosureSuper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state);
    54   bool apply_to_weak_ref_discovered_field() { return true; }
    55 };
    57 class G1ParPushHeapRSClosure : public G1ParClosureSuper {
    58 public:
    59   G1ParPushHeapRSClosure(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state) :
    60     G1ParClosureSuper(g1, par_scan_state) { }
    61   template <class T> void do_oop_nv(T* p);
    62   virtual void do_oop(oop* p)          { do_oop_nv(p); }
    63   virtual void do_oop(narrowOop* p)    { do_oop_nv(p); }
    64 };
    66 class G1ParScanClosure : public G1ParClosureSuper {
    67 public:
    68   G1ParScanClosure(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state) :
    69     G1ParClosureSuper(g1, par_scan_state) { }
    70   template <class T> void do_oop_nv(T* p);
    71   virtual void do_oop(oop* p)          { do_oop_nv(p); }
    72   virtual void do_oop(narrowOop* p)    { do_oop_nv(p); }
    73 };
    75 #define G1_PARTIAL_ARRAY_MASK 0x2
    77 template <class T> inline bool has_partial_array_mask(T* ref) {
    78   return ((uintptr_t)ref & G1_PARTIAL_ARRAY_MASK) == G1_PARTIAL_ARRAY_MASK;
    79 }
    81 template <class T> inline T* set_partial_array_mask(T obj) {
    82   assert(((uintptr_t)obj & G1_PARTIAL_ARRAY_MASK) == 0, "Information loss!");
    83   return (T*) ((uintptr_t)obj | G1_PARTIAL_ARRAY_MASK);
    84 }
    86 template <class T> inline oop clear_partial_array_mask(T* ref) {
    87   return oop((intptr_t)ref & ~G1_PARTIAL_ARRAY_MASK);
    88 }
    90 class G1ParScanPartialArrayClosure : public G1ParClosureSuper {
    91   G1ParScanClosure _scanner;
    92 public:
    93   G1ParScanPartialArrayClosure(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state) :
    94     G1ParClosureSuper(g1, par_scan_state), _scanner(g1, par_scan_state) { }
    95   template <class T> void do_oop_nv(T* p);
    96   virtual void do_oop(oop* p)       { do_oop_nv(p); }
    97   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
    98 };
   101 class G1ParCopyHelper : public G1ParClosureSuper {
   102   G1ParScanClosure *_scanner;
   103 protected:
   104   template <class T> void mark_forwardee(T* p);
   105   oop copy_to_survivor_space(oop obj);
   106 public:
   107   G1ParCopyHelper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state,
   108                   G1ParScanClosure *scanner) :
   109     G1ParClosureSuper(g1, par_scan_state), _scanner(scanner) { }
   110 };
   112 template<bool do_gen_barrier, G1Barrier barrier,
   113          bool do_mark_forwardee>
   114 class G1ParCopyClosure : public G1ParCopyHelper {
   115   G1ParScanClosure _scanner;
   116   template <class T> void do_oop_work(T* p);
   117 public:
   118   G1ParCopyClosure(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state) :
   119     _scanner(g1, par_scan_state), G1ParCopyHelper(g1, par_scan_state, &_scanner) { }
   120   template <class T> void do_oop_nv(T* p) {
   121     do_oop_work(p);
   122     if (do_mark_forwardee)
   123       mark_forwardee(p);
   124   }
   125   virtual void do_oop(oop* p)       { do_oop_nv(p); }
   126   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
   127 };
   129 typedef G1ParCopyClosure<false, G1BarrierNone, false> G1ParScanExtRootClosure;
   130 typedef G1ParCopyClosure<true,  G1BarrierNone, false> G1ParScanPermClosure;
   131 typedef G1ParCopyClosure<false, G1BarrierRS,   false> G1ParScanHeapRSClosure;
   132 typedef G1ParCopyClosure<false, G1BarrierNone, true> G1ParScanAndMarkExtRootClosure;
   133 typedef G1ParCopyClosure<true,  G1BarrierNone, true> G1ParScanAndMarkPermClosure;
   134 typedef G1ParCopyClosure<false, G1BarrierRS,   true> G1ParScanAndMarkHeapRSClosure;
   136 // This is the only case when we set skip_cset_test. Basically, this
   137 // closure is (should?) only be called directly while we're draining
   138 // the overflow and task queues. In that case we know that the
   139 // reference in question points into the collection set, otherwise we
   140 // would not have pushed it on the queue. The following is defined in
   141 // g1_specialized_oop_closures.hpp.
   142 // typedef G1ParCopyClosure<false, G1BarrierEvac, false, true> G1ParScanHeapEvacClosure;
   143 // We need a separate closure to handle references during evacuation
   144 // failure processing, as we cannot asume that the reference already
   145 // points into the collection set (like G1ParScanHeapEvacClosure does).
   146 typedef G1ParCopyClosure<false, G1BarrierEvac, false> G1ParScanHeapEvacFailureClosure;
   148 class FilterIntoCSClosure: public OopClosure {
   149   G1CollectedHeap* _g1;
   150   OopClosure* _oc;
   151   DirtyCardToOopClosure* _dcto_cl;
   152 public:
   153   FilterIntoCSClosure(  DirtyCardToOopClosure* dcto_cl,
   154                         G1CollectedHeap* g1, OopClosure* oc) :
   155     _dcto_cl(dcto_cl), _g1(g1), _oc(oc)
   156   {}
   157   template <class T> void do_oop_nv(T* p);
   158   virtual void do_oop(oop* p)        { do_oop_nv(p); }
   159   virtual void do_oop(narrowOop* p)  { do_oop_nv(p); }
   160   bool apply_to_weak_ref_discovered_field() { return true; }
   161   bool do_header() { return false; }
   162 };
   164 class FilterInHeapRegionAndIntoCSClosure : public OopsInHeapRegionClosure {
   165   G1CollectedHeap* _g1;
   166   OopsInHeapRegionClosure* _oc;
   167 public:
   168   FilterInHeapRegionAndIntoCSClosure(G1CollectedHeap* g1,
   169                                      OopsInHeapRegionClosure* oc) :
   170     _g1(g1), _oc(oc)
   171   {}
   172   template <class T> void do_oop_nv(T* p);
   173   virtual void do_oop(oop* p) { do_oop_nv(p); }
   174   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
   175   bool apply_to_weak_ref_discovered_field() { return true; }
   176   bool do_header() { return false; }
   177   void set_region(HeapRegion* from) {
   178     _oc->set_region(from);
   179   }
   180 };
   182 class FilterAndMarkInHeapRegionAndIntoCSClosure : public OopsInHeapRegionClosure {
   183   G1CollectedHeap* _g1;
   184   ConcurrentMark* _cm;
   185   OopsInHeapRegionClosure* _oc;
   186 public:
   187   FilterAndMarkInHeapRegionAndIntoCSClosure(G1CollectedHeap* g1,
   188                                             OopsInHeapRegionClosure* oc,
   189                                             ConcurrentMark* cm)
   190   : _g1(g1), _oc(oc), _cm(cm) { }
   192   template <class T> void do_oop_nv(T* p);
   193   virtual void do_oop(oop* p) { do_oop_nv(p); }
   194   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
   195   bool apply_to_weak_ref_discovered_field() { return true; }
   196   bool do_header() { return false; }
   197   void set_region(HeapRegion* from) {
   198     _oc->set_region(from);
   199   }
   200 };
   202 class FilterOutOfRegionClosure: public OopClosure {
   203   HeapWord* _r_bottom;
   204   HeapWord* _r_end;
   205   OopClosure* _oc;
   206   int _out_of_region;
   207 public:
   208   FilterOutOfRegionClosure(HeapRegion* r, OopClosure* oc);
   209   template <class T> void do_oop_nv(T* p);
   210   virtual void do_oop(oop* p) { do_oop_nv(p); }
   211   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
   212   bool apply_to_weak_ref_discovered_field() { return true; }
   213   bool do_header() { return false; }
   214   int out_of_region() { return _out_of_region; }
   215 };
   217 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1OOPCLOSURES_HPP

mercurial