< prev index next >

src/share/vm/oops/objArrayKlass.cpp

Print this page
rev 12906 : [mq]: gc_interface


  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/moduleEntry.hpp"
  27 #include "classfile/packageEntry.hpp"
  28 #include "classfile/symbolTable.hpp"
  29 #include "classfile/systemDictionary.hpp"
  30 #include "classfile/vmSymbols.hpp"
  31 #include "gc/shared/collectedHeap.inline.hpp"
  32 #include "gc/shared/specialized_oop_closures.hpp"
  33 #include "memory/iterator.inline.hpp"
  34 #include "memory/metadataFactory.hpp"
  35 #include "memory/resourceArea.hpp"
  36 #include "memory/universe.inline.hpp"
  37 #include "oops/arrayKlass.inline.hpp"
  38 #include "oops/instanceKlass.hpp"
  39 #include "oops/klass.inline.hpp"
  40 #include "oops/objArrayKlass.inline.hpp"
  41 #include "oops/objArrayOop.inline.hpp"
  42 #include "oops/oop.inline.hpp"
  43 #include "oops/symbol.hpp"

  44 #include "runtime/handles.inline.hpp"
  45 #include "runtime/mutexLocker.hpp"
  46 #include "utilities/copy.hpp"
  47 #include "utilities/macros.hpp"
  48 
  49 ObjArrayKlass* ObjArrayKlass::allocate(ClassLoaderData* loader_data, int n, Klass* k, Symbol* name, TRAPS) {
  50   assert(ObjArrayKlass::header_size() <= InstanceKlass::header_size(),
  51       "array klasses must be same size as InstanceKlass");
  52 
  53   int size = ArrayKlass::static_size(ObjArrayKlass::header_size());
  54 
  55   return new (loader_data, size, THREAD) ObjArrayKlass(n, k, name);
  56 }
  57 
  58 Klass* ObjArrayKlass::allocate_objArray_klass(ClassLoaderData* loader_data,
  59                                                 int n, Klass* element_klass, TRAPS) {
  60 
  61   // Eagerly allocate the direct array supertype.
  62   Klass* super_klass = NULL;
  63   if (!Universe::is_bootstrapping() || SystemDictionary::Object_klass_loaded()) {
  64     Klass* element_super = element_klass->super();
  65     if (element_super != NULL) {
  66       // The element type has a direct super.  E.g., String[] has direct super of Object[].


 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_0(vmSymbols::java_lang_NegativeArraySizeException());
 213         }
 214       }
 215     }
 216   }
 217   return h_array();
 218 }
 219 
 220 // Either oop or narrowOop depending on UseCompressedOops.
 221 template <class T> void ObjArrayKlass::do_copy(arrayOop s, T* src,
 222                                arrayOop d, T* dst, int length, TRAPS) {
 223 
 224   BarrierSet* bs = Universe::heap()->barrier_set();
 225   // For performance reasons, we assume we are that the write barrier we
 226   // are using has optimized modes for arrays of references.  At least one
 227   // of the asserts below will fail if this is not the case.
 228   assert(bs->has_write_ref_array_opt(), "Barrier set must have ref array opt");
 229   assert(bs->has_write_ref_array_pre_opt(), "For pre-barrier as well.");
 230 
 231   if (s == d) {
 232     // since source and destination are equal we do not need conversion checks.
 233     assert(length > 0, "sanity check");
 234     bs->write_ref_array_pre(dst, length);
 235     Copy::conjoint_oops_atomic(src, dst, length);
 236   } else {
 237     // We have to make sure all elements conform to the destination array
 238     Klass* bound = ObjArrayKlass::cast(d->klass())->element_klass();
 239     Klass* stype = ObjArrayKlass::cast(s->klass())->element_klass();
 240     if (stype == bound || stype->is_subtype_of(bound)) {
 241       // elements are guaranteed to be subtypes, so no check necessary
 242       bs->write_ref_array_pre(dst, length);
 243       Copy::conjoint_oops_atomic(src, dst, length);
 244     } else {
 245       // slow case: need individual subtype checks
 246       // note: don't use obj_at_put below because it includes a redundant store check
 247       T* from = src;
 248       T* end = from + length;
 249       for (T* p = dst; from < end; from++, p++) {
 250         // XXX this is going to be slow.
 251         T element = *from;
 252         // even slower now
 253         bool element_is_null = oopDesc::is_null(element);
 254         oop new_val = element_is_null ? oop(NULL)
 255                                       : oopDesc::decode_heap_oop_not_null(element);
 256         if (element_is_null ||
 257             (new_val->klass())->is_subtype_of(bound)) {
 258           bs->write_ref_field_pre(p, new_val);
 259           *p = element;
 260         } else {
 261           // We must do a barrier to cover the partial copy.
 262           const size_t pd = pointer_delta(p, dst, (size_t)heapOopSize);
 263           // pointer delta is scaled to number of elements (length field in
 264           // objArrayOop) which we assume is 32 bit.
 265           assert(pd == (size_t)(int)pd, "length field overflow");
 266           bs->write_ref_array((HeapWord*)dst, pd);
 267           THROW(vmSymbols::java_lang_ArrayStoreException());
 268           return;
 269         }
 270       }
 271     }
 272   }
 273   bs->write_ref_array((HeapWord*)dst, length);
 274 }
 275 
 276 void ObjArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d,
 277                                int dst_pos, int length, TRAPS) {
 278   assert(s->is_objArray(), "must be obj array");
 279 
 280   if (!d->is_objArray()) {
 281     THROW(vmSymbols::java_lang_ArrayStoreException());
 282   }
 283 
 284   // Check is all offsets and lengths are non negative
 285   if (src_pos < 0 || dst_pos < 0 || length < 0) {
 286     THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
 287   }
 288   // Check if the ranges are valid
 289   if  ( (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length())
 290      || (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length()) ) {
 291     THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
 292   }
 293 




  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/moduleEntry.hpp"
  27 #include "classfile/packageEntry.hpp"
  28 #include "classfile/symbolTable.hpp"
  29 #include "classfile/systemDictionary.hpp"
  30 #include "classfile/vmSymbols.hpp"
  31 #include "gc/shared/collectedHeap.inline.hpp"
  32 #include "gc/shared/specialized_oop_closures.hpp"
  33 #include "memory/iterator.inline.hpp"
  34 #include "memory/metadataFactory.hpp"
  35 #include "memory/resourceArea.hpp"
  36 #include "memory/universe.inline.hpp"
  37 #include "oops/arrayKlass.inline.hpp"
  38 #include "oops/instanceKlass.hpp"
  39 #include "oops/klass.inline.hpp"
  40 #include "oops/objArrayKlass.inline.hpp"
  41 #include "oops/objArrayOop.inline.hpp"
  42 #include "oops/oop.inline.hpp"
  43 #include "oops/symbol.hpp"
  44 #include "runtime/access.inline.hpp"
  45 #include "runtime/handles.inline.hpp"
  46 #include "runtime/mutexLocker.hpp"

  47 #include "utilities/macros.hpp"
  48 
  49 ObjArrayKlass* ObjArrayKlass::allocate(ClassLoaderData* loader_data, int n, Klass* k, Symbol* name, TRAPS) {
  50   assert(ObjArrayKlass::header_size() <= InstanceKlass::header_size(),
  51       "array klasses must be same size as InstanceKlass");
  52 
  53   int size = ArrayKlass::static_size(ObjArrayKlass::header_size());
  54 
  55   return new (loader_data, size, THREAD) ObjArrayKlass(n, k, name);
  56 }
  57 
  58 Klass* ObjArrayKlass::allocate_objArray_klass(ClassLoaderData* loader_data,
  59                                                 int n, Klass* element_klass, TRAPS) {
  60 
  61   // Eagerly allocate the direct array supertype.
  62   Klass* super_klass = NULL;
  63   if (!Universe::is_bootstrapping() || SystemDictionary::Object_klass_loaded()) {
  64     Klass* element_super = element_klass->super();
  65     if (element_super != NULL) {
  66       // The element type has a direct super.  E.g., String[] has direct super of Object[].


 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_0(vmSymbols::java_lang_NegativeArraySizeException());
 213         }
 214       }
 215     }
 216   }
 217   return h_array();
 218 }
 219 
 220 // Either oop or narrowOop depending on UseCompressedOops.
 221 template <class T> void ObjArrayKlass::do_copy(arrayOop s, T* src,
 222                                arrayOop d, T* dst, int length, TRAPS) {








 223   if (s == d) {
 224     // since source and destination are equal we do not need conversion checks.
 225     assert(length > 0, "sanity check");
 226     HeapAccess<DEST_CONJOINT | DEST_COVARIANT | ACCESS_ATOMIC>::oop_copy(s, d, src, dst, length);

 227   } else {
 228     // We have to make sure all elements conform to the destination array
 229     Klass* bound = ObjArrayKlass::cast(d->klass())->element_klass();
 230     Klass* stype = ObjArrayKlass::cast(s->klass())->element_klass();
 231     if (stype == bound || stype->is_subtype_of(bound)) {
 232       // elements are guaranteed to be subtypes, so no check necessary
 233       HeapAccess<DEST_DISJOINT | DEST_COVARIANT | ACCESS_ATOMIC>::oop_copy(s, d, src, dst, length);

 234     } else {
 235       // slow case: need individual subtype checks
 236       if (!HeapAccess<DEST_DISJOINT | DEST_CONTRAVARIANT | ACCESS_ATOMIC>::oop_copy(s, d, src, dst, length)) {




















 237         THROW(vmSymbols::java_lang_ArrayStoreException());


 238       }
 239     }
 240   }

 241 }
 242 
 243 void ObjArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d,
 244                                int dst_pos, int length, TRAPS) {
 245   assert(s->is_objArray(), "must be obj array");
 246 
 247   if (!d->is_objArray()) {
 248     THROW(vmSymbols::java_lang_ArrayStoreException());
 249   }
 250 
 251   // Check is all offsets and lengths are non negative
 252   if (src_pos < 0 || dst_pos < 0 || length < 0) {
 253     THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
 254   }
 255   // Check if the ranges are valid
 256   if  ( (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length())
 257      || (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length()) ) {
 258     THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
 259   }
 260 


< prev index next >