Mercurial > hg > truffle
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()) |