< prev index next >

src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp

Print this page




  13  *
  14  * You should have received a copy of the GNU General Public License version
  15  * 2 along with this work; if not, write to the Free Software Foundation,
  16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  17  *
  18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  19  * or visit www.oracle.com if you need additional information or have any
  20  * questions.
  21  *
  22  */
  23 
  24 #include "precompiled.hpp"
  25 #include "memory/allocation.hpp"
  26 #include "gc/shenandoah/shenandoahBrooksPointer.hpp"
  27 #include "gc/shenandoah/shenandoahHeapRegionSet.inline.hpp"
  28 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
  29 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
  30 #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
  31 #include "gc/shenandoah/shenandoahTraversalGC.hpp"
  32 #include "gc/shared/space.inline.hpp"

  33 #include "memory/iterator.inline.hpp"
  34 #include "memory/resourceArea.hpp"
  35 #include "memory/universe.hpp"
  36 #include "oops/oop.inline.hpp"
  37 #include "runtime/java.hpp"
  38 #include "runtime/mutexLocker.hpp"
  39 #include "runtime/os.hpp"
  40 #include "runtime/safepoint.hpp"
  41 
  42 size_t ShenandoahHeapRegion::RegionCount = 0;
  43 size_t ShenandoahHeapRegion::RegionSizeBytes = 0;
  44 size_t ShenandoahHeapRegion::RegionSizeWords = 0;
  45 size_t ShenandoahHeapRegion::RegionSizeBytesShift = 0;
  46 size_t ShenandoahHeapRegion::RegionSizeWordsShift = 0;
  47 size_t ShenandoahHeapRegion::RegionSizeBytesMask = 0;
  48 size_t ShenandoahHeapRegion::RegionSizeWordsMask = 0;
  49 size_t ShenandoahHeapRegion::HumongousThresholdBytes = 0;
  50 size_t ShenandoahHeapRegion::HumongousThresholdWords = 0;
  51 size_t ShenandoahHeapRegion::MaxTLABSizeBytes = 0;
  52 size_t ShenandoahHeapRegion::MaxTLABSizeWords = 0;


  77 
  78 size_t ShenandoahHeapRegion::region_number() const {
  79   return _region_number;
  80 }
  81 
  82 void ShenandoahHeapRegion::report_illegal_transition(const char *method) {
  83   ResourceMark rm;
  84   stringStream ss;
  85   ss.print("Illegal region state transition from \"%s\", at %s\n  ", region_state_to_string(_state), method);
  86   print_on(&ss);
  87   fatal("%s", ss.as_string());
  88 }
  89 
  90 void ShenandoahHeapRegion::make_regular_allocation() {
  91   _heap->assert_heaplock_owned_by_current_thread();
  92 
  93   switch (_state) {
  94     case _empty_uncommitted:
  95       do_commit();
  96     case _empty_committed:
  97       _state = _regular;
  98     case _regular:
  99     case _pinned:
 100       return;
 101     default:
 102       report_illegal_transition("regular allocation");
 103   }
 104 }
 105 
 106 void ShenandoahHeapRegion::make_regular_bypass() {
 107   _heap->assert_heaplock_owned_by_current_thread();
 108   assert (_heap->is_full_gc_in_progress() || _heap->is_degenerated_gc_in_progress(),
 109           "only for full or degen GC");
 110 
 111   switch (_state) {
 112     case _empty_uncommitted:
 113       do_commit();
 114     case _empty_committed:
 115     case _cset:
 116     case _humongous_start:
 117     case _humongous_cont:
 118       _state = _regular;
 119       return;
 120     case _pinned_cset:
 121       _state = _pinned;
 122       return;
 123     case _regular:
 124     case _pinned:
 125       return;
 126     default:
 127       report_illegal_transition("regular bypass");
 128   }
 129 }
 130 
 131 void ShenandoahHeapRegion::make_humongous_start() {
 132   _heap->assert_heaplock_owned_by_current_thread();
 133   switch (_state) {
 134     case _empty_uncommitted:
 135       do_commit();
 136     case _empty_committed:
 137       _state = _humongous_start;
 138       return;
 139     default:
 140       report_illegal_transition("humongous start allocation");
 141   }
 142 }
 143 
 144 void ShenandoahHeapRegion::make_humongous_start_bypass() {
 145   _heap->assert_heaplock_owned_by_current_thread();
 146   assert (_heap->is_full_gc_in_progress(), "only for full GC");
 147 
 148   switch (_state) {
 149     case _empty_committed:
 150     case _regular:
 151     case _humongous_start:
 152     case _humongous_cont:
 153       _state = _humongous_start;
 154       return;
 155     default:
 156       report_illegal_transition("humongous start bypass");
 157   }
 158 }
 159 
 160 void ShenandoahHeapRegion::make_humongous_cont() {
 161   _heap->assert_heaplock_owned_by_current_thread();
 162   switch (_state) {
 163     case _empty_uncommitted:
 164       do_commit();
 165     case _empty_committed:
 166       _state = _humongous_cont;
 167       return;
 168     default:
 169       report_illegal_transition("humongous continuation allocation");
 170   }
 171 }
 172 
 173 void ShenandoahHeapRegion::make_humongous_cont_bypass() {
 174   _heap->assert_heaplock_owned_by_current_thread();
 175   assert (_heap->is_full_gc_in_progress(), "only for full GC");
 176 
 177   switch (_state) {
 178     case _empty_committed:
 179     case _regular:
 180     case _humongous_start:
 181     case _humongous_cont:
 182       _state = _humongous_cont;
 183       return;
 184     default:
 185       report_illegal_transition("humongous continuation bypass");
 186   }
 187 }
 188 
 189 void ShenandoahHeapRegion::make_pinned() {
 190   _heap->assert_heaplock_owned_by_current_thread();
 191   switch (_state) {
 192     case _regular:
 193       assert (_critical_pins == 0, "sanity");
 194       _state = _pinned;
 195     case _pinned_cset:
 196     case _pinned:
 197       _critical_pins++;
 198       return;
 199     case _humongous_start:
 200       assert (_critical_pins == 0, "sanity");
 201       _state = _pinned_humongous_start;
 202     case _pinned_humongous_start:
 203       _critical_pins++;
 204       return;
 205     case _cset:
 206       guarantee(_heap->cancelled_gc(), "only valid when evac has been cancelled");
 207       assert (_critical_pins == 0, "sanity");
 208       _state = _pinned_cset;
 209       _critical_pins++;
 210       return;
 211     default:
 212       report_illegal_transition("pinning");
 213   }
 214 }
 215 
 216 void ShenandoahHeapRegion::make_unpinned() {
 217   _heap->assert_heaplock_owned_by_current_thread();
 218   switch (_state) {
 219     case _pinned:
 220       assert (_critical_pins > 0, "sanity");
 221       _critical_pins--;
 222       if (_critical_pins == 0) {
 223         _state = _regular;
 224       }
 225       return;
 226     case _regular:
 227     case _humongous_start:
 228       assert (_critical_pins == 0, "sanity");
 229       return;
 230     case _pinned_cset:
 231       guarantee(_heap->cancelled_gc(), "only valid when evac has been cancelled");
 232       assert (_critical_pins > 0, "sanity");
 233       _critical_pins--;
 234       if (_critical_pins == 0) {
 235         _state = _cset;
 236       }
 237       return;
 238     case _pinned_humongous_start:
 239       assert (_critical_pins > 0, "sanity");
 240       _critical_pins--;
 241       if (_critical_pins == 0) {
 242         _state = _humongous_start;
 243       }
 244       return;
 245     default:
 246       report_illegal_transition("unpinning");
 247   }
 248 }
 249 
 250 void ShenandoahHeapRegion::make_cset() {
 251   _heap->assert_heaplock_owned_by_current_thread();
 252   switch (_state) {
 253     case _regular:
 254       _state = _cset;
 255     case _cset:
 256       return;
 257     default:
 258       report_illegal_transition("cset");
 259   }
 260 }
 261 
 262 void ShenandoahHeapRegion::make_trash() {
 263   _heap->assert_heaplock_owned_by_current_thread();
 264   switch (_state) {
 265     case _cset:
 266       // Reclaiming cset regions
 267     case _humongous_start:
 268     case _humongous_cont:
 269       // Reclaiming humongous regions
 270     case _regular:
 271       // Immediate region reclaim
 272       _state = _trash;
 273       return;
 274     default:
 275       report_illegal_transition("trashing");
 276   }
 277 }
 278 
 279 void ShenandoahHeapRegion::make_trash_immediate() {
 280   make_trash();
 281 
 282   // On this path, we know there are no marked objects in the region,
 283   // tell marking context about it to bypass bitmap resets.
 284   _heap->complete_marking_context()->reset_top_bitmap(this);
 285 }
 286 
 287 void ShenandoahHeapRegion::make_empty() {
 288   _heap->assert_heaplock_owned_by_current_thread();
 289   switch (_state) {
 290     case _trash:
 291       _state = _empty_committed;
 292       _empty_time = os::elapsedTime();
 293       return;
 294     default:
 295       report_illegal_transition("emptying");
 296   }
 297 }
 298 
 299 void ShenandoahHeapRegion::make_uncommitted() {
 300   _heap->assert_heaplock_owned_by_current_thread();
 301   switch (_state) {
 302     case _empty_committed:
 303       do_uncommit();
 304       _state = _empty_uncommitted;
 305       return;
 306     default:
 307       report_illegal_transition("uncommiting");
 308   }
 309 }
 310 
 311 void ShenandoahHeapRegion::make_committed_bypass() {
 312   _heap->assert_heaplock_owned_by_current_thread();
 313   assert (_heap->is_full_gc_in_progress(), "only for full GC");
 314 
 315   switch (_state) {
 316     case _empty_uncommitted:
 317       do_commit();
 318       _state = _empty_committed;
 319       return;
 320     default:
 321       report_illegal_transition("commit bypass");
 322   }
 323 }
 324 
 325 void ShenandoahHeapRegion::clear_live_data() {
 326   OrderAccess::release_store_fence<size_t>(&_live_data, 0);
 327 }
 328 
 329 void ShenandoahHeapRegion::reset_alloc_metadata() {
 330   _tlab_allocs = 0;
 331   _gclab_allocs = 0;
 332   _shared_allocs = 0;
 333   _seqnum_first_alloc_mutator = 0;
 334   _seqnum_last_alloc_mutator = 0;
 335   _seqnum_first_alloc_gc = 0;
 336   _seqnum_last_alloc_gc = 0;
 337 }
 338 


 660 }
 661 
 662 void ShenandoahHeapRegion::do_commit() {
 663   if (!os::commit_memory((char *) _reserved.start(), _reserved.byte_size(), false)) {
 664     report_java_out_of_memory("Unable to commit region");
 665   }
 666   if (!_heap->commit_bitmap_slice(this)) {
 667     report_java_out_of_memory("Unable to commit bitmaps for region");
 668   }
 669   _heap->increase_committed(ShenandoahHeapRegion::region_size_bytes());
 670 }
 671 
 672 void ShenandoahHeapRegion::do_uncommit() {
 673   if (!os::uncommit_memory((char *) _reserved.start(), _reserved.byte_size())) {
 674     report_java_out_of_memory("Unable to uncommit region");
 675   }
 676   if (!_heap->uncommit_bitmap_slice(this)) {
 677     report_java_out_of_memory("Unable to uncommit bitmaps for region");
 678   }
 679   _heap->decrease_committed(ShenandoahHeapRegion::region_size_bytes());













 680 }


  13  *
  14  * You should have received a copy of the GNU General Public License version
  15  * 2 along with this work; if not, write to the Free Software Foundation,
  16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  17  *
  18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  19  * or visit www.oracle.com if you need additional information or have any
  20  * questions.
  21  *
  22  */
  23 
  24 #include "precompiled.hpp"
  25 #include "memory/allocation.hpp"
  26 #include "gc/shenandoah/shenandoahBrooksPointer.hpp"
  27 #include "gc/shenandoah/shenandoahHeapRegionSet.inline.hpp"
  28 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
  29 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
  30 #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
  31 #include "gc/shenandoah/shenandoahTraversalGC.hpp"
  32 #include "gc/shared/space.inline.hpp"
  33 #include "jfr/jfrEvents.hpp"
  34 #include "memory/iterator.inline.hpp"
  35 #include "memory/resourceArea.hpp"
  36 #include "memory/universe.hpp"
  37 #include "oops/oop.inline.hpp"
  38 #include "runtime/java.hpp"
  39 #include "runtime/mutexLocker.hpp"
  40 #include "runtime/os.hpp"
  41 #include "runtime/safepoint.hpp"
  42 
  43 size_t ShenandoahHeapRegion::RegionCount = 0;
  44 size_t ShenandoahHeapRegion::RegionSizeBytes = 0;
  45 size_t ShenandoahHeapRegion::RegionSizeWords = 0;
  46 size_t ShenandoahHeapRegion::RegionSizeBytesShift = 0;
  47 size_t ShenandoahHeapRegion::RegionSizeWordsShift = 0;
  48 size_t ShenandoahHeapRegion::RegionSizeBytesMask = 0;
  49 size_t ShenandoahHeapRegion::RegionSizeWordsMask = 0;
  50 size_t ShenandoahHeapRegion::HumongousThresholdBytes = 0;
  51 size_t ShenandoahHeapRegion::HumongousThresholdWords = 0;
  52 size_t ShenandoahHeapRegion::MaxTLABSizeBytes = 0;
  53 size_t ShenandoahHeapRegion::MaxTLABSizeWords = 0;


  78 
  79 size_t ShenandoahHeapRegion::region_number() const {
  80   return _region_number;
  81 }
  82 
  83 void ShenandoahHeapRegion::report_illegal_transition(const char *method) {
  84   ResourceMark rm;
  85   stringStream ss;
  86   ss.print("Illegal region state transition from \"%s\", at %s\n  ", region_state_to_string(_state), method);
  87   print_on(&ss);
  88   fatal("%s", ss.as_string());
  89 }
  90 
  91 void ShenandoahHeapRegion::make_regular_allocation() {
  92   _heap->assert_heaplock_owned_by_current_thread();
  93 
  94   switch (_state) {
  95     case _empty_uncommitted:
  96       do_commit();
  97     case _empty_committed:
  98       set_state(_regular);
  99     case _regular:
 100     case _pinned:
 101       return;
 102     default:
 103       report_illegal_transition("regular allocation");
 104   }
 105 }
 106 
 107 void ShenandoahHeapRegion::make_regular_bypass() {
 108   _heap->assert_heaplock_owned_by_current_thread();
 109   assert (_heap->is_full_gc_in_progress() || _heap->is_degenerated_gc_in_progress(),
 110           "only for full or degen GC");
 111 
 112   switch (_state) {
 113     case _empty_uncommitted:
 114       do_commit();
 115     case _empty_committed:
 116     case _cset:
 117     case _humongous_start:
 118     case _humongous_cont:
 119       set_state(_regular);
 120       return;
 121     case _pinned_cset:
 122       set_state(_pinned);
 123       return;
 124     case _regular:
 125     case _pinned:
 126       return;
 127     default:
 128       report_illegal_transition("regular bypass");
 129   }
 130 }
 131 
 132 void ShenandoahHeapRegion::make_humongous_start() {
 133   _heap->assert_heaplock_owned_by_current_thread();
 134   switch (_state) {
 135     case _empty_uncommitted:
 136       do_commit();
 137     case _empty_committed:
 138       set_state(_humongous_start);
 139       return;
 140     default:
 141       report_illegal_transition("humongous start allocation");
 142   }
 143 }
 144 
 145 void ShenandoahHeapRegion::make_humongous_start_bypass() {
 146   _heap->assert_heaplock_owned_by_current_thread();
 147   assert (_heap->is_full_gc_in_progress(), "only for full GC");
 148 
 149   switch (_state) {
 150     case _empty_committed:
 151     case _regular:
 152     case _humongous_start:
 153     case _humongous_cont:
 154       set_state(_humongous_start);
 155       return;
 156     default:
 157       report_illegal_transition("humongous start bypass");
 158   }
 159 }
 160 
 161 void ShenandoahHeapRegion::make_humongous_cont() {
 162   _heap->assert_heaplock_owned_by_current_thread();
 163   switch (_state) {
 164     case _empty_uncommitted:
 165       do_commit();
 166     case _empty_committed:
 167      set_state(_humongous_cont);
 168       return;
 169     default:
 170       report_illegal_transition("humongous continuation allocation");
 171   }
 172 }
 173 
 174 void ShenandoahHeapRegion::make_humongous_cont_bypass() {
 175   _heap->assert_heaplock_owned_by_current_thread();
 176   assert (_heap->is_full_gc_in_progress(), "only for full GC");
 177 
 178   switch (_state) {
 179     case _empty_committed:
 180     case _regular:
 181     case _humongous_start:
 182     case _humongous_cont:
 183       set_state(_humongous_cont);
 184       return;
 185     default:
 186       report_illegal_transition("humongous continuation bypass");
 187   }
 188 }
 189 
 190 void ShenandoahHeapRegion::make_pinned() {
 191   _heap->assert_heaplock_owned_by_current_thread();
 192   switch (_state) {
 193     case _regular:
 194       assert (_critical_pins == 0, "sanity");
 195       set_state(_pinned);
 196     case _pinned_cset:
 197     case _pinned:
 198       _critical_pins++;
 199       return;
 200     case _humongous_start:
 201       assert (_critical_pins == 0, "sanity");
 202       set_state(_pinned_humongous_start);
 203     case _pinned_humongous_start:
 204       _critical_pins++;
 205       return;
 206     case _cset:
 207       guarantee(_heap->cancelled_gc(), "only valid when evac has been cancelled");
 208       assert (_critical_pins == 0, "sanity");
 209       _state = _pinned_cset;
 210       _critical_pins++;
 211       return;
 212     default:
 213       report_illegal_transition("pinning");
 214   }
 215 }
 216 
 217 void ShenandoahHeapRegion::make_unpinned() {
 218   _heap->assert_heaplock_owned_by_current_thread();
 219   switch (_state) {
 220     case _pinned:
 221       assert (_critical_pins > 0, "sanity");
 222       _critical_pins--;
 223       if (_critical_pins == 0) {
 224         set_state(_regular);
 225       }
 226       return;
 227     case _regular:
 228     case _humongous_start:
 229       assert (_critical_pins == 0, "sanity");
 230       return;
 231     case _pinned_cset:
 232       guarantee(_heap->cancelled_gc(), "only valid when evac has been cancelled");
 233       assert (_critical_pins > 0, "sanity");
 234       _critical_pins--;
 235       if (_critical_pins == 0) {
 236         set_state(_cset);
 237       }
 238       return;
 239     case _pinned_humongous_start:
 240       assert (_critical_pins > 0, "sanity");
 241       _critical_pins--;
 242       if (_critical_pins == 0) {
 243         set_state(_humongous_start);
 244       }
 245       return;
 246     default:
 247       report_illegal_transition("unpinning");
 248   }
 249 }
 250 
 251 void ShenandoahHeapRegion::make_cset() {
 252   _heap->assert_heaplock_owned_by_current_thread();
 253   switch (_state) {
 254     case _regular:
 255       set_state(_cset);
 256     case _cset:
 257       return;
 258     default:
 259       report_illegal_transition("cset");
 260   }
 261 }
 262 
 263 void ShenandoahHeapRegion::make_trash() {
 264   _heap->assert_heaplock_owned_by_current_thread();
 265   switch (_state) {
 266     case _cset:
 267       // Reclaiming cset regions
 268     case _humongous_start:
 269     case _humongous_cont:
 270       // Reclaiming humongous regions
 271     case _regular:
 272       // Immediate region reclaim
 273       set_state(_trash);
 274       return;
 275     default:
 276       report_illegal_transition("trashing");
 277   }
 278 }
 279 
 280 void ShenandoahHeapRegion::make_trash_immediate() {
 281   make_trash();
 282 
 283   // On this path, we know there are no marked objects in the region,
 284   // tell marking context about it to bypass bitmap resets.
 285   _heap->complete_marking_context()->reset_top_bitmap(this);
 286 }
 287 
 288 void ShenandoahHeapRegion::make_empty() {
 289   _heap->assert_heaplock_owned_by_current_thread();
 290   switch (_state) {
 291     case _trash:
 292       set_state(_empty_committed);
 293       _empty_time = os::elapsedTime();
 294       return;
 295     default:
 296       report_illegal_transition("emptying");
 297   }
 298 }
 299 
 300 void ShenandoahHeapRegion::make_uncommitted() {
 301   _heap->assert_heaplock_owned_by_current_thread();
 302   switch (_state) {
 303     case _empty_committed:
 304       do_uncommit();
 305       set_state(_empty_uncommitted);
 306       return;
 307     default:
 308       report_illegal_transition("uncommiting");
 309   }
 310 }
 311 
 312 void ShenandoahHeapRegion::make_committed_bypass() {
 313   _heap->assert_heaplock_owned_by_current_thread();
 314   assert (_heap->is_full_gc_in_progress(), "only for full GC");
 315 
 316   switch (_state) {
 317     case _empty_uncommitted:
 318       do_commit();
 319       set_state(_empty_committed);
 320       return;
 321     default:
 322       report_illegal_transition("commit bypass");
 323   }
 324 }
 325 
 326 void ShenandoahHeapRegion::clear_live_data() {
 327   OrderAccess::release_store_fence<size_t>(&_live_data, 0);
 328 }
 329 
 330 void ShenandoahHeapRegion::reset_alloc_metadata() {
 331   _tlab_allocs = 0;
 332   _gclab_allocs = 0;
 333   _shared_allocs = 0;
 334   _seqnum_first_alloc_mutator = 0;
 335   _seqnum_last_alloc_mutator = 0;
 336   _seqnum_first_alloc_gc = 0;
 337   _seqnum_last_alloc_gc = 0;
 338 }
 339 


 661 }
 662 
 663 void ShenandoahHeapRegion::do_commit() {
 664   if (!os::commit_memory((char *) _reserved.start(), _reserved.byte_size(), false)) {
 665     report_java_out_of_memory("Unable to commit region");
 666   }
 667   if (!_heap->commit_bitmap_slice(this)) {
 668     report_java_out_of_memory("Unable to commit bitmaps for region");
 669   }
 670   _heap->increase_committed(ShenandoahHeapRegion::region_size_bytes());
 671 }
 672 
 673 void ShenandoahHeapRegion::do_uncommit() {
 674   if (!os::uncommit_memory((char *) _reserved.start(), _reserved.byte_size())) {
 675     report_java_out_of_memory("Unable to uncommit region");
 676   }
 677   if (!_heap->uncommit_bitmap_slice(this)) {
 678     report_java_out_of_memory("Unable to uncommit bitmaps for region");
 679   }
 680   _heap->decrease_committed(ShenandoahHeapRegion::region_size_bytes());
 681 }
 682 
 683 void ShenandoahHeapRegion::set_state(RegionState to) {
 684   EventShenandoahHeapRegionStateChange evt;
 685   if (evt.should_commit()){
 686     evt.set_index(region_number());
 687     evt.set_start((uintptr_t)bottom());
 688     evt.set_used(used());
 689     evt.set_from(_state);
 690     evt.set_to(to);
 691     evt.commit();
 692   }
 693   _state = to;
 694 }
< prev index next >