1073 ac_failed = -1, // arraycopy failed |
1073 ac_failed = -1, // arraycopy failed |
1074 ac_ok = 0 // arraycopy succeeded |
1074 ac_ok = 0 // arraycopy succeeded |
1075 }; |
1075 }; |
1076 |
1076 |
1077 |
1077 |
|
1078 // Below length is the # elements copied. |
1078 template <class T> int obj_arraycopy_work(oopDesc* src, T* src_addr, |
1079 template <class T> int obj_arraycopy_work(oopDesc* src, T* src_addr, |
1079 oopDesc* dst, T* dst_addr, |
1080 oopDesc* dst, T* dst_addr, |
1080 int length) { |
1081 int length) { |
1081 |
1082 |
1082 // For performance reasons, we assume we are using a card marking write |
1083 // For performance reasons, we assume we are using a card marking write |
1083 // barrier. The assert will fail if this is not the case. |
1084 // barrier. The assert will fail if this is not the case. |
1084 // Note that we use the non-virtual inlineable variant of write_ref_array. |
1085 // Note that we use the non-virtual inlineable variant of write_ref_array. |
1085 BarrierSet* bs = Universe::heap()->barrier_set(); |
1086 BarrierSet* bs = Universe::heap()->barrier_set(); |
1086 assert(bs->has_write_ref_array_opt(), |
1087 assert(bs->has_write_ref_array_opt(), "Barrier set must have ref array opt"); |
1087 "Barrier set must have ref array opt"); |
1088 assert(bs->has_write_ref_array_pre_opt(), "For pre-barrier as well."); |
1088 if (src == dst) { |
1089 if (src == dst) { |
1089 // same object, no check |
1090 // same object, no check |
|
1091 bs->write_ref_array_pre(dst_addr, length); |
1090 Copy::conjoint_oops_atomic(src_addr, dst_addr, length); |
1092 Copy::conjoint_oops_atomic(src_addr, dst_addr, length); |
1091 bs->write_ref_array(MemRegion((HeapWord*)dst_addr, |
1093 bs->write_ref_array((HeapWord*)dst_addr, length); |
1092 (HeapWord*)(dst_addr + length))); |
|
1093 return ac_ok; |
1094 return ac_ok; |
1094 } else { |
1095 } else { |
1095 klassOop bound = objArrayKlass::cast(dst->klass())->element_klass(); |
1096 klassOop bound = objArrayKlass::cast(dst->klass())->element_klass(); |
1096 klassOop stype = objArrayKlass::cast(src->klass())->element_klass(); |
1097 klassOop stype = objArrayKlass::cast(src->klass())->element_klass(); |
1097 if (stype == bound || Klass::cast(stype)->is_subtype_of(bound)) { |
1098 if (stype == bound || Klass::cast(stype)->is_subtype_of(bound)) { |
1098 // Elements are guaranteed to be subtypes, so no check necessary |
1099 // Elements are guaranteed to be subtypes, so no check necessary |
|
1100 bs->write_ref_array_pre(dst_addr, length); |
1099 Copy::conjoint_oops_atomic(src_addr, dst_addr, length); |
1101 Copy::conjoint_oops_atomic(src_addr, dst_addr, length); |
1100 bs->write_ref_array(MemRegion((HeapWord*)dst_addr, |
1102 bs->write_ref_array((HeapWord*)dst_addr, length); |
1101 (HeapWord*)(dst_addr + length))); |
|
1102 return ac_ok; |
1103 return ac_ok; |
1103 } |
1104 } |
1104 } |
1105 } |
1105 return ac_failed; |
1106 return ac_failed; |
1106 } |
1107 } |
1160 #ifndef PRODUCT |
1161 #ifndef PRODUCT |
1161 _oop_arraycopy_cnt++; |
1162 _oop_arraycopy_cnt++; |
1162 #endif |
1163 #endif |
1163 |
1164 |
1164 if (num == 0) return; |
1165 if (num == 0) return; |
|
1166 BarrierSet* bs = Universe::heap()->barrier_set(); |
|
1167 assert(bs->has_write_ref_array_opt(), "Barrier set must have ref array opt"); |
|
1168 assert(bs->has_write_ref_array_pre_opt(), "For pre-barrier as well."); |
|
1169 if (UseCompressedOops) { |
|
1170 bs->write_ref_array_pre((narrowOop*)dst, num); |
|
1171 } else { |
|
1172 bs->write_ref_array_pre((oop*)dst, num); |
|
1173 } |
1165 Copy::conjoint_oops_atomic((oop*) src, (oop*) dst, num); |
1174 Copy::conjoint_oops_atomic((oop*) src, (oop*) dst, num); |
1166 BarrierSet* bs = Universe::heap()->barrier_set(); |
1175 bs->write_ref_array(dst, num); |
1167 bs->write_ref_array(MemRegion(dst, dst + num)); |
|
1168 JRT_END |
1176 JRT_END |
1169 |
1177 |
1170 |
1178 |
1171 #ifndef PRODUCT |
1179 #ifndef PRODUCT |
1172 void Runtime1::print_statistics() { |
1180 void Runtime1::print_statistics() { |