mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8056071: compiler/whitebox/IsMethodCompilableTest.java fails with 'method() is not compilable after 3 iterations'
Always use MDO if valid and always compile trivial methods with C1 if available. Reviewed-by: kvn, iveresov
This commit is contained in:
parent
bdac822811
commit
00aa20db4a
8 changed files with 33 additions and 14 deletions
|
@ -401,8 +401,10 @@ class Bytecodes: AllStatic {
|
|||
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 ||
|
||||
|
|
|
@ -588,6 +588,15 @@ bool Method::is_accessor() const {
|
|||
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();
|
||||
|
|
|
@ -595,6 +595,9 @@ class Method : public Metadata {
|
|||
// 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;
|
||||
|
||||
|
|
|
@ -1134,7 +1134,7 @@ void MethodData::init() {
|
|||
_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
|
||||
|
|
|
@ -2096,7 +2096,8 @@ private:
|
|||
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 @@ public:
|
|||
}
|
||||
#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; }
|
||||
|
|
|
@ -317,8 +317,8 @@ void AdvancedThresholdPolicy::create_mdo(methodHandle mh, JavaThread* THREAD) {
|
|||
* 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
|
||||
|
|
|
@ -54,13 +54,17 @@ bool SimpleThresholdPolicy::loop_predicate_helper(int i, int b, double scale) {
|
|||
// 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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue