hotspot/src/share/vm/oops/typeArrayKlass.cpp
changeset 13952 e3cf184080bc
parent 13728 882756847a04
child 13961 aeaa21c167d1
equal deleted inserted replaced
13918:b01a48301e67 13952:e3cf184080bc
    38 #include "oops/oop.inline.hpp"
    38 #include "oops/oop.inline.hpp"
    39 #include "oops/typeArrayKlass.hpp"
    39 #include "oops/typeArrayKlass.hpp"
    40 #include "oops/typeArrayOop.hpp"
    40 #include "oops/typeArrayOop.hpp"
    41 #include "runtime/handles.inline.hpp"
    41 #include "runtime/handles.inline.hpp"
    42 
    42 
    43 bool typeArrayKlass::compute_is_subtype_of(Klass* k) {
    43 bool TypeArrayKlass::compute_is_subtype_of(Klass* k) {
    44   if (!k->oop_is_typeArray()) {
    44   if (!k->oop_is_typeArray()) {
    45     return arrayKlass::compute_is_subtype_of(k);
    45     return ArrayKlass::compute_is_subtype_of(k);
    46   }
    46   }
    47 
    47 
    48   typeArrayKlass* tak = typeArrayKlass::cast(k);
    48   TypeArrayKlass* tak = TypeArrayKlass::cast(k);
    49   if (dimension() != tak->dimension()) return false;
    49   if (dimension() != tak->dimension()) return false;
    50 
    50 
    51   return element_type() == tak->element_type();
    51   return element_type() == tak->element_type();
    52 }
    52 }
    53 
    53 
    54 typeArrayKlass* typeArrayKlass::create_klass(BasicType type,
    54 TypeArrayKlass* TypeArrayKlass::create_klass(BasicType type,
    55                                       const char* name_str, TRAPS) {
    55                                       const char* name_str, TRAPS) {
    56   Symbol* sym = NULL;
    56   Symbol* sym = NULL;
    57   if (name_str != NULL) {
    57   if (name_str != NULL) {
    58     sym = SymbolTable::new_permanent_symbol(name_str, CHECK_NULL);
    58     sym = SymbolTable::new_permanent_symbol(name_str, CHECK_NULL);
    59   }
    59   }
    60 
    60 
    61   ClassLoaderData* null_loader_data = ClassLoaderData::the_null_class_loader_data();
    61   ClassLoaderData* null_loader_data = ClassLoaderData::the_null_class_loader_data();
    62 
    62 
    63   typeArrayKlass* ak = typeArrayKlass::allocate(null_loader_data, type, sym, CHECK_NULL);
    63   TypeArrayKlass* ak = TypeArrayKlass::allocate(null_loader_data, type, sym, CHECK_NULL);
    64 
    64 
    65   // Add all classes to our internal class loader list here,
    65   // Add all classes to our internal class loader list here,
    66   // including classes in the bootstrap (NULL) class loader.
    66   // including classes in the bootstrap (NULL) class loader.
    67   // GC walks these as strong roots.
    67   // GC walks these as strong roots.
    68   null_loader_data->add_class(ak);
    68   null_loader_data->add_class(ak);
    71   complete_create_array_klass(ak, ak->super(), CHECK_NULL);
    71   complete_create_array_klass(ak, ak->super(), CHECK_NULL);
    72 
    72 
    73   return ak;
    73   return ak;
    74 }
    74 }
    75 
    75 
    76 typeArrayKlass* typeArrayKlass::allocate(ClassLoaderData* loader_data, BasicType type, Symbol* name, TRAPS) {
    76 TypeArrayKlass* TypeArrayKlass::allocate(ClassLoaderData* loader_data, BasicType type, Symbol* name, TRAPS) {
    77   assert(typeArrayKlass::header_size() <= InstanceKlass::header_size(),
    77   assert(TypeArrayKlass::header_size() <= InstanceKlass::header_size(),
    78       "array klasses must be same size as InstanceKlass");
    78       "array klasses must be same size as InstanceKlass");
    79 
    79 
    80   int size = arrayKlass::static_size(typeArrayKlass::header_size());
    80   int size = ArrayKlass::static_size(TypeArrayKlass::header_size());
    81 
    81 
    82   return new (loader_data, size, THREAD) typeArrayKlass(type, name);
    82   return new (loader_data, size, THREAD) TypeArrayKlass(type, name);
    83 }
    83 }
    84 
    84 
    85 typeArrayKlass::typeArrayKlass(BasicType type, Symbol* name) : arrayKlass(name) {
    85 TypeArrayKlass::TypeArrayKlass(BasicType type, Symbol* name) : ArrayKlass(name) {
    86   set_layout_helper(array_layout_helper(type));
    86   set_layout_helper(array_layout_helper(type));
    87   assert(oop_is_array(), "sanity");
    87   assert(oop_is_array(), "sanity");
    88   assert(oop_is_typeArray(), "sanity");
    88   assert(oop_is_typeArray(), "sanity");
    89 
    89 
    90   set_max_length(arrayOopDesc::max_array_length(type));
    90   set_max_length(arrayOopDesc::max_array_length(type));
    91   assert(size() >= typeArrayKlass::header_size(), "bad size");
    91   assert(size() >= TypeArrayKlass::header_size(), "bad size");
    92 
    92 
    93   set_class_loader_data(ClassLoaderData::the_null_class_loader_data());
    93   set_class_loader_data(ClassLoaderData::the_null_class_loader_data());
    94 }
    94 }
    95 
    95 
    96 typeArrayOop typeArrayKlass::allocate_common(int length, bool do_zero, TRAPS) {
    96 typeArrayOop TypeArrayKlass::allocate_common(int length, bool do_zero, TRAPS) {
    97   assert(log2_element_size() >= 0, "bad scale");
    97   assert(log2_element_size() >= 0, "bad scale");
    98   if (length >= 0) {
    98   if (length >= 0) {
    99     if (length <= max_length()) {
    99     if (length <= max_length()) {
   100       size_t size = typeArrayOopDesc::object_size(layout_helper(), length);
   100       size_t size = typeArrayOopDesc::object_size(layout_helper(), length);
   101       KlassHandle h_k(THREAD, this);
   101       KlassHandle h_k(THREAD, this);
   115   } else {
   115   } else {
   116     THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
   116     THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
   117   }
   117   }
   118 }
   118 }
   119 
   119 
   120 oop typeArrayKlass::multi_allocate(int rank, jint* last_size, TRAPS) {
   120 oop TypeArrayKlass::multi_allocate(int rank, jint* last_size, TRAPS) {
   121   // For typeArrays this is only called for the last dimension
   121   // For typeArrays this is only called for the last dimension
   122   assert(rank == 1, "just checking");
   122   assert(rank == 1, "just checking");
   123   int length = *last_size;
   123   int length = *last_size;
   124   return allocate(length, THREAD);
   124   return allocate(length, THREAD);
   125 }
   125 }
   126 
   126 
   127 
   127 
   128 void typeArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS) {
   128 void TypeArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS) {
   129   assert(s->is_typeArray(), "must be type array");
   129   assert(s->is_typeArray(), "must be type array");
   130 
   130 
   131   // Check destination
   131   // Check destination
   132   if (!d->is_typeArray() || element_type() != typeArrayKlass::cast(d->klass())->element_type()) {
   132   if (!d->is_typeArray() || element_type() != TypeArrayKlass::cast(d->klass())->element_type()) {
   133     THROW(vmSymbols::java_lang_ArrayStoreException());
   133     THROW(vmSymbols::java_lang_ArrayStoreException());
   134   }
   134   }
   135 
   135 
   136   // Check is all offsets and lengths are non negative
   136   // Check is all offsets and lengths are non negative
   137   if (src_pos < 0 || dst_pos < 0 || length < 0) {
   137   if (src_pos < 0 || dst_pos < 0 || length < 0) {
   154   Copy::conjoint_memory_atomic(src, dst, (size_t)length << l2es);
   154   Copy::conjoint_memory_atomic(src, dst, (size_t)length << l2es);
   155 }
   155 }
   156 
   156 
   157 
   157 
   158 // create a klass of array holding typeArrays
   158 // create a klass of array holding typeArrays
   159 Klass* typeArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) {
   159 Klass* TypeArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) {
   160   int dim = dimension();
   160   int dim = dimension();
   161   assert(dim <= n, "check order of chain");
   161   assert(dim <= n, "check order of chain");
   162     if (dim == n)
   162     if (dim == n)
   163       return this;
   163       return this;
   164 
   164 
   171       MutexLocker mc(Compile_lock, THREAD);   // for vtables
   171       MutexLocker mc(Compile_lock, THREAD);   // for vtables
   172       // Atomic create higher dimension and link into list
   172       // Atomic create higher dimension and link into list
   173       MutexLocker mu(MultiArray_lock, THREAD);
   173       MutexLocker mu(MultiArray_lock, THREAD);
   174 
   174 
   175       if (higher_dimension() == NULL) {
   175       if (higher_dimension() == NULL) {
   176         Klass* oak = objArrayKlass::allocate_objArray_klass(
   176         Klass* oak = ObjArrayKlass::allocate_objArray_klass(
   177               class_loader_data(), dim + 1, this, CHECK_NULL);
   177               class_loader_data(), dim + 1, this, CHECK_NULL);
   178         objArrayKlass* h_ak = objArrayKlass::cast(oak);
   178         ObjArrayKlass* h_ak = ObjArrayKlass::cast(oak);
   179         h_ak->set_lower_dimension(this);
   179         h_ak->set_lower_dimension(this);
   180         OrderAccess::storestore();
   180         OrderAccess::storestore();
   181         set_higher_dimension(h_ak);
   181         set_higher_dimension(h_ak);
   182         assert(h_ak->oop_is_objArray(), "incorrect initialization of objArrayKlass");
   182         assert(h_ak->oop_is_objArray(), "incorrect initialization of ObjArrayKlass");
   183       }
   183       }
   184     }
   184     }
   185   } else {
   185   } else {
   186     CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
   186     CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
   187   }
   187   }
   188   objArrayKlass* h_ak = objArrayKlass::cast(higher_dimension());
   188   ObjArrayKlass* h_ak = ObjArrayKlass::cast(higher_dimension());
   189   if (or_null) {
   189   if (or_null) {
   190     return h_ak->array_klass_or_null(n);
   190     return h_ak->array_klass_or_null(n);
   191   }
   191   }
   192   return h_ak->array_klass(n, CHECK_NULL);
   192   return h_ak->array_klass(n, CHECK_NULL);
   193 }
   193 }
   194 
   194 
   195 Klass* typeArrayKlass::array_klass_impl(bool or_null, TRAPS) {
   195 Klass* TypeArrayKlass::array_klass_impl(bool or_null, TRAPS) {
   196   return array_klass_impl(or_null, dimension() +  1, THREAD);
   196   return array_klass_impl(or_null, dimension() +  1, THREAD);
   197 }
   197 }
   198 
   198 
   199 int typeArrayKlass::oop_size(oop obj) const {
   199 int TypeArrayKlass::oop_size(oop obj) const {
   200   assert(obj->is_typeArray(),"must be a type array");
   200   assert(obj->is_typeArray(),"must be a type array");
   201   typeArrayOop t = typeArrayOop(obj);
   201   typeArrayOop t = typeArrayOop(obj);
   202   return t->object_size();
   202   return t->object_size();
   203 }
   203 }
   204 
   204 
   205 void typeArrayKlass::oop_follow_contents(oop obj) {
   205 void TypeArrayKlass::oop_follow_contents(oop obj) {
   206   assert(obj->is_typeArray(),"must be a type array");
   206   assert(obj->is_typeArray(),"must be a type array");
   207   // Performance tweak: We skip iterating over the klass pointer since we
   207   // Performance tweak: We skip iterating over the klass pointer since we
   208   // know that Universe::typeArrayKlass never moves.
   208   // know that Universe::TypeArrayKlass never moves.
   209 }
   209 }
   210 
   210 
   211 #ifndef SERIALGC
   211 #ifndef SERIALGC
   212 void typeArrayKlass::oop_follow_contents(ParCompactionManager* cm, oop obj) {
   212 void TypeArrayKlass::oop_follow_contents(ParCompactionManager* cm, oop obj) {
   213   assert(obj->is_typeArray(),"must be a type array");
   213   assert(obj->is_typeArray(),"must be a type array");
   214   // Performance tweak: We skip iterating over the klass pointer since we
   214   // Performance tweak: We skip iterating over the klass pointer since we
   215   // know that Universe::typeArrayKlass never moves.
   215   // know that Universe::TypeArrayKlass never moves.
   216 }
   216 }
   217 #endif // SERIALGC
   217 #endif // SERIALGC
   218 
   218 
   219 int typeArrayKlass::oop_adjust_pointers(oop obj) {
   219 int TypeArrayKlass::oop_adjust_pointers(oop obj) {
   220   assert(obj->is_typeArray(),"must be a type array");
   220   assert(obj->is_typeArray(),"must be a type array");
   221   typeArrayOop t = typeArrayOop(obj);
   221   typeArrayOop t = typeArrayOop(obj);
   222   // Performance tweak: We skip iterating over the klass pointer since we
   222   // Performance tweak: We skip iterating over the klass pointer since we
   223   // know that Universe::typeArrayKlass never moves.
   223   // know that Universe::TypeArrayKlass never moves.
   224   return t->object_size();
   224   return t->object_size();
   225 }
   225 }
   226 
   226 
   227 int typeArrayKlass::oop_oop_iterate(oop obj, ExtendedOopClosure* blk) {
   227 int TypeArrayKlass::oop_oop_iterate(oop obj, ExtendedOopClosure* blk) {
   228   assert(obj->is_typeArray(),"must be a type array");
   228   assert(obj->is_typeArray(),"must be a type array");
   229   typeArrayOop t = typeArrayOop(obj);
   229   typeArrayOop t = typeArrayOop(obj);
   230   // Performance tweak: We skip iterating over the klass pointer since we
   230   // Performance tweak: We skip iterating over the klass pointer since we
   231   // know that Universe::typeArrayKlass never moves.
   231   // know that Universe::TypeArrayKlass never moves.
   232   return t->object_size();
   232   return t->object_size();
   233 }
   233 }
   234 
   234 
   235 int typeArrayKlass::oop_oop_iterate_m(oop obj, ExtendedOopClosure* blk, MemRegion mr) {
   235 int TypeArrayKlass::oop_oop_iterate_m(oop obj, ExtendedOopClosure* blk, MemRegion mr) {
   236   assert(obj->is_typeArray(),"must be a type array");
   236   assert(obj->is_typeArray(),"must be a type array");
   237   typeArrayOop t = typeArrayOop(obj);
   237   typeArrayOop t = typeArrayOop(obj);
   238   // Performance tweak: We skip iterating over the klass pointer since we
   238   // Performance tweak: We skip iterating over the klass pointer since we
   239   // know that Universe::typeArrayKlass never moves.
   239   // know that Universe::TypeArrayKlass never moves.
   240   return t->object_size();
   240   return t->object_size();
   241 }
   241 }
   242 
   242 
   243 #ifndef SERIALGC
   243 #ifndef SERIALGC
   244 void typeArrayKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
   244 void TypeArrayKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
   245   ShouldNotReachHere();
   245   ShouldNotReachHere();
   246   assert(obj->is_typeArray(),"must be a type array");
   246   assert(obj->is_typeArray(),"must be a type array");
   247 }
   247 }
   248 
   248 
   249 int
   249 int
   250 typeArrayKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
   250 TypeArrayKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
   251   assert(obj->is_typeArray(),"must be a type array");
   251   assert(obj->is_typeArray(),"must be a type array");
   252   return typeArrayOop(obj)->object_size();
   252   return typeArrayOop(obj)->object_size();
   253 }
   253 }
   254 #endif // SERIALGC
   254 #endif // SERIALGC
   255 
   255 
   256 void typeArrayKlass::initialize(TRAPS) {
   256 void TypeArrayKlass::initialize(TRAPS) {
   257   // Nothing to do. Having this function is handy since objArrayKlasses can be
   257   // Nothing to do. Having this function is handy since objArrayKlasses can be
   258   // initialized by calling initialize on their bottom_klass, see objArrayKlass::initialize
   258   // initialized by calling initialize on their bottom_klass, see ObjArrayKlass::initialize
   259 }
   259 }
   260 
   260 
   261 const char* typeArrayKlass::external_name(BasicType type) {
   261 const char* TypeArrayKlass::external_name(BasicType type) {
   262   switch (type) {
   262   switch (type) {
   263     case T_BOOLEAN: return "[Z";
   263     case T_BOOLEAN: return "[Z";
   264     case T_CHAR:    return "[C";
   264     case T_CHAR:    return "[C";
   265     case T_FLOAT:   return "[F";
   265     case T_FLOAT:   return "[F";
   266     case T_DOUBLE:  return "[D";
   266     case T_DOUBLE:  return "[D";
   274 }
   274 }
   275 
   275 
   276 
   276 
   277 // Printing
   277 // Printing
   278 
   278 
   279 void typeArrayKlass::print_on(outputStream* st) const {
   279 void TypeArrayKlass::print_on(outputStream* st) const {
   280 #ifndef PRODUCT
   280 #ifndef PRODUCT
   281   assert(is_klass(), "must be klass");
   281   assert(is_klass(), "must be klass");
   282   print_value_on(st);
   282   print_value_on(st);
   283   Klass::print_on(st);
   283   Klass::print_on(st);
   284 #endif //PRODUCT
   284 #endif //PRODUCT
   285 }
   285 }
   286 
   286 
   287 void typeArrayKlass::print_value_on(outputStream* st) const {
   287 void TypeArrayKlass::print_value_on(outputStream* st) const {
   288   assert(is_klass(), "must be klass");
   288   assert(is_klass(), "must be klass");
   289   st->print("{type array ");
   289   st->print("{type array ");
   290   switch (element_type()) {
   290   switch (element_type()) {
   291     case T_BOOLEAN: st->print("bool");    break;
   291     case T_BOOLEAN: st->print("bool");    break;
   292     case T_CHAR:    st->print("char");    break;
   292     case T_CHAR:    st->print("char");    break;
   362     st->print_cr(" - %3d: 0x%x 0x%x", index, high(v), low(v));
   362     st->print_cr(" - %3d: 0x%x 0x%x", index, high(v), low(v));
   363   }
   363   }
   364 }
   364 }
   365 
   365 
   366 
   366 
   367 void typeArrayKlass::oop_print_on(oop obj, outputStream* st) {
   367 void TypeArrayKlass::oop_print_on(oop obj, outputStream* st) {
   368   arrayKlass::oop_print_on(obj, st);
   368   ArrayKlass::oop_print_on(obj, st);
   369   typeArrayOop ta = typeArrayOop(obj);
   369   typeArrayOop ta = typeArrayOop(obj);
   370   int print_len = MIN2((intx) ta->length(), MaxElementPrintSize);
   370   int print_len = MIN2((intx) ta->length(), MaxElementPrintSize);
   371   switch (element_type()) {
   371   switch (element_type()) {
   372     case T_BOOLEAN: print_boolean_array(ta, print_len, st); break;
   372     case T_BOOLEAN: print_boolean_array(ta, print_len, st); break;
   373     case T_CHAR:    print_char_array(ta, print_len, st);    break;
   373     case T_CHAR:    print_char_array(ta, print_len, st);    break;
   385   }
   385   }
   386 }
   386 }
   387 
   387 
   388 #endif // PRODUCT
   388 #endif // PRODUCT
   389 
   389 
   390 const char* typeArrayKlass::internal_name() const {
   390 const char* TypeArrayKlass::internal_name() const {
   391   return Klass::external_name();
   391   return Klass::external_name();
   392 }
   392 }