8177899: Tests fail due to code cache exhaustion on machines with many cores
authorthartmann
Tue, 30 Oct 2018 09:06:08 +0100
changeset 52325 0451e0a2f1f5
parent 52324 0c5fc2063221
child 52326 77018c2b97df
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
src/hotspot/share/c1/c1_Compiler.cpp
src/hotspot/share/code/codeCache.cpp
src/hotspot/share/opto/c2compiler.cpp
src/hotspot/share/opto/c2compiler.hpp
src/hotspot/share/opto/compile.cpp
src/hotspot/share/runtime/compilationPolicy.cpp
src/hotspot/share/runtime/tieredThresholdPolicy.cpp
--- a/src/hotspot/share/c1/c1_Compiler.cpp	Mon Oct 29 17:11:46 2018 -0400
+++ b/src/hotspot/share/c1/c1_Compiler.cpp	Tue Oct 30 09:06:08 2018 +0100
@@ -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);
   }
--- a/src/hotspot/share/code/codeCache.cpp	Mon Oct 29 17:11:46 2018 -0400
+++ b/src/hotspot/share/code/codeCache.cpp	Tue Oct 30 09:06:08 2018 +0100
@@ -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
--- a/src/hotspot/share/opto/c2compiler.cpp	Mon Oct 29 17:11:46 2018 -0400
+++ b/src/hotspot/share/opto/c2compiler.cpp	Tue Oct 30 09:06:08 2018 +0100
@@ -604,7 +604,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;
 }
--- a/src/hotspot/share/opto/c2compiler.hpp	Mon Oct 29 17:11:46 2018 -0400
+++ b/src/hotspot/share/opto/c2compiler.hpp	Tue Oct 30 09:06:08 2018 +0100
@@ -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
--- a/src/hotspot/share/opto/compile.cpp	Mon Oct 29 17:11:46 2018 -0400
+++ b/src/hotspot/share/opto/compile.cpp	Tue Oct 30 09:06:08 2018 +0100
@@ -544,9 +544,7 @@
 
     ResourceMark rm;
     _scratch_const_size = const_size;
-    int locs_size = sizeof(relocInfo) * MAX_locs_size;
-    int slop = 2 * CodeSection::end_slop(); // space between sections
-    int size = (MAX_inst_size + MAX_stubs_size + _scratch_const_size + slop + locs_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);
--- a/src/hotspot/share/runtime/compilationPolicy.cpp	Mon Oct 29 17:11:46 2018 -0400
+++ b/src/hotspot/share/runtime/compilationPolicy.cpp	Tue Oct 30 09:06:08 2018 +0100
@@ -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_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);
   } else {
     _compiler_count = CICompilerCount;
--- a/src/hotspot/share/runtime/tieredThresholdPolicy.cpp	Mon Oct 29 17:11:46 2018 -0400
+++ b/src/hotspot/share/runtime/tieredThresholdPolicy.cpp	Tue Oct 30 09:06:08 2018 +0100
@@ -38,6 +38,9 @@
 
 #ifdef TIERED
 
+#include "c1/c1_Compiler.hpp"
+#include "opto/c2compiler.hpp"
+
 template<CompLevel level>
 bool TieredThresholdPolicy::call_predicate_helper(int i, int b, double scale, Method* method) {
   double threshold_scaling;
@@ -215,6 +218,7 @@
 
 void TieredThresholdPolicy::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)) {
@@ -225,6 +229,15 @@
     int log_cpu = log2_intptr(os::active_processor_count());
     int loglog_cpu = log2_intptr(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
@@ -241,7 +254,7 @@
   }
 #endif
 
-  if (TieredStopAtLevel < CompLevel_full_optimization) {
+  if (c1_only) {
     // No C2 compiler thread required
     set_c1_count(count);
   } else {