8177899: Tests fail due to code cache exhaustion on machines with many cores
Implemented upper limit on CICompilerCount based on code cache size. Reviewed-by: kvn, mdoerr
This commit is contained in:
parent
d9d067369b
commit
4b27547977
@ -79,7 +79,6 @@ void Compiler::initialize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Compiler::code_buffer_size() {
|
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();
|
return Compilation::desired_max_code_buffer_size() + Compilation::desired_max_constant_size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,10 +89,7 @@ BufferBlob* Compiler::init_buffer_blob() {
|
|||||||
|
|
||||||
// setup CodeBuffer. Preallocate a BufferBlob of size
|
// setup CodeBuffer. Preallocate a BufferBlob of size
|
||||||
// NMethodSizeLimit plus some extra space for constants.
|
// NMethodSizeLimit plus some extra space for constants.
|
||||||
int code_buffer_size = Compilation::desired_max_code_buffer_size() +
|
BufferBlob* buffer_blob = BufferBlob::create("C1 temporary CodeBuffer", code_buffer_size());
|
||||||
Compilation::desired_max_constant_size();
|
|
||||||
|
|
||||||
BufferBlob* buffer_blob = BufferBlob::create("C1 temporary CodeBuffer", code_buffer_size);
|
|
||||||
if (buffer_blob != NULL) {
|
if (buffer_blob != NULL) {
|
||||||
CompilerThread::current()->set_buffer_blob(buffer_blob);
|
CompilerThread::current()->set_buffer_blob(buffer_blob);
|
||||||
}
|
}
|
||||||
|
@ -274,10 +274,10 @@ void CodeCache::initialize_heaps() {
|
|||||||
}
|
}
|
||||||
// Make sure we have enough space for VM internal code
|
// Make sure we have enough space for VM internal code
|
||||||
uint min_code_cache_size = CodeCacheMinimumUseSpace DEBUG_ONLY(* 3);
|
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(
|
vm_exit_during_initialization(err_msg(
|
||||||
"Not enough space in non-nmethod code heap to run VM: " SIZE_FORMAT "K < " SIZE_FORMAT "K",
|
"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
|
// Verify sizes and update flag values
|
||||||
|
@ -604,7 +604,9 @@ bool C2Compiler::is_intrinsic_supported(const methodHandle& method, bool is_virt
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int C2Compiler::initial_code_buffer_size() {
|
int C2Compiler::initial_code_buffer_size(int const_size) {
|
||||||
assert(SegmentedCodeCache, "Should be only used with a segmented code cache");
|
// See Compile::init_scratch_buffer_blob
|
||||||
return Compile::MAX_inst_size + Compile::MAX_locs_size + initial_const_capacity;
|
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;
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#define SHARE_VM_OPTO_C2COMPILER_HPP
|
#define SHARE_VM_OPTO_C2COMPILER_HPP
|
||||||
|
|
||||||
#include "compiler/abstractCompiler.hpp"
|
#include "compiler/abstractCompiler.hpp"
|
||||||
|
#include "opto/output.hpp"
|
||||||
|
|
||||||
class C2Compiler : public AbstractCompiler {
|
class C2Compiler : public AbstractCompiler {
|
||||||
private:
|
private:
|
||||||
@ -66,7 +67,7 @@ public:
|
|||||||
virtual bool is_intrinsic_supported(const methodHandle& method, bool is_virtual);
|
virtual bool is_intrinsic_supported(const methodHandle& method, bool is_virtual);
|
||||||
|
|
||||||
// Initial size of the code buffer (may be increased at runtime)
|
// 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
|
#endif // SHARE_VM_OPTO_C2COMPILER_HPP
|
||||||
|
@ -544,9 +544,7 @@ void Compile::init_scratch_buffer_blob(int const_size) {
|
|||||||
|
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
_scratch_const_size = const_size;
|
_scratch_const_size = const_size;
|
||||||
int locs_size = sizeof(relocInfo) * MAX_locs_size;
|
int size = C2Compiler::initial_code_buffer_size(const_size);
|
||||||
int slop = 2 * CodeSection::end_slop(); // space between sections
|
|
||||||
int size = (MAX_inst_size + MAX_stubs_size + _scratch_const_size + slop + locs_size);
|
|
||||||
blob = BufferBlob::create("Compile::scratch_buffer", size);
|
blob = BufferBlob::create("Compile::scratch_buffer", size);
|
||||||
// Record the buffer blob for next time.
|
// Record the buffer blob for next time.
|
||||||
set_scratch_buffer_blob(blob);
|
set_scratch_buffer_blob(blob);
|
||||||
|
@ -46,6 +46,13 @@
|
|||||||
#include "utilities/events.hpp"
|
#include "utilities/events.hpp"
|
||||||
#include "utilities/globalDefinitions.hpp"
|
#include "utilities/globalDefinitions.hpp"
|
||||||
|
|
||||||
|
#ifdef COMPILER1
|
||||||
|
#include "c1/c1_Compiler.hpp"
|
||||||
|
#endif
|
||||||
|
#ifdef COMPILER2
|
||||||
|
#include "opto/c2compiler.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
CompilationPolicy* CompilationPolicy::_policy;
|
CompilationPolicy* CompilationPolicy::_policy;
|
||||||
elapsedTimer CompilationPolicy::_accumulated_time;
|
elapsedTimer CompilationPolicy::_accumulated_time;
|
||||||
bool CompilationPolicy::_in_vm_startup;
|
bool CompilationPolicy::_in_vm_startup;
|
||||||
@ -222,6 +229,19 @@ void NonTieredCompPolicy::initialize() {
|
|||||||
// max(log2(8)-1,1) = 2 compiler threads on an 8-way machine.
|
// max(log2(8)-1,1) = 2 compiler threads on an 8-way machine.
|
||||||
// May help big-app startup time.
|
// May help big-app startup time.
|
||||||
_compiler_count = MAX2(log2_intptr(os::active_processor_count())-1,1);
|
_compiler_count = MAX2(log2_intptr(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);
|
FLAG_SET_ERGO(intx, CICompilerCount, _compiler_count);
|
||||||
} else {
|
} else {
|
||||||
_compiler_count = CICompilerCount;
|
_compiler_count = CICompilerCount;
|
||||||
|
@ -38,6 +38,9 @@
|
|||||||
|
|
||||||
#ifdef TIERED
|
#ifdef TIERED
|
||||||
|
|
||||||
|
#include "c1/c1_Compiler.hpp"
|
||||||
|
#include "opto/c2compiler.hpp"
|
||||||
|
|
||||||
template<CompLevel level>
|
template<CompLevel level>
|
||||||
bool TieredThresholdPolicy::call_predicate_helper(int i, int b, double scale, Method* method) {
|
bool TieredThresholdPolicy::call_predicate_helper(int i, int b, double scale, Method* method) {
|
||||||
double threshold_scaling;
|
double threshold_scaling;
|
||||||
@ -215,6 +218,7 @@ void TieredThresholdPolicy::print_event(EventType type, const methodHandle& mh,
|
|||||||
|
|
||||||
void TieredThresholdPolicy::initialize() {
|
void TieredThresholdPolicy::initialize() {
|
||||||
int count = CICompilerCount;
|
int count = CICompilerCount;
|
||||||
|
bool c1_only = TieredStopAtLevel < CompLevel_full_optimization;
|
||||||
#ifdef _LP64
|
#ifdef _LP64
|
||||||
// Turn on ergonomic compiler count selection
|
// Turn on ergonomic compiler count selection
|
||||||
if (FLAG_IS_DEFAULT(CICompilerCountPerCPU) && FLAG_IS_DEFAULT(CICompilerCount)) {
|
if (FLAG_IS_DEFAULT(CICompilerCountPerCPU) && FLAG_IS_DEFAULT(CICompilerCount)) {
|
||||||
@ -225,6 +229,15 @@ void TieredThresholdPolicy::initialize() {
|
|||||||
int log_cpu = log2_intptr(os::active_processor_count());
|
int log_cpu = log2_intptr(os::active_processor_count());
|
||||||
int loglog_cpu = log2_intptr(MAX2(log_cpu, 1));
|
int loglog_cpu = log2_intptr(MAX2(log_cpu, 1));
|
||||||
count = MAX2(log_cpu * loglog_cpu * 3 / 2, 2);
|
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);
|
FLAG_SET_ERGO(intx, CICompilerCount, count);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -241,7 +254,7 @@ void TieredThresholdPolicy::initialize() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (TieredStopAtLevel < CompLevel_full_optimization) {
|
if (c1_only) {
|
||||||
// No C2 compiler thread required
|
// No C2 compiler thread required
|
||||||
set_c1_count(count);
|
set_c1_count(count);
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user