< prev index next >

src/hotspot/share/oops/typeArrayKlass.cpp

Print this page




  78 TypeArrayKlass::TypeArrayKlass(BasicType type, Symbol* name) : ArrayKlass(name, ID) {
  79   set_layout_helper(array_layout_helper(type));
  80   assert(is_array_klass(), "sanity");
  81   assert(is_typeArray_klass(), "sanity");
  82 
  83   set_max_length(arrayOopDesc::max_array_length(type));
  84   assert(size() >= TypeArrayKlass::header_size(), "bad size");
  85 
  86   set_class_loader_data(ClassLoaderData::the_null_class_loader_data());
  87 }
  88 
  89 typeArrayOop TypeArrayKlass::allocate_common(int length, bool do_zero, TRAPS) {
  90   assert(log2_element_size() >= 0, "bad scale");
  91   check_array_allocation_length(length, max_length(), CHECK_NULL);
  92   size_t size = typeArrayOopDesc::object_size(layout_helper(), length);
  93   return (typeArrayOop)Universe::heap()->array_allocate(this, (int)size, length,
  94                                                         do_zero, CHECK_NULL);
  95 }
  96 
  97 oop TypeArrayKlass::multi_allocate(int rank, jint* last_size, TRAPS) {
  98   // For typeArrays this is only called for the last dimension
  99   assert(rank == 1, "just checking");
 100   int length = *last_size;
 101   return allocate(length, THREAD);
 102 }
 103 
 104 
 105 void TypeArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS) {
 106   assert(s->is_typeArray(), "must be type array");
 107 
 108   // Check destination type.
 109   if (!d->is_typeArray()) {
 110     ResourceMark rm(THREAD);
 111     stringStream ss;
 112     if (d->is_objArray()) {
 113       ss.print("arraycopy: type mismatch: can not copy %s[] into object array[]",
 114                type2name_tab[ArrayKlass::cast(s->klass())->element_type()]);
 115     } else {
 116       ss.print("arraycopy: destination type %s is not an array", d->klass()->external_name());
 117     }
 118     THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());


 154                type2name_tab[ArrayKlass::cast(s->klass())->element_type()], s->length());
 155     } else {
 156       ss.print("arraycopy: last destination index %u out of bounds for %s[%d]",
 157                (unsigned int) length + (unsigned int) dst_pos,
 158                type2name_tab[ArrayKlass::cast(d->klass())->element_type()], d->length());
 159     }
 160     THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
 161   }
 162   // Check zero copy
 163   if (length == 0)
 164     return;
 165 
 166   // This is an attempt to make the copy_array fast.
 167   int l2es = log2_element_size();
 168   size_t src_offset = arrayOopDesc::base_offset_in_bytes(element_type()) + ((size_t)src_pos << l2es);
 169   size_t dst_offset = arrayOopDesc::base_offset_in_bytes(element_type()) + ((size_t)dst_pos << l2es);
 170   ArrayAccess<ARRAYCOPY_ATOMIC>::arraycopy<void>(s, src_offset, d, dst_offset, (size_t)length << l2es);
 171 }
 172 
 173 // create a klass of array holding typeArrays
 174 Klass* TypeArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) {

 175   int dim = dimension();
 176   assert(dim <= n, "check order of chain");
 177     if (dim == n)
 178       return this;
 179 
 180   // lock-free read needs acquire semantics
 181   if (higher_dimension_acquire() == NULL) {
 182     if (or_null)  return NULL;
 183 
 184     ResourceMark rm;
 185     JavaThread *jt = (JavaThread *)THREAD;
 186     {
 187       // Atomic create higher dimension and link into list
 188       MutexLocker mu(MultiArray_lock, THREAD);
 189 
 190       if (higher_dimension() == NULL) {
 191         Klass* oak = ObjArrayKlass::allocate_objArray_klass(
 192               class_loader_data(), dim + 1, this, CHECK_NULL);
 193         ObjArrayKlass* h_ak = ObjArrayKlass::cast(oak);
 194         h_ak->set_lower_dimension(this);
 195         // use 'release' to pair with lock-free load
 196         release_set_higher_dimension(h_ak);
 197         assert(h_ak->is_objArray_klass(), "incorrect initialization of ObjArrayKlass");
 198       }
 199     }
 200   } else {
 201     CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
 202   }
 203   ObjArrayKlass* h_ak = ObjArrayKlass::cast(higher_dimension());
 204   if (or_null) {
 205     return h_ak->array_klass_or_null(n);
 206   }
 207   return h_ak->array_klass(n, THREAD);
 208 }
 209 
 210 Klass* TypeArrayKlass::array_klass_impl(bool or_null, TRAPS) {
 211   return array_klass_impl(or_null, dimension() +  1, THREAD);
 212 }
 213 
 214 int TypeArrayKlass::oop_size(oop obj) const {
 215   assert(obj->is_typeArray(),"must be a type array");
 216   typeArrayOop t = typeArrayOop(obj);
 217   return t->object_size();
 218 }
 219 
 220 void TypeArrayKlass::initialize(TRAPS) {
 221   // Nothing to do. Having this function is handy since objArrayKlasses can be
 222   // initialized by calling initialize on their bottom_klass, see ObjArrayKlass::initialize
 223 }
 224 
 225 const char* TypeArrayKlass::external_name(BasicType type) {
 226   switch (type) {
 227     case T_BOOLEAN: return "[Z";
 228     case T_CHAR:    return "[C";
 229     case T_FLOAT:   return "[F";
 230     case T_DOUBLE:  return "[D";
 231     case T_BYTE:    return "[B";




  78 TypeArrayKlass::TypeArrayKlass(BasicType type, Symbol* name) : ArrayKlass(name, ID) {
  79   set_layout_helper(array_layout_helper(type));
  80   assert(is_array_klass(), "sanity");
  81   assert(is_typeArray_klass(), "sanity");
  82 
  83   set_max_length(arrayOopDesc::max_array_length(type));
  84   assert(size() >= TypeArrayKlass::header_size(), "bad size");
  85 
  86   set_class_loader_data(ClassLoaderData::the_null_class_loader_data());
  87 }
  88 
  89 typeArrayOop TypeArrayKlass::allocate_common(int length, bool do_zero, TRAPS) {
  90   assert(log2_element_size() >= 0, "bad scale");
  91   check_array_allocation_length(length, max_length(), CHECK_NULL);
  92   size_t size = typeArrayOopDesc::object_size(layout_helper(), length);
  93   return (typeArrayOop)Universe::heap()->array_allocate(this, (int)size, length,
  94                                                         do_zero, CHECK_NULL);
  95 }
  96 
  97 oop TypeArrayKlass::multi_allocate(int rank, jint* last_size, TRAPS) {

  98   assert(rank == 1, "just checking");
  99   int length = *last_size;
 100   return allocate(length, THREAD);
 101 }
 102 
 103 
 104 void TypeArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS) {
 105   assert(s->is_typeArray(), "must be type array");
 106 
 107   // Check destination type.
 108   if (!d->is_typeArray()) {
 109     ResourceMark rm(THREAD);
 110     stringStream ss;
 111     if (d->is_objArray()) {
 112       ss.print("arraycopy: type mismatch: can not copy %s[] into object array[]",
 113                type2name_tab[ArrayKlass::cast(s->klass())->element_type()]);
 114     } else {
 115       ss.print("arraycopy: destination type %s is not an array", d->klass()->external_name());
 116     }
 117     THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());


 153                type2name_tab[ArrayKlass::cast(s->klass())->element_type()], s->length());
 154     } else {
 155       ss.print("arraycopy: last destination index %u out of bounds for %s[%d]",
 156                (unsigned int) length + (unsigned int) dst_pos,
 157                type2name_tab[ArrayKlass::cast(d->klass())->element_type()], d->length());
 158     }
 159     THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
 160   }
 161   // Check zero copy
 162   if (length == 0)
 163     return;
 164 
 165   // This is an attempt to make the copy_array fast.
 166   int l2es = log2_element_size();
 167   size_t src_offset = arrayOopDesc::base_offset_in_bytes(element_type()) + ((size_t)src_pos << l2es);
 168   size_t dst_offset = arrayOopDesc::base_offset_in_bytes(element_type()) + ((size_t)dst_pos << l2es);
 169   ArrayAccess<ARRAYCOPY_ATOMIC>::arraycopy<void>(s, src_offset, d, dst_offset, (size_t)length << l2es);
 170 }
 171 
 172 // create a klass of array holding typeArrays
 173 Klass* TypeArrayKlass::array_klass_impl(ArrayStorageProperties storage_props, bool or_null, int n, TRAPS) {
 174   assert(storage_props.is_empty(), "Didn't expect storage properties");
 175   int dim = dimension();
 176   assert(dim <= n, "check order of chain");
 177     if (dim == n)
 178       return this;
 179 
 180   // lock-free read needs acquire semantics
 181   if (higher_dimension_acquire() == NULL) {
 182     if (or_null)  return NULL;
 183 
 184     ResourceMark rm;
 185     JavaThread *jt = (JavaThread *)THREAD;
 186     {
 187       // Atomic create higher dimension and link into list
 188       MutexLocker mu(MultiArray_lock, THREAD);
 189 
 190       if (higher_dimension() == NULL) {
 191         Klass* oak = ObjArrayKlass::allocate_objArray_klass(
 192               ArrayStorageProperties::empty, dim + 1, this, CHECK_NULL);
 193         ObjArrayKlass* h_ak = ObjArrayKlass::cast(oak);
 194         h_ak->set_lower_dimension(this);
 195         // use 'release' to pair with lock-free load
 196         release_set_higher_dimension(h_ak);
 197         assert(h_ak->is_objArray_klass(), "incorrect initialization of ObjArrayKlass");
 198       }
 199     }
 200   } else {
 201     CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
 202   }
 203   ObjArrayKlass* h_ak = ObjArrayKlass::cast(higher_dimension());
 204   if (or_null) {
 205     return h_ak->array_klass_or_null(storage_props, n);
 206   }
 207   return h_ak->array_klass(storage_props, n, THREAD);
 208 }
 209 
 210 Klass* TypeArrayKlass::array_klass_impl(ArrayStorageProperties storage_props, bool or_null, TRAPS) {
 211   return array_klass_impl(storage_props, or_null, dimension() +  1, THREAD);
 212 }
 213 
 214 int TypeArrayKlass::oop_size(oop obj) const {
 215   assert(obj->is_typeArray(),"must be a type array");
 216   typeArrayOop t = typeArrayOop(obj);
 217   return t->object_size();
 218 }
 219 
 220 void TypeArrayKlass::initialize(TRAPS) {
 221   // Nothing to do. Having this function is handy since objArrayKlasses can be
 222   // initialized by calling initialize on their bottom_klass, see ObjArrayKlass::initialize
 223 }
 224 
 225 const char* TypeArrayKlass::external_name(BasicType type) {
 226   switch (type) {
 227     case T_BOOLEAN: return "[Z";
 228     case T_CHAR:    return "[C";
 229     case T_FLOAT:   return "[F";
 230     case T_DOUBLE:  return "[D";
 231     case T_BYTE:    return "[B";


< prev index next >