< prev index next >

src/share/vm/opto/macro.cpp

Print this page




1109   if (_fallthroughcatchproj != NULL) {
1110     _igvn.replace_node(_fallthroughcatchproj, alloc->in(TypeFunc::Control));
1111   }
1112   if (_memproj_fallthrough != NULL) {
1113     _igvn.replace_node(_memproj_fallthrough, alloc->in(TypeFunc::Memory));
1114   }
1115   if (_memproj_catchall != NULL) {
1116     _igvn.replace_node(_memproj_catchall, C->top());
1117   }
1118   if (_ioproj_fallthrough != NULL) {
1119     _igvn.replace_node(_ioproj_fallthrough, alloc->in(TypeFunc::I_O));
1120   }
1121   if (_ioproj_catchall != NULL) {
1122     _igvn.replace_node(_ioproj_catchall, C->top());
1123   }
1124   if (_catchallcatchproj != NULL) {
1125     _igvn.replace_node(_catchallcatchproj, C->top());
1126   }
1127 }
1128 





































































1129 bool PhaseMacroExpand::eliminate_allocate_node(AllocateNode *alloc) {
1130   // Don't do scalar replacement if the frame can be popped by JVMTI:
1131   // if reallocation fails during deoptimization we'll pop all
1132   // interpreter frames for this compiled frame and that won't play
1133   // nice with JVMTI popframe.
1134   if (!EliminateAllocations || JvmtiExport::can_pop_frame() || !alloc->_is_non_escaping) {
1135     return false;
1136   }
1137   Node* klass = alloc->in(AllocateNode::KlassNode);
1138   const TypeKlassPtr* tklass = _igvn.type(klass)->is_klassptr();
1139   Node* res = alloc->result_cast();
1140   // Eliminate boxing allocations which are not used
1141   // regardless scalar replacable status.
1142   bool boxing_alloc = C->eliminate_boxing() &&
1143                       tklass->klass()->is_instance_klass()  &&
1144                       tklass->klass()->as_instance_klass()->is_box_klass();
1145   if (!alloc->_is_scalar_replaceable && (!boxing_alloc || (res != NULL))) {
1146     return false;
1147   }
1148 


1617                                             CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc_base),
1618                                             "dtrace_object_alloc",
1619                                             TypeRawPtr::BOTTOM);
1620 
1621       // Get base of thread-local storage area
1622       Node* thread = new ThreadLocalNode();
1623       transform_later(thread);
1624 
1625       call->init_req(TypeFunc::Parms+0, thread);
1626       call->init_req(TypeFunc::Parms+1, fast_oop);
1627       call->init_req(TypeFunc::Control, fast_oop_ctrl);
1628       call->init_req(TypeFunc::I_O    , top()); // does no i/o
1629       call->init_req(TypeFunc::Memory , fast_oop_rawmem);
1630       call->init_req(TypeFunc::ReturnAdr, alloc->in(TypeFunc::ReturnAdr));
1631       call->init_req(TypeFunc::FramePtr, alloc->in(TypeFunc::FramePtr));
1632       transform_later(call);
1633       fast_oop_ctrl = new ProjNode(call,TypeFunc::Control);
1634       transform_later(fast_oop_ctrl);
1635       fast_oop_rawmem = new ProjNode(call,TypeFunc::Memory);
1636       transform_later(fast_oop_rawmem);



























































1637     }
1638 
1639     // Plug in the successful fast-path into the result merge point
1640     result_region    ->init_req(fast_result_path, fast_oop_ctrl);
1641     result_phi_rawoop->init_req(fast_result_path, fast_oop);
1642     result_phi_i_o   ->init_req(fast_result_path, i_o);
1643     result_phi_rawmem->init_req(fast_result_path, fast_oop_rawmem);
1644   } else {
1645     slow_region = ctrl;
1646     result_phi_i_o = i_o; // Rename it to use in the following code.
1647   }
1648 
1649   // Generate slow-path call
1650   CallNode *call = new CallStaticJavaNode(slow_call_type, slow_call_address,
1651                                OptoRuntime::stub_name(slow_call_address),
1652                                alloc->jvms()->bci(),
1653                                TypePtr::BOTTOM);
1654   call->init_req( TypeFunc::Control, slow_region );
1655   call->init_req( TypeFunc::I_O    , top() )     ;   // does no i/o
1656   call->init_req( TypeFunc::Memory , slow_mem ); // may gc ptrs




1109   if (_fallthroughcatchproj != NULL) {
1110     _igvn.replace_node(_fallthroughcatchproj, alloc->in(TypeFunc::Control));
1111   }
1112   if (_memproj_fallthrough != NULL) {
1113     _igvn.replace_node(_memproj_fallthrough, alloc->in(TypeFunc::Memory));
1114   }
1115   if (_memproj_catchall != NULL) {
1116     _igvn.replace_node(_memproj_catchall, C->top());
1117   }
1118   if (_ioproj_fallthrough != NULL) {
1119     _igvn.replace_node(_ioproj_fallthrough, alloc->in(TypeFunc::I_O));
1120   }
1121   if (_ioproj_catchall != NULL) {
1122     _igvn.replace_node(_ioproj_catchall, C->top());
1123   }
1124   if (_catchallcatchproj != NULL) {
1125     _igvn.replace_node(_catchallcatchproj, C->top());
1126   }
1127 }
1128 
1129 void PhaseMacroExpand::conditional_sample(Node *should_sample,
1130                                           BoolTest::mask test,
1131                                           float probability,
1132                                           CallLeafNode *call,
1133                                           Node *thread,
1134                                           Node **fast_oop_ctrl,
1135                                           Node **fast_oop_rawmem,
1136                                           Node **fast_oop,
1137                                           Node *size_in_bytes,
1138                                           Node *in_node) {
1139   Node* sample_cmp = new CmpXNode(should_sample, _igvn.MakeConX(0));
1140   transform_later(sample_cmp);
1141 
1142   Node *sample_bool = new BoolNode(sample_cmp, test);
1143   transform_later(sample_bool);
1144 
1145   IfNode *sample_if = new IfNode(*fast_oop_ctrl,
1146                                  sample_bool,
1147                                  probability,
1148                                  COUNT_UNKNOWN);
1149   transform_later(sample_if);
1150 
1151   // Slow-path call to sample
1152   Node *sample_true = new IfTrueNode(sample_if);
1153   transform_later(sample_true);
1154 
1155   // Fast path to no sample
1156   Node *sample_false = new IfFalseNode(sample_if);
1157   transform_later(sample_false);
1158 
1159   // Create postdominators for both the control and data flow paths.
1160   Node *sample_region = new RegionNode(3);
1161   Node *sample_phi_rawmem = new PhiNode(sample_region,
1162                                         Type::MEMORY,
1163                                         TypeRawPtr::BOTTOM);
1164 
1165   sample_region->init_req(1, sample_false);
1166   sample_phi_rawmem->init_req(1, *fast_oop_rawmem);
1167 
1168   // Invoke the sampling method on the slow path.
1169   int size = TypeFunc::Parms + 2;
1170 
1171   call->init_req(TypeFunc::Parms+0, thread);
1172   call->init_req(TypeFunc::Parms+1, *fast_oop);
1173   call->init_req(TypeFunc::Parms+2, size_in_bytes);
1174 #ifdef _LP64
1175   // The size is TypeX, so in a 64-bit JVM this a long, and we need
1176   //   // a second, dummy argument (an idiosyncracy of C2).
1177   call->init_req(TypeFunc::Parms+3, C->top());
1178 #endif
1179   call->init_req( TypeFunc::Control, sample_true);
1180   call->init_req( TypeFunc::I_O    , top());   // does no i/o
1181   call->init_req( TypeFunc::Memory , *fast_oop_rawmem );
1182   call->init_req( TypeFunc::ReturnAdr, in_node->in(TypeFunc::ReturnAdr));
1183   call->init_req( TypeFunc::FramePtr, in_node->in(TypeFunc::FramePtr));
1184   transform_later(call);
1185   Node *sample_oop_rawmem = new ProjNode(call, TypeFunc::Memory);
1186   transform_later(sample_oop_rawmem);
1187 
1188   // Tie the slow path to the postdominating node.
1189   sample_region->init_req(2, sample_true);
1190   sample_phi_rawmem->init_req(2, sample_oop_rawmem);
1191   transform_later(sample_region);
1192 
1193   *fast_oop_ctrl = sample_region;
1194   *fast_oop_rawmem = sample_phi_rawmem;
1195   transform_later(*fast_oop_rawmem);
1196 }
1197 
1198 bool PhaseMacroExpand::eliminate_allocate_node(AllocateNode *alloc) {
1199   // Don't do scalar replacement if the frame can be popped by JVMTI:
1200   // if reallocation fails during deoptimization we'll pop all
1201   // interpreter frames for this compiled frame and that won't play
1202   // nice with JVMTI popframe.
1203   if (!EliminateAllocations || JvmtiExport::can_pop_frame() || !alloc->_is_non_escaping) {
1204     return false;
1205   }
1206   Node* klass = alloc->in(AllocateNode::KlassNode);
1207   const TypeKlassPtr* tklass = _igvn.type(klass)->is_klassptr();
1208   Node* res = alloc->result_cast();
1209   // Eliminate boxing allocations which are not used
1210   // regardless scalar replacable status.
1211   bool boxing_alloc = C->eliminate_boxing() &&
1212                       tklass->klass()->is_instance_klass()  &&
1213                       tklass->klass()->as_instance_klass()->is_box_klass();
1214   if (!alloc->_is_scalar_replaceable && (!boxing_alloc || (res != NULL))) {
1215     return false;
1216   }
1217 


1686                                             CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc_base),
1687                                             "dtrace_object_alloc",
1688                                             TypeRawPtr::BOTTOM);
1689 
1690       // Get base of thread-local storage area
1691       Node* thread = new ThreadLocalNode();
1692       transform_later(thread);
1693 
1694       call->init_req(TypeFunc::Parms+0, thread);
1695       call->init_req(TypeFunc::Parms+1, fast_oop);
1696       call->init_req(TypeFunc::Control, fast_oop_ctrl);
1697       call->init_req(TypeFunc::I_O    , top()); // does no i/o
1698       call->init_req(TypeFunc::Memory , fast_oop_rawmem);
1699       call->init_req(TypeFunc::ReturnAdr, alloc->in(TypeFunc::ReturnAdr));
1700       call->init_req(TypeFunc::FramePtr, alloc->in(TypeFunc::FramePtr));
1701       transform_later(call);
1702       fast_oop_ctrl = new ProjNode(call,TypeFunc::Control);
1703       transform_later(fast_oop_ctrl);
1704       fast_oop_rawmem = new ProjNode(call,TypeFunc::Memory);
1705       transform_later(fast_oop_rawmem);
1706     }
1707 
1708     if (HeapMonitoring::initialized()) {
1709       // Inlined version of HeapMonitoring::object_alloc_base
1710       // Get base of thread-local storage area
1711       Node* thread = new ThreadLocalNode();
1712       transform_later(thread);
1713 
1714       ByteSize sample_offset = JavaThread::bytes_until_sample_offset();
1715 
1716       // Do test to see if we should sample.
1717       // Get bytes_until_sample from thread local storage.
1718       Node *bytes_until_sample = make_load(fast_oop_ctrl,
1719                                            fast_oop_rawmem,
1720                                            thread,
1721                                            in_bytes(sample_offset),
1722                                            TypeX_X,
1723                                            TypeX_X->basic_type());
1724 
1725       // new_bytes_until_sample = bytes_until_sample - size_in_bytes
1726       Node *new_bytes_until_sample =
1727           new SubXNode(bytes_until_sample, size_in_bytes);
1728       transform_later(new_bytes_until_sample);
1729 
1730       // bytes_until_sample = new_bytes_until_sample;
1731       fast_oop_rawmem = make_store(fast_oop_ctrl,
1732                                    fast_oop_rawmem,
1733                                    thread,
1734                                    in_bytes(sample_offset),
1735                                    new_bytes_until_sample,
1736                                    TypeX_X->basic_type());
1737 
1738       // Call to make if sampling succeeds
1739       CallLeafNode *call = new CallLeafNode(
1740           OptoRuntime::heap_object_alloc_Type(),
1741           CAST_FROM_FN_PTR(address,
1742                            HeapMonitoring::object_alloc_do_sample),
1743           "object_alloc_do_sample",
1744           TypeRawPtr::BOTTOM);
1745 
1746       // Copy debug information and adjust JVMState information:
1747       //   We are copying the debug information because the allocation JVMS
1748       //   might be modified/removed, etc. But also we want to preserve the JVMS
1749       //   in case this node is from an inlined method.
1750       copy_call_debug_info((CallNode *) alloc, call);
1751 
1752       // if (new_bytes_until_sample < 0)
1753       conditional_sample(new_bytes_until_sample,
1754                          BoolTest::le,
1755                          // Probability
1756                          // ~1/10000
1757                          PROB_UNLIKELY_MAG(4),
1758                          call,
1759                          thread,
1760                          &fast_oop_ctrl,
1761                          &fast_oop_rawmem,
1762                          &fast_oop,
1763                          size_in_bytes,
1764                          alloc);
1765     }
1766 
1767     // Plug in the successful fast-path into the result merge point
1768     result_region    ->init_req(fast_result_path, fast_oop_ctrl);
1769     result_phi_rawoop->init_req(fast_result_path, fast_oop);
1770     result_phi_i_o   ->init_req(fast_result_path, i_o);
1771     result_phi_rawmem->init_req(fast_result_path, fast_oop_rawmem);
1772   } else {
1773     slow_region = ctrl;
1774     result_phi_i_o = i_o; // Rename it to use in the following code.
1775   }
1776 
1777   // Generate slow-path call
1778   CallNode *call = new CallStaticJavaNode(slow_call_type, slow_call_address,
1779                                OptoRuntime::stub_name(slow_call_address),
1780                                alloc->jvms()->bci(),
1781                                TypePtr::BOTTOM);
1782   call->init_req( TypeFunc::Control, slow_region );
1783   call->init_req( TypeFunc::I_O    , top() )     ;   // does no i/o
1784   call->init_req( TypeFunc::Memory , slow_mem ); // may gc ptrs


< prev index next >