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 }