< prev index next >

src/hotspot/share/oops/objArrayKlass.cpp

Print this page




 146     bk = element_klass;
 147   }
 148   assert(bk != NULL && (bk->is_instance_klass()
 149       || bk->is_typeArray_klass()), "invalid bottom klass");
 150   this->set_bottom_klass(bk);
 151   this->set_class_loader_data(bk->class_loader_data());
 152 
 153   this->set_layout_helper(array_layout_helper(T_OBJECT));
 154   assert(this->is_array_klass(), "sanity");
 155   assert(this->is_objArray_klass(), "sanity");
 156 }
 157 
 158 int ObjArrayKlass::oop_size(oop obj) const {
 159   assert(obj->is_objArray(), "must be object array");
 160   return objArrayOop(obj)->object_size();
 161 }
 162 
 163 objArrayOop ObjArrayKlass::allocate(int length, TRAPS) {
 164   check_array_allocation_length(length, arrayOopDesc::max_array_length(T_OBJECT), CHECK_0);
 165   int size = objArrayOopDesc::object_size(length);
 166   bool populate_null_free = storage_properties().is_null_free() && (dimension() == 1);
 167   objArrayOop array =  (objArrayOop)Universe::heap()->array_allocate(this, size, length,
 168                                                        /* do_zero */ true, THREAD);
 169   if (populate_null_free) {

 170     assert(element_klass()->is_value(), "Unexpected");
 171     assert(!element_klass()->is_array_klass(), "ArrayKlass unexpected here");

 172     element_klass()->initialize(CHECK_NULL);
 173     // Populate default values...
 174     objArrayHandle array_h(THREAD, array);
 175     instanceOop value = (instanceOop) ValueKlass::cast(element_klass())->default_value();
 176     for (int i = 0; i < length; i++) {
 177       array_h->obj_at_put(i, value);
 178     }
 179   }
 180   return array;
 181 }
 182 
 183 oop ObjArrayKlass::multi_allocate(int rank, jint* sizes, TRAPS) {
 184   int length = *sizes;
 185   if (rank == 1) { // last dim may be valueArray, check if we have any special storage requirements
 186     if ((!element_klass()->is_array_klass()) && storage_properties().is_null_free()) {
 187       return oopFactory::new_valueArray(element_klass(), length, CHECK_NULL);
 188     } else {
 189       return oopFactory::new_objArray(element_klass(), length, CHECK_NULL);
 190     }
 191   }


 200     for (int index = 0; index < length; index++) {
 201       ArrayKlass* ak = ArrayKlass::cast(ld_klass);
 202       oop sub_array = ak->multi_allocate(rank-1, &sizes[1], CHECK_NULL);
 203       h_array->obj_at_put(index, sub_array);
 204     }
 205   } else {
 206     // Since this array dimension has zero length, nothing will be
 207     // allocated, however the lower dimension values must be checked
 208     // for illegal values.
 209     for (int i = 0; i < rank - 1; ++i) {
 210       sizes += 1;
 211       if (*sizes < 0) {
 212         THROW_MSG_0(vmSymbols::java_lang_NegativeArraySizeException(), err_msg("%d", *sizes));
 213       }
 214     }
 215   }
 216   return h_array();
 217 }
 218 
 219 ArrayStorageProperties ObjArrayKlass::storage_properties() {
 220   return name()->is_Q_array_signature() ? ArrayStorageProperties::null_free : ArrayStorageProperties::empty;
 221 }
 222 
 223 // Either oop or narrowOop depending on UseCompressedOops.
 224 void ObjArrayKlass::do_copy(arrayOop s, size_t src_offset,
 225                             arrayOop d, size_t dst_offset, int length, TRAPS) {
 226   if (oopDesc::equals(s, d)) {
 227     // since source and destination are equal we do not need conversion checks.
 228     assert(length > 0, "sanity check");
 229     ArrayAccess<>::oop_arraycopy(s, src_offset, d, dst_offset, length);
 230   } else {
 231     // We have to make sure all elements conform to the destination array
 232     Klass* bound = ObjArrayKlass::cast(d->klass())->element_klass();
 233     Klass* stype = ObjArrayKlass::cast(s->klass())->element_klass();
 234     if (stype == bound || stype->is_subtype_of(bound)) {
 235       // elements are guaranteed to be subtypes, so no check necessary
 236       ArrayAccess<ARRAYCOPY_DISJOINT>::oop_arraycopy(s, src_offset, d, dst_offset, length);
 237     } else {
 238       // slow case: need individual subtype checks
 239       // note: don't use obj_at_put below because it includes a redundant store check
 240       if (!ArrayAccess<ARRAYCOPY_DISJOINT | ARRAYCOPY_CHECKCAST>::oop_arraycopy(s, src_offset, d, dst_offset, length)) {




 146     bk = element_klass;
 147   }
 148   assert(bk != NULL && (bk->is_instance_klass()
 149       || bk->is_typeArray_klass()), "invalid bottom klass");
 150   this->set_bottom_klass(bk);
 151   this->set_class_loader_data(bk->class_loader_data());
 152 
 153   this->set_layout_helper(array_layout_helper(T_OBJECT));
 154   assert(this->is_array_klass(), "sanity");
 155   assert(this->is_objArray_klass(), "sanity");
 156 }
 157 
 158 int ObjArrayKlass::oop_size(oop obj) const {
 159   assert(obj->is_objArray(), "must be object array");
 160   return objArrayOop(obj)->object_size();
 161 }
 162 
 163 objArrayOop ObjArrayKlass::allocate(int length, TRAPS) {
 164   check_array_allocation_length(length, arrayOopDesc::max_array_length(T_OBJECT), CHECK_0);
 165   int size = objArrayOopDesc::object_size(length);
 166   bool populate_null_free = storage_properties().is_null_free();
 167   objArrayOop array =  (objArrayOop)Universe::heap()->array_allocate(this, size, length,
 168                                                        /* do_zero */ true, THREAD);
 169   if (populate_null_free) {
 170     assert(dimension() == 1, "Can only populate the final dimension");
 171     assert(element_klass()->is_value(), "Unexpected");
 172     assert(!element_klass()->is_array_klass(), "ArrayKlass unexpected here");
 173     assert(!ValueKlass::cast(element_klass())->flatten_array(), "Expected valueArrayOop allocation");
 174     element_klass()->initialize(CHECK_NULL);
 175     // Populate default values...
 176     objArrayHandle array_h(THREAD, array);
 177     instanceOop value = (instanceOop) ValueKlass::cast(element_klass())->default_value();
 178     for (int i = 0; i < length; i++) {
 179       array_h->obj_at_put(i, value);
 180     }
 181   }
 182   return array;
 183 }
 184 
 185 oop ObjArrayKlass::multi_allocate(int rank, jint* sizes, TRAPS) {
 186   int length = *sizes;
 187   if (rank == 1) { // last dim may be valueArray, check if we have any special storage requirements
 188     if ((!element_klass()->is_array_klass()) && storage_properties().is_null_free()) {
 189       return oopFactory::new_valueArray(element_klass(), length, CHECK_NULL);
 190     } else {
 191       return oopFactory::new_objArray(element_klass(), length, CHECK_NULL);
 192     }
 193   }


 202     for (int index = 0; index < length; index++) {
 203       ArrayKlass* ak = ArrayKlass::cast(ld_klass);
 204       oop sub_array = ak->multi_allocate(rank-1, &sizes[1], CHECK_NULL);
 205       h_array->obj_at_put(index, sub_array);
 206     }
 207   } else {
 208     // Since this array dimension has zero length, nothing will be
 209     // allocated, however the lower dimension values must be checked
 210     // for illegal values.
 211     for (int i = 0; i < rank - 1; ++i) {
 212       sizes += 1;
 213       if (*sizes < 0) {
 214         THROW_MSG_0(vmSymbols::java_lang_NegativeArraySizeException(), err_msg("%d", *sizes));
 215       }
 216     }
 217   }
 218   return h_array();
 219 }
 220 
 221 ArrayStorageProperties ObjArrayKlass::storage_properties() {
 222   return name()->is_Q_singledim_array_signature() ? ArrayStorageProperties::null_free : ArrayStorageProperties::empty;
 223 }
 224 
 225 // Either oop or narrowOop depending on UseCompressedOops.
 226 void ObjArrayKlass::do_copy(arrayOop s, size_t src_offset,
 227                             arrayOop d, size_t dst_offset, int length, TRAPS) {
 228   if (oopDesc::equals(s, d)) {
 229     // since source and destination are equal we do not need conversion checks.
 230     assert(length > 0, "sanity check");
 231     ArrayAccess<>::oop_arraycopy(s, src_offset, d, dst_offset, length);
 232   } else {
 233     // We have to make sure all elements conform to the destination array
 234     Klass* bound = ObjArrayKlass::cast(d->klass())->element_klass();
 235     Klass* stype = ObjArrayKlass::cast(s->klass())->element_klass();
 236     if (stype == bound || stype->is_subtype_of(bound)) {
 237       // elements are guaranteed to be subtypes, so no check necessary
 238       ArrayAccess<ARRAYCOPY_DISJOINT>::oop_arraycopy(s, src_offset, d, dst_offset, length);
 239     } else {
 240       // slow case: need individual subtype checks
 241       // note: don't use obj_at_put below because it includes a redundant store check
 242       if (!ArrayAccess<ARRAYCOPY_DISJOINT | ARRAYCOPY_CHECKCAST>::oop_arraycopy(s, src_offset, d, dst_offset, length)) {


< prev index next >