1.1 --- a/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp Tue Nov 23 13:22:55 2010 -0800 1.2 +++ b/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp Tue Aug 24 17:24:33 2010 -0400 1.3 @@ -27,13 +27,22 @@ 1.4 #include "gc_implementation/g1/g1CollectorPolicy.hpp" 1.5 #include "gc_implementation/g1/vm_operations_g1.hpp" 1.6 #include "gc_implementation/shared/isGCActiveMark.hpp" 1.7 +#include "gc_implementation/g1/vm_operations_g1.hpp" 1.8 #include "runtime/interfaceSupport.hpp" 1.9 1.10 +VM_G1CollectForAllocation::VM_G1CollectForAllocation( 1.11 + unsigned int gc_count_before, 1.12 + size_t word_size) 1.13 + : VM_G1OperationWithAllocRequest(gc_count_before, word_size) { 1.14 + guarantee(word_size > 0, "an allocation should always be requested"); 1.15 +} 1.16 + 1.17 void VM_G1CollectForAllocation::doit() { 1.18 JvmtiGCForAllocationMarker jgcm; 1.19 G1CollectedHeap* g1h = G1CollectedHeap::heap(); 1.20 - _res = g1h->satisfy_failed_allocation(_size); 1.21 - assert(g1h->is_in_or_null(_res), "result not in heap"); 1.22 + _result = g1h->satisfy_failed_allocation(_word_size, &_pause_succeeded); 1.23 + assert(_result == NULL || _pause_succeeded, 1.24 + "if we get back a result, the pause should have succeeded"); 1.25 } 1.26 1.27 void VM_G1CollectFull::doit() { 1.28 @@ -43,6 +52,25 @@ 1.29 g1h->do_full_collection(false /* clear_all_soft_refs */); 1.30 } 1.31 1.32 +VM_G1IncCollectionPause::VM_G1IncCollectionPause( 1.33 + unsigned int gc_count_before, 1.34 + size_t word_size, 1.35 + bool should_initiate_conc_mark, 1.36 + double target_pause_time_ms, 1.37 + GCCause::Cause gc_cause) 1.38 + : VM_G1OperationWithAllocRequest(gc_count_before, word_size), 1.39 + _should_initiate_conc_mark(should_initiate_conc_mark), 1.40 + _target_pause_time_ms(target_pause_time_ms), 1.41 + _full_collections_completed_before(0) { 1.42 + guarantee(target_pause_time_ms > 0.0, 1.43 + err_msg("target_pause_time_ms = %1.6lf should be positive", 1.44 + target_pause_time_ms)); 1.45 + guarantee(word_size == 0 || gc_cause == GCCause::_g1_inc_collection_pause, 1.46 + "we can only request an allocation if the GC cause is for " 1.47 + "an incremental GC pause"); 1.48 + _gc_cause = gc_cause; 1.49 +} 1.50 + 1.51 void VM_G1IncCollectionPause::doit() { 1.52 JvmtiGCForAllocationMarker jgcm; 1.53 G1CollectedHeap* g1h = G1CollectedHeap::heap(); 1.54 @@ -51,6 +79,18 @@ 1.55 (_gc_cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent)), 1.56 "only a GC locker or a System.gc() induced GC should start a cycle"); 1.57 1.58 + if (_word_size > 0) { 1.59 + // An allocation has been requested. So, try to do that first. 1.60 + _result = g1h->attempt_allocation_at_safepoint(_word_size, 1.61 + false /* expect_null_cur_alloc_region */); 1.62 + if (_result != NULL) { 1.63 + // If we can successfully allocate before we actually do the 1.64 + // pause then we will consider this pause successful. 1.65 + _pause_succeeded = true; 1.66 + return; 1.67 + } 1.68 + } 1.69 + 1.70 GCCauseSetter x(g1h, _gc_cause); 1.71 if (_should_initiate_conc_mark) { 1.72 // It's safer to read full_collections_completed() here, given 1.73 @@ -63,7 +103,16 @@ 1.74 // will do so if one is not already in progress. 1.75 bool res = g1h->g1_policy()->force_initial_mark_if_outside_cycle(); 1.76 } 1.77 - g1h->do_collection_pause_at_safepoint(_target_pause_time_ms); 1.78 + 1.79 + _pause_succeeded = 1.80 + g1h->do_collection_pause_at_safepoint(_target_pause_time_ms); 1.81 + if (_pause_succeeded && _word_size > 0) { 1.82 + // An allocation had been requested. 1.83 + _result = g1h->attempt_allocation_at_safepoint(_word_size, 1.84 + true /* expect_null_cur_alloc_region */); 1.85 + } else { 1.86 + assert(_result == NULL, "invariant"); 1.87 + } 1.88 } 1.89 1.90 void VM_G1IncCollectionPause::doit_epilogue() {