55 const TypeLong* lidxtype = TypeLong::make(CONST64(0), index_max, Type::WidenMax);
56 idx = transform_later( new ConvI2LNode(idx, lidxtype) );
57 #endif
58 Node* scale = new LShiftXNode(idx, intcon(shift));
59 transform_later(scale);
60 return basic_plus_adr(ary, base, scale);
61 }
62
63 Node* PhaseMacroExpand::ConvI2L(Node* offset) {
64 return transform_later(new ConvI2LNode(offset));
65 }
66
67 Node* PhaseMacroExpand::make_leaf_call(Node* ctrl, Node* mem,
68 const TypeFunc* call_type, address call_addr,
69 const char* call_name,
70 const TypePtr* adr_type,
71 Node* parm0, Node* parm1,
72 Node* parm2, Node* parm3,
73 Node* parm4, Node* parm5,
74 Node* parm6, Node* parm7) {
75 int size = call_type->domain()->cnt();
76 Node* call = new CallLeafNoFPNode(call_type, call_addr, call_name, adr_type);
77 call->init_req(TypeFunc::Control, ctrl);
78 call->init_req(TypeFunc::I_O , top());
79 call->init_req(TypeFunc::Memory , mem);
80 call->init_req(TypeFunc::ReturnAdr, top());
81 call->init_req(TypeFunc::FramePtr, top());
82
83 // Hook each parm in order. Stop looking at the first NULL.
84 if (parm0 != NULL) { call->init_req(TypeFunc::Parms+0, parm0);
85 if (parm1 != NULL) { call->init_req(TypeFunc::Parms+1, parm1);
86 if (parm2 != NULL) { call->init_req(TypeFunc::Parms+2, parm2);
87 if (parm3 != NULL) { call->init_req(TypeFunc::Parms+3, parm3);
88 if (parm4 != NULL) { call->init_req(TypeFunc::Parms+4, parm4);
89 if (parm5 != NULL) { call->init_req(TypeFunc::Parms+5, parm5);
90 if (parm6 != NULL) { call->init_req(TypeFunc::Parms+6, parm6);
91 if (parm7 != NULL) { call->init_req(TypeFunc::Parms+7, parm7);
92 /* close each nested if ===> */ } } } } } } } }
93 assert(call->in(call->req()-1) != NULL, "must initialize all parms");
94
95 return call;
1066 Node* src_start = src;
1067 Node* dest_start = dest;
1068 if (src_offset != NULL || dest_offset != NULL) {
1069 src_start = array_element_address(src, src_offset, basic_elem_type);
1070 dest_start = array_element_address(dest, dest_offset, basic_elem_type);
1071 }
1072
1073 // Figure out which arraycopy runtime method to call.
1074 const char* copyfunc_name = "arraycopy";
1075 address copyfunc_addr =
1076 basictype2arraycopy(basic_elem_type, src_offset, dest_offset,
1077 disjoint_bases, copyfunc_name, dest_uninitialized);
1078
1079 const TypeFunc* call_type = OptoRuntime::fast_arraycopy_Type();
1080 Node* call = make_leaf_call(*ctrl, *mem, call_type, copyfunc_addr, copyfunc_name, adr_type,
1081 src_start, dest_start, copy_length XTOP);
1082
1083 finish_arraycopy_call(call, ctrl, mem, adr_type);
1084 }
1085
1086 void PhaseMacroExpand::expand_arraycopy_node(ArrayCopyNode *ac) {
1087 Node* ctrl = ac->in(TypeFunc::Control);
1088 Node* io = ac->in(TypeFunc::I_O);
1089 Node* src = ac->in(ArrayCopyNode::Src);
1090 Node* src_offset = ac->in(ArrayCopyNode::SrcPos);
1091 Node* dest = ac->in(ArrayCopyNode::Dest);
1092 Node* dest_offset = ac->in(ArrayCopyNode::DestPos);
1093 Node* length = ac->in(ArrayCopyNode::Length);
1094 MergeMemNode* merge_mem = NULL;
1095
1096 if (ac->is_clonebasic()) {
1097 assert (src_offset == NULL && dest_offset == NULL, "for clone offsets should be null");
1098 Node* mem = ac->in(TypeFunc::Memory);
1099 const char* copyfunc_name = "arraycopy";
1100 address copyfunc_addr =
1101 basictype2arraycopy(T_LONG, NULL, NULL,
1102 true, copyfunc_name, true);
1103
1104 const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM;
1105 const TypeFunc* call_type = OptoRuntime::fast_arraycopy_Type();
1106
1107 Node* call = make_leaf_call(ctrl, mem, call_type, copyfunc_addr, copyfunc_name, raw_adr_type, src, dest, length XTOP);
1108 transform_later(call);
1109
1110 _igvn.replace_node(ac, call);
1111 return;
1112 } else if (ac->is_copyof() || ac->is_copyofrange() || ac->is_cloneoop()) {
1113 Node* mem = ac->in(TypeFunc::Memory);
1114 merge_mem = MergeMemNode::make(mem);
1115 transform_later(merge_mem);
1116
1117 RegionNode* slow_region = new RegionNode(1);
1118 transform_later(slow_region);
1119
1120 AllocateArrayNode* alloc = NULL;
1121 if (ac->is_alloc_tightly_coupled()) {
1122 alloc = AllocateArrayNode::Ideal_array_allocation(dest, &_igvn);
1123 assert(alloc != NULL, "expect alloc");
1124 }
1125
1126 const TypePtr* adr_type = _igvn.type(dest)->is_oopptr()->add_offset(Type::OffsetBot);
1127 if (ac->_dest_type != TypeOopPtr::BOTTOM) {
1128 adr_type = ac->_dest_type->add_offset(Type::OffsetBot)->is_ptr();
1129 }
1130 generate_arraycopy(ac, alloc, &ctrl, merge_mem, &io,
|
55 const TypeLong* lidxtype = TypeLong::make(CONST64(0), index_max, Type::WidenMax);
56 idx = transform_later( new ConvI2LNode(idx, lidxtype) );
57 #endif
58 Node* scale = new LShiftXNode(idx, intcon(shift));
59 transform_later(scale);
60 return basic_plus_adr(ary, base, scale);
61 }
62
63 Node* PhaseMacroExpand::ConvI2L(Node* offset) {
64 return transform_later(new ConvI2LNode(offset));
65 }
66
67 Node* PhaseMacroExpand::make_leaf_call(Node* ctrl, Node* mem,
68 const TypeFunc* call_type, address call_addr,
69 const char* call_name,
70 const TypePtr* adr_type,
71 Node* parm0, Node* parm1,
72 Node* parm2, Node* parm3,
73 Node* parm4, Node* parm5,
74 Node* parm6, Node* parm7) {
75 Node* call = new CallLeafNoFPNode(call_type, call_addr, call_name, adr_type);
76 call->init_req(TypeFunc::Control, ctrl);
77 call->init_req(TypeFunc::I_O , top());
78 call->init_req(TypeFunc::Memory , mem);
79 call->init_req(TypeFunc::ReturnAdr, top());
80 call->init_req(TypeFunc::FramePtr, top());
81
82 // Hook each parm in order. Stop looking at the first NULL.
83 if (parm0 != NULL) { call->init_req(TypeFunc::Parms+0, parm0);
84 if (parm1 != NULL) { call->init_req(TypeFunc::Parms+1, parm1);
85 if (parm2 != NULL) { call->init_req(TypeFunc::Parms+2, parm2);
86 if (parm3 != NULL) { call->init_req(TypeFunc::Parms+3, parm3);
87 if (parm4 != NULL) { call->init_req(TypeFunc::Parms+4, parm4);
88 if (parm5 != NULL) { call->init_req(TypeFunc::Parms+5, parm5);
89 if (parm6 != NULL) { call->init_req(TypeFunc::Parms+6, parm6);
90 if (parm7 != NULL) { call->init_req(TypeFunc::Parms+7, parm7);
91 /* close each nested if ===> */ } } } } } } } }
92 assert(call->in(call->req()-1) != NULL, "must initialize all parms");
93
94 return call;
1065 Node* src_start = src;
1066 Node* dest_start = dest;
1067 if (src_offset != NULL || dest_offset != NULL) {
1068 src_start = array_element_address(src, src_offset, basic_elem_type);
1069 dest_start = array_element_address(dest, dest_offset, basic_elem_type);
1070 }
1071
1072 // Figure out which arraycopy runtime method to call.
1073 const char* copyfunc_name = "arraycopy";
1074 address copyfunc_addr =
1075 basictype2arraycopy(basic_elem_type, src_offset, dest_offset,
1076 disjoint_bases, copyfunc_name, dest_uninitialized);
1077
1078 const TypeFunc* call_type = OptoRuntime::fast_arraycopy_Type();
1079 Node* call = make_leaf_call(*ctrl, *mem, call_type, copyfunc_addr, copyfunc_name, adr_type,
1080 src_start, dest_start, copy_length XTOP);
1081
1082 finish_arraycopy_call(call, ctrl, mem, adr_type);
1083 }
1084
1085 bool PhaseMacroExpand::clone_needs_postbarrier(ArrayCopyNode *ac) {
1086 Node* src = ac->in(ArrayCopyNode::Src);
1087 const TypeOopPtr* src_type = _igvn.type(src)->is_oopptr();
1088 if (src_type->isa_instptr() != NULL) {
1089 ciInstanceKlass* ik = src_type->klass()->as_instance_klass();
1090 if ((src_type->klass_is_exact() || (!ik->is_interface() && !ik->has_subklass())) && !ik->has_injected_fields()) {
1091 if (ik->has_object_fields()) {
1092 return true;
1093 } else {
1094 if (!src_type->klass_is_exact()) {
1095 C->dependencies()->assert_leaf_type(ik);
1096 }
1097 }
1098 } else {
1099 return true;
1100 }
1101 } else if (src_type->isa_aryptr()) {
1102 BasicType src_elem = src_type->klass()->as_array_klass()->element_type()->basic_type();
1103 if (src_elem == T_OBJECT || src_elem == T_ARRAY) {
1104 return true;
1105 }
1106 } else {
1107 return true;
1108 }
1109 return false;
1110 }
1111
1112 void PhaseMacroExpand::expand_arraycopy_node(ArrayCopyNode *ac) {
1113 Node* ctrl = ac->in(TypeFunc::Control);
1114 Node* io = ac->in(TypeFunc::I_O);
1115 Node* src = ac->in(ArrayCopyNode::Src);
1116 Node* src_offset = ac->in(ArrayCopyNode::SrcPos);
1117 Node* dest = ac->in(ArrayCopyNode::Dest);
1118 Node* dest_offset = ac->in(ArrayCopyNode::DestPos);
1119 Node* length = ac->in(ArrayCopyNode::Length);
1120 MergeMemNode* merge_mem = NULL;
1121
1122 if (ac->is_clonebasic()) {
1123 assert (src_offset == NULL && dest_offset == NULL, "for clone offsets should be null");
1124 Node* mem = ac->in(TypeFunc::Memory);
1125 const char* copyfunc_name = "arraycopy";
1126 address copyfunc_addr =
1127 basictype2arraycopy(T_LONG, NULL, NULL,
1128 true, copyfunc_name, true);
1129
1130 const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM;
1131 const TypeFunc* call_type = OptoRuntime::fast_arraycopy_Type();
1132
1133 Node* call = make_leaf_call(ctrl, mem, call_type, copyfunc_addr, copyfunc_name, raw_adr_type, src, dest, length XTOP);
1134 transform_later(call);
1135
1136 if (clone_needs_postbarrier(ac)) {
1137 const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM;
1138 Node* c = new ProjNode(call,TypeFunc::Control);
1139 transform_later(c);
1140 Node* m = new ProjNode(call, TypeFunc::Memory);
1141 transform_later(m);
1142 BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
1143 bs->array_copy_post_barrier_at_expansion(ac, c, m, _igvn);
1144 Node* out_c = ac->proj_out(TypeFunc::Control);
1145 Node* out_m = ac->proj_out(TypeFunc::Memory);
1146 _igvn.replace_node(out_c, c);
1147 _igvn.replace_node(out_m, m);
1148 } else {
1149 _igvn.replace_node(ac, call);
1150 }
1151 return;
1152 } else if (ac->is_copyof() || ac->is_copyofrange() || ac->is_cloneoop()) {
1153 Node* mem = ac->in(TypeFunc::Memory);
1154 merge_mem = MergeMemNode::make(mem);
1155 transform_later(merge_mem);
1156
1157 RegionNode* slow_region = new RegionNode(1);
1158 transform_later(slow_region);
1159
1160 AllocateArrayNode* alloc = NULL;
1161 if (ac->is_alloc_tightly_coupled()) {
1162 alloc = AllocateArrayNode::Ideal_array_allocation(dest, &_igvn);
1163 assert(alloc != NULL, "expect alloc");
1164 }
1165
1166 const TypePtr* adr_type = _igvn.type(dest)->is_oopptr()->add_offset(Type::OffsetBot);
1167 if (ac->_dest_type != TypeOopPtr::BOTTOM) {
1168 adr_type = ac->_dest_type->add_offset(Type::OffsetBot)->is_ptr();
1169 }
1170 generate_arraycopy(ac, alloc, &ctrl, merge_mem, &io,
|