bool ObjArrayClass::compute_is_subtype_of(JavaClass* other_class) { if (!other_class->is_obj_array_class()) { return ArrayClass::compute_is_subtype_of(other_class); } ObjArrayClass::Raw other = other_class; JavaClass::Raw element = element_class(); JavaClass::Raw other_element = other().element_class(); return element().is_subtype_of(&other_element); }
void ObjArray::array_copy(ObjArray* src, jint src_pos, ObjArray* dst, jint dst_pos, jint length JVM_TRAPS) { // Special case. Boundary cases must be checked first // This allows the following call: copy_array(s, s.length(), // d.length(), 0). This is correct, since the position is supposed // to be an 'in between point', i.e., s.length(), points to the // right of the last element. if (length == 0) { return; } OopDesc** src_start = (OopDesc**) src->field_base(base_offset() + src_pos * oopSize); OopDesc** dst_start = (OopDesc**) dst->field_base(base_offset() + dst_pos * oopSize); if (src->equals(dst)) { // since source and destination are equal we do not need conversion checks. jvm_memmove(dst_start, src_start, length * oopSize); oop_write_barrier_range(dst_start, length); } else { // We have to make sure all elements conform to the destination array ObjArrayClass::Raw dst_class = dst->blueprint(); ObjArrayClass::Raw src_class = src->blueprint(); JavaClass::Raw bound = dst_class().element_class(); JavaClass::Raw stype = src_class().element_class(); if (stype.equals(&bound) || stype().is_subtype_of(&bound)) { // elements are guaranteed to be subtypes, so no check necessary jvm_memmove(dst_start, src_start, length * oopSize); oop_write_barrier_range(dst_start, length); return; } // Slow case: need individual subtype checks // Do store checks first so they're guaranteed to be done even if // an exception is thrown obj_at_put contains a write barrier already Oop::Raw element; JavaClass::Raw element_class; for (int index =0; index < length; index++) { element = src->obj_at( src_pos + index); if (element.is_null()) { dst->obj_at_put(dst_pos + index, &element); } else { element_class = element.blueprint(); if (element_class().is_subtype_of(&bound)) { dst->obj_at_put(dst_pos + index, &element); } else { Throw::array_store_exception(subtype_check_failed JVM_THROW); } } } } }