7025742: Can not use CodeCache::unallocated_capacity() with fragmented CodeCache
Use largest_free_block() instead of unallocated_capacity(). Reviewed-by: iveresov, never, ysr
This commit is contained in:
parent
84ef74286f
commit
fd6487f201
@ -939,9 +939,16 @@ void CodeCache::print_bounds(outputStream* st) {
|
|||||||
_heap->high(),
|
_heap->high(),
|
||||||
_heap->high_boundary());
|
_heap->high_boundary());
|
||||||
st->print_cr(" total_blobs=" UINT32_FORMAT " nmethods=" UINT32_FORMAT
|
st->print_cr(" total_blobs=" UINT32_FORMAT " nmethods=" UINT32_FORMAT
|
||||||
" adapters=" UINT32_FORMAT " free_code_cache=" SIZE_FORMAT
|
" adapters=" UINT32_FORMAT " free_code_cache=" SIZE_FORMAT "Kb"
|
||||||
" largest_free_block=" SIZE_FORMAT,
|
" largest_free_block=" SIZE_FORMAT,
|
||||||
CodeCache::nof_blobs(), CodeCache::nof_nmethods(),
|
nof_blobs(), nof_nmethods(), nof_adapters(),
|
||||||
CodeCache::nof_adapters(), CodeCache::unallocated_capacity(),
|
unallocated_capacity()/K, largest_free_block());
|
||||||
CodeCache::largest_free_block());
|
}
|
||||||
|
|
||||||
|
void CodeCache::log_state(outputStream* st) {
|
||||||
|
st->print(" total_blobs='" UINT32_FORMAT "' nmethods='" UINT32_FORMAT "'"
|
||||||
|
" adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'"
|
||||||
|
" largest_free_block='" SIZE_FORMAT "'",
|
||||||
|
nof_blobs(), nof_nmethods(), nof_adapters(),
|
||||||
|
unallocated_capacity(), largest_free_block());
|
||||||
}
|
}
|
||||||
|
@ -147,6 +147,7 @@ class CodeCache : AllStatic {
|
|||||||
static void verify(); // verifies the code cache
|
static void verify(); // verifies the code cache
|
||||||
static void print_trace(const char* event, CodeBlob* cb, int size = 0) PRODUCT_RETURN;
|
static void print_trace(const char* event, CodeBlob* cb, int size = 0) PRODUCT_RETURN;
|
||||||
static void print_bounds(outputStream* st); // Prints a summary of the bounds of the code cache
|
static void print_bounds(outputStream* st); // Prints a summary of the bounds of the code cache
|
||||||
|
static void log_state(outputStream* st);
|
||||||
|
|
||||||
// The full limits of the codeCache
|
// The full limits of the codeCache
|
||||||
static address low_bound() { return (address) _heap->low_boundary(); }
|
static address low_bound() { return (address) _heap->low_boundary(); }
|
||||||
@ -159,7 +160,7 @@ class CodeCache : AllStatic {
|
|||||||
static size_t max_capacity() { return _heap->max_capacity(); }
|
static size_t max_capacity() { return _heap->max_capacity(); }
|
||||||
static size_t unallocated_capacity() { return _heap->unallocated_capacity(); }
|
static size_t unallocated_capacity() { return _heap->unallocated_capacity(); }
|
||||||
static size_t largest_free_block() { return _heap->largest_free_block(); }
|
static size_t largest_free_block() { return _heap->largest_free_block(); }
|
||||||
static bool needs_flushing() { return unallocated_capacity() < CodeCacheFlushingMinimumFreeSpace; }
|
static bool needs_flushing() { return largest_free_block() < CodeCacheFlushingMinimumFreeSpace; }
|
||||||
|
|
||||||
static bool needs_cache_clean() { return _needs_cache_clean; }
|
static bool needs_cache_clean() { return _needs_cache_clean; }
|
||||||
static void set_needs_cache_clean(bool v) { _needs_cache_clean = v; }
|
static void set_needs_cache_clean(bool v) { _needs_cache_clean = v; }
|
||||||
|
@ -762,7 +762,7 @@ nmethod::nmethod(
|
|||||||
|
|
||||||
void* nmethod::operator new(size_t size, int nmethod_size) {
|
void* nmethod::operator new(size_t size, int nmethod_size) {
|
||||||
// Always leave some room in the CodeCache for I2C/C2I adapters
|
// Always leave some room in the CodeCache for I2C/C2I adapters
|
||||||
if (CodeCache::unallocated_capacity() < CodeCacheMinimumFreeSpace) return NULL;
|
if (CodeCache::largest_free_block() < CodeCacheMinimumFreeSpace) return NULL;
|
||||||
return CodeCache::allocate(nmethod_size);
|
return CodeCache::allocate(nmethod_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1364,7 +1364,7 @@ void CompileBroker::compiler_thread_loop() {
|
|||||||
// We need this HandleMark to avoid leaking VM handles.
|
// We need this HandleMark to avoid leaking VM handles.
|
||||||
HandleMark hm(thread);
|
HandleMark hm(thread);
|
||||||
|
|
||||||
if (CodeCache::unallocated_capacity() < CodeCacheMinimumFreeSpace) {
|
if (CodeCache::largest_free_block() < CodeCacheMinimumFreeSpace) {
|
||||||
// the code cache is really full
|
// the code cache is really full
|
||||||
handle_full_code_cache();
|
handle_full_code_cache();
|
||||||
} else if (UseCodeCacheFlushing && CodeCache::needs_flushing()) {
|
} else if (UseCodeCacheFlushing && CodeCache::needs_flushing()) {
|
||||||
@ -1645,11 +1645,13 @@ void CompileBroker::handle_full_code_cache() {
|
|||||||
if (UseCompiler || AlwaysCompileLoopMethods ) {
|
if (UseCompiler || AlwaysCompileLoopMethods ) {
|
||||||
if (xtty != NULL) {
|
if (xtty != NULL) {
|
||||||
xtty->begin_elem("code_cache_full");
|
xtty->begin_elem("code_cache_full");
|
||||||
|
CodeCache::log_state(xtty);
|
||||||
xtty->stamp();
|
xtty->stamp();
|
||||||
xtty->end_elem();
|
xtty->end_elem();
|
||||||
}
|
}
|
||||||
warning("CodeCache is full. Compiler has been disabled.");
|
warning("CodeCache is full. Compiler has been disabled.");
|
||||||
warning("Try increasing the code cache size using -XX:ReservedCodeCacheSize=");
|
warning("Try increasing the code cache size using -XX:ReservedCodeCacheSize=");
|
||||||
|
CodeCache::print_bounds(tty);
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
if (CompileTheWorld || ExitOnFullCodeCache) {
|
if (CompileTheWorld || ExitOnFullCodeCache) {
|
||||||
before_exit(JavaThread::current());
|
before_exit(JavaThread::current());
|
||||||
|
@ -316,12 +316,19 @@ size_t CodeHeap::allocated_capacity() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t CodeHeap::largest_free_block() const {
|
size_t CodeHeap::largest_free_block() const {
|
||||||
|
// First check unused space excluding free blocks.
|
||||||
|
size_t free_sz = size(_free_segments);
|
||||||
|
size_t unused = max_capacity() - allocated_capacity() - free_sz;
|
||||||
|
if (unused >= free_sz)
|
||||||
|
return unused;
|
||||||
|
|
||||||
|
// Now check largest free block.
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
for (FreeBlock* b = _freelist; b != NULL; b = b->link()) {
|
for (FreeBlock* b = _freelist; b != NULL; b = b->link()) {
|
||||||
if (b->length() > len)
|
if (b->length() > len)
|
||||||
len = b->length();
|
len = b->length();
|
||||||
}
|
}
|
||||||
return size(len);
|
return MAX2(unused, size(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free list management
|
// Free list management
|
||||||
|
@ -1028,7 +1028,7 @@ void NonSafepointEmitter::emit_non_safepoint() {
|
|||||||
|
|
||||||
// helper for Fill_buffer bailout logic
|
// helper for Fill_buffer bailout logic
|
||||||
static void turn_off_compiler(Compile* C) {
|
static void turn_off_compiler(Compile* C) {
|
||||||
if (CodeCache::unallocated_capacity() >= CodeCacheMinimumFreeSpace*10) {
|
if (CodeCache::largest_free_block() >= CodeCacheMinimumFreeSpace*10) {
|
||||||
// Do not turn off compilation if a single giant method has
|
// Do not turn off compilation if a single giant method has
|
||||||
// blown the code cache size.
|
// blown the code cache size.
|
||||||
C->record_failure("excessive request to CodeCache");
|
C->record_failure("excessive request to CodeCache");
|
||||||
|
@ -426,9 +426,7 @@ void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) {
|
|||||||
tty->vprint(format, ap);
|
tty->vprint(format, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
tty->print_cr(" total_blobs='" UINT32_FORMAT "' nmethods='" UINT32_FORMAT "'"
|
CodeCache::log_state(tty); tty->cr();
|
||||||
" adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'",
|
|
||||||
CodeCache::nof_blobs(), CodeCache::nof_nmethods(), CodeCache::nof_adapters(), CodeCache::unallocated_capacity());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LogCompilation && (xtty != NULL)) {
|
if (LogCompilation && (xtty != NULL)) {
|
||||||
@ -440,9 +438,7 @@ void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) {
|
|||||||
xtty->vprint(format, ap);
|
xtty->vprint(format, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
xtty->print(" total_blobs='" UINT32_FORMAT "' nmethods='" UINT32_FORMAT "'"
|
CodeCache::log_state(xtty);
|
||||||
" adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'",
|
|
||||||
CodeCache::nof_blobs(), CodeCache::nof_nmethods(), CodeCache::nof_adapters(), CodeCache::unallocated_capacity());
|
|
||||||
xtty->stamp();
|
xtty->stamp();
|
||||||
xtty->end_elem();
|
xtty->end_elem();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user