mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 03:24:38 +02:00
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:
parent
fb63e29743
commit
2ea233816f
3 changed files with 73 additions and 67 deletions
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue