# HG changeset patch # User kvn # Date 1206730349 25200 # Node ID e1e86702e43e137e3a06c6f5420ae38dc23a5ac8 # Parent 36cd3cc4d27be491d89dc65bc6682396f1a3bae2 6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments Summary: bcEscapeAnalyzer does not analyze methods with no oop arguments. Reviewed-by: rasbold diff -r 36cd3cc4d27b -r e1e86702e43e src/share/vm/ci/bcEscapeAnalyzer.cpp --- a/src/share/vm/ci/bcEscapeAnalyzer.cpp Thu Mar 27 09:12:54 2008 -0700 +++ b/src/share/vm/ci/bcEscapeAnalyzer.cpp Fri Mar 28 11:52:29 2008 -0700 @@ -1247,8 +1247,14 @@ initialize(); - // do not scan method if it has no object parameters - if (_arg_local.is_empty()) { + // Do not scan method if it has no object parameters and + // does not returns an object (_return_allocated is set in initialize()). + if (_arg_local.is_empty() && !_return_allocated) { + // Clear all info since method's bytecode was not analysed and + // set pessimistic escape information. + clear_escape_info(); + methodData()->set_eflag(methodDataOopDesc::allocated_escapes); + methodData()->set_eflag(methodDataOopDesc::unknown_modified); methodData()->set_eflag(methodDataOopDesc::estimated); return; } @@ -1259,45 +1265,8 @@ success = do_analysis(); } - // dump result of bytecode analysis -#ifndef PRODUCT - if (BCEATraceLevel >= 3) { - tty->print("[EA] estimated escape information for"); - if (iid != vmIntrinsics::_none) - tty->print(" intrinsic"); - method()->print_short_name(); - tty->print_cr(has_dependencies() ? " (not stored)" : ""); - tty->print(" non-escaping args: "); - _arg_local.print_on(tty); - tty->print(" stack-allocatable args: "); - _arg_stack.print_on(tty); - if (_return_local) { - tty->print(" returned args: "); - _arg_returned.print_on(tty); - } else if (is_return_allocated()) { - tty->print_cr(" allocated return values"); - } else { - tty->print_cr(" non-local return values"); - } - tty->print(" modified args: "); - for (int i = 0; i < _arg_size; i++) { - if (_arg_modified[i] == 0) - tty->print(" 0"); - else - tty->print(" 0x%x", _arg_modified[i]); - } - tty->cr(); - tty->print(" flags: "); - if (_unknown_modified) - tty->print(" unknown_modified"); - if (_return_allocated) - tty->print(" return_allocated"); - tty->cr(); - } - -#endif - // don't store interprocedural escape information if it introduces dependencies - // or if method data is empty + // don't store interprocedural escape information if it introduces + // dependencies or if method data is empty // if (!has_dependencies() && !methodData()->is_empty()) { for (i = 0; i < _arg_size; i++) { @@ -1316,6 +1285,15 @@ if (_return_local) { methodData()->set_eflag(methodDataOopDesc::return_local); } + if (_return_allocated) { + methodData()->set_eflag(methodDataOopDesc::return_allocated); + } + if (_allocated_escapes) { + methodData()->set_eflag(methodDataOopDesc::allocated_escapes); + } + if (_unknown_modified) { + methodData()->set_eflag(methodDataOopDesc::unknown_modified); + } methodData()->set_eflag(methodDataOopDesc::estimated); } } @@ -1331,33 +1309,47 @@ _arg_modified[i] = methodData()->arg_modified(i); } _return_local = methodData()->eflag_set(methodDataOopDesc::return_local); - - // dump result of loaded escape information -#ifndef PRODUCT - if (BCEATraceLevel >= 4) { - tty->print(" non-escaping args: "); - _arg_local.print_on(tty); - tty->print(" stack-allocatable args: "); - _arg_stack.print_on(tty); - if (_return_local) { - tty->print(" returned args: "); - _arg_returned.print_on(tty); - } else { - tty->print_cr(" non-local return values"); - } - tty->print(" modified args: "); - for (int i = 0; i < _arg_size; i++) { - if (_arg_modified[i] == 0) - tty->print(" 0"); - else - tty->print(" 0x%x", _arg_modified[i]); - } - tty->cr(); - } -#endif + _return_allocated = methodData()->eflag_set(methodDataOopDesc::return_allocated); + _allocated_escapes = methodData()->eflag_set(methodDataOopDesc::allocated_escapes); + _unknown_modified = methodData()->eflag_set(methodDataOopDesc::unknown_modified); } +#ifndef PRODUCT +void BCEscapeAnalyzer::dump() { + tty->print("[EA] estimated escape information for"); + method()->print_short_name(); + tty->print_cr(has_dependencies() ? " (not stored)" : ""); + tty->print(" non-escaping args: "); + _arg_local.print_on(tty); + tty->print(" stack-allocatable args: "); + _arg_stack.print_on(tty); + if (_return_local) { + tty->print(" returned args: "); + _arg_returned.print_on(tty); + } else if (is_return_allocated()) { + tty->print_cr(" return allocated value"); + } else { + tty->print_cr(" return non-local value"); + } + tty->print(" modified args: "); + for (int i = 0; i < _arg_size; i++) { + if (_arg_modified[i] == 0) + tty->print(" 0"); + else + tty->print(" 0x%x", _arg_modified[i]); + } + tty->cr(); + tty->print(" flags: "); + if (_return_allocated) + tty->print(" return_allocated"); + if (_allocated_escapes) + tty->print(" allocated_escapes"); + if (_unknown_modified) + tty->print(" unknown_modified"); + tty->cr(); +} +#endif BCEscapeAnalyzer::BCEscapeAnalyzer(ciMethod* method, BCEscapeAnalyzer* parent) : _conservative(method == NULL || !EstimateArgEscape) @@ -1401,6 +1393,12 @@ compute_escape_info(); methodData()->update_escape_info(); } +#ifndef PRODUCT + if (BCEATraceLevel >= 3) { + // dump escape information + dump(); + } +#endif } } diff -r 36cd3cc4d27b -r e1e86702e43e src/share/vm/ci/bcEscapeAnalyzer.hpp --- a/src/share/vm/ci/bcEscapeAnalyzer.hpp Thu Mar 27 09:12:54 2008 -0700 +++ b/src/share/vm/ci/bcEscapeAnalyzer.hpp Fri Mar 28 11:52:29 2008 -0700 @@ -50,9 +50,9 @@ uint *_arg_modified; bool _return_local; + bool _return_allocated; bool _allocated_escapes; bool _unknown_modified; - bool _return_allocated; ciObjectList _dependencies; @@ -153,4 +153,9 @@ // Copy dependencies from this analysis into "deps" void copy_dependencies(Dependencies *deps); + +#ifndef PRODUCT + // dump escape information + void dump(); +#endif }; diff -r 36cd3cc4d27b -r e1e86702e43e src/share/vm/oops/methodDataOop.hpp --- a/src/share/vm/oops/methodDataOop.hpp Thu Mar 27 09:12:54 2008 -0700 +++ b/src/share/vm/oops/methodDataOop.hpp Fri Mar 28 11:52:29 2008 -0700 @@ -1253,7 +1253,10 @@ // Support for interprocedural escape analysis, from Thomas Kotzmann. enum EscapeFlag { estimated = 1 << 0, - return_local = 1 << 1 + return_local = 1 << 1, + return_allocated = 1 << 2, + allocated_escapes = 1 << 3, + unknown_modified = 1 << 4 }; intx eflags() { return _eflags; }