7025742: Can not use CodeCache::unallocated_capacity() with fragmented CodeCache
Summary: Use largest_free_block() instead of unallocated_capacity().
Reviewed-by: iveresov, never, ysr
--- a/hotspot/src/share/vm/code/codeCache.cpp Sun Mar 06 22:09:23 2011 -0800
+++ b/hotspot/src/share/vm/code/codeCache.cpp Wed Mar 09 09:15:16 2011 -0800
@@ -939,9 +939,16 @@
_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());
+}
--- a/hotspot/src/share/vm/code/codeCache.hpp Sun Mar 06 22:09:23 2011 -0800
+++ b/hotspot/src/share/vm/code/codeCache.hpp Wed Mar 09 09:15:16 2011 -0800
@@ -147,6 +147,7 @@
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 @@
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; }
--- a/hotspot/src/share/vm/code/nmethod.cpp Sun Mar 06 22:09:23 2011 -0800
+++ b/hotspot/src/share/vm/code/nmethod.cpp Wed Mar 09 09:15:16 2011 -0800
@@ -762,7 +762,7 @@
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);
}
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp Sun Mar 06 22:09:23 2011 -0800
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Wed Mar 09 09:15:16 2011 -0800
@@ -1364,7 +1364,7 @@
// 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 @@
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());
--- a/hotspot/src/share/vm/memory/heap.cpp Sun Mar 06 22:09:23 2011 -0800
+++ b/hotspot/src/share/vm/memory/heap.cpp Wed Mar 09 09:15:16 2011 -0800
@@ -316,12 +316,19 @@
}
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
--- a/hotspot/src/share/vm/opto/output.cpp Sun Mar 06 22:09:23 2011 -0800
+++ b/hotspot/src/share/vm/opto/output.cpp Wed Mar 09 09:15:16 2011 -0800
@@ -1028,7 +1028,7 @@
// 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");
--- a/hotspot/src/share/vm/runtime/sweeper.cpp Sun Mar 06 22:09:23 2011 -0800
+++ b/hotspot/src/share/vm/runtime/sweeper.cpp Wed Mar 09 09:15:16 2011 -0800
@@ -426,9 +426,7 @@
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 @@
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();
}