From 9474ff7bf7844844e6a082dd4d9f9bba4816ce18 Mon Sep 17 00:00:00 2001 From: kvn Date: Wed, 9 Mar 2011 09:15:16 -0800 Subject: [PATCH] 7025742: Can not use CodeCache::unallocated_capacity() with fragmented CodeCache Summary: Use largest_free_block() instead of unallocated_capacity(). Reviewed-by: iveresov, never, ysr --- src/share/vm/code/codeCache.cpp | 15 +++++++++++---- src/share/vm/code/codeCache.hpp | 3 ++- src/share/vm/code/nmethod.cpp | 2 +- src/share/vm/compiler/compileBroker.cpp | 4 +++- src/share/vm/memory/heap.cpp | 9 ++++++++- src/share/vm/opto/output.cpp | 2 +- src/share/vm/runtime/sweeper.cpp | 8 ++------ 7 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/share/vm/code/codeCache.cpp b/src/share/vm/code/codeCache.cpp index db35aea6e..ebed49bd7 100644 --- a/src/share/vm/code/codeCache.cpp +++ b/src/share/vm/code/codeCache.cpp @@ -939,9 +939,16 @@ void CodeCache::print_bounds(outputStream* st) { _heap->high(), _heap->high_boundary()); 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, - CodeCache::nof_blobs(), CodeCache::nof_nmethods(), - CodeCache::nof_adapters(), CodeCache::unallocated_capacity(), - CodeCache::largest_free_block()); + nof_blobs(), nof_nmethods(), nof_adapters(), + unallocated_capacity()/K, 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()); } diff --git a/src/share/vm/code/codeCache.hpp b/src/share/vm/code/codeCache.hpp index df8de7f3f..a467a4020 100644 --- a/src/share/vm/code/codeCache.hpp +++ b/src/share/vm/code/codeCache.hpp @@ -147,6 +147,7 @@ class CodeCache : AllStatic { static void verify(); // verifies the code cache 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 log_state(outputStream* st); // The full limits of the codeCache 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 unallocated_capacity() { return _heap->unallocated_capacity(); } 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 void set_needs_cache_clean(bool v) { _needs_cache_clean = v; } diff --git a/src/share/vm/code/nmethod.cpp b/src/share/vm/code/nmethod.cpp index d401ddc62..7be605042 100644 --- a/src/share/vm/code/nmethod.cpp +++ b/src/share/vm/code/nmethod.cpp @@ -762,7 +762,7 @@ nmethod::nmethod( void* nmethod::operator new(size_t size, int nmethod_size) { // 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); } diff --git a/src/share/vm/compiler/compileBroker.cpp b/src/share/vm/compiler/compileBroker.cpp index d12385f2f..0d90e11d2 100644 --- a/src/share/vm/compiler/compileBroker.cpp +++ b/src/share/vm/compiler/compileBroker.cpp @@ -1364,7 +1364,7 @@ void CompileBroker::compiler_thread_loop() { // We need this HandleMark to avoid leaking VM handles. HandleMark hm(thread); - if (CodeCache::unallocated_capacity() < CodeCacheMinimumFreeSpace) { + if (CodeCache::largest_free_block() < CodeCacheMinimumFreeSpace) { // the code cache is really full handle_full_code_cache(); } else if (UseCodeCacheFlushing && CodeCache::needs_flushing()) { @@ -1645,11 +1645,13 @@ void CompileBroker::handle_full_code_cache() { if (UseCompiler || AlwaysCompileLoopMethods ) { if (xtty != NULL) { xtty->begin_elem("code_cache_full"); + CodeCache::log_state(xtty); xtty->stamp(); xtty->end_elem(); } warning("CodeCache is full. Compiler has been disabled."); warning("Try increasing the code cache size using -XX:ReservedCodeCacheSize="); + CodeCache::print_bounds(tty); #ifndef PRODUCT if (CompileTheWorld || ExitOnFullCodeCache) { before_exit(JavaThread::current()); diff --git a/src/share/vm/memory/heap.cpp b/src/share/vm/memory/heap.cpp index 94676f78d..2d46b6112 100644 --- a/src/share/vm/memory/heap.cpp +++ b/src/share/vm/memory/heap.cpp @@ -316,12 +316,19 @@ size_t CodeHeap::allocated_capacity() 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; for (FreeBlock* b = _freelist; b != NULL; b = b->link()) { if (b->length() > len) len = b->length(); } - return size(len); + return MAX2(unused, size(len)); } // Free list management diff --git a/src/share/vm/opto/output.cpp b/src/share/vm/opto/output.cpp index de2942316..a57508b41 100644 --- a/src/share/vm/opto/output.cpp +++ b/src/share/vm/opto/output.cpp @@ -1028,7 +1028,7 @@ void NonSafepointEmitter::emit_non_safepoint() { // helper for Fill_buffer bailout logic 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 // blown the code cache size. C->record_failure("excessive request to CodeCache"); diff --git a/src/share/vm/runtime/sweeper.cpp b/src/share/vm/runtime/sweeper.cpp index 94ee13145..c845b1761 100644 --- a/src/share/vm/runtime/sweeper.cpp +++ b/src/share/vm/runtime/sweeper.cpp @@ -426,9 +426,7 @@ void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) { tty->vprint(format, ap); va_end(ap); } - tty->print_cr(" total_blobs='" UINT32_FORMAT "' nmethods='" UINT32_FORMAT "'" - " adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", - CodeCache::nof_blobs(), CodeCache::nof_nmethods(), CodeCache::nof_adapters(), CodeCache::unallocated_capacity()); + CodeCache::log_state(tty); tty->cr(); } if (LogCompilation && (xtty != NULL)) { @@ -440,9 +438,7 @@ void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) { xtty->vprint(format, ap); va_end(ap); } - xtty->print(" total_blobs='" UINT32_FORMAT "' nmethods='" UINT32_FORMAT "'" - " adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", - CodeCache::nof_blobs(), CodeCache::nof_nmethods(), CodeCache::nof_adapters(), CodeCache::unallocated_capacity()); + CodeCache::log_state(xtty); xtty->stamp(); xtty->end_elem(); } -- GitLab