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
--- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp Thu Mar 27 09:12:54 2008 -0700
+++ b/hotspot/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
}
}
--- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.hpp Thu Mar 27 09:12:54 2008 -0700
+++ b/hotspot/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
};
--- a/hotspot/src/share/vm/oops/methodDataOop.hpp Thu Mar 27 09:12:54 2008 -0700
+++ b/hotspot/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; }