# HG changeset patch # User thartmann # Date 1540886768 -3600 # Tue Oct 30 09:06:08 2018 +0100 # Node ID 21c4912c9c40ef324326ca905ec792533ca721c1 # Parent c02113ad7e6501bd917d2cd3b825312e227f8201 8177899: Tests fail due to code cache exhaustion on machines with many cores Summary: Implemented upper limit on CICompilerCount based on code cache size. Reviewed-by: kvn, mdoerr diff --git a/src/hotspot/share/c1/c1_Compiler.cpp b/src/hotspot/share/c1/c1_Compiler.cpp --- a/src/hotspot/share/c1/c1_Compiler.cpp +++ b/src/hotspot/share/c1/c1_Compiler.cpp @@ -79,7 +79,6 @@ } int Compiler::code_buffer_size() { - assert(SegmentedCodeCache, "Should be only used with a segmented code cache"); return Compilation::desired_max_code_buffer_size() + Compilation::desired_max_constant_size(); } @@ -90,10 +89,7 @@ // setup CodeBuffer. Preallocate a BufferBlob of size // NMethodSizeLimit plus some extra space for constants. - int code_buffer_size = Compilation::desired_max_code_buffer_size() + - Compilation::desired_max_constant_size(); - - BufferBlob* buffer_blob = BufferBlob::create("C1 temporary CodeBuffer", code_buffer_size); + BufferBlob* buffer_blob = BufferBlob::create("C1 temporary CodeBuffer", code_buffer_size()); if (buffer_blob != NULL) { CompilerThread::current()->set_buffer_blob(buffer_blob); } diff --git a/src/hotspot/share/code/codeCache.cpp b/src/hotspot/share/code/codeCache.cpp --- a/src/hotspot/share/code/codeCache.cpp +++ b/src/hotspot/share/code/codeCache.cpp @@ -274,10 +274,10 @@ } // Make sure we have enough space for VM internal code uint min_code_cache_size = CodeCacheMinimumUseSpace DEBUG_ONLY(* 3); - if (non_nmethod_size < (min_code_cache_size + code_buffers_size)) { + if (non_nmethod_size < min_code_cache_size) { vm_exit_during_initialization(err_msg( "Not enough space in non-nmethod code heap to run VM: " SIZE_FORMAT "K < " SIZE_FORMAT "K", - non_nmethod_size/K, (min_code_cache_size + code_buffers_size)/K)); + non_nmethod_size/K, min_code_cache_size/K)); } // Verify sizes and update flag values diff --git a/src/hotspot/share/opto/c2compiler.cpp b/src/hotspot/share/opto/c2compiler.cpp --- a/src/hotspot/share/opto/c2compiler.cpp +++ b/src/hotspot/share/opto/c2compiler.cpp @@ -616,7 +616,9 @@ return true; } -int C2Compiler::initial_code_buffer_size() { - assert(SegmentedCodeCache, "Should be only used with a segmented code cache"); - return Compile::MAX_inst_size + Compile::MAX_locs_size + initial_const_capacity; +int C2Compiler::initial_code_buffer_size(int const_size) { + // See Compile::init_scratch_buffer_blob + int locs_size = sizeof(relocInfo) * Compile::MAX_locs_size; + int slop = 2 * CodeSection::end_slop(); // space between sections + return Compile::MAX_inst_size + Compile::MAX_stubs_size + const_size + slop + locs_size; } diff --git a/src/hotspot/share/opto/c2compiler.hpp b/src/hotspot/share/opto/c2compiler.hpp --- a/src/hotspot/share/opto/c2compiler.hpp +++ b/src/hotspot/share/opto/c2compiler.hpp @@ -26,6 +26,7 @@ #define SHARE_VM_OPTO_C2COMPILER_HPP #include "compiler/abstractCompiler.hpp" +#include "opto/output.hpp" class C2Compiler : public AbstractCompiler { private: @@ -66,7 +67,7 @@ virtual bool is_intrinsic_supported(const methodHandle& method, bool is_virtual); // Initial size of the code buffer (may be increased at runtime) - static int initial_code_buffer_size(); + static int initial_code_buffer_size(int const_size = initial_const_capacity); }; #endif // SHARE_VM_OPTO_C2COMPILER_HPP diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp --- a/src/hotspot/share/opto/compile.cpp +++ b/src/hotspot/share/opto/compile.cpp @@ -544,7 +544,7 @@ ResourceMark rm; _scratch_const_size = const_size; - int size = (MAX_inst_size + MAX_stubs_size + _scratch_const_size); + int size = C2Compiler::initial_code_buffer_size(const_size); blob = BufferBlob::create("Compile::scratch_buffer", size); // Record the buffer blob for next time. set_scratch_buffer_blob(blob); diff --git a/src/hotspot/share/runtime/compilationPolicy.cpp b/src/hotspot/share/runtime/compilationPolicy.cpp --- a/src/hotspot/share/runtime/compilationPolicy.cpp +++ b/src/hotspot/share/runtime/compilationPolicy.cpp @@ -46,6 +46,13 @@ #include "utilities/events.hpp" #include "utilities/globalDefinitions.hpp" +#ifdef COMPILER1 +#include "c1/c1_Compiler.hpp" +#endif +#ifdef COMPILER2 +#include "opto/c2compiler.hpp" +#endif + CompilationPolicy* CompilationPolicy::_policy; elapsedTimer CompilationPolicy::_accumulated_time; bool CompilationPolicy::_in_vm_startup; @@ -222,6 +229,19 @@ // max(log2(8)-1,1) = 2 compiler threads on an 8-way machine. // May help big-app startup time. _compiler_count = MAX2(log2_int(os::active_processor_count())-1,1); + // Make sure there is enough space in the code cache to hold all the compiler buffers + size_t buffer_size = 1; +#ifdef COMPILER1 + buffer_size = is_client_compilation_mode_vm() ? Compiler::code_buffer_size() : buffer_size; +#endif +#ifdef COMPILER2 + buffer_size = is_server_compilation_mode_vm() ? C2Compiler::initial_code_buffer_size() : buffer_size; +#endif + int max_count = (ReservedCodeCacheSize - (CodeCacheMinimumUseSpace DEBUG_ONLY(* 3))) / (int)buffer_size; + if (_compiler_count > max_count) { + // Lower the compiler count such that all buffers fit into the code cache + _compiler_count = MAX2(max_count, 1); + } FLAG_SET_ERGO(intx, CICompilerCount, _compiler_count); } else { _compiler_count = CICompilerCount; diff --git a/src/hotspot/share/runtime/simpleThresholdPolicy.cpp b/src/hotspot/share/runtime/simpleThresholdPolicy.cpp --- a/src/hotspot/share/runtime/simpleThresholdPolicy.cpp +++ b/src/hotspot/share/runtime/simpleThresholdPolicy.cpp @@ -37,6 +37,9 @@ #ifdef TIERED +#include "c1/c1_Compiler.hpp" +#include "opto/c2compiler.hpp" + void SimpleThresholdPolicy::print_counters(const char* prefix, const methodHandle& mh) { int invocation_count = mh->invocation_count(); int backedge_count = mh->backedge_count(); @@ -141,6 +144,7 @@ void SimpleThresholdPolicy::initialize() { int count = CICompilerCount; + bool c1_only = TieredStopAtLevel < CompLevel_full_optimization; #ifdef _LP64 // Turn on ergonomic compiler count selection if (FLAG_IS_DEFAULT(CICompilerCountPerCPU) && FLAG_IS_DEFAULT(CICompilerCount)) { @@ -151,6 +155,15 @@ int log_cpu = log2_int(os::active_processor_count()); int loglog_cpu = log2_int(MAX2(log_cpu, 1)); count = MAX2(log_cpu * loglog_cpu * 3 / 2, 2); + // Make sure there is enough space in the code cache to hold all the compiler buffers + size_t c1_size = Compiler::code_buffer_size(); + size_t c2_size = C2Compiler::initial_code_buffer_size(); + size_t buffer_size = c1_only ? c1_size : (c1_size/3 + 2*c2_size/3); + int max_count = (ReservedCodeCacheSize - (CodeCacheMinimumUseSpace DEBUG_ONLY(* 3))) / (int)buffer_size; + if (count > max_count) { + // Lower the compiler count such that all buffers fit into the code cache + count = MAX2(max_count, c1_only ? 1 : 2); + } FLAG_SET_ERGO(intx, CICompilerCount, count); } #else @@ -167,7 +180,7 @@ } #endif - if (TieredStopAtLevel < CompLevel_full_optimization) { + if (c1_only) { // No C2 compiler thread required set_c1_count(count); } else {