# HG changeset patch # User kvn # Date 1293648103 28800 # Node ID 12998f95a3345275b11234a81682f7e6b5925a72 # Parent f078cdefa6748f3fe535471c43f3e0c9fa134d69 7008325: CodeCache exhausted on sparc starting from hs20b04 Summary: remove clear_scratch_buffer_blob and let init_scratch_buffer_blob free and allocate a new blob if required. Reviewed-by: twisti diff -r f078cdefa674 -r 12998f95a334 hotspot/src/share/vm/code/codeCache.cpp --- a/hotspot/src/share/vm/code/codeCache.cpp Tue Dec 28 17:34:02 2010 -0800 +++ b/hotspot/src/share/vm/code/codeCache.cpp Wed Dec 29 10:41:43 2010 -0800 @@ -939,7 +939,9 @@ _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 + " largest_free_block=" SIZE_FORMAT, CodeCache::nof_blobs(), CodeCache::nof_nmethods(), - CodeCache::nof_adapters(), CodeCache::unallocated_capacity()); + CodeCache::nof_adapters(), CodeCache::unallocated_capacity(), + CodeCache::largest_free_block()); } diff -r f078cdefa674 -r 12998f95a334 hotspot/src/share/vm/code/codeCache.hpp --- a/hotspot/src/share/vm/code/codeCache.hpp Tue Dec 28 17:34:02 2010 -0800 +++ b/hotspot/src/share/vm/code/codeCache.hpp Wed Dec 29 10:41:43 2010 -0800 @@ -158,6 +158,7 @@ static size_t capacity() { return _heap->capacity(); } 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_cache_clean() { return _needs_cache_clean; } diff -r f078cdefa674 -r 12998f95a334 hotspot/src/share/vm/memory/heap.cpp --- a/hotspot/src/share/vm/memory/heap.cpp Tue Dec 28 17:34:02 2010 -0800 +++ b/hotspot/src/share/vm/memory/heap.cpp Wed Dec 29 10:41:43 2010 -0800 @@ -315,6 +315,15 @@ return l; } +size_t CodeHeap::largest_free_block() const { + size_t len = 0; + for (FreeBlock* b = _freelist; b != NULL; b = b->link()) { + if (b->length() > len) + len = b->length(); + } + return size(len); +} + // Free list management FreeBlock *CodeHeap::following_block(FreeBlock *b) { diff -r f078cdefa674 -r 12998f95a334 hotspot/src/share/vm/memory/heap.hpp --- a/hotspot/src/share/vm/memory/heap.hpp Tue Dec 28 17:34:02 2010 -0800 +++ b/hotspot/src/share/vm/memory/heap.hpp Wed Dec 29 10:41:43 2010 -0800 @@ -161,6 +161,7 @@ size_t max_capacity() const; size_t allocated_capacity() const; size_t unallocated_capacity() const { return max_capacity() - allocated_capacity(); } + size_t largest_free_block() const; // Debugging void verify(); diff -r f078cdefa674 -r 12998f95a334 hotspot/src/share/vm/opto/compile.cpp --- a/hotspot/src/share/vm/opto/compile.cpp Tue Dec 28 17:34:02 2010 -0800 +++ b/hotspot/src/share/vm/opto/compile.cpp Wed Dec 29 10:41:43 2010 -0800 @@ -444,22 +444,32 @@ } +//-----------------------init_scratch_buffer_blob------------------------------ +// Construct a temporary BufferBlob and cache it for this compile. void Compile::init_scratch_buffer_blob(int const_size) { - if (scratch_buffer_blob() != NULL) return; + // If there is already a scratch buffer blob allocated and the + // constant section is big enough, use it. Otherwise free the + // current and allocate a new one. + BufferBlob* blob = scratch_buffer_blob(); + if ((blob != NULL) && (const_size <= _scratch_const_size)) { + // Use the current blob. + } else { + if (blob != NULL) { + BufferBlob::free(blob); + } - // Construct a temporary CodeBuffer to have it construct a BufferBlob - // Cache this BufferBlob for this compile. - ResourceMark rm; - _scratch_const_size = const_size; - int size = (MAX_inst_size + MAX_stubs_size + _scratch_const_size); - BufferBlob* blob = BufferBlob::create("Compile::scratch_buffer", size); - // Record the buffer blob for next time. - set_scratch_buffer_blob(blob); - // Have we run out of code space? - if (scratch_buffer_blob() == NULL) { - // Let CompilerBroker disable further compilations. - record_failure("Not enough space for scratch buffer in CodeCache"); - return; + ResourceMark rm; + _scratch_const_size = const_size; + int size = (MAX_inst_size + MAX_stubs_size + _scratch_const_size); + blob = BufferBlob::create("Compile::scratch_buffer", size); + // Record the buffer blob for next time. + set_scratch_buffer_blob(blob); + // Have we run out of code space? + if (scratch_buffer_blob() == NULL) { + // Let CompilerBroker disable further compilations. + record_failure("Not enough space for scratch buffer in CodeCache"); + return; + } } // Initialize the relocation buffers @@ -468,13 +478,6 @@ } -void Compile::clear_scratch_buffer_blob() { - assert(scratch_buffer_blob(), "no BufferBlob set"); - set_scratch_buffer_blob(NULL); - set_scratch_locs_memory(NULL); -} - - //-----------------------scratch_emit_size------------------------------------- // Helper function that computes size by emitting code uint Compile::scratch_emit_size(const Node* n) { diff -r f078cdefa674 -r 12998f95a334 hotspot/src/share/vm/opto/output.cpp --- a/hotspot/src/share/vm/opto/output.cpp Tue Dec 28 17:34:02 2010 -0800 +++ b/hotspot/src/share/vm/opto/output.cpp Wed Dec 29 10:41:43 2010 -0800 @@ -1746,9 +1746,6 @@ // Walk backwards over each basic block, computing the needed alignment // Walk over all the basic blocks scheduling.DoScheduling(); - - // Clear the BufferBlob used for scheduling. - clear_scratch_buffer_blob(); } //------------------------------ComputeLocalLatenciesForward-------------------