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 {
|