< 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/shenandoahForwarding.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;


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


 661 }
 662 
 663 void ShenandoahHeapRegion::do_commit() {
 664   if (!_heap->is_heap_region_special() && !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 (!_heap->is_heap_region_special() && !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 }


  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/shenandoahForwarding.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;


  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       set_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       set_state(_regular);
 119       return;
 120     case _pinned_cset:
 121       set_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       set_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       set_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      set_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       set_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       set_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       set_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         set_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         set_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         set_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       set_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       set_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       set_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       set_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       set_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 


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