8056071: compiler/whitebox/IsMethodCompilableTest.java fails with 'method() is not compilable after 3 iterations'
Summary: Always use MDO if valid and always compile trivial methods with C1 if available.
Reviewed-by: kvn, iveresov
--- a/hotspot/src/share/vm/interpreter/bytecodes.hpp Mon Nov 10 19:04:38 2014 +0300
+++ b/hotspot/src/share/vm/interpreter/bytecodes.hpp Tue Nov 11 11:05:41 2014 +0100
@@ -401,8 +401,10 @@
static bool is_astore (Code code) { return (code == _astore || code == _astore_0 || code == _astore_1
|| code == _astore_2 || code == _astore_3); }
+ static bool is_const (Code code) { return (_aconst_null <= code && code <= _ldc2_w); }
static bool is_zero_const (Code code) { return (code == _aconst_null || code == _iconst_0
|| code == _fconst_0 || code == _dconst_0); }
+ static bool is_return (Code code) { return (_ireturn <= code && code <= _return); }
static bool is_invoke (Code code) { return (_invokevirtual <= code && code <= _invokedynamic); }
static bool has_receiver (Code code) { assert(is_invoke(code), ""); return code == _invokevirtual ||
code == _invokespecial ||
--- a/hotspot/src/share/vm/oops/method.cpp Mon Nov 10 19:04:38 2014 +0300
+++ b/hotspot/src/share/vm/oops/method.cpp Tue Nov 11 11:05:41 2014 +0100
@@ -588,6 +588,15 @@
return true;
}
+bool Method::is_constant_getter() const {
+ int last_index = code_size() - 1;
+ // Check if the first 1-3 bytecodes are a constant push
+ // and the last bytecode is a return.
+ return (2 <= code_size() && code_size() <= 4 &&
+ Bytecodes::is_const(java_code_at(0)) &&
+ Bytecodes::length_for(java_code_at(0)) == last_index &&
+ Bytecodes::is_return(java_code_at(last_index)));
+}
bool Method::is_initializer() const {
return name() == vmSymbols::object_initializer_name() || is_static_initializer();
--- a/hotspot/src/share/vm/oops/method.hpp Mon Nov 10 19:04:38 2014 +0300
+++ b/hotspot/src/share/vm/oops/method.hpp Tue Nov 11 11:05:41 2014 +0100
@@ -595,6 +595,9 @@
// returns true if the method is an accessor function (setter/getter).
bool is_accessor() const;
+ // returns true if the method does nothing but return a constant of primitive type
+ bool is_constant_getter() const;
+
// returns true if the method is an initializer (<init> or <clinit>).
bool is_initializer() const;
--- a/hotspot/src/share/vm/oops/methodData.cpp Mon Nov 10 19:04:38 2014 +0300
+++ b/hotspot/src/share/vm/oops/methodData.cpp Tue Nov 11 11:05:41 2014 +0100
@@ -1134,7 +1134,7 @@
_tenure_traps = 0;
_num_loops = 0;
_num_blocks = 0;
- _would_profile = true;
+ _would_profile = unknown;
#if INCLUDE_RTM_OPT
_rtm_state = NoRTM; // No RTM lock eliding by default
--- a/hotspot/src/share/vm/oops/methodData.hpp Mon Nov 10 19:04:38 2014 +0300
+++ b/hotspot/src/share/vm/oops/methodData.hpp Tue Nov 11 11:05:41 2014 +0100
@@ -2096,7 +2096,8 @@
short _num_loops;
short _num_blocks;
// Does this method contain anything worth profiling?
- bool _would_profile;
+ enum WouldProfile {unknown, no_profile, profile};
+ WouldProfile _would_profile;
// Size of _data array in bytes. (Excludes header and extra_data fields.)
int _data_size;
@@ -2270,8 +2271,8 @@
}
#endif
- void set_would_profile(bool p) { _would_profile = p; }
- bool would_profile() const { return _would_profile; }
+ void set_would_profile(bool p) { _would_profile = p ? profile : no_profile; }
+ bool would_profile() const { return _would_profile != no_profile; }
int num_loops() const { return _num_loops; }
void set_num_loops(int n) { _num_loops = n; }
--- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp Mon Nov 10 19:04:38 2014 +0300
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp Tue Nov 11 11:05:41 2014 +0100
@@ -317,8 +317,8 @@
* c. 0 -> (3->2) -> 4.
* In this case we enqueue a method for compilation at level 3, but the C1 queue is long enough
* to enable the profiling to fully occur at level 0. In this case we change the compilation level
- * of the method to 2, because it'll allow it to run much faster without full profiling while c2
- * is compiling.
+ * of the method to 2 while the request is still in-queue, because it'll allow it to run much faster
+ * without full profiling while c2 is compiling.
*
* d. 0 -> 3 -> 1 or 0 -> 2 -> 1.
* After a method was once compiled with C1 it can be identified as trivial and be compiled to
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.inline.hpp Mon Nov 10 19:04:38 2014 +0300
+++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.inline.hpp Tue Nov 11 11:05:41 2014 +0100
@@ -54,13 +54,17 @@
// Simple methods are as good being compiled with C1 as C2.
// Determine if a given method is such a case.
bool SimpleThresholdPolicy::is_trivial(Method* method) {
- if (method->is_accessor()) return true;
- if (method->code() != NULL) {
- MethodData* mdo = method->method_data();
- if (mdo != NULL && mdo->num_loops() == 0 &&
- (method->code_size() < 5 || (mdo->num_blocks() < 4) && (method->code_size() < 15))) {
- return !mdo->would_profile();
- }
+ if (method->is_accessor() ||
+ method->is_constant_getter()) {
+ return true;
+ }
+ if (method->has_loops() || method->code_size() >= 15) {
+ return false;
+ }
+ MethodData* mdo = method->method_data();
+ if (mdo != NULL && !mdo->would_profile() &&
+ (method->code_size() < 5 || (mdo->num_blocks() < 4))) {
+ return true;
}
return false;
}
--- a/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java Mon Nov 10 19:04:38 2014 +0300
+++ b/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java Tue Nov 11 11:05:41 2014 +0100
@@ -29,7 +29,7 @@
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main ClassFileInstaller com.oracle.java.testlibrary.Platform
- * @run main/othervm/timeout=2400 -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:PerMethodRecompilationCutoff=3 -XX:CompileCommand=compileonly,SimpleTestCase$Helper::* IsMethodCompilableTest
+ * @run main/othervm/timeout=2400 -Xbootclasspath/a:. -Xmixed -XX:-TieredCompilation -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:PerMethodRecompilationCutoff=3 -XX:CompileCommand=compileonly,SimpleTestCase$Helper::* IsMethodCompilableTest
* @summary testing of WB::isMethodCompilable()
* @author igor.ignatyev@oracle.com
*/