8066771: Refactor VM GC operations caused by allocation failure
Reviewed-by: brutisso, jmasa
--- a/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp Fri Feb 13 09:48:49 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp Fri Feb 13 10:31:52 2015 +0100
@@ -38,7 +38,7 @@
size_t word_size)
: VM_G1OperationWithAllocRequest(gc_count_before, word_size,
GCCause::_allocation_failure) {
- guarantee(word_size > 0, "an allocation should always be requested");
+ guarantee(word_size != 0, "An allocation should always be requested with this operation.");
}
void VM_G1CollectForAllocation::doit() {
@@ -73,7 +73,7 @@
}
bool VM_G1IncCollectionPause::doit_prologue() {
- bool res = VM_GC_Operation::doit_prologue();
+ bool res = VM_G1OperationWithAllocRequest::doit_prologue();
if (!res) {
if (_should_initiate_conc_mark) {
// The prologue can fail for a couple of reasons. The first is that another GC
@@ -163,7 +163,7 @@
}
void VM_G1IncCollectionPause::doit_epilogue() {
- VM_GC_Operation::doit_epilogue();
+ VM_G1OperationWithAllocRequest::doit_epilogue();
// If the pause was initiated by a System.gc() and
// +ExplicitGCInvokesConcurrent, we have to wait here for the cycle
--- a/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.hpp Fri Feb 13 09:48:49 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.hpp Fri Feb 13 10:31:52 2015 +0100
@@ -36,10 +36,8 @@
// - VM_G1CollectForAllocation
// - VM_G1IncCollectionPause
-class VM_G1OperationWithAllocRequest: public VM_GC_Operation {
+class VM_G1OperationWithAllocRequest : public VM_CollectForAllocation {
protected:
- size_t _word_size;
- HeapWord* _result;
bool _pause_succeeded;
AllocationContext_t _allocation_context;
@@ -47,9 +45,8 @@
VM_G1OperationWithAllocRequest(uint gc_count_before,
size_t word_size,
GCCause::Cause gc_cause)
- : VM_GC_Operation(gc_count_before, gc_cause),
- _word_size(word_size), _result(NULL), _pause_succeeded(false) { }
- HeapWord* result() { return _result; }
+ : VM_CollectForAllocation(word_size, gc_count_before, gc_cause),
+ _pause_succeeded(false) {}
bool pause_succeeded() { return _pause_succeeded; }
void set_allocation_context(AllocationContext_t context) { _allocation_context = context; }
AllocationContext_t allocation_context() { return _allocation_context; }
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp Fri Feb 13 09:48:49 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp Fri Feb 13 10:31:52 2015 +0100
@@ -32,12 +32,10 @@
#include "utilities/dtrace.hpp"
// The following methods are used by the parallel scavenge collector
-VM_ParallelGCFailedAllocation::VM_ParallelGCFailedAllocation(size_t size,
+VM_ParallelGCFailedAllocation::VM_ParallelGCFailedAllocation(size_t word_size,
uint gc_count) :
- VM_GC_Operation(gc_count, GCCause::_allocation_failure),
- _size(size),
- _result(NULL)
-{
+ VM_CollectForAllocation(word_size, gc_count, GCCause::_allocation_failure) {
+ assert(word_size != 0, "An allocation should always be requested with this operation.");
}
void VM_ParallelGCFailedAllocation::doit() {
@@ -47,7 +45,7 @@
assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "must be a ParallelScavengeHeap");
GCCauseSetter gccs(heap, _gc_cause);
- _result = heap->failed_mem_allocate(_size);
+ _result = heap->failed_mem_allocate(_word_size);
if (_result == NULL && GC_locker::is_active_and_needs_gc()) {
set_gc_locked();
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.hpp Fri Feb 13 09:48:49 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.hpp Fri Feb 13 10:31:52 2015 +0100
@@ -29,20 +29,14 @@
#include "gc_implementation/shared/vmGCOperations.hpp"
#include "gc_interface/gcCause.hpp"
-class VM_ParallelGCFailedAllocation: public VM_GC_Operation {
- private:
- size_t _size;
- HeapWord* _result;
-
+class VM_ParallelGCFailedAllocation : public VM_CollectForAllocation {
public:
- VM_ParallelGCFailedAllocation(size_t size, uint gc_count);
+ VM_ParallelGCFailedAllocation(size_t word_size, uint gc_count);
virtual VMOp_Type type() const {
return VMOp_ParallelGCFailedAllocation;
}
virtual void doit();
-
- HeapWord* result() const { return _result; }
};
class VM_ParallelGCSystemGC: public VM_GC_Operation {
--- a/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp Fri Feb 13 09:48:49 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp Fri Feb 13 10:31:52 2015 +0100
@@ -179,10 +179,10 @@
GenCollectedHeap* gch = GenCollectedHeap::heap();
GCCauseSetter gccs(gch, _gc_cause);
- _res = gch->satisfy_failed_allocation(_size, _tlab);
- assert(gch->is_in_reserved_or_null(_res), "result not in heap");
+ _result = gch->satisfy_failed_allocation(_word_size, _tlab);
+ assert(gch->is_in_reserved_or_null(_result), "result not in heap");
- if (_res == NULL && GC_locker::is_active_and_needs_gc()) {
+ if (_result == NULL && GC_locker::is_active_and_needs_gc()) {
set_gc_locked();
}
}
--- a/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.hpp Fri Feb 13 09:48:49 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.hpp Fri Feb 13 10:31:52 2015 +0100
@@ -38,11 +38,12 @@
// VM_Operation
// VM_GC_Operation
// VM_GC_HeapInspection
-// VM_GenCollectForAllocation
// VM_GenCollectFull
// VM_GenCollectFullConcurrent
-// VM_ParallelGCFailedAllocation
// VM_ParallelGCSystemGC
+// VM_CollectForAllocation
+// VM_GenCollectForAllocation
+// VM_ParallelGCFailedAllocation
// VM_GC_Operation
// - implements methods common to all classes in the hierarchy:
// prevents multiple gc requests and manages lock on heap;
@@ -51,6 +52,7 @@
// - prints class histogram on SIGBREAK if PrintClassHistogram
// is specified; and also the attach "inspectheap" operation
//
+// VM_CollectForAllocation
// VM_GenCollectForAllocation
// VM_ParallelGCFailedAllocation
// - this operation is invoked when allocation is failed;
@@ -160,25 +162,34 @@
bool collect();
};
+class VM_CollectForAllocation : public VM_GC_Operation {
+ protected:
+ size_t _word_size; // Size of object to be allocated (in number of words)
+ HeapWord* _result; // Allocation result (NULL if allocation failed)
-class VM_GenCollectForAllocation: public VM_GC_Operation {
+ public:
+ VM_CollectForAllocation(size_t word_size, uint gc_count_before, GCCause::Cause cause)
+ : VM_GC_Operation(gc_count_before, cause), _result(NULL), _word_size(word_size) {}
+
+ HeapWord* result() const {
+ return _result;
+ }
+};
+
+class VM_GenCollectForAllocation : public VM_CollectForAllocation {
private:
- HeapWord* _res;
- size_t _size; // size of object to be allocated.
bool _tlab; // alloc is of a tlab.
public:
- VM_GenCollectForAllocation(size_t size,
+ VM_GenCollectForAllocation(size_t word_size,
bool tlab,
uint gc_count_before)
- : VM_GC_Operation(gc_count_before, GCCause::_allocation_failure),
- _size(size),
+ : VM_CollectForAllocation(word_size, gc_count_before, GCCause::_allocation_failure),
_tlab(tlab) {
- _res = NULL;
+ assert(word_size != 0, "An allocation should always be requested with this operation.");
}
~VM_GenCollectForAllocation() {}
virtual VMOp_Type type() const { return VMOp_GenCollectForAllocation; }
virtual void doit();
- HeapWord* result() const { return _res; }
};
// VM operation to invoke a collection of the heap as a