1 /* 2 * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 # include "incls/_precompiled.incl" 26 # include "incls/_objArrayKlassKlass.cpp.incl" 27 28 klassOop objArrayKlassKlass::create_klass(TRAPS) { 29 objArrayKlassKlass o; 30 KlassHandle h_this_klass(THREAD, Universe::klassKlassObj()); 31 KlassHandle k = base_create_klass(h_this_klass, header_size(), o.vtbl_value(), CHECK_0); 32 assert(k()->size() == align_object_size(header_size()), "wrong size for object"); 33 java_lang_Class::create_mirror(k, CHECK_0); // Allocate mirror 34 return k(); 35 } 36 37 klassOop objArrayKlassKlass::allocate_system_objArray_klass(TRAPS) { 38 // system_objArrays have no instance klass, so allocate with fake class, then reset to NULL 39 KlassHandle kk(THREAD, Universe::intArrayKlassObj()); 40 klassOop k = allocate_objArray_klass(1, kk, CHECK_0); 41 objArrayKlass* tk = (objArrayKlass*) k->klass_part(); 42 tk->set_element_klass(NULL); 43 tk->set_bottom_klass(NULL); 44 return k; 45 } 46 47 48 klassOop objArrayKlassKlass::allocate_objArray_klass(int n, KlassHandle element_klass, TRAPS) { 49 objArrayKlassKlassHandle this_oop(THREAD, as_klassOop()); 50 return allocate_objArray_klass_impl(this_oop, n, element_klass, THREAD); 51 } 52 53 klassOop objArrayKlassKlass::allocate_objArray_klass_impl(objArrayKlassKlassHandle this_oop, 54 int n, KlassHandle element_klass, TRAPS) { 55 56 // Eagerly allocate the direct array supertype. 57 KlassHandle super_klass = KlassHandle(); 58 if (!Universe::is_bootstrapping()) { 59 KlassHandle element_super (THREAD, element_klass->super()); 60 if (element_super.not_null()) { 61 // The element type has a direct super. E.g., String[] has direct super of Object[]. 62 super_klass = KlassHandle(THREAD, element_super->array_klass_or_null()); 63 bool supers_exist = super_klass.not_null(); 64 // Also, see if the element has secondary supertypes. 65 // We need an array type for each. 66 objArrayHandle element_supers = objArrayHandle(THREAD, 67 element_klass->secondary_supers()); 68 for( int i = element_supers->length()-1; i >= 0; i-- ) { 69 klassOop elem_super = (klassOop) element_supers->obj_at(i); 70 if (Klass::cast(elem_super)->array_klass_or_null() == NULL) { 71 supers_exist = false; 72 break; 73 } 74 } 75 if (!supers_exist) { 76 // Oops. Not allocated yet. Back out, allocate it, and retry. 77 #ifndef PRODUCT 78 if (WizardMode) { 79 tty->print_cr("Must retry array klass creation for depth %d",n); 80 } 81 #endif 82 KlassHandle ek; 83 { 84 MutexUnlocker mu(MultiArray_lock); 85 MutexUnlocker mc(Compile_lock); // for vtables 86 klassOop sk = element_super->array_klass(CHECK_0); 87 super_klass = KlassHandle(THREAD, sk); 88 for( int i = element_supers->length()-1; i >= 0; i-- ) { 89 KlassHandle elem_super (THREAD, element_supers->obj_at(i)); 90 elem_super->array_klass(CHECK_0); 91 } 92 // Now retry from the beginning 93 klassOop klass_oop = element_klass->array_klass(n, CHECK_0); 94 // Create a handle because the enclosing brace, when locking 95 // can cause a gc. Better to have this function return a Handle. 96 ek = KlassHandle(THREAD, klass_oop); 97 } // re-lock 98 return ek(); 99 } 100 } else { 101 // The element type is already Object. Object[] has direct super of Object. 102 super_klass = KlassHandle(THREAD, SystemDictionary::Object_klass()); 103 } 104 } 105 106 // Create type name for klass (except for symbol arrays, since symbolKlass 107 // does not have a name). This will potentially allocate an object, cause 108 // GC, and all other kinds of things. Hence, this must be done before we 109 // get a handle to the new objArrayKlass we want to construct. We cannot 110 // block while holding a handling to a partly initialized object. 111 symbolHandle name = symbolHandle(); 112 113 if (!element_klass->oop_is_symbol()) { 114 ResourceMark rm(THREAD); 115 char *name_str = element_klass->name()->as_C_string(); 116 int len = element_klass->name()->utf8_length(); 117 char *new_str = NEW_RESOURCE_ARRAY(char, len + 4); 118 int idx = 0; 119 new_str[idx++] = '['; 120 if (element_klass->oop_is_instance()) { // it could be an array or simple type 121 new_str[idx++] = 'L'; 122 } 123 memcpy(&new_str[idx], name_str, len * sizeof(char)); 124 idx += len; 125 if (element_klass->oop_is_instance()) { 126 new_str[idx++] = ';'; 127 } 128 new_str[idx++] = '\0'; 129 name = oopFactory::new_symbol_handle(new_str, CHECK_0); 130 } 131 132 objArrayKlass o; 133 arrayKlassHandle k = arrayKlass::base_create_array_klass(o.vtbl_value(), 134 objArrayKlass::header_size(), 135 this_oop, 136 CHECK_0); 137 138 139 // Initialize instance variables 140 objArrayKlass* oak = objArrayKlass::cast(k()); 141 oak->set_dimension(n); 142 oak->set_element_klass(element_klass()); 143 oak->set_name(name()); 144 145 klassOop bk; 146 if (element_klass->oop_is_objArray()) { 147 bk = objArrayKlass::cast(element_klass())->bottom_klass(); 148 } else { 149 bk = element_klass(); 150 } 151 assert(bk != NULL && (Klass::cast(bk)->oop_is_instance() || Klass::cast(bk)->oop_is_typeArray()), "invalid bottom klass"); 152 oak->set_bottom_klass(bk); 153 154 oak->set_layout_helper(array_layout_helper(T_OBJECT)); 155 assert(oak->oop_is_javaArray(), "sanity"); 156 assert(oak->oop_is_objArray(), "sanity"); 157 158 // Call complete_create_array_klass after all instance variables has been initialized. 159 arrayKlass::complete_create_array_klass(k, super_klass, CHECK_0); 160 161 return k(); 162 } 163 164 165 void objArrayKlassKlass::oop_follow_contents(oop obj) { 166 assert(obj->is_klass(), "must be klass"); 167 assert(klassOop(obj)->klass_part()->oop_is_objArray_slow(), "must be obj array"); 168 169 objArrayKlass* oak = objArrayKlass::cast((klassOop)obj); 170 MarkSweep::mark_and_push(oak->element_klass_addr()); 171 MarkSweep::mark_and_push(oak->bottom_klass_addr()); 172 173 arrayKlassKlass::oop_follow_contents(obj); 174 } 175 176 #ifndef SERIALGC 177 void objArrayKlassKlass::oop_follow_contents(ParCompactionManager* cm, 178 oop obj) { 179 assert(obj->is_klass(), "must be klass"); 180 assert(klassOop(obj)->klass_part()->oop_is_objArray_slow(), "must be obj array"); 181 182 objArrayKlass* oak = objArrayKlass::cast((klassOop)obj); 183 PSParallelCompact::mark_and_push(cm, oak->element_klass_addr()); 184 PSParallelCompact::mark_and_push(cm, oak->bottom_klass_addr()); 185 186 arrayKlassKlass::oop_follow_contents(cm, obj); 187 } 188 #endif // SERIALGC 189 190 191 int objArrayKlassKlass::oop_adjust_pointers(oop obj) { 192 assert(obj->is_klass(), "must be klass"); 193 assert(klassOop(obj)->klass_part()->oop_is_objArray_slow(), "must be obj array"); 194 195 objArrayKlass* oak = objArrayKlass::cast((klassOop)obj); 196 MarkSweep::adjust_pointer(oak->element_klass_addr()); 197 MarkSweep::adjust_pointer(oak->bottom_klass_addr()); 198 199 return arrayKlassKlass::oop_adjust_pointers(obj); 200 } 201 202 203 204 int objArrayKlassKlass::oop_oop_iterate(oop obj, OopClosure* blk) { 205 assert(obj->is_klass(), "must be klass"); 206 assert(klassOop(obj)->klass_part()->oop_is_objArray_slow(), "must be obj array"); 207 208 objArrayKlass* oak = objArrayKlass::cast((klassOop)obj); 209 blk->do_oop(oak->element_klass_addr()); 210 blk->do_oop(oak->bottom_klass_addr()); 211 212 return arrayKlassKlass::oop_oop_iterate(obj, blk); 213 } 214 215 216 int 217 objArrayKlassKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) { 218 assert(obj->is_klass(), "must be klass"); 219 assert(klassOop(obj)->klass_part()->oop_is_objArray_slow(), "must be obj array"); 220 221 objArrayKlass* oak = objArrayKlass::cast((klassOop)obj); 222 oop* addr; 223 addr = oak->element_klass_addr(); 224 if (mr.contains(addr)) blk->do_oop(addr); 225 addr = oak->bottom_klass_addr(); 226 if (mr.contains(addr)) blk->do_oop(addr); 227 228 return arrayKlassKlass::oop_oop_iterate(obj, blk); 229 } 230 231 #ifndef SERIALGC 232 void objArrayKlassKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { 233 assert(obj->blueprint()->oop_is_objArrayKlass(),"must be an obj array klass"); 234 } 235 236 int objArrayKlassKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { 237 assert(obj->is_klass(), "must be klass"); 238 assert(klassOop(obj)->klass_part()->oop_is_objArray_slow(), "must be obj array"); 239 240 objArrayKlass* oak = objArrayKlass::cast((klassOop)obj); 241 PSParallelCompact::adjust_pointer(oak->element_klass_addr()); 242 PSParallelCompact::adjust_pointer(oak->bottom_klass_addr()); 243 244 return arrayKlassKlass::oop_update_pointers(cm, obj); 245 } 246 247 int objArrayKlassKlass::oop_update_pointers(ParCompactionManager* cm, oop obj, 248 HeapWord* beg_addr, 249 HeapWord* end_addr) { 250 assert(obj->is_klass(), "must be klass"); 251 assert(klassOop(obj)->klass_part()->oop_is_objArray_slow(), "must be obj array"); 252 253 oop* p; 254 objArrayKlass* oak = objArrayKlass::cast((klassOop)obj); 255 p = oak->element_klass_addr(); 256 PSParallelCompact::adjust_pointer(p, beg_addr, end_addr); 257 p = oak->bottom_klass_addr(); 258 PSParallelCompact::adjust_pointer(p, beg_addr, end_addr); 259 260 return arrayKlassKlass::oop_update_pointers(cm, obj, beg_addr, end_addr); 261 } 262 #endif // SERIALGC 263 264 #ifndef PRODUCT 265 266 // Printing 267 268 void objArrayKlassKlass::oop_print_on(oop obj, outputStream* st) { 269 assert(obj->is_klass(), "must be klass"); 270 objArrayKlass* oak = (objArrayKlass*) klassOop(obj)->klass_part(); 271 klassKlass::oop_print_on(obj, st); 272 st->print(" - instance klass: "); 273 oak->element_klass()->print_value_on(st); 274 st->cr(); 275 } 276 277 #endif //PRODUCT 278 279 void objArrayKlassKlass::oop_print_value_on(oop obj, outputStream* st) { 280 assert(obj->is_klass(), "must be klass"); 281 objArrayKlass* oak = (objArrayKlass*) klassOop(obj)->klass_part(); 282 283 oak->element_klass()->print_value_on(st); 284 st->print("[]"); 285 } 286 287 const char* objArrayKlassKlass::internal_name() const { 288 return "{object array class}"; 289 } 290 291 292 // Verification 293 294 void objArrayKlassKlass::oop_verify_on(oop obj, outputStream* st) { 295 klassKlass::oop_verify_on(obj, st); 296 objArrayKlass* oak = objArrayKlass::cast((klassOop)obj); 297 guarantee(oak->element_klass()->is_perm(), "should be in permspace"); 298 guarantee(oak->element_klass()->is_klass(), "should be klass"); 299 guarantee(oak->bottom_klass()->is_perm(), "should be in permspace"); 300 guarantee(oak->bottom_klass()->is_klass(), "should be klass"); 301 Klass* bk = Klass::cast(oak->bottom_klass()); 302 guarantee(bk->oop_is_instance() || bk->oop_is_typeArray(), "invalid bottom klass"); 303 }