# HG changeset patch # User twisti # Date 1314780045 25200 # Node ID de847cac9235b56defdfc7968f8cdc3a2089d841 # Parent b346f13112d829737972c73293294f6c9eaec47b 7078382: JSR 292: don't count method handle adapters against inlining budgets Reviewed-by: kvn, never diff -r b346f13112d8 -r de847cac9235 src/share/vm/c1/c1_GraphBuilder.cpp --- a/src/share/vm/c1/c1_GraphBuilder.cpp Tue Aug 30 19:01:58 2011 -0700 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp Wed Aug 31 01:40:45 2011 -0700 @@ -3430,7 +3430,7 @@ } else { if (inline_level() > MaxInlineLevel ) INLINE_BAILOUT("too-deep inlining"); if (recursive_inline_level(callee) > MaxRecursiveInlineLevel) INLINE_BAILOUT("too-deep recursive inlining"); - if (callee->code_size() > max_inline_size() ) INLINE_BAILOUT("callee is too large"); + if (callee->code_size_for_inlining() > max_inline_size() ) INLINE_BAILOUT("callee is too large"); // don't inline throwable methods unless the inlining tree is rooted in a throwable class if (callee->name() == ciSymbol::object_initializer_name() && diff -r b346f13112d8 -r de847cac9235 src/share/vm/ci/ciMethod.cpp --- a/src/share/vm/ci/ciMethod.cpp Tue Aug 30 19:01:58 2011 -0700 +++ b/src/share/vm/ci/ciMethod.cpp Wed Aug 31 01:40:45 2011 -0700 @@ -1017,6 +1017,34 @@ } // ------------------------------------------------------------------ +// ciMethod::code_size_for_inlining +// +// Code size for inlining decisions. +// +// Don't fully count method handle adapters against inlining budgets: +// the metric we use here is the number of call sites in the adapter +// as they are probably the instructions which generate some code. +int ciMethod::code_size_for_inlining() { + check_is_loaded(); + + // Method handle adapters + if (is_method_handle_adapter()) { + // Count call sites + int call_site_count = 0; + ciBytecodeStream iter(this); + while (iter.next() != ciBytecodeStream::EOBC()) { + if (Bytecodes::is_invoke(iter.cur_bc())) { + call_site_count++; + } + } + return call_site_count; + } + + // Normal method + return code_size(); +} + +// ------------------------------------------------------------------ // ciMethod::instructions_size // // This is a rough metric for "fat" methods, compared before inlining diff -r b346f13112d8 -r de847cac9235 src/share/vm/ci/ciMethod.hpp --- a/src/share/vm/ci/ciMethod.hpp Tue Aug 30 19:01:58 2011 -0700 +++ b/src/share/vm/ci/ciMethod.hpp Wed Aug 31 01:40:45 2011 -0700 @@ -157,6 +157,9 @@ int interpreter_invocation_count() const { check_is_loaded(); return _interpreter_invocation_count; } int interpreter_throwout_count() const { check_is_loaded(); return _interpreter_throwout_count; } + // Code size for inlining decisions. + int code_size_for_inlining(); + int comp_level(); int highest_osr_comp_level(); diff -r b346f13112d8 -r de847cac9235 src/share/vm/ci/ciStreams.hpp --- a/src/share/vm/ci/ciStreams.hpp Tue Aug 30 19:01:58 2011 -0700 +++ b/src/share/vm/ci/ciStreams.hpp Wed Aug 31 01:40:45 2011 -0700 @@ -129,7 +129,8 @@ // Return current ByteCode and increment PC to next bytecode, skipping all // intermediate constants. Returns EOBC at end. // Expected usage: - // while( (bc = iter.next()) != EOBC() ) { ... } + // ciBytecodeStream iter(m); + // while (iter.next() != ciBytecodeStream::EOBC()) { ... } Bytecodes::Code next() { _bc_start = _pc; // Capture start of bc if( _pc >= _end ) return EOBC(); // End-Of-Bytecodes diff -r b346f13112d8 -r de847cac9235 src/share/vm/interpreter/bytecodes.hpp --- a/src/share/vm/interpreter/bytecodes.hpp Tue Aug 30 19:01:58 2011 -0700 +++ b/src/share/vm/interpreter/bytecodes.hpp Wed Aug 31 01:40:45 2011 -0700 @@ -419,6 +419,8 @@ static bool is_zero_const (Code code) { return (code == _aconst_null || code == _iconst_0 || code == _fconst_0 || code == _dconst_0); } + static bool is_invoke (Code code) { return (_invokevirtual <= code && code <= _invokedynamic); } + static int compute_flags (const char* format, int more_flags = 0); // compute the flags static int flags (int code, bool is_wide) { assert(code == (u_char)code, "must be a byte"); diff -r b346f13112d8 -r de847cac9235 src/share/vm/opto/bytecodeInfo.cpp --- a/src/share/vm/opto/bytecodeInfo.cpp Tue Aug 30 19:01:58 2011 -0700 +++ b/src/share/vm/opto/bytecodeInfo.cpp Wed Aug 31 01:40:45 2011 -0700 @@ -45,7 +45,7 @@ _method(callee), _site_invoke_ratio(site_invoke_ratio), _max_inline_level(max_inline_level), - _count_inline_bcs(method()->code_size()) + _count_inline_bcs(method()->code_size_for_inlining()) { NOT_PRODUCT(_count_inlines = 0;) if (_caller_jvms != NULL) { @@ -107,7 +107,7 @@ // positive filter: should send be inlined? returns NULL (--> yes) // or rejection msg - int size = callee_method->code_size(); + int size = callee_method->code_size_for_inlining(); // Check for too many throws (and not too huge) if(callee_method->interpreter_throwout_count() > InlineThrowCount && @@ -244,7 +244,7 @@ } // use frequency-based objections only for non-trivial methods - if (callee_method->code_size() <= MaxTrivialSize) return NULL; + if (callee_method->code_size_for_inlining() <= MaxTrivialSize) return NULL; // don't use counts with -Xcomp or CTW if (UseInterpreter && !CompileTheWorld) { @@ -305,7 +305,7 @@ } // suppress a few checks for accessors and trivial methods - if (callee_method->code_size() > MaxTrivialSize) { + if (callee_method->code_size_for_inlining() > MaxTrivialSize) { // don't inline into giant methods if (C->unique() > (uint)NodeCountInliningCutoff) { @@ -349,7 +349,7 @@ } } - int size = callee_method->code_size(); + int size = callee_method->code_size_for_inlining(); if (UseOldInlining && ClipInlining && (int)count_inline_bcs() + size >= DesiredMethodLimit) {