예제 #1
0
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);
}
예제 #2
0
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);
        }
      }
    }
  }
}