src/share/vm/opto/graphKit.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/opto

src/share/vm/opto/graphKit.cpp

Print this page
rev 7691 : 6912521: System.arraycopy works slower than the simple loop for little lengths
Summary: convert small array copies to series of loads and stores
Reviewed-by:


1646   }
1647   return store_oop(ctl, obj, adr, adr_type, val, val_type, bt, true, mo);
1648 }
1649 
1650 
1651 //-------------------------array_element_address-------------------------
1652 Node* GraphKit::array_element_address(Node* ary, Node* idx, BasicType elembt,
1653                                       const TypeInt* sizetype) {
1654   uint shift  = exact_log2(type2aelembytes(elembt));
1655   uint header = arrayOopDesc::base_offset_in_bytes(elembt);
1656 
1657   // short-circuit a common case (saves lots of confusing waste motion)
1658   jint idx_con = find_int_con(idx, -1);
1659   if (idx_con >= 0) {
1660     intptr_t offset = header + ((intptr_t)idx_con << shift);
1661     return basic_plus_adr(ary, offset);
1662   }
1663 
1664   // must be correct type for alignment purposes
1665   Node* base  = basic_plus_adr(ary, header);
1666 #ifdef _LP64
1667   // The scaled index operand to AddP must be a clean 64-bit value.
1668   // Java allows a 32-bit int to be incremented to a negative
1669   // value, which appears in a 64-bit register as a large
1670   // positive number.  Using that large positive number as an
1671   // operand in pointer arithmetic has bad consequences.
1672   // On the other hand, 32-bit overflow is rare, and the possibility
1673   // can often be excluded, if we annotate the ConvI2L node with
1674   // a type assertion that its value is known to be a small positive
1675   // number.  (The prior range check has ensured this.)
1676   // This assertion is used by ConvI2LNode::Ideal.
1677   int index_max = max_jint - 1;  // array size is max_jint, index is one less
1678   if (sizetype != NULL)  index_max = sizetype->_hi - 1;
1679   const TypeLong* lidxtype = TypeLong::make(CONST64(0), index_max, Type::WidenMax);
1680   idx = _gvn.transform( new ConvI2LNode(idx, lidxtype) );
1681 #endif
1682   Node* scale = _gvn.transform( new LShiftXNode(idx, intcon(shift)) );
1683   return basic_plus_adr(ary, base, scale);
1684 }
1685 
1686 //-------------------------load_array_element-------------------------
1687 Node* GraphKit::load_array_element(Node* ctl, Node* ary, Node* idx, const TypeAryPtr* arytype) {
1688   const Type* elemtype = arytype->elem();
1689   BasicType elembt = elemtype->array_element_basic_type();
1690   Node* adr = array_element_address(ary, idx, elembt, arytype->size());
1691   Node* ld = make_load(ctl, adr, elemtype, elembt, arytype, MemNode::unordered);
1692   return ld;
1693 }
1694 
1695 //-------------------------set_arguments_for_java_call-------------------------
1696 // Arguments (pre-popped from the stack) are taken from the JVMS.
1697 void GraphKit::set_arguments_for_java_call(CallJavaNode* call) {
1698   // Add the call arguments:
1699   uint nargs = call->method()->arg_size();
1700   for (uint i = 0; i < nargs; i++) {
1701     Node* arg = argument(i);




1646   }
1647   return store_oop(ctl, obj, adr, adr_type, val, val_type, bt, true, mo);
1648 }
1649 
1650 
1651 //-------------------------array_element_address-------------------------
1652 Node* GraphKit::array_element_address(Node* ary, Node* idx, BasicType elembt,
1653                                       const TypeInt* sizetype) {
1654   uint shift  = exact_log2(type2aelembytes(elembt));
1655   uint header = arrayOopDesc::base_offset_in_bytes(elembt);
1656 
1657   // short-circuit a common case (saves lots of confusing waste motion)
1658   jint idx_con = find_int_con(idx, -1);
1659   if (idx_con >= 0) {
1660     intptr_t offset = header + ((intptr_t)idx_con << shift);
1661     return basic_plus_adr(ary, offset);
1662   }
1663 
1664   // must be correct type for alignment purposes
1665   Node* base  = basic_plus_adr(ary, header);
1666   idx = Compile::conv_I2X_index(&_gvn, idx, sizetype);















1667   Node* scale = _gvn.transform( new LShiftXNode(idx, intcon(shift)) );
1668   return basic_plus_adr(ary, base, scale);
1669 }
1670 
1671 //-------------------------load_array_element-------------------------
1672 Node* GraphKit::load_array_element(Node* ctl, Node* ary, Node* idx, const TypeAryPtr* arytype) {
1673   const Type* elemtype = arytype->elem();
1674   BasicType elembt = elemtype->array_element_basic_type();
1675   Node* adr = array_element_address(ary, idx, elembt, arytype->size());
1676   Node* ld = make_load(ctl, adr, elemtype, elembt, arytype, MemNode::unordered);
1677   return ld;
1678 }
1679 
1680 //-------------------------set_arguments_for_java_call-------------------------
1681 // Arguments (pre-popped from the stack) are taken from the JVMS.
1682 void GraphKit::set_arguments_for_java_call(CallJavaNode* call) {
1683   // Add the call arguments:
1684   uint nargs = call->method()->arg_size();
1685   for (uint i = 0; i < nargs; i++) {
1686     Node* arg = argument(i);


src/share/vm/opto/graphKit.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File