changeset 57570:410409d9eda1

8236050: Some compiler tests fail when executed with custom TieredLevel Summary: Make sure TieredStopAtLevel is properly supported for different compilation modes Reviewed-by: redestad, thartmann
author iveresov
date Tue, 07 Jan 2020 07:31:28 -0800
parents 2a5117972a35
children b567c4b48777
files src/hotspot/share/compiler/compilationPolicy.cpp src/hotspot/share/compiler/compilationPolicy.hpp src/hotspot/share/compiler/compilerDefinitions.cpp src/hotspot/share/compiler/compilerDefinitions.hpp src/hotspot/share/compiler/tieredThresholdPolicy.cpp src/hotspot/share/compiler/tieredThresholdPolicy.hpp test/hotspot/jtreg/compiler/tiered/TieredModesTest.java
diffstat 7 files changed, 142 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/compiler/compilationPolicy.cpp	Tue Jan 07 09:21:07 2020 -0500
+++ b/src/hotspot/share/compiler/compilationPolicy.cpp	Tue Jan 07 07:31:28 2020 -0800
@@ -104,7 +104,7 @@
       return;
     }
     CompileBroker::compile_method(selected_method, InvocationEntryBci,
-        CompilationPolicy::policy()->initial_compile_level(),
+        CompilationPolicy::policy()->initial_compile_level(selected_method),
         methodHandle(), 0, CompileTask::Reason_MustBeCompiled, CHECK);
   }
 }
--- a/src/hotspot/share/compiler/compilationPolicy.hpp	Tue Jan 07 09:21:07 2020 -0500
+++ b/src/hotspot/share/compiler/compilationPolicy.hpp	Tue Jan 07 07:31:28 2020 -0800
@@ -59,7 +59,7 @@
   static CompileTask* select_task_helper(CompileQueue* compile_queue);
 
   // Return initial compile level that is used with Xcomp
-  virtual CompLevel initial_compile_level() = 0;
+  virtual CompLevel initial_compile_level(const methodHandle& method) = 0;
   virtual int compiler_count(CompLevel comp_level) = 0;
   // main notification entry, return a pointer to an nmethod if the OSR is required,
   // returns NULL otherwise.
@@ -97,7 +97,7 @@
   void method_back_branch_event(const methodHandle& m, int bci, JavaThread* thread);
  public:
   SimpleCompPolicy() : _compiler_count(0) { }
-  virtual CompLevel initial_compile_level() { return CompLevel_highest_tier; }
+  virtual CompLevel initial_compile_level(const methodHandle& m) { return CompLevel_highest_tier; }
   virtual int compiler_count(CompLevel comp_level);
   virtual void do_safepoint_work();
   virtual void reprofile(ScopeDesc* trap_scope, bool is_osr);
--- a/src/hotspot/share/compiler/compilerDefinitions.cpp	Tue Jan 07 09:21:07 2020 -0500
+++ b/src/hotspot/share/compiler/compilerDefinitions.cpp	Tue Jan 07 07:31:28 2020 -0800
@@ -57,9 +57,6 @@
       jio_fprintf(defaultStream::error_stream(), "Unsupported compilation mode '%s', supported modes are: quick-only, high-only, high-only-quick-internal\n", CompilationMode);
       return false;
     }
-    if (disable_intermediate()) {
-      CompLevel_initial_compile = CompLevel_full_optimization;
-    }
   }
   return true;
 }
@@ -74,16 +71,6 @@
 CompLevel  CompLevel_highest_tier      = CompLevel_none;
 #endif
 
-#if defined(TIERED)
-CompLevel  CompLevel_initial_compile   = CompLevel_full_profile;        // tiered
-#elif defined(COMPILER1) || INCLUDE_JVMCI
-CompLevel  CompLevel_initial_compile   = CompLevel_simple;              // pure C1 or JVMCI
-#elif defined(COMPILER2)
-CompLevel  CompLevel_initial_compile   = CompLevel_full_optimization;   // pure C2
-#else
-CompLevel  CompLevel_initial_compile   = CompLevel_none;
-#endif
-
 #if defined(COMPILER2)
 CompMode  Compilation_mode             = CompMode_server;
 #elif defined(COMPILER1)
@@ -145,7 +132,6 @@
 void set_client_compilation_mode() {
   Compilation_mode = CompMode_client;
   CompLevel_highest_tier = CompLevel_simple;
-  CompLevel_initial_compile = CompLevel_simple;
   FLAG_SET_ERGO(TieredCompilation, false);
   FLAG_SET_ERGO(ProfileInterpreter, false);
 #if INCLUDE_JVMCI
--- a/src/hotspot/share/compiler/compilerDefinitions.hpp	Tue Jan 07 09:21:07 2020 -0500
+++ b/src/hotspot/share/compiler/compilerDefinitions.hpp	Tue Jan 07 07:31:28 2020 -0800
@@ -83,7 +83,6 @@
 #endif
 
 extern CompLevel CompLevel_highest_tier;
-extern CompLevel CompLevel_initial_compile;
 
 enum CompMode {
   CompMode_none = 0,
--- a/src/hotspot/share/compiler/tieredThresholdPolicy.cpp	Tue Jan 07 09:21:07 2020 -0500
+++ b/src/hotspot/share/compiler/tieredThresholdPolicy.cpp	Tue Jan 07 07:31:28 2020 -0800
@@ -307,6 +307,78 @@
   set_start_time(os::javaTimeMillis());
 }
 
+
+#ifdef ASSERT
+bool TieredThresholdPolicy::verify_level(CompLevel level) {
+  // AOT and interpreter levels are always valid.
+  if (level == CompLevel_aot || level == CompLevel_none) {
+    return true;
+  }
+  if (CompilationModeFlag::normal()) {
+    return true;
+  } else if (CompilationModeFlag::quick_only()) {
+    return level == CompLevel_simple;
+  } else if (CompilationModeFlag::high_only()) {
+    return level == CompLevel_full_optimization;
+  } else if (CompilationModeFlag::high_only_quick_internal()) {
+    return level == CompLevel_full_optimization || level == CompLevel_simple;
+  }
+  return false;
+}
+#endif
+
+
+CompLevel TieredThresholdPolicy::limit_level(CompLevel level) {
+  if (CompilationModeFlag::quick_only()) {
+    level = MIN2(level, CompLevel_simple);
+  }
+  assert(verify_level(level), "Invalid compilation level %d", level);
+  if (level <= TieredStopAtLevel) {
+    return level;
+  }
+  // Some compilation levels are not valid depending on a compilation mode:
+  // a) quick_only - levels 2,3,4 are invalid; levels -1,0,1 are valid;
+  // b) high_only - levels 1,2,3 are invalid; levels -1,0,4 are valid;
+  // c) high_only_quick_internal - levels 2,3 are invalid; levels -1,0,1,4 are valid.
+  // The invalid levels are actually sequential so a single comparison is sufficient.
+  // Down here we already have (level > TieredStopAtLevel), which also implies that
+  // (TieredStopAtLevel < Highest Possible Level), so we need to return a level that is:
+  // a) a max level that is strictly less than the highest for a given compilation mode
+  // b) less or equal to TieredStopAtLevel
+  if (CompilationModeFlag::normal() || CompilationModeFlag::quick_only()) {
+    return (CompLevel)TieredStopAtLevel;
+  }
+
+  if (CompilationModeFlag::high_only() || CompilationModeFlag::high_only_quick_internal()) {
+    return MIN2(CompLevel_none, (CompLevel)TieredStopAtLevel);
+  }
+
+  ShouldNotReachHere();
+  return CompLevel_any;
+}
+
+CompLevel TieredThresholdPolicy::initial_compile_level_helper(const methodHandle& method) {
+  if (CompilationModeFlag::normal()) {
+    return CompLevel_full_profile;
+  } else if (CompilationModeFlag::quick_only()) {
+    return CompLevel_simple;
+  } else if (CompilationModeFlag::high_only()) {
+    return CompLevel_full_optimization;
+  } else if (CompilationModeFlag::high_only_quick_internal()) {
+    if (force_comp_at_level_simple(method)) {
+      return CompLevel_simple;
+    } else {
+      return CompLevel_full_optimization;
+    }
+  }
+  ShouldNotReachHere();
+  return CompLevel_any;
+}
+
+CompLevel TieredThresholdPolicy::initial_compile_level(const methodHandle& method) {
+  return limit_level(initial_compile_level_helper(method));
+}
+
 void TieredThresholdPolicy::set_carry_if_necessary(InvocationCounter *counter) {
   if (!counter->carry() && counter->count() > InvocationCounter::count_limit / 2) {
     counter->set_carry_flag();
@@ -457,12 +529,7 @@
 
 // Check if the method can be compiled, change level if necessary
 void TieredThresholdPolicy::compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread) {
-  assert(level <= TieredStopAtLevel, "Invalid compilation level");
-  if (CompilationModeFlag::quick_only()) {
-    assert(level <= CompLevel_simple, "Invalid compilation level");
-  } else if (CompilationModeFlag::disable_intermediate()) {
-    assert(level != CompLevel_full_profile && level != CompLevel_limited_profile, "C1 profiling levels shouldn't be used with intermediate levels disabled");
-  }
+  assert(verify_level(level) && level <= TieredStopAtLevel, "Invalid compilation level %d", level);
 
   if (level == CompLevel_none) {
     if (mh->has_compiled_code()) {
@@ -924,9 +991,11 @@
       }
     }
   }
-  return MIN2(next_level, CompilationModeFlag::quick_only() ? CompLevel_simple : (CompLevel)TieredStopAtLevel);
+  return limit_level(next_level);
 }
 
+
+
 // Determine if a method should be compiled with a normal entry point at a different level.
 CompLevel TieredThresholdPolicy::call_event(const methodHandle& method, CompLevel cur_level, JavaThread* thread) {
   CompLevel osr_level = MIN2((CompLevel) method->highest_osr_comp_level(),
@@ -1027,7 +1096,7 @@
       if (level == CompLevel_aot) {
         // Recompile the enclosing method to prevent infinite OSRs. Stay at AOT level while it's compiling.
         if (max_osr_level != CompLevel_none && !CompileBroker::compilation_is_in_queue(mh)) {
-          CompLevel enclosing_level = MIN2(CompilationModeFlag::quick_only() ? CompLevel_simple : (CompLevel)TieredStopAtLevel, CompLevel_full_profile);
+          CompLevel enclosing_level = limit_level(CompLevel_full_profile);
           compile(mh, InvocationEntryBci, enclosing_level, thread);
         }
       } else {
--- a/src/hotspot/share/compiler/tieredThresholdPolicy.hpp	Tue Jan 07 09:21:07 2020 -0500
+++ b/src/hotspot/share/compiler/tieredThresholdPolicy.hpp	Tue Jan 07 07:31:28 2020 -0800
@@ -170,8 +170,14 @@
   inline void set_carry_if_necessary(InvocationCounter *counter);
   // Set carry flags in the counters (in Method* and MDO).
   inline void handle_counter_overflow(Method* method);
+  // Verify that a level is consistent with the compilation mode
+  bool verify_level(CompLevel level);
+  // Clamp the request level according to various constraints.
+  inline CompLevel limit_level(CompLevel level);
+  // Return desired initial compilation level for Xcomp
+  CompLevel initial_compile_level_helper(const methodHandle& method);
   // Call and loop predicates determine whether a transition to a higher compilation
-  // level should be performed (pointers to predicate functions are passed to common_TF().
+  // level should be performed (pointers to predicate functions are passed to common().
   // Predicates also take compiler load into account.
   typedef bool (TieredThresholdPolicy::*Predicate)(int i, int b, CompLevel cur_level, const methodHandle& method);
   bool call_predicate(int i, int b, CompLevel cur_level, const methodHandle& method);
@@ -253,7 +259,8 @@
     if (is_c2_compile(comp_level)) return c2_count();
     return 0;
   }
-  virtual CompLevel initial_compile_level() { return MIN2((CompLevel)TieredStopAtLevel, CompLevel_initial_compile); }
+  // Return initial compile level to use with Xcomp (depends on compilation mode).
+  virtual CompLevel initial_compile_level(const methodHandle& method);
   virtual void do_safepoint_work() { }
   virtual void delay_compilation(Method* method) { }
   virtual void disable_compilation(Method* method) { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/tiered/TieredModesTest.java	Tue Jan 07 07:31:28 2020 -0800
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test TieredModesTest
+ * @summary Check that non-default tiered compilation modes tolerate invalid TieredStopAtLevel values
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *
+ * @run main/othervm -XX:+TieredCompilation -XX:CompilationMode=quick-only -XX:TieredStopAtLevel=3
+ *                   -XX:CompileCommand=compileonly,compiler.tiered.TieredModesTest::test
+ *                   compiler.tiered.TieredModesTest
+ * @run main/othervm -XX:+TieredCompilation -XX:CompilationMode=high-only -XX:TieredStopAtLevel=3
+ *                   -XX:CompileCommand=compileonly,compiler.tiered.TieredModesTest::test
+ *                   compiler.tiered.TieredModesTest
+ * @run main/othervm -XX:+TieredCompilation -XX:CompilationMode=high-only-quick-internal -XX:TieredStopAtLevel=3
+ *                   -XX:CompileCommand=compileonly,compiler.tiered.TieredModesTest::test
+ *                   compiler.tiered.TieredModesTest
+ */
+
+package compiler.tiered;
+
+public class TieredModesTest {
+    public static int sideEffect = 0;
+    private static void test() {
+      sideEffect++;
+    }
+    public static void main(String... args) {
+      for (int i = 0; i < 100_000; i++) {
+        test();
+      }
+    }
+}