comparison src/share/vm/ci/bcEscapeAnalyzer.cpp @ 78:e1e86702e43e

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
author kvn
date Fri, 28 Mar 2008 11:52:29 -0700
parents 48a3fa21394b
children 09c2ba680204
comparison
equal deleted inserted replaced
77:36cd3cc4d27b 78:e1e86702e43e
1245 1245
1246 bool success; 1246 bool success;
1247 1247
1248 initialize(); 1248 initialize();
1249 1249
1250 // do not scan method if it has no object parameters 1250 // Do not scan method if it has no object parameters and
1251 if (_arg_local.is_empty()) { 1251 // does not returns an object (_return_allocated is set in initialize()).
1252 if (_arg_local.is_empty() && !_return_allocated) {
1253 // Clear all info since method's bytecode was not analysed and
1254 // set pessimistic escape information.
1255 clear_escape_info();
1256 methodData()->set_eflag(methodDataOopDesc::allocated_escapes);
1257 methodData()->set_eflag(methodDataOopDesc::unknown_modified);
1252 methodData()->set_eflag(methodDataOopDesc::estimated); 1258 methodData()->set_eflag(methodDataOopDesc::estimated);
1253 return; 1259 return;
1254 } 1260 }
1255 1261
1256 if (iid != vmIntrinsics::_none) 1262 if (iid != vmIntrinsics::_none)
1257 success = compute_escape_for_intrinsic(iid); 1263 success = compute_escape_for_intrinsic(iid);
1258 else { 1264 else {
1259 success = do_analysis(); 1265 success = do_analysis();
1260 } 1266 }
1261 1267
1262 // dump result of bytecode analysis 1268 // don't store interprocedural escape information if it introduces
1263 #ifndef PRODUCT 1269 // dependencies or if method data is empty
1264 if (BCEATraceLevel >= 3) {
1265 tty->print("[EA] estimated escape information for");
1266 if (iid != vmIntrinsics::_none)
1267 tty->print(" intrinsic");
1268 method()->print_short_name();
1269 tty->print_cr(has_dependencies() ? " (not stored)" : "");
1270 tty->print(" non-escaping args: ");
1271 _arg_local.print_on(tty);
1272 tty->print(" stack-allocatable args: ");
1273 _arg_stack.print_on(tty);
1274 if (_return_local) {
1275 tty->print(" returned args: ");
1276 _arg_returned.print_on(tty);
1277 } else if (is_return_allocated()) {
1278 tty->print_cr(" allocated return values");
1279 } else {
1280 tty->print_cr(" non-local return values");
1281 }
1282 tty->print(" modified args: ");
1283 for (int i = 0; i < _arg_size; i++) {
1284 if (_arg_modified[i] == 0)
1285 tty->print(" 0");
1286 else
1287 tty->print(" 0x%x", _arg_modified[i]);
1288 }
1289 tty->cr();
1290 tty->print(" flags: ");
1291 if (_unknown_modified)
1292 tty->print(" unknown_modified");
1293 if (_return_allocated)
1294 tty->print(" return_allocated");
1295 tty->cr();
1296 }
1297
1298 #endif
1299 // don't store interprocedural escape information if it introduces dependencies
1300 // or if method data is empty
1301 // 1270 //
1302 if (!has_dependencies() && !methodData()->is_empty()) { 1271 if (!has_dependencies() && !methodData()->is_empty()) {
1303 for (i = 0; i < _arg_size; i++) { 1272 for (i = 0; i < _arg_size; i++) {
1304 if (_arg_local.at(i)) { 1273 if (_arg_local.at(i)) {
1305 assert(_arg_stack.at(i), "inconsistent escape info"); 1274 assert(_arg_stack.at(i), "inconsistent escape info");
1314 methodData()->set_arg_modified(i, _arg_modified[i]); 1283 methodData()->set_arg_modified(i, _arg_modified[i]);
1315 } 1284 }
1316 if (_return_local) { 1285 if (_return_local) {
1317 methodData()->set_eflag(methodDataOopDesc::return_local); 1286 methodData()->set_eflag(methodDataOopDesc::return_local);
1318 } 1287 }
1288 if (_return_allocated) {
1289 methodData()->set_eflag(methodDataOopDesc::return_allocated);
1290 }
1291 if (_allocated_escapes) {
1292 methodData()->set_eflag(methodDataOopDesc::allocated_escapes);
1293 }
1294 if (_unknown_modified) {
1295 methodData()->set_eflag(methodDataOopDesc::unknown_modified);
1296 }
1319 methodData()->set_eflag(methodDataOopDesc::estimated); 1297 methodData()->set_eflag(methodDataOopDesc::estimated);
1320 } 1298 }
1321 } 1299 }
1322 1300
1323 void BCEscapeAnalyzer::read_escape_info() { 1301 void BCEscapeAnalyzer::read_escape_info() {
1329 _arg_stack.at_put(i, methodData()->is_arg_stack(i)); 1307 _arg_stack.at_put(i, methodData()->is_arg_stack(i));
1330 _arg_returned.at_put(i, methodData()->is_arg_returned(i)); 1308 _arg_returned.at_put(i, methodData()->is_arg_returned(i));
1331 _arg_modified[i] = methodData()->arg_modified(i); 1309 _arg_modified[i] = methodData()->arg_modified(i);
1332 } 1310 }
1333 _return_local = methodData()->eflag_set(methodDataOopDesc::return_local); 1311 _return_local = methodData()->eflag_set(methodDataOopDesc::return_local);
1334 1312 _return_allocated = methodData()->eflag_set(methodDataOopDesc::return_allocated);
1335 // dump result of loaded escape information 1313 _allocated_escapes = methodData()->eflag_set(methodDataOopDesc::allocated_escapes);
1314 _unknown_modified = methodData()->eflag_set(methodDataOopDesc::unknown_modified);
1315
1316 }
1317
1336 #ifndef PRODUCT 1318 #ifndef PRODUCT
1337 if (BCEATraceLevel >= 4) { 1319 void BCEscapeAnalyzer::dump() {
1338 tty->print(" non-escaping args: "); 1320 tty->print("[EA] estimated escape information for");
1339 _arg_local.print_on(tty); 1321 method()->print_short_name();
1340 tty->print(" stack-allocatable args: "); 1322 tty->print_cr(has_dependencies() ? " (not stored)" : "");
1341 _arg_stack.print_on(tty); 1323 tty->print(" non-escaping args: ");
1342 if (_return_local) { 1324 _arg_local.print_on(tty);
1343 tty->print(" returned args: "); 1325 tty->print(" stack-allocatable args: ");
1344 _arg_returned.print_on(tty); 1326 _arg_stack.print_on(tty);
1345 } else { 1327 if (_return_local) {
1346 tty->print_cr(" non-local return values"); 1328 tty->print(" returned args: ");
1347 } 1329 _arg_returned.print_on(tty);
1348 tty->print(" modified args: "); 1330 } else if (is_return_allocated()) {
1349 for (int i = 0; i < _arg_size; i++) { 1331 tty->print_cr(" return allocated value");
1350 if (_arg_modified[i] == 0) 1332 } else {
1351 tty->print(" 0"); 1333 tty->print_cr(" return non-local value");
1352 else 1334 }
1353 tty->print(" 0x%x", _arg_modified[i]); 1335 tty->print(" modified args: ");
1354 } 1336 for (int i = 0; i < _arg_size; i++) {
1355 tty->cr(); 1337 if (_arg_modified[i] == 0)
1356 } 1338 tty->print(" 0");
1339 else
1340 tty->print(" 0x%x", _arg_modified[i]);
1341 }
1342 tty->cr();
1343 tty->print(" flags: ");
1344 if (_return_allocated)
1345 tty->print(" return_allocated");
1346 if (_allocated_escapes)
1347 tty->print(" allocated_escapes");
1348 if (_unknown_modified)
1349 tty->print(" unknown_modified");
1350 tty->cr();
1351 }
1357 #endif 1352 #endif
1358
1359 }
1360
1361 1353
1362 BCEscapeAnalyzer::BCEscapeAnalyzer(ciMethod* method, BCEscapeAnalyzer* parent) 1354 BCEscapeAnalyzer::BCEscapeAnalyzer(ciMethod* method, BCEscapeAnalyzer* parent)
1363 : _conservative(method == NULL || !EstimateArgEscape) 1355 : _conservative(method == NULL || !EstimateArgEscape)
1364 , _method(method) 1356 , _method(method)
1365 , _methodData(method ? method->method_data() : NULL) 1357 , _methodData(method ? method->method_data() : NULL)
1399 method->name()->as_utf8())); 1391 method->name()->as_utf8()));
1400 1392
1401 compute_escape_info(); 1393 compute_escape_info();
1402 methodData()->update_escape_info(); 1394 methodData()->update_escape_info();
1403 } 1395 }
1396 #ifndef PRODUCT
1397 if (BCEATraceLevel >= 3) {
1398 // dump escape information
1399 dump();
1400 }
1401 #endif
1404 } 1402 }
1405 } 1403 }
1406 1404
1407 void BCEscapeAnalyzer::copy_dependencies(Dependencies *deps) { 1405 void BCEscapeAnalyzer::copy_dependencies(Dependencies *deps) {
1408 if(!has_dependencies()) 1406 if(!has_dependencies())