< prev index next >

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

Print this page

  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #include "precompiled.hpp"
  27 #include "memory/allocation.hpp"
  28 #include "memory/universe.hpp"
  29 
  30 #include "gc/shared/classUnloadingContext.hpp"
  31 #include "gc/shared/gcArguments.hpp"
  32 #include "gc/shared/gcTimer.hpp"
  33 #include "gc/shared/gcTraceTime.inline.hpp"
  34 #include "gc/shared/locationPrinter.inline.hpp"
  35 #include "gc/shared/memAllocator.hpp"
  36 #include "gc/shared/plab.hpp"

  37 #include "gc/shared/tlab_globals.hpp"
  38 
  39 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
  40 #include "gc/shenandoah/shenandoahClosures.inline.hpp"
  41 #include "gc/shenandoah/shenandoahCollectionSet.hpp"
  42 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
  43 #include "gc/shenandoah/shenandoahConcurrentMark.hpp"
  44 #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
  45 #include "gc/shenandoah/shenandoahControlThread.hpp"
  46 #include "gc/shenandoah/shenandoahFreeSet.hpp"
  47 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
  48 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
  49 #include "gc/shenandoah/shenandoahHeapRegion.inline.hpp"
  50 #include "gc/shenandoah/shenandoahHeapRegionSet.hpp"
  51 #include "gc/shenandoah/shenandoahInitLogger.hpp"
  52 #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
  53 #include "gc/shenandoah/shenandoahMemoryPool.hpp"
  54 #include "gc/shenandoah/shenandoahMetrics.hpp"
  55 #include "gc/shenandoah/shenandoahMonitoringSupport.hpp"
  56 #include "gc/shenandoah/shenandoahOopClosures.inline.hpp"

 422   // just as there are G1-specific options.
 423   {
 424     ShenandoahSATBMarkQueueSet& satbqs = ShenandoahBarrierSet::satb_mark_queue_set();
 425     satbqs.set_process_completed_buffers_threshold(20); // G1SATBProcessCompletedThreshold
 426     satbqs.set_buffer_enqueue_threshold_percentage(60); // G1SATBBufferEnqueueingThresholdPercent
 427   }
 428 
 429   _monitoring_support = new ShenandoahMonitoringSupport(this);
 430   _phase_timings = new ShenandoahPhaseTimings(max_workers());
 431   ShenandoahCodeRoots::initialize();
 432 
 433   if (ShenandoahPacing) {
 434     _pacer = new ShenandoahPacer(this);
 435     _pacer->setup_for_idle();
 436   }
 437 
 438   _control_thread = new ShenandoahControlThread();
 439 
 440   ShenandoahInitLogger::print();
 441 


 442   return JNI_OK;
 443 }
 444 
 445 void ShenandoahHeap::initialize_mode() {
 446   if (ShenandoahGCMode != nullptr) {
 447     if (strcmp(ShenandoahGCMode, "satb") == 0) {
 448       _gc_mode = new ShenandoahSATBMode();
 449     } else if (strcmp(ShenandoahGCMode, "iu") == 0) {
 450       _gc_mode = new ShenandoahIUMode();
 451     } else if (strcmp(ShenandoahGCMode, "passive") == 0) {
 452       _gc_mode = new ShenandoahPassiveMode();
 453     } else {
 454       vm_exit_during_initialization("Unknown -XX:ShenandoahGCMode option");
 455     }
 456   } else {
 457     vm_exit_during_initialization("Unknown -XX:ShenandoahGCMode option (null)");
 458   }
 459   _gc_mode->initialize_flags();
 460   if (_gc_mode->is_diagnostic() && !UnlockDiagnosticVMOptions) {
 461     vm_exit_during_initialization(

1111         break;
1112       }
1113     }
1114   }
1115 };
1116 
1117 void ShenandoahHeap::evacuate_collection_set(bool concurrent) {
1118   ShenandoahEvacuationTask task(this, _collection_set, concurrent);
1119   workers()->run_task(&task);
1120 }
1121 
1122 oop ShenandoahHeap::evacuate_object(oop p, Thread* thread) {
1123   if (ShenandoahThreadLocalData::is_oom_during_evac(Thread::current())) {
1124     // This thread went through the OOM during evac protocol and it is safe to return
1125     // the forward pointer. It must not attempt to evacuate any more.
1126     return ShenandoahBarrierSet::resolve_forwarded(p);
1127   }
1128 
1129   assert(ShenandoahThreadLocalData::is_evac_allowed(thread), "must be enclosed in oom-evac scope");
1130 
1131   size_t size = p->size();
1132 
1133   assert(!heap_region_containing(p)->is_humongous(), "never evacuate humongous objects");
1134 
1135   bool alloc_from_gclab = true;
1136   HeapWord* copy = nullptr;
1137 
1138 #ifdef ASSERT
1139   if (ShenandoahOOMDuringEvacALot &&
1140       (os::random() & 1) == 0) { // Simulate OOM every ~2nd slow-path call
1141     copy = nullptr;
1142   } else {
1143 #endif
1144     if (UseTLAB) {
1145       copy = allocate_from_gclab(thread, size);
1146     }
1147     if (copy == nullptr) {
1148       ShenandoahAllocRequest req = ShenandoahAllocRequest::for_shared_gc(size);
1149       copy = allocate_memory(req);
1150       alloc_from_gclab = false;
1151     }
1152 #ifdef ASSERT
1153   }
1154 #endif
1155 
1156   if (copy == nullptr) {
1157     control_thread()->handle_alloc_failure_evac(size);
1158 
1159     _oom_evac_handler.handle_out_of_memory_during_evacuation();
1160 
1161     return ShenandoahBarrierSet::resolve_forwarded(p);
1162   }
1163 
1164   // Copy the object:
1165   Copy::aligned_disjoint_words(cast_from_oop<HeapWord*>(p), copy, size);
1166 
1167   // Try to install the new forwarding pointer.
1168   oop copy_val = cast_to_oop(copy);
1169   ContinuationGCSupport::relativize_stack_chunk(copy_val);
1170 

















1171   oop result = ShenandoahForwarding::try_update_forwardee(p, copy_val);
1172   if (result == copy_val) {
1173     // Successfully evacuated. Our copy is now the public one!
1174     shenandoah_assert_correct(nullptr, copy_val);
1175     return copy_val;
1176   }  else {
1177     // Failed to evacuate. We need to deal with the object that is left behind. Since this
1178     // new allocation is certainly after TAMS, it will be considered live in the next cycle.
1179     // But if it happens to contain references to evacuated regions, those references would
1180     // not get updated for this stale copy during this cycle, and we will crash while scanning
1181     // it the next cycle.
1182     //
1183     // For GCLAB allocations, it is enough to rollback the allocation ptr. Either the next
1184     // object will overwrite this stale copy, or the filler object on LAB retirement will
1185     // do this. For non-GCLAB allocations, we have no way to retract the allocation, and
1186     // have to explicitly overwrite the copy with the filler object. With that overwrite,
1187     // we have to keep the fwdptr initialized and pointing to our (stale) copy.
1188     if (alloc_from_gclab) {
1189       ShenandoahThreadLocalData::gclab(thread)->undo_allocation(copy, size);
1190     } else {

  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #include "precompiled.hpp"
  27 #include "memory/allocation.hpp"
  28 #include "memory/universe.hpp"
  29 
  30 #include "gc/shared/classUnloadingContext.hpp"
  31 #include "gc/shared/gcArguments.hpp"
  32 #include "gc/shared/gcTimer.hpp"
  33 #include "gc/shared/gcTraceTime.inline.hpp"
  34 #include "gc/shared/locationPrinter.inline.hpp"
  35 #include "gc/shared/memAllocator.hpp"
  36 #include "gc/shared/plab.hpp"
  37 #include "gc/shared/slidingForwarding.hpp"
  38 #include "gc/shared/tlab_globals.hpp"
  39 
  40 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
  41 #include "gc/shenandoah/shenandoahClosures.inline.hpp"
  42 #include "gc/shenandoah/shenandoahCollectionSet.hpp"
  43 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
  44 #include "gc/shenandoah/shenandoahConcurrentMark.hpp"
  45 #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
  46 #include "gc/shenandoah/shenandoahControlThread.hpp"
  47 #include "gc/shenandoah/shenandoahFreeSet.hpp"
  48 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
  49 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
  50 #include "gc/shenandoah/shenandoahHeapRegion.inline.hpp"
  51 #include "gc/shenandoah/shenandoahHeapRegionSet.hpp"
  52 #include "gc/shenandoah/shenandoahInitLogger.hpp"
  53 #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
  54 #include "gc/shenandoah/shenandoahMemoryPool.hpp"
  55 #include "gc/shenandoah/shenandoahMetrics.hpp"
  56 #include "gc/shenandoah/shenandoahMonitoringSupport.hpp"
  57 #include "gc/shenandoah/shenandoahOopClosures.inline.hpp"

 423   // just as there are G1-specific options.
 424   {
 425     ShenandoahSATBMarkQueueSet& satbqs = ShenandoahBarrierSet::satb_mark_queue_set();
 426     satbqs.set_process_completed_buffers_threshold(20); // G1SATBProcessCompletedThreshold
 427     satbqs.set_buffer_enqueue_threshold_percentage(60); // G1SATBBufferEnqueueingThresholdPercent
 428   }
 429 
 430   _monitoring_support = new ShenandoahMonitoringSupport(this);
 431   _phase_timings = new ShenandoahPhaseTimings(max_workers());
 432   ShenandoahCodeRoots::initialize();
 433 
 434   if (ShenandoahPacing) {
 435     _pacer = new ShenandoahPacer(this);
 436     _pacer->setup_for_idle();
 437   }
 438 
 439   _control_thread = new ShenandoahControlThread();
 440 
 441   ShenandoahInitLogger::print();
 442 
 443   SlidingForwarding::initialize(_heap_region, ShenandoahHeapRegion::region_size_words());
 444 
 445   return JNI_OK;
 446 }
 447 
 448 void ShenandoahHeap::initialize_mode() {
 449   if (ShenandoahGCMode != nullptr) {
 450     if (strcmp(ShenandoahGCMode, "satb") == 0) {
 451       _gc_mode = new ShenandoahSATBMode();
 452     } else if (strcmp(ShenandoahGCMode, "iu") == 0) {
 453       _gc_mode = new ShenandoahIUMode();
 454     } else if (strcmp(ShenandoahGCMode, "passive") == 0) {
 455       _gc_mode = new ShenandoahPassiveMode();
 456     } else {
 457       vm_exit_during_initialization("Unknown -XX:ShenandoahGCMode option");
 458     }
 459   } else {
 460     vm_exit_during_initialization("Unknown -XX:ShenandoahGCMode option (null)");
 461   }
 462   _gc_mode->initialize_flags();
 463   if (_gc_mode->is_diagnostic() && !UnlockDiagnosticVMOptions) {
 464     vm_exit_during_initialization(

1114         break;
1115       }
1116     }
1117   }
1118 };
1119 
1120 void ShenandoahHeap::evacuate_collection_set(bool concurrent) {
1121   ShenandoahEvacuationTask task(this, _collection_set, concurrent);
1122   workers()->run_task(&task);
1123 }
1124 
1125 oop ShenandoahHeap::evacuate_object(oop p, Thread* thread) {
1126   if (ShenandoahThreadLocalData::is_oom_during_evac(Thread::current())) {
1127     // This thread went through the OOM during evac protocol and it is safe to return
1128     // the forward pointer. It must not attempt to evacuate any more.
1129     return ShenandoahBarrierSet::resolve_forwarded(p);
1130   }
1131 
1132   assert(ShenandoahThreadLocalData::is_evac_allowed(thread), "must be enclosed in oom-evac scope");
1133 
1134   size_t size = p->forward_safe_size();
1135 
1136   assert(!heap_region_containing(p)->is_humongous(), "never evacuate humongous objects");
1137 
1138   bool alloc_from_gclab = true;
1139   HeapWord* copy = nullptr;
1140 
1141 #ifdef ASSERT
1142   if (ShenandoahOOMDuringEvacALot &&
1143       (os::random() & 1) == 0) { // Simulate OOM every ~2nd slow-path call
1144     copy = nullptr;
1145   } else {
1146 #endif
1147     if (UseTLAB) {
1148       copy = allocate_from_gclab(thread, size);
1149     }
1150     if (copy == nullptr) {
1151       ShenandoahAllocRequest req = ShenandoahAllocRequest::for_shared_gc(size);
1152       copy = allocate_memory(req);
1153       alloc_from_gclab = false;
1154     }
1155 #ifdef ASSERT
1156   }
1157 #endif
1158 
1159   if (copy == nullptr) {
1160     control_thread()->handle_alloc_failure_evac(size);
1161 
1162     _oom_evac_handler.handle_out_of_memory_during_evacuation();
1163 
1164     return ShenandoahBarrierSet::resolve_forwarded(p);
1165   }
1166 
1167   // Copy the object:
1168   Copy::aligned_disjoint_words(cast_from_oop<HeapWord*>(p), copy, size);


1169   oop copy_val = cast_to_oop(copy);

1170 
1171   if (UseCompactObjectHeaders) {
1172     // The copy above is not atomic. Make sure we have seen the proper mark
1173     // and re-install it into the copy, so that Klass* is guaranteed to be correct.
1174     markWord mark = copy_val->mark();
1175     if (!mark.is_marked()) {
1176       copy_val->set_mark(mark);
1177       ContinuationGCSupport::relativize_stack_chunk(copy_val);
1178     } else {
1179       // If we copied a mark-word that indicates 'forwarded' state, the object
1180       // installation would not succeed. We cannot access Klass* anymore either.
1181       // Skip the transformation.
1182     }
1183   } else {
1184     ContinuationGCSupport::relativize_stack_chunk(copy_val);
1185   }
1186 
1187   // Try to install the new forwarding pointer.
1188   oop result = ShenandoahForwarding::try_update_forwardee(p, copy_val);
1189   if (result == copy_val) {
1190     // Successfully evacuated. Our copy is now the public one!
1191     shenandoah_assert_correct(nullptr, copy_val);
1192     return copy_val;
1193   }  else {
1194     // Failed to evacuate. We need to deal with the object that is left behind. Since this
1195     // new allocation is certainly after TAMS, it will be considered live in the next cycle.
1196     // But if it happens to contain references to evacuated regions, those references would
1197     // not get updated for this stale copy during this cycle, and we will crash while scanning
1198     // it the next cycle.
1199     //
1200     // For GCLAB allocations, it is enough to rollback the allocation ptr. Either the next
1201     // object will overwrite this stale copy, or the filler object on LAB retirement will
1202     // do this. For non-GCLAB allocations, we have no way to retract the allocation, and
1203     // have to explicitly overwrite the copy with the filler object. With that overwrite,
1204     // we have to keep the fwdptr initialized and pointing to our (stale) copy.
1205     if (alloc_from_gclab) {
1206       ShenandoahThreadLocalData::gclab(thread)->undo_allocation(copy, size);
1207     } else {
< prev index next >