hotspot/src/share/vm/c1/c1_Runtime1.cpp
changeset 360 21d113ecbf6a
parent 1 489c9b5090e2
child 670 ddf3e9583f2f
child 1374 4c24294029a9
equal deleted inserted replaced
357:f4edb0d9f109 360:21d113ecbf6a
  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