1.1 --- a/src/share/vm/oops/typeArrayKlass.cpp Fri Aug 31 16:39:35 2012 -0700 1.2 +++ b/src/share/vm/oops/typeArrayKlass.cpp Sat Sep 01 13:25:18 2012 -0400 1.3 @@ -23,23 +23,25 @@ 1.4 */ 1.5 1.6 #include "precompiled.hpp" 1.7 +#include "classfile/symbolTable.hpp" 1.8 #include "classfile/systemDictionary.hpp" 1.9 #include "classfile/vmSymbols.hpp" 1.10 #include "gc_interface/collectedHeap.hpp" 1.11 #include "gc_interface/collectedHeap.inline.hpp" 1.12 +#include "memory/metadataFactory.hpp" 1.13 #include "memory/resourceArea.hpp" 1.14 #include "memory/universe.hpp" 1.15 #include "memory/universe.inline.hpp" 1.16 #include "oops/instanceKlass.hpp" 1.17 -#include "oops/klassOop.hpp" 1.18 -#include "oops/objArrayKlassKlass.hpp" 1.19 +#include "oops/klass.inline.hpp" 1.20 +#include "oops/objArrayKlass.hpp" 1.21 #include "oops/oop.inline.hpp" 1.22 #include "oops/typeArrayKlass.hpp" 1.23 #include "oops/typeArrayOop.hpp" 1.24 #include "runtime/handles.inline.hpp" 1.25 1.26 -bool typeArrayKlass::compute_is_subtype_of(klassOop k) { 1.27 - if (!k->klass_part()->oop_is_typeArray()) { 1.28 +bool typeArrayKlass::compute_is_subtype_of(Klass* k) { 1.29 + if (!k->oop_is_typeArray()) { 1.30 return arrayKlass::compute_is_subtype_of(k); 1.31 } 1.32 1.33 @@ -49,31 +51,46 @@ 1.34 return element_type() == tak->element_type(); 1.35 } 1.36 1.37 -klassOop typeArrayKlass::create_klass(BasicType type, int scale, 1.38 +typeArrayKlass* typeArrayKlass::create_klass(BasicType type, 1.39 const char* name_str, TRAPS) { 1.40 - typeArrayKlass o; 1.41 - 1.42 Symbol* sym = NULL; 1.43 if (name_str != NULL) { 1.44 sym = SymbolTable::new_permanent_symbol(name_str, CHECK_NULL); 1.45 } 1.46 - KlassHandle klassklass (THREAD, Universe::typeArrayKlassKlassObj()); 1.47 1.48 - arrayKlassHandle k = base_create_array_klass(o.vtbl_value(), header_size(), klassklass, CHECK_NULL); 1.49 - typeArrayKlass* ak = typeArrayKlass::cast(k()); 1.50 - ak->set_name(sym); 1.51 - ak->set_layout_helper(array_layout_helper(type)); 1.52 - assert(scale == (1 << ak->log2_element_size()), "scale must check out"); 1.53 - assert(ak->oop_is_javaArray(), "sanity"); 1.54 - assert(ak->oop_is_typeArray(), "sanity"); 1.55 - ak->set_max_length(arrayOopDesc::max_array_length(type)); 1.56 - assert(k()->size() > header_size(), "bad size"); 1.57 + ClassLoaderData* null_loader_data = ClassLoaderData::the_null_class_loader_data(); 1.58 + 1.59 + typeArrayKlass* ak = typeArrayKlass::allocate(null_loader_data, type, sym, CHECK_NULL); 1.60 + 1.61 + // Add all classes to our internal class loader list here, 1.62 + // including classes in the bootstrap (NULL) class loader. 1.63 + // GC walks these as strong roots. 1.64 + null_loader_data->add_class(ak); 1.65 1.66 // Call complete_create_array_klass after all instance variables have been initialized. 1.67 - KlassHandle super (THREAD, k->super()); 1.68 - complete_create_array_klass(k, super, CHECK_NULL); 1.69 + complete_create_array_klass(ak, ak->super(), CHECK_NULL); 1.70 1.71 - return k(); 1.72 + return ak; 1.73 +} 1.74 + 1.75 +typeArrayKlass* typeArrayKlass::allocate(ClassLoaderData* loader_data, BasicType type, Symbol* name, TRAPS) { 1.76 + assert(typeArrayKlass::header_size() <= InstanceKlass::header_size(), 1.77 + "array klasses must be same size as InstanceKlass"); 1.78 + 1.79 + int size = arrayKlass::static_size(typeArrayKlass::header_size()); 1.80 + 1.81 + return new (loader_data, size, THREAD) typeArrayKlass(type, name); 1.82 +} 1.83 + 1.84 +typeArrayKlass::typeArrayKlass(BasicType type, Symbol* name) : arrayKlass(name) { 1.85 + set_layout_helper(array_layout_helper(type)); 1.86 + assert(oop_is_array(), "sanity"); 1.87 + assert(oop_is_typeArray(), "sanity"); 1.88 + 1.89 + set_max_length(arrayOopDesc::max_array_length(type)); 1.90 + assert(size() >= typeArrayKlass::header_size(), "bad size"); 1.91 + 1.92 + set_class_loader_data(ClassLoaderData::the_null_class_loader_data()); 1.93 } 1.94 1.95 typeArrayOop typeArrayKlass::allocate_common(int length, bool do_zero, TRAPS) { 1.96 @@ -81,7 +98,7 @@ 1.97 if (length >= 0) { 1.98 if (length <= max_length()) { 1.99 size_t size = typeArrayOopDesc::object_size(layout_helper(), length); 1.100 - KlassHandle h_k(THREAD, as_klassOop()); 1.101 + KlassHandle h_k(THREAD, this); 1.102 typeArrayOop t; 1.103 CollectedHeap* ch = Universe::heap(); 1.104 if (do_zero) { 1.105 @@ -89,7 +106,6 @@ 1.106 } else { 1.107 t = (typeArrayOop)CollectedHeap::array_allocate_nozero(h_k, (int)size, length, CHECK_NULL); 1.108 } 1.109 - assert(t->is_parsable(), "Don't publish unless parsable"); 1.110 return t; 1.111 } else { 1.112 report_java_out_of_memory("Requested array size exceeds VM limit"); 1.113 @@ -101,16 +117,6 @@ 1.114 } 1.115 } 1.116 1.117 -typeArrayOop typeArrayKlass::allocate_permanent(int length, TRAPS) { 1.118 - if (length < 0) THROW_0(vmSymbols::java_lang_NegativeArraySizeException()); 1.119 - int size = typeArrayOopDesc::object_size(layout_helper(), length); 1.120 - KlassHandle h_k(THREAD, as_klassOop()); 1.121 - typeArrayOop t = (typeArrayOop) 1.122 - CollectedHeap::permanent_array_allocate(h_k, size, length, CHECK_NULL); 1.123 - assert(t->is_parsable(), "Can't publish until parsable"); 1.124 - return t; 1.125 -} 1.126 - 1.127 oop typeArrayKlass::multi_allocate(int rank, jint* last_size, TRAPS) { 1.128 // For typeArrays this is only called for the last dimension 1.129 assert(rank == 1, "just checking"); 1.130 @@ -150,19 +156,13 @@ 1.131 1.132 1.133 // create a klass of array holding typeArrays 1.134 -klassOop typeArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) { 1.135 - typeArrayKlassHandle h_this(THREAD, as_klassOop()); 1.136 - return array_klass_impl(h_this, or_null, n, THREAD); 1.137 -} 1.138 +Klass* typeArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) { 1.139 + int dim = dimension(); 1.140 + assert(dim <= n, "check order of chain"); 1.141 + if (dim == n) 1.142 + return this; 1.143 1.144 -klassOop typeArrayKlass::array_klass_impl(typeArrayKlassHandle h_this, bool or_null, int n, TRAPS) { 1.145 - int dimension = h_this->dimension(); 1.146 - assert(dimension <= n, "check order of chain"); 1.147 - if (dimension == n) 1.148 - return h_this(); 1.149 - 1.150 - objArrayKlassHandle h_ak(THREAD, h_this->higher_dimension()); 1.151 - if (h_ak.is_null()) { 1.152 + if (higher_dimension() == NULL) { 1.153 if (or_null) return NULL; 1.154 1.155 ResourceMark rm; 1.156 @@ -172,28 +172,27 @@ 1.157 // Atomic create higher dimension and link into list 1.158 MutexLocker mu(MultiArray_lock, THREAD); 1.159 1.160 - h_ak = objArrayKlassHandle(THREAD, h_this->higher_dimension()); 1.161 - if (h_ak.is_null()) { 1.162 - klassOop oak = objArrayKlassKlass::cast( 1.163 - Universe::objArrayKlassKlassObj())->allocate_objArray_klass( 1.164 - dimension + 1, h_this, CHECK_NULL); 1.165 - h_ak = objArrayKlassHandle(THREAD, oak); 1.166 - h_ak->set_lower_dimension(h_this()); 1.167 + if (higher_dimension() == NULL) { 1.168 + Klass* oak = objArrayKlass::allocate_objArray_klass( 1.169 + class_loader_data(), dim + 1, this, CHECK_NULL); 1.170 + objArrayKlass* h_ak = objArrayKlass::cast(oak); 1.171 + h_ak->set_lower_dimension(this); 1.172 OrderAccess::storestore(); 1.173 - h_this->set_higher_dimension(h_ak()); 1.174 + set_higher_dimension(h_ak); 1.175 assert(h_ak->oop_is_objArray(), "incorrect initialization of objArrayKlass"); 1.176 } 1.177 } 1.178 } else { 1.179 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); 1.180 } 1.181 + objArrayKlass* h_ak = objArrayKlass::cast(higher_dimension()); 1.182 if (or_null) { 1.183 return h_ak->array_klass_or_null(n); 1.184 } 1.185 return h_ak->array_klass(n, CHECK_NULL); 1.186 } 1.187 1.188 -klassOop typeArrayKlass::array_klass_impl(bool or_null, TRAPS) { 1.189 +Klass* typeArrayKlass::array_klass_impl(bool or_null, TRAPS) { 1.190 return array_klass_impl(or_null, dimension() + 1, THREAD); 1.191 } 1.192 1.193 @@ -225,7 +224,7 @@ 1.194 return t->object_size(); 1.195 } 1.196 1.197 -int typeArrayKlass::oop_oop_iterate(oop obj, OopClosure* blk) { 1.198 +int typeArrayKlass::oop_oop_iterate(oop obj, ExtendedOopClosure* blk) { 1.199 assert(obj->is_typeArray(),"must be a type array"); 1.200 typeArrayOop t = typeArrayOop(obj); 1.201 // Performance tweak: We skip iterating over the klass pointer since we 1.202 @@ -233,7 +232,7 @@ 1.203 return t->object_size(); 1.204 } 1.205 1.206 -int typeArrayKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) { 1.207 +int typeArrayKlass::oop_oop_iterate_m(oop obj, ExtendedOopClosure* blk, MemRegion mr) { 1.208 assert(obj->is_typeArray(),"must be a type array"); 1.209 typeArrayOop t = typeArrayOop(obj); 1.210 // Performance tweak: We skip iterating over the klass pointer since we 1.211 @@ -243,6 +242,7 @@ 1.212 1.213 #ifndef SERIALGC 1.214 void typeArrayKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { 1.215 + ShouldNotReachHere(); 1.216 assert(obj->is_typeArray(),"must be a type array"); 1.217 } 1.218 1.219 @@ -273,8 +273,35 @@ 1.220 return NULL; 1.221 } 1.222 1.223 + 1.224 +// Printing 1.225 + 1.226 +void typeArrayKlass::print_on(outputStream* st) const { 1.227 #ifndef PRODUCT 1.228 -// Printing 1.229 + assert(is_klass(), "must be klass"); 1.230 + print_value_on(st); 1.231 + Klass::print_on(st); 1.232 +#endif //PRODUCT 1.233 +} 1.234 + 1.235 +void typeArrayKlass::print_value_on(outputStream* st) const { 1.236 + assert(is_klass(), "must be klass"); 1.237 + st->print("{type array "); 1.238 + switch (element_type()) { 1.239 + case T_BOOLEAN: st->print("bool"); break; 1.240 + case T_CHAR: st->print("char"); break; 1.241 + case T_FLOAT: st->print("float"); break; 1.242 + case T_DOUBLE: st->print("double"); break; 1.243 + case T_BYTE: st->print("byte"); break; 1.244 + case T_SHORT: st->print("short"); break; 1.245 + case T_INT: st->print("int"); break; 1.246 + case T_LONG: st->print("long"); break; 1.247 + default: ShouldNotReachHere(); 1.248 + } 1.249 + st->print("}"); 1.250 +} 1.251 + 1.252 +#ifndef PRODUCT 1.253 1.254 static void print_boolean_array(typeArrayOop ta, int print_len, outputStream* st) { 1.255 for (int index = 0; index < print_len; index++) {