6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments

BcEscapeAnalyzer does not analyze methods with no oop arguments.

Reviewed-by: rasbold
This commit is contained in:
Vladimir Kozlov 2008-03-28 11:52:29 -07:00
parent fb63e29743
commit 2ea233816f
3 changed files with 73 additions and 67 deletions

View file

@ -1247,8 +1247,14 @@ void BCEscapeAnalyzer::compute_escape_info() {
initialize(); initialize();
// do not scan method if it has no object parameters // Do not scan method if it has no object parameters and
if (_arg_local.is_empty()) { // 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); methodData()->set_eflag(methodDataOopDesc::estimated);
return; return;
} }
@ -1259,45 +1265,8 @@ void BCEscapeAnalyzer::compute_escape_info() {
success = do_analysis(); success = do_analysis();
} }
// dump result of bytecode analysis // don't store interprocedural escape information if it introduces
#ifndef PRODUCT // dependencies or if method data is empty
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
// //
if (!has_dependencies() && !methodData()->is_empty()) { if (!has_dependencies() && !methodData()->is_empty()) {
for (i = 0; i < _arg_size; i++) { for (i = 0; i < _arg_size; i++) {
@ -1316,6 +1285,15 @@ void BCEscapeAnalyzer::compute_escape_info() {
if (_return_local) { if (_return_local) {
methodData()->set_eflag(methodDataOopDesc::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); methodData()->set_eflag(methodDataOopDesc::estimated);
} }
} }
@ -1331,10 +1309,17 @@ void BCEscapeAnalyzer::read_escape_info() {
_arg_modified[i] = methodData()->arg_modified(i); _arg_modified[i] = methodData()->arg_modified(i);
} }
_return_local = methodData()->eflag_set(methodDataOopDesc::return_local); _return_local = methodData()->eflag_set(methodDataOopDesc::return_local);
_return_allocated = methodData()->eflag_set(methodDataOopDesc::return_allocated);
_allocated_escapes = methodData()->eflag_set(methodDataOopDesc::allocated_escapes);
_unknown_modified = methodData()->eflag_set(methodDataOopDesc::unknown_modified);
}
// dump result of loaded escape information
#ifndef PRODUCT #ifndef PRODUCT
if (BCEATraceLevel >= 4) { 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: "); tty->print(" non-escaping args: ");
_arg_local.print_on(tty); _arg_local.print_on(tty);
tty->print(" stack-allocatable args: "); tty->print(" stack-allocatable args: ");
@ -1342,8 +1327,10 @@ void BCEscapeAnalyzer::read_escape_info() {
if (_return_local) { if (_return_local) {
tty->print(" returned args: "); tty->print(" returned args: ");
_arg_returned.print_on(tty); _arg_returned.print_on(tty);
} else if (is_return_allocated()) {
tty->print_cr(" return allocated value");
} else { } else {
tty->print_cr(" non-local return values"); tty->print_cr(" return non-local value");
} }
tty->print(" modified args: "); tty->print(" modified args: ");
for (int i = 0; i < _arg_size; i++) { for (int i = 0; i < _arg_size; i++) {
@ -1353,11 +1340,16 @@ void BCEscapeAnalyzer::read_escape_info() {
tty->print(" 0x%x", _arg_modified[i]); tty->print(" 0x%x", _arg_modified[i]);
} }
tty->cr(); tty->cr();
} tty->print(" flags: ");
#endif 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) BCEscapeAnalyzer::BCEscapeAnalyzer(ciMethod* method, BCEscapeAnalyzer* parent)
: _conservative(method == NULL || !EstimateArgEscape) : _conservative(method == NULL || !EstimateArgEscape)
@ -1401,6 +1393,12 @@ BCEscapeAnalyzer::BCEscapeAnalyzer(ciMethod* method, BCEscapeAnalyzer* parent)
compute_escape_info(); compute_escape_info();
methodData()->update_escape_info(); methodData()->update_escape_info();
} }
#ifndef PRODUCT
if (BCEATraceLevel >= 3) {
// dump escape information
dump();
}
#endif
} }
} }

View file

@ -50,9 +50,9 @@ class BCEscapeAnalyzer : public ResourceObj {
uint *_arg_modified; uint *_arg_modified;
bool _return_local; bool _return_local;
bool _return_allocated;
bool _allocated_escapes; bool _allocated_escapes;
bool _unknown_modified; bool _unknown_modified;
bool _return_allocated;
ciObjectList _dependencies; ciObjectList _dependencies;
@ -153,4 +153,9 @@ class BCEscapeAnalyzer : public ResourceObj {
// Copy dependencies from this analysis into "deps" // Copy dependencies from this analysis into "deps"
void copy_dependencies(Dependencies *deps); void copy_dependencies(Dependencies *deps);
#ifndef PRODUCT
// dump escape information
void dump();
#endif
}; };

View file

@ -1253,7 +1253,10 @@ public:
// Support for interprocedural escape analysis, from Thomas Kotzmann. // Support for interprocedural escape analysis, from Thomas Kotzmann.
enum EscapeFlag { enum EscapeFlag {
estimated = 1 << 0, 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; } intx eflags() { return _eflags; }