hotspot/src/share/vm/opto/bytecodeInfo.cpp

Print this page
rev 611 : Merge

*** 1,10 **** #ifdef USE_PRAGMA_IDENT_SRC #pragma ident "@(#)bytecodeInfo.cpp 1.122 07/05/05 17:06:12 JVM" #endif /* ! * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. --- 1,10 ---- #ifdef USE_PRAGMA_IDENT_SRC #pragma ident "@(#)bytecodeInfo.cpp 1.122 07/05/05 17:06:12 JVM" #endif /* ! * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 26,48 **** */ #include "incls/_precompiled.incl" #include "incls/_bytecodeInfo.cpp.incl" - // These variables are declared in parse1.cpp - extern int explicit_null_checks_inserted; - extern int explicit_null_checks_elided; - extern int explicit_null_checks_inserted_old; - extern int explicit_null_checks_elided_old; - extern int nodes_created_old; - extern int nodes_created; - extern int methods_parsed_old; - extern int methods_parsed; - extern int methods_seen; - extern int methods_seen_old; - - //============================================================================= //------------------------------InlineTree------------------------------------- InlineTree::InlineTree( Compile* c, const InlineTree *caller_tree, ciMethod* callee, JVMState* caller_jvms, int caller_bci, float site_invoke_ratio ) : C(c), _caller_jvms(caller_jvms), _caller_tree((InlineTree*)caller_tree), --- 26,35 ----
*** 80,91 **** static void print_indent(int depth) { tty->print(" "); for (int i = depth; i != 0; --i) tty->print(" "); } // positive filter: should send be inlined? returns NULL, if yes, or rejection msg ! const char* InlineTree::shouldInline(ciMethod* callee_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const { // Allows targeted inlining if(callee_method->should_inline()) { *wci_result = *(WarmCallInfo::always_hot()); if (PrintInlining && Verbose) { print_indent(inline_depth()); --- 67,90 ---- static void print_indent(int depth) { tty->print(" "); for (int i = depth; i != 0; --i) tty->print(" "); } + static bool is_init_with_ea(ciMethod* callee_method, + ciMethod* caller_method, Compile* C) { + // True when EA is ON and a java constructor is called or + // a super constructor is called from an inlined java constructor. + return C->do_escape_analysis() && EliminateAllocations && + ( callee_method->is_initializer() || + (caller_method->is_initializer() && + caller_method != C->method() && + caller_method->holder()->is_subclass_of(callee_method->holder())) + ); + } + // positive filter: should send be inlined? returns NULL, if yes, or rejection msg ! const char* InlineTree::shouldInline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const { // Allows targeted inlining if(callee_method->should_inline()) { *wci_result = *(WarmCallInfo::always_hot()); if (PrintInlining && Verbose) { print_indent(inline_depth());
*** 98,108 **** // or rejection msg int max_size = C->max_inline_size(); int size = callee_method->code_size(); // Check for too many throws (and not too huge) ! if(callee_method->interpreter_throwout_count() > InlineThrowCount && size < InlineThrowMaxSize ) { wci_result->set_profit(wci_result->profit() * 100); if (PrintInlining && Verbose) { print_indent(inline_depth()); tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count()); } --- 97,108 ---- // or rejection msg int max_size = C->max_inline_size(); int size = callee_method->code_size(); // Check for too many throws (and not too huge) ! if(callee_method->interpreter_throwout_count() > InlineThrowCount && ! size < InlineThrowMaxSize ) { wci_result->set_profit(wci_result->profit() * 100); if (PrintInlining && Verbose) { print_indent(inline_depth()); tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count()); }
*** 115,137 **** int call_site_count = method()->scale_count(profile.count()); int invoke_count = method()->interpreter_invocation_count(); assert( invoke_count != 0, "Require invokation count greater than zero"); int freq = call_site_count/invoke_count; // bump the max size if the call is frequent ! if ((freq >= InlineFrequencyRatio) || (call_site_count >= InlineFrequencyCount)) { max_size = C->freq_inline_size(); if (size <= max_size && TraceFrequencyInlining) { print_indent(inline_depth()); tty->print_cr("Inlined frequent method (freq=%d count=%d):", freq, call_site_count); print_indent(inline_depth()); callee_method->print(); tty->cr(); } } else { // Not hot. Check for medium-sized pre-existing nmethod at cold sites. ! if (callee_method->has_compiled_code() && callee_method->instructions_size() > InlineSmallCode/4) return "already compiled into a medium method"; } if (size > max_size) { if (max_size > C->max_inline_size()) return "hot method too big"; --- 115,142 ---- int call_site_count = method()->scale_count(profile.count()); int invoke_count = method()->interpreter_invocation_count(); assert( invoke_count != 0, "Require invokation count greater than zero"); int freq = call_site_count/invoke_count; + // bump the max size if the call is frequent ! if ((freq >= InlineFrequencyRatio) || ! (call_site_count >= InlineFrequencyCount) || ! is_init_with_ea(callee_method, caller_method, C)) { ! max_size = C->freq_inline_size(); if (size <= max_size && TraceFrequencyInlining) { print_indent(inline_depth()); tty->print_cr("Inlined frequent method (freq=%d count=%d):", freq, call_site_count); print_indent(inline_depth()); callee_method->print(); tty->cr(); } } else { // Not hot. Check for medium-sized pre-existing nmethod at cold sites. ! if (callee_method->has_compiled_code() && ! callee_method->instructions_size() > InlineSmallCode/4) return "already compiled into a medium method"; } if (size > max_size) { if (max_size > C->max_inline_size()) return "hot method too big";
*** 140,150 **** return NULL; } // negative filter: should send NOT be inlined? returns NULL, ok to inline, or rejection msg ! const char* InlineTree::shouldNotInline(ciMethod *callee_method, WarmCallInfo* wci_result) const { // negative filter: should send NOT be inlined? returns NULL (--> inline) or rejection msg if (!UseOldInlining) { const char* fail = NULL; if (callee_method->is_abstract()) fail = "abstract method"; // note: we allow ik->is_abstract() --- 145,155 ---- return NULL; } // negative filter: should send NOT be inlined? returns NULL, ok to inline, or rejection msg ! const char* InlineTree::shouldNotInline(ciMethod *callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const { // negative filter: should send NOT be inlined? returns NULL (--> inline) or rejection msg if (!UseOldInlining) { const char* fail = NULL; if (callee_method->is_abstract()) fail = "abstract method"; // note: we allow ik->is_abstract()
*** 205,217 **** return "exception method"; } // use frequency-based objections only for non-trivial methods if (callee_method->code_size() <= MaxTrivialSize) return NULL; ! if (UseInterpreter && !CompileTheWorld) { // don't use counts with -Xcomp or CTW ! if (!callee_method->has_compiled_code() && !callee_method->was_executed_more_than(0)) return "never executed"; ! if (!callee_method->was_executed_more_than(MIN2(MinInliningThreshold, CompileThreshold >> 1))) return "executed < MinInliningThreshold times"; } if (callee_method->should_not_inline()) { return "disallowed by CompilerOracle"; } --- 210,236 ---- return "exception method"; } // use frequency-based objections only for non-trivial methods if (callee_method->code_size() <= MaxTrivialSize) return NULL; ! ! // don't use counts with -Xcomp or CTW ! if (UseInterpreter && !CompileTheWorld) { ! ! if (!callee_method->has_compiled_code() && ! !callee_method->was_executed_more_than(0)) { ! return "never executed"; ! } ! ! if (is_init_with_ea(callee_method, caller_method, C)) { ! ! // Escape Analysis: inline all executed constructors ! ! } else if (!callee_method->was_executed_more_than(MIN2(MinInliningThreshold, ! CompileThreshold >> 1))) { ! return "executed < MinInliningThreshold times"; ! } } if (callee_method->should_not_inline()) { return "disallowed by CompilerOracle"; }
*** 220,258 **** } //-----------------------------try_to_inline----------------------------------- // return NULL if ok, reason for not inlining otherwise // Relocated from "InliningClosure::try_to_inline" ! const char* InlineTree::try_to_inline(ciMethod* callee_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) { ! ciMethod* caller_method = method(); // Old algorithm had funny accumulating BC-size counters if (UseOldInlining && ClipInlining && (int)count_inline_bcs() >= DesiredMethodLimit) { return "size > DesiredMethodLimit"; } const char *msg = NULL; ! if ((msg = shouldInline(callee_method, caller_bci, profile, wci_result)) != NULL) return msg; ! if ((msg = shouldNotInline(callee_method, wci_result)) != NULL) return msg; bool is_accessor = InlineAccessors && callee_method->is_accessor(); // suppress a few checks for accessors and trivial methods if (!is_accessor && callee_method->code_size() > MaxTrivialSize) { // don't inline into giant methods ! if (C->unique() > (uint)NodeCountInliningCutoff) return "NodeCountInliningCutoff"; // don't inline unreached call sites ! if (profile.count() == 0) return "call site not reached"; } ! if (!C->do_inlining() && InlineAccessors && !is_accessor) return "not an accessor"; ! ! if( inline_depth() > MaxInlineLevel ) return "inlining too deep"; if( method() == callee_method && ! inline_depth() > MaxRecursiveInlineLevel ) return "recursively inlining too deep"; int size = callee_method->code_size(); if (UseOldInlining && ClipInlining && (int)count_inline_bcs() + size >= DesiredMethodLimit) { --- 239,298 ---- } //-----------------------------try_to_inline----------------------------------- // return NULL if ok, reason for not inlining otherwise // Relocated from "InliningClosure::try_to_inline" ! const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) { // Old algorithm had funny accumulating BC-size counters if (UseOldInlining && ClipInlining && (int)count_inline_bcs() >= DesiredMethodLimit) { return "size > DesiredMethodLimit"; } const char *msg = NULL; ! if ((msg = shouldInline(callee_method, caller_method, caller_bci, ! profile, wci_result)) != NULL) { ! return msg; ! } ! if ((msg = shouldNotInline(callee_method, caller_method, ! wci_result)) != NULL) { ! return msg; ! } bool is_accessor = InlineAccessors && callee_method->is_accessor(); // suppress a few checks for accessors and trivial methods if (!is_accessor && callee_method->code_size() > MaxTrivialSize) { + // don't inline into giant methods ! if (C->unique() > (uint)NodeCountInliningCutoff) { ! return "NodeCountInliningCutoff"; ! } ! ! if ((!UseInterpreter || CompileTheWorld) && ! is_init_with_ea(callee_method, caller_method, C)) { + // Escape Analysis stress testing when running Xcomp or CTW: + // inline constructors even if they are not reached. + + } else if (profile.count() == 0) { // don't inline unreached call sites ! return "call site not reached"; ! } } ! if (!C->do_inlining() && InlineAccessors && !is_accessor) { ! return "not an accessor"; ! } ! if( inline_depth() > MaxInlineLevel ) { ! return "inlining too deep"; ! } if( method() == callee_method && ! inline_depth() > MaxRecursiveInlineLevel ) { ! return "recursively inlining too deep"; ! } int size = callee_method->code_size(); if (UseOldInlining && ClipInlining && (int)count_inline_bcs() + size >= DesiredMethodLimit) {
*** 337,347 **** return NULL; } // Check if inlining policy says no. WarmCallInfo wci = *(initial_wci); ! failure_msg = try_to_inline(callee_method, caller_bci, profile, &wci); if (failure_msg != NULL && C->log() != NULL) { C->log()->begin_elem("inline_fail reason='"); C->log()->text("%s", failure_msg); C->log()->end_elem("'"); } --- 377,387 ---- return NULL; } // Check if inlining policy says no. WarmCallInfo wci = *(initial_wci); ! failure_msg = try_to_inline(callee_method, caller_method, caller_bci, profile, &wci); if (failure_msg != NULL && C->log() != NULL) { C->log()->begin_elem("inline_fail reason='"); C->log()->text("%s", failure_msg); C->log()->end_elem("'"); }
*** 465,493 **** } iltp = sub; } return iltp; } - - // ---------------------------------------------------------------------------- - #ifndef PRODUCT - - static void per_method_stats() { - // Compute difference between this method's cumulative totals and old totals - int explicit_null_checks_cur = explicit_null_checks_inserted - explicit_null_checks_inserted_old; - int elided_null_checks_cur = explicit_null_checks_elided - explicit_null_checks_elided_old; - - // Print differences - if( explicit_null_checks_cur ) - tty->print_cr("XXX Explicit NULL checks inserted: %d", explicit_null_checks_cur); - if( elided_null_checks_cur ) - tty->print_cr("XXX Explicit NULL checks removed at parse time: %d", elided_null_checks_cur); - - // Store the current cumulative totals - nodes_created_old = nodes_created; - methods_parsed_old = methods_parsed; - methods_seen_old = methods_seen; - explicit_null_checks_inserted_old = explicit_null_checks_inserted; - explicit_null_checks_elided_old = explicit_null_checks_elided; - } - - #endif --- 505,509 ----