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) |