8012322: Tiered: CompilationPolicy::can_be_compiled(CompLevel_all) mistakenly return false

Fri, 26 Apr 2013 07:21:41 -0700

author
iignatyev
date
Fri, 26 Apr 2013 07:21:41 -0700
changeset 5032
d1c9384eecb4
parent 5029
7b23cb975cf2
child 5033
93b8272814cf

8012322: Tiered: CompilationPolicy::can_be_compiled(CompLevel_all) mistakenly return false
Reviewed-by: kvn, vlivanov

src/share/vm/classfile/classLoader.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/compilationPolicy.cpp file | annotate | diff | comparison | revisions
test/compiler/whitebox/CompilerWhiteBoxTest.java file | annotate | diff | comparison | revisions
test/compiler/whitebox/MakeMethodNotCompilableTest.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/classfile/classLoader.cpp	Thu Apr 25 11:09:24 2013 -0700
     1.2 +++ b/src/share/vm/classfile/classLoader.cpp	Fri Apr 26 07:21:41 2013 -0700
     1.3 @@ -1345,9 +1345,10 @@
     1.4            tty->print_cr("CompileTheWorld (%d) : %s", _compile_the_world_class_counter, buffer);
     1.5            // Preload all classes to get around uncommon traps
     1.6            // Iterate over all methods in class
     1.7 +          int comp_level = CompilationPolicy::policy()->initial_compile_level();
     1.8            for (int n = 0; n < k->methods()->length(); n++) {
     1.9              methodHandle m (THREAD, k->methods()->at(n));
    1.10 -            if (CompilationPolicy::can_be_compiled(m)) {
    1.11 +            if (CompilationPolicy::can_be_compiled(m, comp_level)) {
    1.12  
    1.13                if (++_codecache_sweep_counter == CompileTheWorldSafepointInterval) {
    1.14                  // Give sweeper a chance to keep up with CTW
    1.15 @@ -1356,7 +1357,7 @@
    1.16                  _codecache_sweep_counter = 0;
    1.17                }
    1.18                // Force compilation
    1.19 -              CompileBroker::compile_method(m, InvocationEntryBci, CompilationPolicy::policy()->initial_compile_level(),
    1.20 +              CompileBroker::compile_method(m, InvocationEntryBci, comp_level,
    1.21                                              methodHandle(), 0, "CTW", THREAD);
    1.22                if (HAS_PENDING_EXCEPTION) {
    1.23                  clear_pending_exception_if_not_oom(CHECK);
     2.1 --- a/src/share/vm/runtime/compilationPolicy.cpp	Thu Apr 25 11:09:24 2013 -0700
     2.2 +++ b/src/share/vm/runtime/compilationPolicy.cpp	Fri Apr 26 07:21:41 2013 -0700
     2.3 @@ -109,6 +109,9 @@
     2.4  
     2.5  // Returns true if m is allowed to be compiled
     2.6  bool CompilationPolicy::can_be_compiled(methodHandle m, int comp_level) {
     2.7 +  // allow any levels for WhiteBox
     2.8 +  assert(WhiteBoxAPI || comp_level == CompLevel_all || is_compile(comp_level), "illegal compilation level");
     2.9 +
    2.10    if (m->is_abstract()) return false;
    2.11    if (DontCompileHugeMethods && m->code_size() > HugeMethodLimit) return false;
    2.12  
    2.13 @@ -122,7 +125,13 @@
    2.14      return false;
    2.15    }
    2.16    if (comp_level == CompLevel_all) {
    2.17 -    return !m->is_not_compilable(CompLevel_simple) && !m->is_not_compilable(CompLevel_full_optimization);
    2.18 +    if (TieredCompilation) {
    2.19 +      // enough to be compilable at any level for tiered
    2.20 +      return !m->is_not_compilable(CompLevel_simple) || !m->is_not_compilable(CompLevel_full_optimization);
    2.21 +    } else {
    2.22 +      // must be compilable at available level for non-tiered
    2.23 +      return !m->is_not_compilable(CompLevel_highest_tier);
    2.24 +    }
    2.25    } else if (is_compile(comp_level)) {
    2.26      return !m->is_not_compilable(comp_level);
    2.27    }
    2.28 @@ -436,7 +445,7 @@
    2.29    reset_counter_for_invocation_event(m);
    2.30    const char* comment = "count";
    2.31  
    2.32 -  if (is_compilation_enabled() && can_be_compiled(m)) {
    2.33 +  if (is_compilation_enabled() && can_be_compiled(m, comp_level)) {
    2.34      nmethod* nm = m->code();
    2.35      if (nm == NULL ) {
    2.36        CompileBroker::compile_method(m, InvocationEntryBci, comp_level, m, hot_count, comment, thread);
    2.37 @@ -449,7 +458,7 @@
    2.38    const int hot_count = m->backedge_count();
    2.39    const char* comment = "backedge_count";
    2.40  
    2.41 -  if (is_compilation_enabled() && !m->is_not_osr_compilable(comp_level) && can_be_compiled(m)) {
    2.42 +  if (is_compilation_enabled() && !m->is_not_osr_compilable(comp_level) && can_be_compiled(m, comp_level)) {
    2.43      CompileBroker::compile_method(m, bci, comp_level, m, hot_count, comment, thread);
    2.44      NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, comp_level, true));)
    2.45    }
    2.46 @@ -467,7 +476,7 @@
    2.47    reset_counter_for_invocation_event(m);
    2.48    const char* comment = "count";
    2.49  
    2.50 -  if (is_compilation_enabled() && m->code() == NULL && can_be_compiled(m)) {
    2.51 +  if (is_compilation_enabled() && m->code() == NULL && can_be_compiled(m, comp_level)) {
    2.52      ResourceMark rm(thread);
    2.53      frame       fr     = thread->last_frame();
    2.54      assert(fr.is_interpreted_frame(), "must be interpreted");
    2.55 @@ -505,7 +514,7 @@
    2.56    const int hot_count = m->backedge_count();
    2.57    const char* comment = "backedge_count";
    2.58  
    2.59 -  if (is_compilation_enabled() && !m->is_not_osr_compilable(comp_level) && can_be_compiled(m)) {
    2.60 +  if (is_compilation_enabled() && !m->is_not_osr_compilable(comp_level) && can_be_compiled(m, comp_level)) {
    2.61      CompileBroker::compile_method(m, bci, comp_level, m, hot_count, comment, thread);
    2.62      NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, comp_level, true));)
    2.63    }
    2.64 @@ -600,7 +609,7 @@
    2.65  
    2.66      // If the caller method is too big or something then we do not want to
    2.67      // compile it just to inline a method
    2.68 -    if (!can_be_compiled(next_m)) {
    2.69 +    if (!can_be_compiled(next_m, CompLevel_any)) {
    2.70        msg = "caller cannot be compiled";
    2.71        break;
    2.72      }
     3.1 --- a/test/compiler/whitebox/CompilerWhiteBoxTest.java	Thu Apr 25 11:09:24 2013 -0700
     3.2 +++ b/test/compiler/whitebox/CompilerWhiteBoxTest.java	Fri Apr 26 07:21:41 2013 -0700
     3.3 @@ -42,6 +42,11 @@
     3.4      protected static int COMP_LEVEL_NONE = 0;
     3.5      /** {@code CompLevel::CompLevel_any}, {@code CompLevel::CompLevel_all} */
     3.6      protected static int COMP_LEVEL_ANY = -1;
     3.7 +    /** {@code CompLevel::CompLevel_simple} -- C1 */
     3.8 +    protected static int COMP_LEVEL_SIMPLE = 1;
     3.9 +    /** {@code CompLevel::CompLevel_full_optimization} -- C2 or Shark */
    3.10 +    protected static int COMP_LEVEL_FULL_OPTIMIZATION = 4;
    3.11 +
    3.12      /** Instance of WhiteBox */
    3.13      protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
    3.14      /** Value of {@code -XX:CompileThreshold} */
    3.15 @@ -91,6 +96,17 @@
    3.16          return result == null ? defaultValue : result;
    3.17      }
    3.18  
    3.19 +    /** copy of is_c1_compile(int) from utilities/globalDefinitions.hpp */
    3.20 +    protected static boolean isC1Compile(int compLevel) {
    3.21 +        return (compLevel > COMP_LEVEL_NONE)
    3.22 +                && (compLevel < COMP_LEVEL_FULL_OPTIMIZATION);
    3.23 +    }
    3.24 +
    3.25 +    /** copy of is_c2_compile(int) from utilities/globalDefinitions.hpp */
    3.26 +    protected static boolean isC2Compile(int compLevel) {
    3.27 +        return compLevel == COMP_LEVEL_FULL_OPTIMIZATION;
    3.28 +    }
    3.29 +
    3.30      /** tested method */
    3.31      protected final Executable method;
    3.32      private final Callable<Integer> callable;
     4.1 --- a/test/compiler/whitebox/MakeMethodNotCompilableTest.java	Thu Apr 25 11:09:24 2013 -0700
     4.2 +++ b/test/compiler/whitebox/MakeMethodNotCompilableTest.java	Fri Apr 26 07:21:41 2013 -0700
     4.3 @@ -23,6 +23,7 @@
     4.4  
     4.5  /*
     4.6   * @test MakeMethodNotCompilableTest
     4.7 + * @bug 8012322
     4.8   * @library /testlibrary /testlibrary/whitebox
     4.9   * @build MakeMethodNotCompilableTest
    4.10   * @run main ClassFileInstaller sun.hotspot.WhiteBox
    4.11 @@ -67,28 +68,69 @@
    4.12          }
    4.13  
    4.14          if (TIERED_COMPILATION) {
    4.15 -            for (int i = 1, n = TIERED_STOP_AT_LEVEL + 1; i < n; ++i) {
    4.16 -                WHITE_BOX.makeMethodNotCompilable(method, i);
    4.17 -                if (WHITE_BOX.isMethodCompilable(method, i)) {
    4.18 +            final int tierLimit = TIERED_STOP_AT_LEVEL + 1;
    4.19 +            for (int testedTier = 1; testedTier < tierLimit; ++testedTier) {
    4.20 +                testTier(testedTier);
    4.21 +            }
    4.22 +            for (int testedTier = 1; testedTier < tierLimit; ++testedTier) {
    4.23 +                WHITE_BOX.makeMethodNotCompilable(method, testedTier);
    4.24 +                if (WHITE_BOX.isMethodCompilable(method, testedTier)) {
    4.25                      throw new RuntimeException(method
    4.26 -                            + " must be not compilable at level" + i);
    4.27 +                            + " must be not compilable at level" + testedTier);
    4.28                  }
    4.29 -                WHITE_BOX.enqueueMethodForCompilation(method, i);
    4.30 +                WHITE_BOX.enqueueMethodForCompilation(method, testedTier);
    4.31                  checkNotCompiled();
    4.32  
    4.33                  if (!WHITE_BOX.isMethodCompilable(method)) {
    4.34                      System.out.println(method
    4.35 -                            + " is not compilable after level " + i);
    4.36 +                            + " is not compilable after level " + testedTier);
    4.37                  }
    4.38              }
    4.39 +        } else {
    4.40 +            compile();
    4.41 +            checkCompiled();
    4.42 +            int compLevel = WHITE_BOX.getMethodCompilationLevel(method);
    4.43 +            WHITE_BOX.deoptimizeMethod(method);
    4.44 +            WHITE_BOX.makeMethodNotCompilable(method, compLevel);
    4.45 +            if (WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY)) {
    4.46 +                throw new RuntimeException(method
    4.47 +                        + " must be not compilable at CompLevel::CompLevel_any,"
    4.48 +                        + " after it is not compilable at " + compLevel);
    4.49 +            }
    4.50 +            WHITE_BOX.clearMethodState(method);
    4.51  
    4.52 -            // WB.clearMethodState() must reset no-compilable flags
    4.53 -            WHITE_BOX.clearMethodState(method);
    4.54 -            if (!WHITE_BOX.isMethodCompilable(method)) {
    4.55 -                throw new RuntimeException(method
    4.56 -                        + " is not compilable after clearMethodState()");
    4.57 +            // nocompilable at opposite level must make no sense
    4.58 +            int oppositeLevel;
    4.59 +            if (isC1Compile(compLevel)) {
    4.60 +              oppositeLevel = COMP_LEVEL_FULL_OPTIMIZATION;
    4.61 +            } else {
    4.62 +              oppositeLevel = COMP_LEVEL_SIMPLE;
    4.63 +            }
    4.64 +            WHITE_BOX.makeMethodNotCompilable(method, oppositeLevel);
    4.65 +
    4.66 +            if (!WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY)) {
    4.67 +                  throw new RuntimeException(method
    4.68 +                        + " must be compilable at CompLevel::CompLevel_any,"
    4.69 +                        + " even it is not compilable at opposite level ["
    4.70 +                        + compLevel + "]");
    4.71 +            }
    4.72 +
    4.73 +            if (!WHITE_BOX.isMethodCompilable(method, compLevel)) {
    4.74 +                  throw new RuntimeException(method
    4.75 +                        + " must be compilable at level " + compLevel
    4.76 +                        + ", even it is not compilable at opposite level ["
    4.77 +                        + compLevel + "]");
    4.78              }
    4.79          }
    4.80 +
    4.81 +        // clearing after tiered/non-tiered tests
    4.82 +        // WB.clearMethodState() must reset no-compilable flags
    4.83 +        WHITE_BOX.clearMethodState(method);
    4.84 +        if (!WHITE_BOX.isMethodCompilable(method)) {
    4.85 +            throw new RuntimeException(method
    4.86 +                    + " is not compilable after clearMethodState()");
    4.87 +        }
    4.88 +
    4.89          WHITE_BOX.makeMethodNotCompilable(method);
    4.90          if (WHITE_BOX.isMethodCompilable(method)) {
    4.91              throw new RuntimeException(method + " must be not compilable");
    4.92 @@ -108,4 +150,65 @@
    4.93          compile();
    4.94          checkCompiled();
    4.95      }
    4.96 +
    4.97 +    // separately tests each tier
    4.98 +    private void testTier(int testedTier) {
    4.99 +        if (!WHITE_BOX.isMethodCompilable(method, testedTier)) {
   4.100 +            throw new RuntimeException(method
   4.101 +                    + " is not compilable on start");
   4.102 +        }
   4.103 +        WHITE_BOX.makeMethodNotCompilable(method, testedTier);
   4.104 +
   4.105 +        // tests for all other tiers
   4.106 +        for (int anotherTier = 1, tierLimit = TIERED_STOP_AT_LEVEL + 1;
   4.107 +                    anotherTier < tierLimit; ++anotherTier) {
   4.108 +            boolean isCompilable = WHITE_BOX.isMethodCompilable(method,
   4.109 +                    anotherTier);
   4.110 +            if (sameCompile(testedTier, anotherTier)) {
   4.111 +                if (isCompilable) {
   4.112 +                    throw new RuntimeException(method
   4.113 +                            + " must be not compilable at level " + anotherTier
   4.114 +                            + ", if it is not compilable at " + testedTier);
   4.115 +                }
   4.116 +                WHITE_BOX.enqueueMethodForCompilation(method, anotherTier);
   4.117 +                checkNotCompiled();
   4.118 +            } else {
   4.119 +                if (!isCompilable) {
   4.120 +                    throw new RuntimeException(method
   4.121 +                            + " must be compilable at level " + anotherTier
   4.122 +                            + ", even if it is not compilable at "
   4.123 +                            + testedTier);
   4.124 +                }
   4.125 +                WHITE_BOX.enqueueMethodForCompilation(method, anotherTier);
   4.126 +                checkCompiled();
   4.127 +                WHITE_BOX.deoptimizeMethod(method);
   4.128 +            }
   4.129 +
   4.130 +            if (!WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY)) {
   4.131 +                throw new RuntimeException(method
   4.132 +                        + " must be compilable at 'CompLevel::CompLevel_any'"
   4.133 +                        + ", if it is not compilable only at " + testedTier);
   4.134 +            }
   4.135 +        }
   4.136 +
   4.137 +        // clear state after test
   4.138 +        WHITE_BOX.clearMethodState(method);
   4.139 +        if (!WHITE_BOX.isMethodCompilable(method, testedTier)) {
   4.140 +            throw new RuntimeException(method
   4.141 +                    + " is not compilable after clearMethodState()");
   4.142 +        }
   4.143 +    }
   4.144 +
   4.145 +    private boolean sameCompile(int level1, int level2) {
   4.146 +        if (level1 == level2) {
   4.147 +            return true;
   4.148 +        }
   4.149 +        if (isC1Compile(level1) && isC1Compile(level2)) {
   4.150 +            return true;
   4.151 +        }
   4.152 +        if (isC2Compile(level1) && isC2Compile(level2)) {
   4.153 +            return true;
   4.154 +        }
   4.155 +        return false;
   4.156 +    }
   4.157  }

mercurial