1072 // for now we just print out the block id |
1072 // for now we just print out the block id |
1073 tty->print("%d ", block_id); |
1073 tty->print("%d ", block_id); |
1074 JRT_END |
1074 JRT_END |
1075 |
1075 |
1076 |
1076 |
|
1077 // Array copy return codes. |
|
1078 enum { |
|
1079 ac_failed = -1, // arraycopy failed |
|
1080 ac_ok = 0 // arraycopy succeeded |
|
1081 }; |
|
1082 |
|
1083 |
|
1084 template <class T> int obj_arraycopy_work(oopDesc* src, T* src_addr, |
|
1085 oopDesc* dst, T* dst_addr, |
|
1086 int length) { |
|
1087 |
|
1088 // For performance reasons, we assume we are using a card marking write |
|
1089 // barrier. The assert will fail if this is not the case. |
|
1090 // Note that we use the non-virtual inlineable variant of write_ref_array. |
|
1091 BarrierSet* bs = Universe::heap()->barrier_set(); |
|
1092 assert(bs->has_write_ref_array_opt(), |
|
1093 "Barrier set must have ref array opt"); |
|
1094 if (src == dst) { |
|
1095 // same object, no check |
|
1096 Copy::conjoint_oops_atomic(src_addr, dst_addr, length); |
|
1097 bs->write_ref_array(MemRegion((HeapWord*)dst_addr, |
|
1098 (HeapWord*)(dst_addr + length))); |
|
1099 return ac_ok; |
|
1100 } else { |
|
1101 klassOop bound = objArrayKlass::cast(dst->klass())->element_klass(); |
|
1102 klassOop stype = objArrayKlass::cast(src->klass())->element_klass(); |
|
1103 if (stype == bound || Klass::cast(stype)->is_subtype_of(bound)) { |
|
1104 // Elements are guaranteed to be subtypes, so no check necessary |
|
1105 Copy::conjoint_oops_atomic(src_addr, dst_addr, length); |
|
1106 bs->write_ref_array(MemRegion((HeapWord*)dst_addr, |
|
1107 (HeapWord*)(dst_addr + length))); |
|
1108 return ac_ok; |
|
1109 } |
|
1110 } |
|
1111 return ac_failed; |
|
1112 } |
|
1113 |
1077 // fast and direct copy of arrays; returning -1, means that an exception may be thrown |
1114 // fast and direct copy of arrays; returning -1, means that an exception may be thrown |
1078 // and we did not copy anything |
1115 // and we did not copy anything |
1079 JRT_LEAF(int, Runtime1::arraycopy(oopDesc* src, int src_pos, oopDesc* dst, int dst_pos, int length)) |
1116 JRT_LEAF(int, Runtime1::arraycopy(oopDesc* src, int src_pos, oopDesc* dst, int dst_pos, int length)) |
1080 #ifndef PRODUCT |
1117 #ifndef PRODUCT |
1081 _generic_arraycopy_cnt++; // Slow-path oop array copy |
1118 _generic_arraycopy_cnt++; // Slow-path oop array copy |
1082 #endif |
1119 #endif |
1083 |
|
1084 enum { |
|
1085 ac_failed = -1, // arraycopy failed |
|
1086 ac_ok = 0 // arraycopy succeeded |
|
1087 }; |
|
1088 |
1120 |
1089 if (src == NULL || dst == NULL || src_pos < 0 || dst_pos < 0 || length < 0) return ac_failed; |
1121 if (src == NULL || dst == NULL || src_pos < 0 || dst_pos < 0 || length < 0) return ac_failed; |
1090 if (!dst->is_array() || !src->is_array()) return ac_failed; |
1122 if (!dst->is_array() || !src->is_array()) return ac_failed; |
1091 if ((unsigned int) arrayOop(src)->length() < (unsigned int)src_pos + (unsigned int)length) return ac_failed; |
1123 if ((unsigned int) arrayOop(src)->length() < (unsigned int)src_pos + (unsigned int)length) return ac_failed; |
1092 if ((unsigned int) arrayOop(dst)->length() < (unsigned int)dst_pos + (unsigned int)length) return ac_failed; |
1124 if ((unsigned int) arrayOop(dst)->length() < (unsigned int)dst_pos + (unsigned int)length) return ac_failed; |
1103 // Potential problem: memmove is not guaranteed to be word atomic |
1135 // Potential problem: memmove is not guaranteed to be word atomic |
1104 // Revisit in Merlin |
1136 // Revisit in Merlin |
1105 memmove(dst_addr, src_addr, length << l2es); |
1137 memmove(dst_addr, src_addr, length << l2es); |
1106 return ac_ok; |
1138 return ac_ok; |
1107 } else if (src->is_objArray() && dst->is_objArray()) { |
1139 } else if (src->is_objArray() && dst->is_objArray()) { |
1108 oop* src_addr = objArrayOop(src)->obj_at_addr(src_pos); |
1140 if (UseCompressedOops) { // will need for tiered |
1109 oop* dst_addr = objArrayOop(dst)->obj_at_addr(dst_pos); |
1141 narrowOop *src_addr = objArrayOop(src)->obj_at_addr<narrowOop>(src_pos); |
1110 // For performance reasons, we assume we are using a card marking write |
1142 narrowOop *dst_addr = objArrayOop(dst)->obj_at_addr<narrowOop>(dst_pos); |
1111 // barrier. The assert will fail if this is not the case. |
1143 return obj_arraycopy_work(src, src_addr, dst, dst_addr, length); |
1112 // Note that we use the non-virtual inlineable variant of write_ref_array. |
|
1113 BarrierSet* bs = Universe::heap()->barrier_set(); |
|
1114 assert(bs->has_write_ref_array_opt(), |
|
1115 "Barrier set must have ref array opt"); |
|
1116 if (src == dst) { |
|
1117 // same object, no check |
|
1118 Copy::conjoint_oops_atomic(src_addr, dst_addr, length); |
|
1119 bs->write_ref_array(MemRegion((HeapWord*)dst_addr, |
|
1120 (HeapWord*)(dst_addr + length))); |
|
1121 return ac_ok; |
|
1122 } else { |
1144 } else { |
1123 klassOop bound = objArrayKlass::cast(dst->klass())->element_klass(); |
1145 oop *src_addr = objArrayOop(src)->obj_at_addr<oop>(src_pos); |
1124 klassOop stype = objArrayKlass::cast(src->klass())->element_klass(); |
1146 oop *dst_addr = objArrayOop(dst)->obj_at_addr<oop>(dst_pos); |
1125 if (stype == bound || Klass::cast(stype)->is_subtype_of(bound)) { |
1147 return obj_arraycopy_work(src, src_addr, dst, dst_addr, length); |
1126 // Elements are guaranteed to be subtypes, so no check necessary |
|
1127 Copy::conjoint_oops_atomic(src_addr, dst_addr, length); |
|
1128 bs->write_ref_array(MemRegion((HeapWord*)dst_addr, |
|
1129 (HeapWord*)(dst_addr + length))); |
|
1130 return ac_ok; |
|
1131 } |
|
1132 } |
1148 } |
1133 } |
1149 } |
1134 return ac_failed; |
1150 return ac_failed; |
1135 JRT_END |
1151 JRT_END |
1136 |
1152 |