提交 bc68b212 编写于 作者: V vlivanov

Merge

......@@ -1345,9 +1345,10 @@ void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) {
tty->print_cr("CompileTheWorld (%d) : %s", _compile_the_world_class_counter, buffer);
// Preload all classes to get around uncommon traps
// Iterate over all methods in class
int comp_level = CompilationPolicy::policy()->initial_compile_level();
for (int n = 0; n < k->methods()->length(); n++) {
methodHandle m (THREAD, k->methods()->at(n));
if (CompilationPolicy::can_be_compiled(m)) {
if (CompilationPolicy::can_be_compiled(m, comp_level)) {
if (++_codecache_sweep_counter == CompileTheWorldSafepointInterval) {
// Give sweeper a chance to keep up with CTW
......@@ -1356,7 +1357,7 @@ void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) {
_codecache_sweep_counter = 0;
}
// Force compilation
CompileBroker::compile_method(m, InvocationEntryBci, CompilationPolicy::policy()->initial_compile_level(),
CompileBroker::compile_method(m, InvocationEntryBci, comp_level,
methodHandle(), 0, "CTW", THREAD);
if (HAS_PENDING_EXCEPTION) {
clear_pending_exception_if_not_oom(CHECK);
......
......@@ -109,6 +109,9 @@ bool CompilationPolicy::must_be_compiled(methodHandle m, int comp_level) {
// Returns true if m is allowed to be compiled
bool CompilationPolicy::can_be_compiled(methodHandle m, int comp_level) {
// allow any levels for WhiteBox
assert(WhiteBoxAPI || comp_level == CompLevel_all || is_compile(comp_level), "illegal compilation level");
if (m->is_abstract()) return false;
if (DontCompileHugeMethods && m->code_size() > HugeMethodLimit) return false;
......@@ -122,7 +125,13 @@ bool CompilationPolicy::can_be_compiled(methodHandle m, int comp_level) {
return false;
}
if (comp_level == CompLevel_all) {
return !m->is_not_compilable(CompLevel_simple) && !m->is_not_compilable(CompLevel_full_optimization);
if (TieredCompilation) {
// enough to be compilable at any level for tiered
return !m->is_not_compilable(CompLevel_simple) || !m->is_not_compilable(CompLevel_full_optimization);
} else {
// must be compilable at available level for non-tiered
return !m->is_not_compilable(CompLevel_highest_tier);
}
} else if (is_compile(comp_level)) {
return !m->is_not_compilable(comp_level);
}
......@@ -436,7 +445,7 @@ void SimpleCompPolicy::method_invocation_event(methodHandle m, JavaThread* threa
reset_counter_for_invocation_event(m);
const char* comment = "count";
if (is_compilation_enabled() && can_be_compiled(m)) {
if (is_compilation_enabled() && can_be_compiled(m, comp_level)) {
nmethod* nm = m->code();
if (nm == NULL ) {
CompileBroker::compile_method(m, InvocationEntryBci, comp_level, m, hot_count, comment, thread);
......@@ -449,7 +458,7 @@ void SimpleCompPolicy::method_back_branch_event(methodHandle m, int bci, JavaThr
const int hot_count = m->backedge_count();
const char* comment = "backedge_count";
if (is_compilation_enabled() && !m->is_not_osr_compilable(comp_level) && can_be_compiled(m)) {
if (is_compilation_enabled() && !m->is_not_osr_compilable(comp_level) && can_be_compiled(m, comp_level)) {
CompileBroker::compile_method(m, bci, comp_level, m, hot_count, comment, thread);
NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, comp_level, true));)
}
......@@ -467,7 +476,7 @@ void StackWalkCompPolicy::method_invocation_event(methodHandle m, JavaThread* th
reset_counter_for_invocation_event(m);
const char* comment = "count";
if (is_compilation_enabled() && m->code() == NULL && can_be_compiled(m)) {
if (is_compilation_enabled() && m->code() == NULL && can_be_compiled(m, comp_level)) {
ResourceMark rm(thread);
frame fr = thread->last_frame();
assert(fr.is_interpreted_frame(), "must be interpreted");
......@@ -505,7 +514,7 @@ void StackWalkCompPolicy::method_back_branch_event(methodHandle m, int bci, Java
const int hot_count = m->backedge_count();
const char* comment = "backedge_count";
if (is_compilation_enabled() && !m->is_not_osr_compilable(comp_level) && can_be_compiled(m)) {
if (is_compilation_enabled() && !m->is_not_osr_compilable(comp_level) && can_be_compiled(m, comp_level)) {
CompileBroker::compile_method(m, bci, comp_level, m, hot_count, comment, thread);
NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, comp_level, true));)
}
......@@ -600,7 +609,7 @@ RFrame* StackWalkCompPolicy::findTopInlinableFrame(GrowableArray<RFrame*>* stack
// If the caller method is too big or something then we do not want to
// compile it just to inline a method
if (!can_be_compiled(next_m)) {
if (!can_be_compiled(next_m, CompLevel_any)) {
msg = "caller cannot be compiled";
break;
}
......
......@@ -42,6 +42,11 @@ public abstract class CompilerWhiteBoxTest {
protected static int COMP_LEVEL_NONE = 0;
/** {@code CompLevel::CompLevel_any}, {@code CompLevel::CompLevel_all} */
protected static int COMP_LEVEL_ANY = -1;
/** {@code CompLevel::CompLevel_simple} -- C1 */
protected static int COMP_LEVEL_SIMPLE = 1;
/** {@code CompLevel::CompLevel_full_optimization} -- C2 or Shark */
protected static int COMP_LEVEL_FULL_OPTIMIZATION = 4;
/** Instance of WhiteBox */
protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
/** Value of {@code -XX:CompileThreshold} */
......@@ -91,6 +96,17 @@ public abstract class CompilerWhiteBoxTest {
return result == null ? defaultValue : result;
}
/** copy of is_c1_compile(int) from utilities/globalDefinitions.hpp */
protected static boolean isC1Compile(int compLevel) {
return (compLevel > COMP_LEVEL_NONE)
&& (compLevel < COMP_LEVEL_FULL_OPTIMIZATION);
}
/** copy of is_c2_compile(int) from utilities/globalDefinitions.hpp */
protected static boolean isC2Compile(int compLevel) {
return compLevel == COMP_LEVEL_FULL_OPTIMIZATION;
}
/** tested method */
protected final Executable method;
private final Callable<Integer> callable;
......
......@@ -23,6 +23,7 @@
/*
* @test MakeMethodNotCompilableTest
* @bug 8012322
* @library /testlibrary /testlibrary/whitebox
* @build MakeMethodNotCompilableTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
......@@ -67,28 +68,69 @@ public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest {
}
if (TIERED_COMPILATION) {
for (int i = 1, n = TIERED_STOP_AT_LEVEL + 1; i < n; ++i) {
WHITE_BOX.makeMethodNotCompilable(method, i);
if (WHITE_BOX.isMethodCompilable(method, i)) {
final int tierLimit = TIERED_STOP_AT_LEVEL + 1;
for (int testedTier = 1; testedTier < tierLimit; ++testedTier) {
testTier(testedTier);
}
for (int testedTier = 1; testedTier < tierLimit; ++testedTier) {
WHITE_BOX.makeMethodNotCompilable(method, testedTier);
if (WHITE_BOX.isMethodCompilable(method, testedTier)) {
throw new RuntimeException(method
+ " must be not compilable at level" + i);
+ " must be not compilable at level" + testedTier);
}
WHITE_BOX.enqueueMethodForCompilation(method, i);
WHITE_BOX.enqueueMethodForCompilation(method, testedTier);
checkNotCompiled();
if (!WHITE_BOX.isMethodCompilable(method)) {
System.out.println(method
+ " is not compilable after level " + i);
+ " is not compilable after level " + testedTier);
}
}
// WB.clearMethodState() must reset no-compilable flags
WHITE_BOX.clearMethodState(method);
if (!WHITE_BOX.isMethodCompilable(method)) {
} else {
compile();
checkCompiled();
int compLevel = WHITE_BOX.getMethodCompilationLevel(method);
WHITE_BOX.deoptimizeMethod(method);
WHITE_BOX.makeMethodNotCompilable(method, compLevel);
if (WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY)) {
throw new RuntimeException(method
+ " is not compilable after clearMethodState()");
+ " must be not compilable at CompLevel::CompLevel_any,"
+ " after it is not compilable at " + compLevel);
}
WHITE_BOX.clearMethodState(method);
// nocompilable at opposite level must make no sense
int oppositeLevel;
if (isC1Compile(compLevel)) {
oppositeLevel = COMP_LEVEL_FULL_OPTIMIZATION;
} else {
oppositeLevel = COMP_LEVEL_SIMPLE;
}
WHITE_BOX.makeMethodNotCompilable(method, oppositeLevel);
if (!WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY)) {
throw new RuntimeException(method
+ " must be compilable at CompLevel::CompLevel_any,"
+ " even it is not compilable at opposite level ["
+ compLevel + "]");
}
if (!WHITE_BOX.isMethodCompilable(method, compLevel)) {
throw new RuntimeException(method
+ " must be compilable at level " + compLevel
+ ", even it is not compilable at opposite level ["
+ compLevel + "]");
}
}
// clearing after tiered/non-tiered tests
// WB.clearMethodState() must reset no-compilable flags
WHITE_BOX.clearMethodState(method);
if (!WHITE_BOX.isMethodCompilable(method)) {
throw new RuntimeException(method
+ " is not compilable after clearMethodState()");
}
WHITE_BOX.makeMethodNotCompilable(method);
if (WHITE_BOX.isMethodCompilable(method)) {
throw new RuntimeException(method + " must be not compilable");
......@@ -108,4 +150,65 @@ public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest {
compile();
checkCompiled();
}
// separately tests each tier
private void testTier(int testedTier) {
if (!WHITE_BOX.isMethodCompilable(method, testedTier)) {
throw new RuntimeException(method
+ " is not compilable on start");
}
WHITE_BOX.makeMethodNotCompilable(method, testedTier);
// tests for all other tiers
for (int anotherTier = 1, tierLimit = TIERED_STOP_AT_LEVEL + 1;
anotherTier < tierLimit; ++anotherTier) {
boolean isCompilable = WHITE_BOX.isMethodCompilable(method,
anotherTier);
if (sameCompile(testedTier, anotherTier)) {
if (isCompilable) {
throw new RuntimeException(method
+ " must be not compilable at level " + anotherTier
+ ", if it is not compilable at " + testedTier);
}
WHITE_BOX.enqueueMethodForCompilation(method, anotherTier);
checkNotCompiled();
} else {
if (!isCompilable) {
throw new RuntimeException(method
+ " must be compilable at level " + anotherTier
+ ", even if it is not compilable at "
+ testedTier);
}
WHITE_BOX.enqueueMethodForCompilation(method, anotherTier);
checkCompiled();
WHITE_BOX.deoptimizeMethod(method);
}
if (!WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY)) {
throw new RuntimeException(method
+ " must be compilable at 'CompLevel::CompLevel_any'"
+ ", if it is not compilable only at " + testedTier);
}
}
// clear state after test
WHITE_BOX.clearMethodState(method);
if (!WHITE_BOX.isMethodCompilable(method, testedTier)) {
throw new RuntimeException(method
+ " is not compilable after clearMethodState()");
}
}
private boolean sameCompile(int level1, int level2) {
if (level1 == level2) {
return true;
}
if (isC1Compile(level1) && isC1Compile(level2)) {
return true;
}
if (isC2Compile(level1) && isC2Compile(level2)) {
return true;
}
return false;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册