Wed, 31 Aug 2011 01:40:45 -0700
7078382: JSR 292: don't count method handle adapters against inlining budgets
Reviewed-by: kvn, never
1.1 --- a/src/share/vm/c1/c1_GraphBuilder.cpp Tue Aug 30 19:01:58 2011 -0700 1.2 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp Wed Aug 31 01:40:45 2011 -0700 1.3 @@ -3430,7 +3430,7 @@ 1.4 } else { 1.5 if (inline_level() > MaxInlineLevel ) INLINE_BAILOUT("too-deep inlining"); 1.6 if (recursive_inline_level(callee) > MaxRecursiveInlineLevel) INLINE_BAILOUT("too-deep recursive inlining"); 1.7 - if (callee->code_size() > max_inline_size() ) INLINE_BAILOUT("callee is too large"); 1.8 + if (callee->code_size_for_inlining() > max_inline_size() ) INLINE_BAILOUT("callee is too large"); 1.9 1.10 // don't inline throwable methods unless the inlining tree is rooted in a throwable class 1.11 if (callee->name() == ciSymbol::object_initializer_name() &&
2.1 --- a/src/share/vm/ci/ciMethod.cpp Tue Aug 30 19:01:58 2011 -0700 2.2 +++ b/src/share/vm/ci/ciMethod.cpp Wed Aug 31 01:40:45 2011 -0700 2.3 @@ -1017,6 +1017,34 @@ 2.4 } 2.5 2.6 // ------------------------------------------------------------------ 2.7 +// ciMethod::code_size_for_inlining 2.8 +// 2.9 +// Code size for inlining decisions. 2.10 +// 2.11 +// Don't fully count method handle adapters against inlining budgets: 2.12 +// the metric we use here is the number of call sites in the adapter 2.13 +// as they are probably the instructions which generate some code. 2.14 +int ciMethod::code_size_for_inlining() { 2.15 + check_is_loaded(); 2.16 + 2.17 + // Method handle adapters 2.18 + if (is_method_handle_adapter()) { 2.19 + // Count call sites 2.20 + int call_site_count = 0; 2.21 + ciBytecodeStream iter(this); 2.22 + while (iter.next() != ciBytecodeStream::EOBC()) { 2.23 + if (Bytecodes::is_invoke(iter.cur_bc())) { 2.24 + call_site_count++; 2.25 + } 2.26 + } 2.27 + return call_site_count; 2.28 + } 2.29 + 2.30 + // Normal method 2.31 + return code_size(); 2.32 +} 2.33 + 2.34 +// ------------------------------------------------------------------ 2.35 // ciMethod::instructions_size 2.36 // 2.37 // This is a rough metric for "fat" methods, compared before inlining
3.1 --- a/src/share/vm/ci/ciMethod.hpp Tue Aug 30 19:01:58 2011 -0700 3.2 +++ b/src/share/vm/ci/ciMethod.hpp Wed Aug 31 01:40:45 2011 -0700 3.3 @@ -157,6 +157,9 @@ 3.4 int interpreter_invocation_count() const { check_is_loaded(); return _interpreter_invocation_count; } 3.5 int interpreter_throwout_count() const { check_is_loaded(); return _interpreter_throwout_count; } 3.6 3.7 + // Code size for inlining decisions. 3.8 + int code_size_for_inlining(); 3.9 + 3.10 int comp_level(); 3.11 int highest_osr_comp_level(); 3.12
4.1 --- a/src/share/vm/ci/ciStreams.hpp Tue Aug 30 19:01:58 2011 -0700 4.2 +++ b/src/share/vm/ci/ciStreams.hpp Wed Aug 31 01:40:45 2011 -0700 4.3 @@ -129,7 +129,8 @@ 4.4 // Return current ByteCode and increment PC to next bytecode, skipping all 4.5 // intermediate constants. Returns EOBC at end. 4.6 // Expected usage: 4.7 - // while( (bc = iter.next()) != EOBC() ) { ... } 4.8 + // ciBytecodeStream iter(m); 4.9 + // while (iter.next() != ciBytecodeStream::EOBC()) { ... } 4.10 Bytecodes::Code next() { 4.11 _bc_start = _pc; // Capture start of bc 4.12 if( _pc >= _end ) return EOBC(); // End-Of-Bytecodes
5.1 --- a/src/share/vm/interpreter/bytecodes.hpp Tue Aug 30 19:01:58 2011 -0700 5.2 +++ b/src/share/vm/interpreter/bytecodes.hpp Wed Aug 31 01:40:45 2011 -0700 5.3 @@ -419,6 +419,8 @@ 5.4 5.5 static bool is_zero_const (Code code) { return (code == _aconst_null || code == _iconst_0 5.6 || code == _fconst_0 || code == _dconst_0); } 5.7 + static bool is_invoke (Code code) { return (_invokevirtual <= code && code <= _invokedynamic); } 5.8 + 5.9 static int compute_flags (const char* format, int more_flags = 0); // compute the flags 5.10 static int flags (int code, bool is_wide) { 5.11 assert(code == (u_char)code, "must be a byte");
6.1 --- a/src/share/vm/opto/bytecodeInfo.cpp Tue Aug 30 19:01:58 2011 -0700 6.2 +++ b/src/share/vm/opto/bytecodeInfo.cpp Wed Aug 31 01:40:45 2011 -0700 6.3 @@ -45,7 +45,7 @@ 6.4 _method(callee), 6.5 _site_invoke_ratio(site_invoke_ratio), 6.6 _max_inline_level(max_inline_level), 6.7 - _count_inline_bcs(method()->code_size()) 6.8 + _count_inline_bcs(method()->code_size_for_inlining()) 6.9 { 6.10 NOT_PRODUCT(_count_inlines = 0;) 6.11 if (_caller_jvms != NULL) { 6.12 @@ -107,7 +107,7 @@ 6.13 6.14 // positive filter: should send be inlined? returns NULL (--> yes) 6.15 // or rejection msg 6.16 - int size = callee_method->code_size(); 6.17 + int size = callee_method->code_size_for_inlining(); 6.18 6.19 // Check for too many throws (and not too huge) 6.20 if(callee_method->interpreter_throwout_count() > InlineThrowCount && 6.21 @@ -244,7 +244,7 @@ 6.22 } 6.23 6.24 // use frequency-based objections only for non-trivial methods 6.25 - if (callee_method->code_size() <= MaxTrivialSize) return NULL; 6.26 + if (callee_method->code_size_for_inlining() <= MaxTrivialSize) return NULL; 6.27 6.28 // don't use counts with -Xcomp or CTW 6.29 if (UseInterpreter && !CompileTheWorld) { 6.30 @@ -305,7 +305,7 @@ 6.31 } 6.32 6.33 // suppress a few checks for accessors and trivial methods 6.34 - if (callee_method->code_size() > MaxTrivialSize) { 6.35 + if (callee_method->code_size_for_inlining() > MaxTrivialSize) { 6.36 6.37 // don't inline into giant methods 6.38 if (C->unique() > (uint)NodeCountInliningCutoff) { 6.39 @@ -349,7 +349,7 @@ 6.40 } 6.41 } 6.42 6.43 - int size = callee_method->code_size(); 6.44 + int size = callee_method->code_size_for_inlining(); 6.45 6.46 if (UseOldInlining && ClipInlining 6.47 && (int)count_inline_bcs() + size >= DesiredMethodLimit) {