< prev index next >

src/hotspot/share/oops/typeArrayKlass.cpp

Print this page




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


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

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




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

  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(ArrayStorageProperties storage_props, bool or_null, int n, TRAPS) {
 175   assert(storage_props.is_empty(), "Didn't expect storage properties");
 176   int dim = dimension();
 177   assert(dim <= n, "check order of chain");
 178     if (dim == n)
 179       return this;
 180 
 181   // lock-free read needs acquire semantics
 182   if (higher_dimension_acquire() == NULL) {
 183     if (or_null)  return NULL;
 184 
 185     ResourceMark rm;

 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 >