< prev index next >

src/hotspot/share/opto/macro.cpp

Print this page




1542     // Plug in the successful fast-path into the result merge point
1543     result_region    ->init_req(fast_result_path, fast_oop_ctrl);
1544     result_phi_rawoop->init_req(fast_result_path, fast_oop);
1545     result_phi_i_o   ->init_req(fast_result_path, i_o);
1546     result_phi_rawmem->init_req(fast_result_path, fast_oop_rawmem);
1547   } else {
1548     slow_region = ctrl;
1549     result_phi_i_o = i_o; // Rename it to use in the following code.
1550   }
1551 
1552   // Generate slow-path call
1553   CallNode *call = new CallStaticJavaNode(slow_call_type, slow_call_address,
1554                                OptoRuntime::stub_name(slow_call_address),
1555                                alloc->jvms()->bci(),
1556                                TypePtr::BOTTOM);
1557   call->init_req( TypeFunc::Control, slow_region );
1558   call->init_req( TypeFunc::I_O    , top() )     ;   // does no i/o
1559   call->init_req( TypeFunc::Memory , slow_mem ); // may gc ptrs
1560   call->init_req( TypeFunc::ReturnAdr, alloc->in(TypeFunc::ReturnAdr) );
1561   call->init_req( TypeFunc::FramePtr, alloc->in(TypeFunc::FramePtr) );
1562 




1563   call->init_req(TypeFunc::Parms+0, klass_node);
1564   if (length != NULL) {
1565     call->init_req(TypeFunc::Parms+1, length);
1566   }
1567 
1568   // Copy debug information and adjust JVMState information, then replace
1569   // allocate node with the call
1570   call->copy_call_debug_info(&_igvn, alloc);
1571   if (!always_slow) {
1572     call->set_cnt(PROB_UNLIKELY_MAG(4));  // Same effect as RC_UNCOMMON.
1573   } else {
1574     // Hook i_o projection to avoid its elimination during allocation
1575     // replacement (when only a slow call is generated).
1576     call->set_req(TypeFunc::I_O, result_phi_i_o);
1577   }
1578   _igvn.replace_node(alloc, call);
1579   transform_later(call);
1580 
1581   // Identify the output projections from the allocate node and
1582   // adjust any references to them.
1583   // The control and io projections look like:
1584   //
1585   //        v---Proj(ctrl) <-----+   v---CatchProj(ctrl)
1586   //  Allocate                   Catch
1587   //        ^---Proj(io) <-------+   ^---CatchProj(io)
1588   //
1589   //  We are interested in the CatchProj nodes.
1590   //
1591   extract_call_projections(call);
1592 
1593   // An allocate node has separate memory projections for the uses on
1594   // the control and i_o paths. Replace the control memory projection with
1595   // result_phi_rawmem (unless we are only generating a slow call when
1596   // both memory projections are combined)
1597   if (!always_slow && _memproj_fallthrough != NULL) {
1598     for (DUIterator_Fast imax, i = _memproj_fallthrough->fast_outs(imax); i < imax; i++) {
1599       Node *use = _memproj_fallthrough->fast_out(i);
1600       _igvn.rehash_node_delayed(use);
1601       imax -= replace_input(use, _memproj_fallthrough, result_phi_rawmem);
1602       // back up iterator
1603       --i;
1604     }
1605   }
1606   // Now change uses of _memproj_catchall to use _memproj_fallthrough and delete
1607   // _memproj_catchall so we end up with a call that has only 1 memory projection.
1608   if (_memproj_catchall != NULL ) {
1609     if (_memproj_fallthrough == NULL) {
1610       _memproj_fallthrough = new ProjNode(call, TypeFunc::Memory);
1611       transform_later(_memproj_fallthrough);
1612     }
1613     for (DUIterator_Fast imax, i = _memproj_catchall->fast_outs(imax); i < imax; i++) {
1614       Node *use = _memproj_catchall->fast_out(i);
1615       _igvn.rehash_node_delayed(use);
1616       imax -= replace_input(use, _memproj_catchall, _memproj_fallthrough);
1617       // back up iterator
1618       --i;
1619     }
1620     assert(_memproj_catchall->outcnt() == 0, "all uses must be deleted");
1621     _igvn.remove_dead_node(_memproj_catchall);
1622   }
1623 
1624   // An allocate node has separate i_o projections for the uses on the control
1625   // and i_o paths. Always replace the control i_o projection with result i_o
1626   // otherwise incoming i_o become dead when only a slow call is generated
1627   // (it is different from memory projections where both projections are
1628   // combined in such case).
1629   if (_ioproj_fallthrough != NULL) {
1630     for (DUIterator_Fast imax, i = _ioproj_fallthrough->fast_outs(imax); i < imax; i++) {
1631       Node *use = _ioproj_fallthrough->fast_out(i);
1632       _igvn.rehash_node_delayed(use);
1633       imax -= replace_input(use, _ioproj_fallthrough, result_phi_i_o);
1634       // back up iterator
1635       --i;
1636     }
1637   }
1638   // Now change uses of _ioproj_catchall to use _ioproj_fallthrough and delete
1639   // _ioproj_catchall so we end up with a call that has only 1 i_o projection.
1640   if (_ioproj_catchall != NULL ) {
1641     if (_ioproj_fallthrough == NULL) {
1642       _ioproj_fallthrough = new ProjNode(call, TypeFunc::I_O);
1643       transform_later(_ioproj_fallthrough);
1644     }
1645     for (DUIterator_Fast imax, i = _ioproj_catchall->fast_outs(imax); i < imax; i++) {
1646       Node *use = _ioproj_catchall->fast_out(i);
1647       _igvn.rehash_node_delayed(use);
1648       imax -= replace_input(use, _ioproj_catchall, _ioproj_fallthrough);
1649       // back up iterator
1650       --i;
1651     }
1652     assert(_ioproj_catchall->outcnt() == 0, "all uses must be deleted");
1653     _igvn.remove_dead_node(_ioproj_catchall);
1654   }
1655 
1656   // if we generated only a slow call, we are done
1657   if (always_slow) {
1658     // Now we can unhook i_o.
1659     if (result_phi_i_o->outcnt() > 1) {
1660       call->set_req(TypeFunc::I_O, top());
1661     } else {
1662       assert(result_phi_i_o->unique_ctrl_out() == call, "");
1663       // Case of new array with negative size known during compilation.
1664       // AllocateArrayNode::Ideal() optimization disconnect unreachable
1665       // following code since call to runtime will throw exception.
1666       // As result there will be no users of i_o after the call.
1667       // Leave i_o attached to this call to avoid problems in preceding graph.
1668     }
1669     return;
1670   }
1671 
1672   if (_fallthroughcatchproj != NULL) {




1542     // Plug in the successful fast-path into the result merge point
1543     result_region    ->init_req(fast_result_path, fast_oop_ctrl);
1544     result_phi_rawoop->init_req(fast_result_path, fast_oop);
1545     result_phi_i_o   ->init_req(fast_result_path, i_o);
1546     result_phi_rawmem->init_req(fast_result_path, fast_oop_rawmem);
1547   } else {
1548     slow_region = ctrl;
1549     result_phi_i_o = i_o; // Rename it to use in the following code.
1550   }
1551 
1552   // Generate slow-path call
1553   CallNode *call = new CallStaticJavaNode(slow_call_type, slow_call_address,
1554                                OptoRuntime::stub_name(slow_call_address),
1555                                alloc->jvms()->bci(),
1556                                TypePtr::BOTTOM);
1557   call->init_req( TypeFunc::Control, slow_region );
1558   call->init_req( TypeFunc::I_O    , top() )     ;   // does no i/o
1559   call->init_req( TypeFunc::Memory , slow_mem ); // may gc ptrs
1560   call->init_req( TypeFunc::ReturnAdr, alloc->in(TypeFunc::ReturnAdr) );
1561   call->init_req( TypeFunc::FramePtr, alloc->in(TypeFunc::FramePtr) );
1562   if (alloc->_larval) {
1563     // Tag the klass pointer to let the runtime know that this is a larval allocation
1564     klass_node = transform_later(new CastP2XNode(NULL, klass_node));
1565     klass_node = transform_later(new OrXNode(klass_node, _igvn.MakeConX(1)));
1566   }
1567   call->init_req(TypeFunc::Parms+0, klass_node);
1568   if (length != NULL) {
1569     call->init_req(TypeFunc::Parms+1, length);
1570   }
1571 
1572   // Copy debug information and adjust JVMState information, then replace
1573   // allocate node with the call
1574   call->copy_call_debug_info(&_igvn, alloc);
1575   if (!always_slow) {
1576     call->set_cnt(PROB_UNLIKELY_MAG(4));  // Same effect as RC_UNCOMMON.
1577   } else {
1578     // Hook i_o projection to avoid its elimination during allocation
1579     // replacement (when only a slow call is generated).
1580     call->set_req(TypeFunc::I_O, result_phi_i_o);
1581   }
1582   _igvn.replace_node(alloc, call);
1583   transform_later(call);
1584 
1585   // Identify the output projections from the allocate node and
1586   // adjust any references to them.
1587   // The control and io projections look like:
1588   //
1589   //        v---Proj(ctrl) <-----+   v---CatchProj(ctrl)
1590   //  Allocate                   Catch
1591   //        ^---Proj(io) <-------+   ^---CatchProj(io)
1592   //
1593   //  We are interested in the CatchProj nodes.
1594   //
1595   extract_call_projections(call);
1596 
1597   // An allocate node has separate memory projections for the uses on
1598   // the control and i_o paths. Replace the control memory projection with
1599   // result_phi_rawmem (unless we are only generating a slow call when
1600   // both memory projections are combined)
1601   if (!always_slow && _memproj_fallthrough != NULL) {
1602     _igvn.replace_in_uses(_memproj_fallthrough, result_phi_rawmem);






1603   }
1604   // Now change uses of _memproj_catchall to use _memproj_fallthrough and delete
1605   // _memproj_catchall so we end up with a call that has only 1 memory projection.
1606   if (_memproj_catchall != NULL) {
1607     if (_memproj_fallthrough == NULL) {
1608       _memproj_fallthrough = new ProjNode(call, TypeFunc::Memory);
1609       transform_later(_memproj_fallthrough);
1610     }
1611     _igvn.replace_in_uses(_memproj_catchall, _memproj_fallthrough);







1612     _igvn.remove_dead_node(_memproj_catchall);
1613   }
1614 
1615   // An allocate node has separate i_o projections for the uses on the control
1616   // and i_o paths. Always replace the control i_o projection with result i_o
1617   // otherwise incoming i_o become dead when only a slow call is generated
1618   // (it is different from memory projections where both projections are
1619   // combined in such case).
1620   if (_ioproj_fallthrough != NULL) {
1621     _igvn.replace_in_uses(_ioproj_fallthrough, result_phi_i_o);






1622   }
1623   // Now change uses of _ioproj_catchall to use _ioproj_fallthrough and delete
1624   // _ioproj_catchall so we end up with a call that has only 1 i_o projection.
1625   if (_ioproj_catchall != NULL) {
1626     if (_ioproj_fallthrough == NULL) {
1627       _ioproj_fallthrough = new ProjNode(call, TypeFunc::I_O);
1628       transform_later(_ioproj_fallthrough);
1629     }
1630     _igvn.replace_in_uses(_ioproj_catchall, _ioproj_fallthrough);







1631     _igvn.remove_dead_node(_ioproj_catchall);
1632   }
1633 
1634   // if we generated only a slow call, we are done
1635   if (always_slow) {
1636     // Now we can unhook i_o.
1637     if (result_phi_i_o->outcnt() > 1) {
1638       call->set_req(TypeFunc::I_O, top());
1639     } else {
1640       assert(result_phi_i_o->unique_ctrl_out() == call, "");
1641       // Case of new array with negative size known during compilation.
1642       // AllocateArrayNode::Ideal() optimization disconnect unreachable
1643       // following code since call to runtime will throw exception.
1644       // As result there will be no users of i_o after the call.
1645       // Leave i_o attached to this call to avoid problems in preceding graph.
1646     }
1647     return;
1648   }
1649 
1650   if (_fallthroughcatchproj != NULL) {


< prev index next >