# HG changeset patch # User thartmann # Date 1415700341 -3600 # Node ID 600c44255e5f69bfbc9b6de2bf21d2be1f65568d # Parent f84125b6f69a64ed2367f54debf8b6cdb8681998 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 diff -r f84125b6f69a -r 600c44255e5f src/share/vm/interpreter/bytecodes.hpp --- a/src/share/vm/interpreter/bytecodes.hpp Tue Nov 18 00:56:42 2014 +0000 +++ b/src/share/vm/interpreter/bytecodes.hpp Tue Nov 11 11:05:41 2014 +0100 @@ -420,8 +420,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 || diff -r f84125b6f69a -r 600c44255e5f src/share/vm/oops/method.cpp --- a/src/share/vm/oops/method.cpp Tue Nov 18 00:56:42 2014 +0000 +++ b/src/share/vm/oops/method.cpp Tue Nov 11 11:05:41 2014 +0100 @@ -558,6 +558,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(); diff -r f84125b6f69a -r 600c44255e5f src/share/vm/oops/method.hpp --- a/src/share/vm/oops/method.hpp Tue Nov 18 00:56:42 2014 +0000 +++ b/src/share/vm/oops/method.hpp Tue Nov 11 11:05:41 2014 +0100 @@ -619,6 +619,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 ( or ). bool is_initializer() const; diff -r f84125b6f69a -r 600c44255e5f src/share/vm/oops/methodData.cpp --- a/src/share/vm/oops/methodData.cpp Tue Nov 18 00:56:42 2014 +0000 +++ b/src/share/vm/oops/methodData.cpp Tue Nov 11 11:05:41 2014 +0100 @@ -1153,7 +1153,7 @@ _backedge_counter_start = 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 diff -r f84125b6f69a -r 600c44255e5f src/share/vm/oops/methodData.hpp --- a/src/share/vm/oops/methodData.hpp Tue Nov 18 00:56:42 2014 +0000 +++ b/src/share/vm/oops/methodData.hpp Tue Nov 11 11:05:41 2014 +0100 @@ -2099,7 +2099,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; @@ -2268,8 +2269,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; } diff -r f84125b6f69a -r 600c44255e5f src/share/vm/runtime/advancedThresholdPolicy.cpp --- a/src/share/vm/runtime/advancedThresholdPolicy.cpp Tue Nov 18 00:56:42 2014 +0000 +++ b/src/share/vm/runtime/advancedThresholdPolicy.cpp Tue Nov 11 11:05:41 2014 +0100 @@ -316,8 +316,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 diff -r f84125b6f69a -r 600c44255e5f src/share/vm/runtime/simpleThresholdPolicy.inline.hpp --- a/src/share/vm/runtime/simpleThresholdPolicy.inline.hpp Tue Nov 18 00:56:42 2014 +0000 +++ b/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; } diff -r f84125b6f69a -r 600c44255e5f test/compiler/whitebox/IsMethodCompilableTest.java --- a/test/compiler/whitebox/IsMethodCompilableTest.java Tue Nov 18 00:56:42 2014 +0000 +++ b/test/compiler/whitebox/IsMethodCompilableTest.java Tue Nov 11 11:05:41 2014 +0100 @@ -28,7 +28,7 @@ * @build IsMethodCompilableTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * @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 */