< prev index next >

src/share/vm/gc_implementation/g1/heapRegion.cpp

Print this page
rev 7177 : 8069760: When iterating over a card, G1 often iterates over much more references than are contained in the card
Summary: Properly bound the iteration work for objArray-oops.
Reviewed-by: mgerdin, kbarrett
rev 7178 : 8067655: Clean up G1 remembered set oop iteration
Summary: Pass on the static type G1ParPushHeapRSClosure to allow oop_iterate devirtualization
Reviewed-by: jmasa, kbarrett


  30 #include "gc_implementation/g1/heapRegion.inline.hpp"
  31 #include "gc_implementation/g1/heapRegionBounds.inline.hpp"
  32 #include "gc_implementation/g1/heapRegionRemSet.hpp"
  33 #include "gc_implementation/g1/heapRegionManager.inline.hpp"
  34 #include "gc_implementation/shared/liveRange.hpp"
  35 #include "memory/genOopClosures.inline.hpp"
  36 #include "memory/iterator.hpp"
  37 #include "memory/space.inline.hpp"
  38 #include "oops/oop.inline.hpp"
  39 #include "runtime/orderAccess.inline.hpp"
  40 
  41 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
  42 
  43 int    HeapRegion::LogOfHRGrainBytes = 0;
  44 int    HeapRegion::LogOfHRGrainWords = 0;
  45 size_t HeapRegion::GrainBytes        = 0;
  46 size_t HeapRegion::GrainWords        = 0;
  47 size_t HeapRegion::CardsPerRegion    = 0;
  48 
  49 HeapRegionDCTOC::HeapRegionDCTOC(G1CollectedHeap* g1,
  50                                  HeapRegion* hr, ExtendedOopClosure* cl,
  51                                  CardTableModRefBS::PrecisionStyle precision,
  52                                  FilterKind fk) :
  53   DirtyCardToOopClosure(hr, cl, precision, NULL),
  54   _hr(hr), _fk(fk), _g1(g1) { }
  55 
  56 FilterOutOfRegionClosure::FilterOutOfRegionClosure(HeapRegion* r,
  57                                                    OopClosure* oc) :
  58   _r_bottom(r->bottom()), _r_end(r->end()), _oc(oc) { }
  59 
  60 template<class ClosureType>
  61 HeapWord* walk_mem_region_loop(ClosureType* cl, G1CollectedHeap* g1h,
  62                                HeapRegion* hr,
  63                                HeapWord* cur, HeapWord* top) {
  64   oop cur_oop = oop(cur);
  65   size_t oop_size = hr->block_size(cur);
  66   HeapWord* next_obj = cur + oop_size;
  67   while (next_obj < top) {
  68     // Keep filtering the remembered set.
  69     if (!g1h->is_obj_dead(cur_oop, hr)) {
  70       // Bottom lies entirely below top, so we can call the
  71       // non-memRegion version of oop_iterate below.
  72       cur_oop->oop_iterate(cl);
  73     }
  74     cur = next_obj;
  75     cur_oop = oop(cur);
  76     oop_size = hr->block_size(cur);
  77     next_obj = cur + oop_size;
  78   }
  79   return cur;
  80 }
  81 
  82 void HeapRegionDCTOC::walk_mem_region(MemRegion mr,
  83                                       HeapWord* bottom,
  84                                       HeapWord* top) {
  85   G1CollectedHeap* g1h = _g1;
  86   size_t oop_size;
  87   ExtendedOopClosure* cl2 = NULL;
  88 
  89   FilterIntoCSClosure intoCSFilt(this, g1h, _cl);
  90   FilterOutOfRegionClosure outOfRegionFilt(_hr, _cl);
  91 
  92   switch (_fk) {
  93   case NoFilterKind:          cl2 = _cl; break;
  94   case IntoCSFilterKind:      cl2 = &intoCSFilt; break;
  95   case OutOfRegionFilterKind: cl2 = &outOfRegionFilt; break;
  96   default:                    ShouldNotReachHere();
  97   }
  98 
  99   // Start filtering what we add to the remembered set. If the object is
 100   // not considered dead, either because it is marked (in the mark bitmap)
 101   // or it was allocated after marking finished, then we add it. Otherwise
 102   // we can safely ignore the object.
 103   if (!g1h->is_obj_dead(oop(bottom), _hr)) {
 104     oop_size = oop(bottom)->oop_iterate(cl2, mr);
 105   } else {
 106     oop_size = _hr->block_size(bottom);
 107   }
 108 
 109   bottom += oop_size;
 110 
 111   if (bottom < top) {
 112     // We replicate the loop below for several kinds of possible filters.
 113     switch (_fk) {
 114     case NoFilterKind:
 115       bottom = walk_mem_region_loop(_cl, g1h, _hr, bottom, top);
 116       break;
 117 
 118     case IntoCSFilterKind: {
 119       FilterIntoCSClosure filt(this, g1h, _cl);
 120       bottom = walk_mem_region_loop(&filt, g1h, _hr, bottom, top);
 121       break;
 122     }
 123 
 124     case OutOfRegionFilterKind: {
 125       FilterOutOfRegionClosure filt(_hr, _cl);
 126       bottom = walk_mem_region_loop(&filt, g1h, _hr, bottom, top);
 127       break;






 128     }
 129 
 130     default:
 131       ShouldNotReachHere();

 132     }
 133 
 134     // Last object. Need to do dead-obj filtering here too.
 135     if (!g1h->is_obj_dead(oop(bottom), _hr)) {
 136       oop(bottom)->oop_iterate(cl2, mr);
 137     }
 138   }
 139 }
 140 
 141 size_t HeapRegion::max_region_size() {
 142   return HeapRegionBounds::max_size();
 143 }
 144 
 145 void HeapRegion::setup_heap_region_size(size_t initial_heap_size, size_t max_heap_size) {
 146   uintx region_size = G1HeapRegionSize;
 147   if (FLAG_IS_DEFAULT(G1HeapRegionSize)) {
 148     size_t average_heap_size = (initial_heap_size + max_heap_size) / 2;
 149     region_size = MAX2(average_heap_size / HeapRegionBounds::target_number(),
 150                        (uintx) HeapRegionBounds::min_size());
 151   }
 152 
 153   int region_size_log = log2_long((jlong) region_size);
 154   // Recalculate the region size to make sure it's a power of
 155   // 2. This means that region_size is the largest power of 2 that's
 156   // <= what we've calculated so far.




  30 #include "gc_implementation/g1/heapRegion.inline.hpp"
  31 #include "gc_implementation/g1/heapRegionBounds.inline.hpp"
  32 #include "gc_implementation/g1/heapRegionRemSet.hpp"
  33 #include "gc_implementation/g1/heapRegionManager.inline.hpp"
  34 #include "gc_implementation/shared/liveRange.hpp"
  35 #include "memory/genOopClosures.inline.hpp"
  36 #include "memory/iterator.hpp"
  37 #include "memory/space.inline.hpp"
  38 #include "oops/oop.inline.hpp"
  39 #include "runtime/orderAccess.inline.hpp"
  40 
  41 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
  42 
  43 int    HeapRegion::LogOfHRGrainBytes = 0;
  44 int    HeapRegion::LogOfHRGrainWords = 0;
  45 size_t HeapRegion::GrainBytes        = 0;
  46 size_t HeapRegion::GrainWords        = 0;
  47 size_t HeapRegion::CardsPerRegion    = 0;
  48 
  49 HeapRegionDCTOC::HeapRegionDCTOC(G1CollectedHeap* g1,
  50                                  HeapRegion* hr,
  51                                  G1ParPushHeapRSClosure* cl,
  52                                  CardTableModRefBS::PrecisionStyle precision) :
  53   DirtyCardToOopClosure(hr, cl, precision, NULL),
  54   _hr(hr), _rs_scan(cl), _g1(g1) { }
  55 
  56 FilterOutOfRegionClosure::FilterOutOfRegionClosure(HeapRegion* r,
  57                                                    OopClosure* oc) :
  58   _r_bottom(r->bottom()), _r_end(r->end()), _oc(oc) { }
  59 






















  60 void HeapRegionDCTOC::walk_mem_region(MemRegion mr,
  61                                       HeapWord* bottom,
  62                                       HeapWord* top) {
  63   G1CollectedHeap* g1h = _g1;
  64   size_t oop_size;
  65   HeapWord* cur = bottom;










  66 
  67   // Start filtering what we add to the remembered set. If the object is
  68   // not considered dead, either because it is marked (in the mark bitmap)
  69   // or it was allocated after marking finished, then we add it. Otherwise
  70   // we can safely ignore the object.
  71   if (!g1h->is_obj_dead(oop(cur), _hr)) {
  72     oop_size = oop(cur)->oop_iterate(_rs_scan, mr);
  73   } else {
  74     oop_size = _hr->block_size(cur);
  75   }
  76 
  77   cur += oop_size;













  78 
  79   if (cur < top) {
  80     oop cur_oop = oop(cur);
  81     oop_size = _hr->block_size(cur);
  82     HeapWord* next_obj = cur + oop_size;
  83     while (next_obj < top) {
  84       // Keep filtering the remembered set.
  85       if (!g1h->is_obj_dead(cur_oop, _hr)) {
  86         // Bottom lies entirely below top, so we can call the
  87         // non-memRegion version of oop_iterate below.
  88         cur_oop->oop_iterate(_rs_scan);
  89       }
  90       cur = next_obj;
  91       cur_oop = oop(cur);
  92       oop_size = _hr->block_size(cur);
  93       next_obj = cur + oop_size;
  94     }
  95 
  96     // Last object. Need to do dead-obj filtering here too.
  97     if (!g1h->is_obj_dead(oop(cur), _hr)) {
  98       oop(cur)->oop_iterate(_rs_scan, mr);
  99     }
 100   }
 101 }
 102 
 103 size_t HeapRegion::max_region_size() {
 104   return HeapRegionBounds::max_size();
 105 }
 106 
 107 void HeapRegion::setup_heap_region_size(size_t initial_heap_size, size_t max_heap_size) {
 108   uintx region_size = G1HeapRegionSize;
 109   if (FLAG_IS_DEFAULT(G1HeapRegionSize)) {
 110     size_t average_heap_size = (initial_heap_size + max_heap_size) / 2;
 111     region_size = MAX2(average_heap_size / HeapRegionBounds::target_number(),
 112                        (uintx) HeapRegionBounds::min_size());
 113   }
 114 
 115   int region_size_log = log2_long((jlong) region_size);
 116   // Recalculate the region size to make sure it's a power of
 117   // 2. This means that region_size is the largest power of 2 that's
 118   // <= what we've calculated so far.


< prev index next >