1386 result_phi_rawoop->init_req(fast_result_path, fast_oop); |
1386 result_phi_rawoop->init_req(fast_result_path, fast_oop); |
1387 result_phi_i_o ->init_req(fast_result_path, i_o); |
1387 result_phi_i_o ->init_req(fast_result_path, i_o); |
1388 result_phi_rawmem->init_req(fast_result_path, fast_oop_rawmem); |
1388 result_phi_rawmem->init_req(fast_result_path, fast_oop_rawmem); |
1389 } else { |
1389 } else { |
1390 slow_region = ctrl; |
1390 slow_region = ctrl; |
|
1391 result_phi_i_o = i_o; // Rename it to use in the following code. |
1391 } |
1392 } |
1392 |
1393 |
1393 // Generate slow-path call |
1394 // Generate slow-path call |
1394 CallNode *call = new (C, slow_call_type->domain()->cnt()) |
1395 CallNode *call = new (C, slow_call_type->domain()->cnt()) |
1395 CallStaticJavaNode(slow_call_type, slow_call_address, |
1396 CallStaticJavaNode(slow_call_type, slow_call_address, |
1410 // Copy debug information and adjust JVMState information, then replace |
1411 // Copy debug information and adjust JVMState information, then replace |
1411 // allocate node with the call |
1412 // allocate node with the call |
1412 copy_call_debug_info((CallNode *) alloc, call); |
1413 copy_call_debug_info((CallNode *) alloc, call); |
1413 if (!always_slow) { |
1414 if (!always_slow) { |
1414 call->set_cnt(PROB_UNLIKELY_MAG(4)); // Same effect as RC_UNCOMMON. |
1415 call->set_cnt(PROB_UNLIKELY_MAG(4)); // Same effect as RC_UNCOMMON. |
|
1416 } else { |
|
1417 // Hook i_o projection to avoid its elimination during allocation |
|
1418 // replacement (when only a slow call is generated). |
|
1419 call->set_req(TypeFunc::I_O, result_phi_i_o); |
1415 } |
1420 } |
1416 _igvn.replace_node(alloc, call); |
1421 _igvn.replace_node(alloc, call); |
1417 transform_later(call); |
1422 transform_later(call); |
1418 |
1423 |
1419 // Identify the output projections from the allocate node and |
1424 // Identify the output projections from the allocate node and |
1426 // |
1431 // |
1427 // We are interested in the CatchProj nodes. |
1432 // We are interested in the CatchProj nodes. |
1428 // |
1433 // |
1429 extract_call_projections(call); |
1434 extract_call_projections(call); |
1430 |
1435 |
1431 // An allocate node has separate memory projections for the uses on the control and i_o paths |
1436 // An allocate node has separate memory projections for the uses on |
1432 // Replace uses of the control memory projection with result_phi_rawmem (unless we are only generating a slow call) |
1437 // the control and i_o paths. Replace the control memory projection with |
|
1438 // result_phi_rawmem (unless we are only generating a slow call when |
|
1439 // both memory projections are combined) |
1433 if (!always_slow && _memproj_fallthrough != NULL) { |
1440 if (!always_slow && _memproj_fallthrough != NULL) { |
1434 for (DUIterator_Fast imax, i = _memproj_fallthrough->fast_outs(imax); i < imax; i++) { |
1441 for (DUIterator_Fast imax, i = _memproj_fallthrough->fast_outs(imax); i < imax; i++) { |
1435 Node *use = _memproj_fallthrough->fast_out(i); |
1442 Node *use = _memproj_fallthrough->fast_out(i); |
1436 _igvn.hash_delete(use); |
1443 _igvn.hash_delete(use); |
1437 imax -= replace_input(use, _memproj_fallthrough, result_phi_rawmem); |
1444 imax -= replace_input(use, _memproj_fallthrough, result_phi_rawmem); |
1438 _igvn._worklist.push(use); |
1445 _igvn._worklist.push(use); |
1439 // back up iterator |
1446 // back up iterator |
1440 --i; |
1447 --i; |
1441 } |
1448 } |
1442 } |
1449 } |
1443 // Now change uses of _memproj_catchall to use _memproj_fallthrough and delete _memproj_catchall so |
1450 // Now change uses of _memproj_catchall to use _memproj_fallthrough and delete |
1444 // we end up with a call that has only 1 memory projection |
1451 // _memproj_catchall so we end up with a call that has only 1 memory projection. |
1445 if (_memproj_catchall != NULL ) { |
1452 if (_memproj_catchall != NULL ) { |
1446 if (_memproj_fallthrough == NULL) { |
1453 if (_memproj_fallthrough == NULL) { |
1447 _memproj_fallthrough = new (C, 1) ProjNode(call, TypeFunc::Memory); |
1454 _memproj_fallthrough = new (C, 1) ProjNode(call, TypeFunc::Memory); |
1448 transform_later(_memproj_fallthrough); |
1455 transform_later(_memproj_fallthrough); |
1449 } |
1456 } |
1453 imax -= replace_input(use, _memproj_catchall, _memproj_fallthrough); |
1460 imax -= replace_input(use, _memproj_catchall, _memproj_fallthrough); |
1454 _igvn._worklist.push(use); |
1461 _igvn._worklist.push(use); |
1455 // back up iterator |
1462 // back up iterator |
1456 --i; |
1463 --i; |
1457 } |
1464 } |
1458 } |
1465 assert(_memproj_catchall->outcnt() == 0, "all uses must be deleted"); |
1459 |
1466 _igvn.remove_dead_node(_memproj_catchall); |
1460 // An allocate node has separate i_o projections for the uses on the control and i_o paths |
1467 } |
1461 // Replace uses of the control i_o projection with result_phi_i_o (unless we are only generating a slow call) |
1468 |
1462 if (_ioproj_fallthrough == NULL) { |
1469 // An allocate node has separate i_o projections for the uses on the control |
1463 _ioproj_fallthrough = new (C, 1) ProjNode(call, TypeFunc::I_O); |
1470 // and i_o paths. Always replace the control i_o projection with result i_o |
1464 transform_later(_ioproj_fallthrough); |
1471 // otherwise incoming i_o become dead when only a slow call is generated |
1465 } else if (!always_slow) { |
1472 // (it is different from memory projections where both projections are |
|
1473 // combined in such case). |
|
1474 if (_ioproj_fallthrough != NULL) { |
1466 for (DUIterator_Fast imax, i = _ioproj_fallthrough->fast_outs(imax); i < imax; i++) { |
1475 for (DUIterator_Fast imax, i = _ioproj_fallthrough->fast_outs(imax); i < imax; i++) { |
1467 Node *use = _ioproj_fallthrough->fast_out(i); |
1476 Node *use = _ioproj_fallthrough->fast_out(i); |
1468 |
|
1469 _igvn.hash_delete(use); |
1477 _igvn.hash_delete(use); |
1470 imax -= replace_input(use, _ioproj_fallthrough, result_phi_i_o); |
1478 imax -= replace_input(use, _ioproj_fallthrough, result_phi_i_o); |
1471 _igvn._worklist.push(use); |
1479 _igvn._worklist.push(use); |
1472 // back up iterator |
1480 // back up iterator |
1473 --i; |
1481 --i; |
1474 } |
1482 } |
1475 } |
1483 } |
1476 // Now change uses of _ioproj_catchall to use _ioproj_fallthrough and delete _ioproj_catchall so |
1484 // Now change uses of _ioproj_catchall to use _ioproj_fallthrough and delete |
1477 // we end up with a call that has only 1 control projection |
1485 // _ioproj_catchall so we end up with a call that has only 1 i_o projection. |
1478 if (_ioproj_catchall != NULL ) { |
1486 if (_ioproj_catchall != NULL ) { |
|
1487 if (_ioproj_fallthrough == NULL) { |
|
1488 _ioproj_fallthrough = new (C, 1) ProjNode(call, TypeFunc::I_O); |
|
1489 transform_later(_ioproj_fallthrough); |
|
1490 } |
1479 for (DUIterator_Fast imax, i = _ioproj_catchall->fast_outs(imax); i < imax; i++) { |
1491 for (DUIterator_Fast imax, i = _ioproj_catchall->fast_outs(imax); i < imax; i++) { |
1480 Node *use = _ioproj_catchall->fast_out(i); |
1492 Node *use = _ioproj_catchall->fast_out(i); |
1481 _igvn.hash_delete(use); |
1493 _igvn.hash_delete(use); |
1482 imax -= replace_input(use, _ioproj_catchall, _ioproj_fallthrough); |
1494 imax -= replace_input(use, _ioproj_catchall, _ioproj_fallthrough); |
1483 _igvn._worklist.push(use); |
1495 _igvn._worklist.push(use); |
1484 // back up iterator |
1496 // back up iterator |
1485 --i; |
1497 --i; |
1486 } |
1498 } |
|
1499 assert(_ioproj_catchall->outcnt() == 0, "all uses must be deleted"); |
|
1500 _igvn.remove_dead_node(_ioproj_catchall); |
1487 } |
1501 } |
1488 |
1502 |
1489 // if we generated only a slow call, we are done |
1503 // if we generated only a slow call, we are done |
1490 if (always_slow) |
1504 if (always_slow) { |
|
1505 // Now we can unhook i_o. |
|
1506 call->set_req(TypeFunc::I_O, top()); |
|
1507 if (result_phi_i_o->outcnt() == 0) |
|
1508 _igvn.remove_dead_node(result_phi_i_o); |
1491 return; |
1509 return; |
|
1510 } |
1492 |
1511 |
1493 |
1512 |
1494 if (_fallthroughcatchproj != NULL) { |
1513 if (_fallthroughcatchproj != NULL) { |
1495 ctrl = _fallthroughcatchproj->clone(); |
1514 ctrl = _fallthroughcatchproj->clone(); |
1496 transform_later(ctrl); |
1515 transform_later(ctrl); |