mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8198509: Move satisfy_failed_metadata_allocation out from CollectorPolicy
Reviewed-by: sjohanss, pliden
This commit is contained in:
parent
380a8b15ec
commit
bd70c72fd2
6 changed files with 83 additions and 84 deletions
|
@ -28,6 +28,7 @@
|
||||||
#include "gc/shared/barrierSet.inline.hpp"
|
#include "gc/shared/barrierSet.inline.hpp"
|
||||||
#include "gc/shared/collectedHeap.hpp"
|
#include "gc/shared/collectedHeap.hpp"
|
||||||
#include "gc/shared/collectedHeap.inline.hpp"
|
#include "gc/shared/collectedHeap.inline.hpp"
|
||||||
|
#include "gc/shared/gcLocker.inline.hpp"
|
||||||
#include "gc/shared/gcHeapSummary.hpp"
|
#include "gc/shared/gcHeapSummary.hpp"
|
||||||
#include "gc/shared/gcTrace.hpp"
|
#include "gc/shared/gcTrace.hpp"
|
||||||
#include "gc/shared/gcTraceTime.inline.hpp"
|
#include "gc/shared/gcTraceTime.inline.hpp"
|
||||||
|
@ -41,9 +42,11 @@
|
||||||
#include "runtime/init.hpp"
|
#include "runtime/init.hpp"
|
||||||
#include "runtime/thread.inline.hpp"
|
#include "runtime/thread.inline.hpp"
|
||||||
#include "runtime/threadSMR.hpp"
|
#include "runtime/threadSMR.hpp"
|
||||||
|
#include "runtime/vmThread.hpp"
|
||||||
#include "services/heapDumper.hpp"
|
#include "services/heapDumper.hpp"
|
||||||
#include "utilities/align.hpp"
|
#include "utilities/align.hpp"
|
||||||
|
|
||||||
|
class ClassLoaderData;
|
||||||
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
int CollectedHeap::_fire_out_of_memory_count = 0;
|
int CollectedHeap::_fire_out_of_memory_count = 0;
|
||||||
|
@ -233,6 +236,80 @@ void CollectedHeap::collect_as_vm_thread(GCCause::Cause cause) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MetaWord* CollectedHeap::satisfy_failed_metadata_allocation(ClassLoaderData* loader_data,
|
||||||
|
size_t word_size,
|
||||||
|
Metaspace::MetadataType mdtype) {
|
||||||
|
uint loop_count = 0;
|
||||||
|
uint gc_count = 0;
|
||||||
|
uint full_gc_count = 0;
|
||||||
|
|
||||||
|
assert(!Heap_lock->owned_by_self(), "Should not be holding the Heap_lock");
|
||||||
|
|
||||||
|
do {
|
||||||
|
MetaWord* result = loader_data->metaspace_non_null()->allocate(word_size, mdtype);
|
||||||
|
if (result != NULL) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GCLocker::is_active_and_needs_gc()) {
|
||||||
|
// If the GCLocker is active, just expand and allocate.
|
||||||
|
// If that does not succeed, wait if this thread is not
|
||||||
|
// in a critical section itself.
|
||||||
|
result = loader_data->metaspace_non_null()->expand_and_allocate(word_size, mdtype);
|
||||||
|
if (result != NULL) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
JavaThread* jthr = JavaThread::current();
|
||||||
|
if (!jthr->in_critical()) {
|
||||||
|
// Wait for JNI critical section to be exited
|
||||||
|
GCLocker::stall_until_clear();
|
||||||
|
// The GC invoked by the last thread leaving the critical
|
||||||
|
// section will be a young collection and a full collection
|
||||||
|
// is (currently) needed for unloading classes so continue
|
||||||
|
// to the next iteration to get a full GC.
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
if (CheckJNICalls) {
|
||||||
|
fatal("Possible deadlock due to allocating while"
|
||||||
|
" in jni critical section");
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // Need lock to get self consistent gc_count's
|
||||||
|
MutexLocker ml(Heap_lock);
|
||||||
|
gc_count = Universe::heap()->total_collections();
|
||||||
|
full_gc_count = Universe::heap()->total_full_collections();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate a VM operation
|
||||||
|
VM_CollectForMetadataAllocation op(loader_data,
|
||||||
|
word_size,
|
||||||
|
mdtype,
|
||||||
|
gc_count,
|
||||||
|
full_gc_count,
|
||||||
|
GCCause::_metadata_GC_threshold);
|
||||||
|
VMThread::execute(&op);
|
||||||
|
|
||||||
|
// If GC was locked out, try again. Check before checking success because the
|
||||||
|
// prologue could have succeeded and the GC still have been locked out.
|
||||||
|
if (op.gc_locked()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op.prologue_succeeded()) {
|
||||||
|
return op.result();
|
||||||
|
}
|
||||||
|
loop_count++;
|
||||||
|
if ((QueuedAllocationWarningCount > 0) &&
|
||||||
|
(loop_count % QueuedAllocationWarningCount == 0)) {
|
||||||
|
log_warning(gc, ergo)("satisfy_failed_metadata_allocation() retries %d times,"
|
||||||
|
" size=" SIZE_FORMAT, loop_count, word_size);
|
||||||
|
}
|
||||||
|
} while (true); // Until a GC is done
|
||||||
|
}
|
||||||
|
|
||||||
void CollectedHeap::set_barrier_set(BarrierSet* barrier_set) {
|
void CollectedHeap::set_barrier_set(BarrierSet* barrier_set) {
|
||||||
_barrier_set = barrier_set;
|
_barrier_set = barrier_set;
|
||||||
BarrierSet::set_bs(barrier_set);
|
BarrierSet::set_bs(barrier_set);
|
||||||
|
|
|
@ -411,6 +411,10 @@ class CollectedHeap : public CHeapObj<mtInternal> {
|
||||||
// the context of the vm thread.
|
// the context of the vm thread.
|
||||||
virtual void collect_as_vm_thread(GCCause::Cause cause);
|
virtual void collect_as_vm_thread(GCCause::Cause cause);
|
||||||
|
|
||||||
|
virtual MetaWord* satisfy_failed_metadata_allocation(ClassLoaderData* loader_data,
|
||||||
|
size_t size,
|
||||||
|
Metaspace::MetadataType mdtype);
|
||||||
|
|
||||||
// Returns the barrier set for this heap
|
// Returns the barrier set for this heap
|
||||||
BarrierSet* barrier_set() { return _barrier_set; }
|
BarrierSet* barrier_set() { return _barrier_set; }
|
||||||
void set_barrier_set(BarrierSet* barrier_set);
|
void set_barrier_set(BarrierSet* barrier_set);
|
||||||
|
|
|
@ -799,83 +799,6 @@ HeapWord* GenCollectorPolicy::satisfy_failed_allocation(size_t size,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaWord* CollectorPolicy::satisfy_failed_metadata_allocation(
|
|
||||||
ClassLoaderData* loader_data,
|
|
||||||
size_t word_size,
|
|
||||||
Metaspace::MetadataType mdtype) {
|
|
||||||
uint loop_count = 0;
|
|
||||||
uint gc_count = 0;
|
|
||||||
uint full_gc_count = 0;
|
|
||||||
|
|
||||||
assert(!Heap_lock->owned_by_self(), "Should not be holding the Heap_lock");
|
|
||||||
|
|
||||||
do {
|
|
||||||
MetaWord* result = loader_data->metaspace_non_null()->allocate(word_size, mdtype);
|
|
||||||
if (result != NULL) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GCLocker::is_active_and_needs_gc()) {
|
|
||||||
// If the GCLocker is active, just expand and allocate.
|
|
||||||
// If that does not succeed, wait if this thread is not
|
|
||||||
// in a critical section itself.
|
|
||||||
result =
|
|
||||||
loader_data->metaspace_non_null()->expand_and_allocate(word_size,
|
|
||||||
mdtype);
|
|
||||||
if (result != NULL) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
JavaThread* jthr = JavaThread::current();
|
|
||||||
if (!jthr->in_critical()) {
|
|
||||||
// Wait for JNI critical section to be exited
|
|
||||||
GCLocker::stall_until_clear();
|
|
||||||
// The GC invoked by the last thread leaving the critical
|
|
||||||
// section will be a young collection and a full collection
|
|
||||||
// is (currently) needed for unloading classes so continue
|
|
||||||
// to the next iteration to get a full GC.
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
if (CheckJNICalls) {
|
|
||||||
fatal("Possible deadlock due to allocating while"
|
|
||||||
" in jni critical section");
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{ // Need lock to get self consistent gc_count's
|
|
||||||
MutexLocker ml(Heap_lock);
|
|
||||||
gc_count = Universe::heap()->total_collections();
|
|
||||||
full_gc_count = Universe::heap()->total_full_collections();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate a VM operation
|
|
||||||
VM_CollectForMetadataAllocation op(loader_data,
|
|
||||||
word_size,
|
|
||||||
mdtype,
|
|
||||||
gc_count,
|
|
||||||
full_gc_count,
|
|
||||||
GCCause::_metadata_GC_threshold);
|
|
||||||
VMThread::execute(&op);
|
|
||||||
|
|
||||||
// If GC was locked out, try again. Check before checking success because the
|
|
||||||
// prologue could have succeeded and the GC still have been locked out.
|
|
||||||
if (op.gc_locked()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (op.prologue_succeeded()) {
|
|
||||||
return op.result();
|
|
||||||
}
|
|
||||||
loop_count++;
|
|
||||||
if ((QueuedAllocationWarningCount > 0) &&
|
|
||||||
(loop_count % QueuedAllocationWarningCount == 0)) {
|
|
||||||
log_warning(gc, ergo)("satisfy_failed_metadata_allocation() retries %d times,"
|
|
||||||
" size=" SIZE_FORMAT, loop_count, word_size);
|
|
||||||
}
|
|
||||||
} while (true); // Until a GC is done
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return true if any of the following is true:
|
// Return true if any of the following is true:
|
||||||
// . the allocation won't fit into the current young gen heap
|
// . the allocation won't fit into the current young gen heap
|
||||||
// . gc locker is occupied (jni critical section)
|
// . gc locker is occupied (jni critical section)
|
||||||
|
|
|
@ -113,10 +113,6 @@ class CollectorPolicy : public CHeapObj<mtGC> {
|
||||||
// Called by the GC after Soft Refs have been cleared to indicate
|
// Called by the GC after Soft Refs have been cleared to indicate
|
||||||
// that the request in _should_clear_all_soft_refs has been fulfilled.
|
// that the request in _should_clear_all_soft_refs has been fulfilled.
|
||||||
virtual void cleared_all_soft_refs();
|
virtual void cleared_all_soft_refs();
|
||||||
|
|
||||||
virtual MetaWord* satisfy_failed_metadata_allocation(ClassLoaderData* loader_data,
|
|
||||||
size_t size,
|
|
||||||
Metaspace::MetadataType mdtype);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ClearedAllSoftRefs : public StackObj {
|
class ClearedAllSoftRefs : public StackObj {
|
||||||
|
|
|
@ -3952,8 +3952,7 @@ MetaWord* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
|
||||||
// Only start a GC if the bootstrapping has completed.
|
// Only start a GC if the bootstrapping has completed.
|
||||||
|
|
||||||
// Try to clean out some memory and retry.
|
// Try to clean out some memory and retry.
|
||||||
result = Universe::heap()->collector_policy()->satisfy_failed_metadata_allocation(
|
result = Universe::heap()->satisfy_failed_metadata_allocation(loader_data, word_size, mdtype);
|
||||||
loader_data, word_size, mdtype);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ class Metaspace : public CHeapObj<mtClass> {
|
||||||
friend class MetaspaceGC;
|
friend class MetaspaceGC;
|
||||||
friend class MetaspaceAux;
|
friend class MetaspaceAux;
|
||||||
friend class MetaspaceShared;
|
friend class MetaspaceShared;
|
||||||
friend class CollectorPolicy;
|
friend class CollectedHeap;
|
||||||
friend class PrintCLDMetaspaceInfoClosure;
|
friend class PrintCLDMetaspaceInfoClosure;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue