src/share/vm/oops/klass.cpp

Thu, 07 Apr 2011 09:53:20 -0700

author
johnc
date
Thu, 07 Apr 2011 09:53:20 -0700
changeset 2781
e1162778c1c8
parent 2497
3582bf76420e
child 2698
38fea01eb669
permissions
-rw-r--r--

7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
Summary: A referent object that is only weakly reachable at the start of concurrent marking but is re-attached to the strongly reachable object graph during marking may not be marked as live. This can cause the reference object to be processed prematurely and leave dangling pointers to the referent object. Implement a read barrier for the java.lang.ref.Reference::referent field by intrinsifying the Reference.get() method, and intercepting accesses though JNI, reflection, and Unsafe, so that when a non-null referent object is read it is also logged in an SATB buffer.
Reviewed-by: kvn, iveresov, never, tonyp, dholmes

     1 /*
     2  * Copyright (c) 1997, 2010, 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  */
    25 #include "precompiled.hpp"
    26 #include "classfile/systemDictionary.hpp"
    27 #include "classfile/vmSymbols.hpp"
    28 #include "gc_interface/collectedHeap.inline.hpp"
    29 #include "memory/oopFactory.hpp"
    30 #include "memory/resourceArea.hpp"
    31 #include "oops/instanceKlass.hpp"
    32 #include "oops/klass.inline.hpp"
    33 #include "oops/klassOop.hpp"
    34 #include "oops/oop.inline.hpp"
    35 #include "oops/oop.inline2.hpp"
    36 #include "runtime/atomic.hpp"
    38 void Klass::set_name(Symbol* n) {
    39   _name = n;
    40   if (_name != NULL) _name->increment_refcount();
    41 }
    43 bool Klass::is_subclass_of(klassOop k) const {
    44   // Run up the super chain and check
    45   klassOop t = as_klassOop();
    47   if (t == k) return true;
    48   t = Klass::cast(t)->super();
    50   while (t != NULL) {
    51     if (t == k) return true;
    52     t = Klass::cast(t)->super();
    53   }
    54   return false;
    55 }
    57 bool Klass::search_secondary_supers(klassOop k) const {
    58   // Put some extra logic here out-of-line, before the search proper.
    59   // This cuts down the size of the inline method.
    61   // This is necessary, since I am never in my own secondary_super list.
    62   if (this->as_klassOop() == k)
    63     return true;
    64   // Scan the array-of-objects for a match
    65   int cnt = secondary_supers()->length();
    66   for (int i = 0; i < cnt; i++) {
    67     if (secondary_supers()->obj_at(i) == k) {
    68       ((Klass*)this)->set_secondary_super_cache(k);
    69       return true;
    70     }
    71   }
    72   return false;
    73 }
    75 // Return self, except for abstract classes with exactly 1
    76 // implementor.  Then return the 1 concrete implementation.
    77 Klass *Klass::up_cast_abstract() {
    78   Klass *r = this;
    79   while( r->is_abstract() ) {   // Receiver is abstract?
    80     Klass *s = r->subklass();   // Check for exactly 1 subklass
    81     if( !s || s->next_sibling() ) // Oops; wrong count; give up
    82       return this;              // Return 'this' as a no-progress flag
    83     r = s;                    // Loop till find concrete class
    84   }
    85   return r;                   // Return the 1 concrete class
    86 }
    88 // Find LCA in class hierarchy
    89 Klass *Klass::LCA( Klass *k2 ) {
    90   Klass *k1 = this;
    91   while( 1 ) {
    92     if( k1->is_subtype_of(k2->as_klassOop()) ) return k2;
    93     if( k2->is_subtype_of(k1->as_klassOop()) ) return k1;
    94     k1 = k1->super()->klass_part();
    95     k2 = k2->super()->klass_part();
    96   }
    97 }
   100 void Klass::check_valid_for_instantiation(bool throwError, TRAPS) {
   101   ResourceMark rm(THREAD);
   102   THROW_MSG(throwError ? vmSymbols::java_lang_InstantiationError()
   103             : vmSymbols::java_lang_InstantiationException(), external_name());
   104 }
   107 void Klass::copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS) {
   108   THROW(vmSymbols::java_lang_ArrayStoreException());
   109 }
   112 void Klass::initialize(TRAPS) {
   113   ShouldNotReachHere();
   114 }
   116 bool Klass::compute_is_subtype_of(klassOop k) {
   117   assert(k->is_klass(), "argument must be a class");
   118   return is_subclass_of(k);
   119 }
   122 methodOop Klass::uncached_lookup_method(Symbol* name, Symbol* signature) const {
   123 #ifdef ASSERT
   124   tty->print_cr("Error: uncached_lookup_method called on a klass oop."
   125                 " Likely error: reflection method does not correctly"
   126                 " wrap return value in a mirror object.");
   127 #endif
   128   ShouldNotReachHere();
   129   return NULL;
   130 }
   132 klassOop Klass::base_create_klass_oop(KlassHandle& klass, int size,
   133                                       const Klass_vtbl& vtbl, TRAPS) {
   134   size = align_object_size(size);
   135   // allocate and initialize vtable
   136   Klass*   kl = (Klass*) vtbl.allocate_permanent(klass, size, CHECK_NULL);
   137   klassOop k  = kl->as_klassOop();
   139   { // Preinitialize supertype information.
   140     // A later call to initialize_supers() may update these settings:
   141     kl->set_super(NULL);
   142     for (juint i = 0; i < Klass::primary_super_limit(); i++) {
   143       kl->_primary_supers[i] = NULL;
   144     }
   145     kl->set_secondary_supers(NULL);
   146     oop_store_without_check((oop*) &kl->_primary_supers[0], k);
   147     kl->set_super_check_offset(primary_supers_offset_in_bytes() + sizeof(oopDesc));
   148   }
   150   kl->set_java_mirror(NULL);
   151   kl->set_modifier_flags(0);
   152   kl->set_layout_helper(Klass::_lh_neutral_value);
   153   kl->set_name(NULL);
   154   AccessFlags af;
   155   af.set_flags(0);
   156   kl->set_access_flags(af);
   157   kl->set_subklass(NULL);
   158   kl->set_next_sibling(NULL);
   159   kl->set_alloc_count(0);
   160   kl->set_alloc_size(0);
   162   kl->set_prototype_header(markOopDesc::prototype());
   163   kl->set_biased_lock_revocation_count(0);
   164   kl->set_last_biased_lock_bulk_revocation_time(0);
   166   return k;
   167 }
   169 KlassHandle Klass::base_create_klass(KlassHandle& klass, int size,
   170                                      const Klass_vtbl& vtbl, TRAPS) {
   171   klassOop ek = base_create_klass_oop(klass, size, vtbl, THREAD);
   172   return KlassHandle(THREAD, ek);
   173 }
   175 void Klass_vtbl::post_new_init_klass(KlassHandle& klass,
   176                                      klassOop new_klass,
   177                                      int size) const {
   178   assert(!new_klass->klass_part()->null_vtbl(), "Not a complete klass");
   179   CollectedHeap::post_allocation_install_obj_klass(klass, new_klass, size);
   180 }
   182 void* Klass_vtbl::operator new(size_t ignored, KlassHandle& klass,
   183                                int size, TRAPS) {
   184   // The vtable pointer is installed during the execution of
   185   // constructors in the call to permanent_obj_allocate().  Delay
   186   // the installation of the klass pointer into the new klass "k"
   187   // until after the vtable pointer has been installed (i.e., until
   188   // after the return of permanent_obj_allocate().
   189   klassOop k =
   190     (klassOop) CollectedHeap::permanent_obj_allocate_no_klass_install(klass,
   191       size, CHECK_NULL);
   192   return k->klass_part();
   193 }
   195 jint Klass::array_layout_helper(BasicType etype) {
   196   assert(etype >= T_BOOLEAN && etype <= T_OBJECT, "valid etype");
   197   // Note that T_ARRAY is not allowed here.
   198   int  hsize = arrayOopDesc::base_offset_in_bytes(etype);
   199   int  esize = type2aelembytes(etype);
   200   bool isobj = (etype == T_OBJECT);
   201   int  tag   =  isobj ? _lh_array_tag_obj_value : _lh_array_tag_type_value;
   202   int lh = array_layout_helper(tag, hsize, etype, exact_log2(esize));
   204   assert(lh < (int)_lh_neutral_value, "must look like an array layout");
   205   assert(layout_helper_is_javaArray(lh), "correct kind");
   206   assert(layout_helper_is_objArray(lh) == isobj, "correct kind");
   207   assert(layout_helper_is_typeArray(lh) == !isobj, "correct kind");
   208   assert(layout_helper_header_size(lh) == hsize, "correct decode");
   209   assert(layout_helper_element_type(lh) == etype, "correct decode");
   210   assert(1 << layout_helper_log2_element_size(lh) == esize, "correct decode");
   212   return lh;
   213 }
   215 bool Klass::can_be_primary_super_slow() const {
   216   if (super() == NULL)
   217     return true;
   218   else if (super()->klass_part()->super_depth() >= primary_super_limit()-1)
   219     return false;
   220   else
   221     return true;
   222 }
   224 void Klass::initialize_supers(klassOop k, TRAPS) {
   225   if (FastSuperclassLimit == 0) {
   226     // None of the other machinery matters.
   227     set_super(k);
   228     return;
   229   }
   230   if (k == NULL) {
   231     set_super(NULL);
   232     oop_store_without_check((oop*) &_primary_supers[0], (oop) this->as_klassOop());
   233     assert(super_depth() == 0, "Object must already be initialized properly");
   234   } else if (k != super() || k == SystemDictionary::Object_klass()) {
   235     assert(super() == NULL || super() == SystemDictionary::Object_klass(),
   236            "initialize this only once to a non-trivial value");
   237     set_super(k);
   238     Klass* sup = k->klass_part();
   239     int sup_depth = sup->super_depth();
   240     juint my_depth  = MIN2(sup_depth + 1, (int)primary_super_limit());
   241     if (!can_be_primary_super_slow())
   242       my_depth = primary_super_limit();
   243     for (juint i = 0; i < my_depth; i++) {
   244       oop_store_without_check((oop*) &_primary_supers[i], (oop) sup->_primary_supers[i]);
   245     }
   246     klassOop *super_check_cell;
   247     if (my_depth < primary_super_limit()) {
   248       oop_store_without_check((oop*) &_primary_supers[my_depth], (oop) this->as_klassOop());
   249       super_check_cell = &_primary_supers[my_depth];
   250     } else {
   251       // Overflow of the primary_supers array forces me to be secondary.
   252       super_check_cell = &_secondary_super_cache;
   253     }
   254     set_super_check_offset((address)super_check_cell - (address) this->as_klassOop());
   256 #ifdef ASSERT
   257     {
   258       juint j = super_depth();
   259       assert(j == my_depth, "computed accessor gets right answer");
   260       klassOop t = as_klassOop();
   261       while (!Klass::cast(t)->can_be_primary_super()) {
   262         t = Klass::cast(t)->super();
   263         j = Klass::cast(t)->super_depth();
   264       }
   265       for (juint j1 = j+1; j1 < primary_super_limit(); j1++) {
   266         assert(primary_super_of_depth(j1) == NULL, "super list padding");
   267       }
   268       while (t != NULL) {
   269         assert(primary_super_of_depth(j) == t, "super list initialization");
   270         t = Klass::cast(t)->super();
   271         --j;
   272       }
   273       assert(j == (juint)-1, "correct depth count");
   274     }
   275 #endif
   276   }
   278   if (secondary_supers() == NULL) {
   279     KlassHandle this_kh (THREAD, this);
   281     // Now compute the list of secondary supertypes.
   282     // Secondaries can occasionally be on the super chain,
   283     // if the inline "_primary_supers" array overflows.
   284     int extras = 0;
   285     klassOop p;
   286     for (p = super(); !(p == NULL || p->klass_part()->can_be_primary_super()); p = p->klass_part()->super()) {
   287       ++extras;
   288     }
   290     // Compute the "real" non-extra secondaries.
   291     objArrayOop secondary_oops = compute_secondary_supers(extras, CHECK);
   292     objArrayHandle secondaries (THREAD, secondary_oops);
   294     // Store the extra secondaries in the first array positions:
   295     int fillp = extras;
   296     for (p = this_kh->super(); !(p == NULL || p->klass_part()->can_be_primary_super()); p = p->klass_part()->super()) {
   297       int i;                    // Scan for overflow primaries being duplicates of 2nd'arys
   299       // This happens frequently for very deeply nested arrays: the
   300       // primary superclass chain overflows into the secondary.  The
   301       // secondary list contains the element_klass's secondaries with
   302       // an extra array dimension added.  If the element_klass's
   303       // secondary list already contains some primary overflows, they
   304       // (with the extra level of array-ness) will collide with the
   305       // normal primary superclass overflows.
   306       for( i = extras; i < secondaries->length(); i++ )
   307         if( secondaries->obj_at(i) == p )
   308           break;
   309       if( i < secondaries->length() )
   310         continue;               // It's a dup, don't put it in
   311       secondaries->obj_at_put(--fillp, p);
   312     }
   313     // See if we had some dup's, so the array has holes in it.
   314     if( fillp > 0 ) {
   315       // Pack the array.  Drop the old secondaries array on the floor
   316       // and let GC reclaim it.
   317       objArrayOop s2 = oopFactory::new_system_objArray(secondaries->length() - fillp, CHECK);
   318       for( int i = 0; i < s2->length(); i++ )
   319         s2->obj_at_put( i, secondaries->obj_at(i+fillp) );
   320       secondaries = objArrayHandle(THREAD, s2);
   321     }
   323   #ifdef ASSERT
   324     if (secondaries() != Universe::the_array_interfaces_array()) {
   325       // We must not copy any NULL placeholders left over from bootstrap.
   326       for (int j = 0; j < secondaries->length(); j++) {
   327         assert(secondaries->obj_at(j) != NULL, "correct bootstrapping order");
   328       }
   329     }
   330   #endif
   332     this_kh->set_secondary_supers(secondaries());
   333   }
   334 }
   336 objArrayOop Klass::compute_secondary_supers(int num_extra_slots, TRAPS) {
   337   assert(num_extra_slots == 0, "override for complex klasses");
   338   return Universe::the_empty_system_obj_array();
   339 }
   342 Klass* Klass::subklass() const {
   343   return _subklass == NULL ? NULL : Klass::cast(_subklass);
   344 }
   346 instanceKlass* Klass::superklass() const {
   347   assert(super() == NULL || super()->klass_part()->oop_is_instance(), "must be instance klass");
   348   return _super == NULL ? NULL : instanceKlass::cast(_super);
   349 }
   351 Klass* Klass::next_sibling() const {
   352   return _next_sibling == NULL ? NULL : Klass::cast(_next_sibling);
   353 }
   355 void Klass::set_subklass(klassOop s) {
   356   assert(s != as_klassOop(), "sanity check");
   357   oop_store_without_check((oop*)&_subklass, s);
   358 }
   360 void Klass::set_next_sibling(klassOop s) {
   361   assert(s != as_klassOop(), "sanity check");
   362   oop_store_without_check((oop*)&_next_sibling, s);
   363 }
   365 void Klass::append_to_sibling_list() {
   366   debug_only(if (!SharedSkipVerify) as_klassOop()->verify();)
   367   // add ourselves to superklass' subklass list
   368   instanceKlass* super = superklass();
   369   if (super == NULL) return;        // special case: class Object
   370   assert(SharedSkipVerify ||
   371          (!super->is_interface()    // interfaces cannot be supers
   372           && (super->superklass() == NULL || !is_interface())),
   373          "an interface can only be a subklass of Object");
   374   klassOop prev_first_subklass = super->subklass_oop();
   375   if (prev_first_subklass != NULL) {
   376     // set our sibling to be the superklass' previous first subklass
   377     set_next_sibling(prev_first_subklass);
   378   }
   379   // make ourselves the superklass' first subklass
   380   super->set_subklass(as_klassOop());
   381   debug_only(if (!SharedSkipVerify) as_klassOop()->verify();)
   382 }
   384 void Klass::remove_from_sibling_list() {
   385   // remove receiver from sibling list
   386   instanceKlass* super = superklass();
   387   assert(super != NULL || as_klassOop() == SystemDictionary::Object_klass(), "should have super");
   388   if (super == NULL) return;        // special case: class Object
   389   if (super->subklass() == this) {
   390     // first subklass
   391     super->set_subklass(_next_sibling);
   392   } else {
   393     Klass* sib = super->subklass();
   394     while (sib->next_sibling() != this) {
   395       sib = sib->next_sibling();
   396     };
   397     sib->set_next_sibling(_next_sibling);
   398   }
   399 }
   401 void Klass::follow_weak_klass_links( BoolObjectClosure* is_alive, OopClosure* keep_alive) {
   402   // This klass is alive but the subklass and siblings are not followed/updated.
   403   // We update the subklass link and the subklass' sibling links here.
   404   // Our own sibling link will be updated by our superclass (which must be alive
   405   // since we are).
   406   assert(is_alive->do_object_b(as_klassOop()), "just checking, this should be live");
   407   if (ClassUnloading) {
   408     klassOop sub = subklass_oop();
   409     if (sub != NULL && !is_alive->do_object_b(sub)) {
   410       // first subklass not alive, find first one alive
   411       do {
   412 #ifndef PRODUCT
   413         if (TraceClassUnloading && WizardMode) {
   414           ResourceMark rm;
   415           tty->print_cr("[Unlinking class (subclass) %s]", sub->klass_part()->external_name());
   416         }
   417 #endif
   418         sub = sub->klass_part()->next_sibling_oop();
   419       } while (sub != NULL && !is_alive->do_object_b(sub));
   420       set_subklass(sub);
   421     }
   422     // now update the subklass' sibling list
   423     while (sub != NULL) {
   424       klassOop next = sub->klass_part()->next_sibling_oop();
   425       if (next != NULL && !is_alive->do_object_b(next)) {
   426         // first sibling not alive, find first one alive
   427         do {
   428 #ifndef PRODUCT
   429           if (TraceClassUnloading && WizardMode) {
   430             ResourceMark rm;
   431             tty->print_cr("[Unlinking class (sibling) %s]", next->klass_part()->external_name());
   432           }
   433 #endif
   434           next = next->klass_part()->next_sibling_oop();
   435         } while (next != NULL && !is_alive->do_object_b(next));
   436         sub->klass_part()->set_next_sibling(next);
   437       }
   438       sub = next;
   439     }
   440   } else {
   441     // Always follow subklass and sibling link. This will prevent any klasses from
   442     // being unloaded (all classes are transitively linked from java.lang.Object).
   443     keep_alive->do_oop(adr_subklass());
   444     keep_alive->do_oop(adr_next_sibling());
   445   }
   446 }
   449 void Klass::remove_unshareable_info() {
   450   if (oop_is_instance()) {
   451     instanceKlass* ik = (instanceKlass*)this;
   452     if (ik->is_linked()) {
   453       ik->unlink_class();
   454     }
   455   }
   456   set_subklass(NULL);
   457   set_next_sibling(NULL);
   458 }
   461 void Klass::shared_symbols_iterate(SymbolClosure* closure) {
   462   closure->do_symbol(&_name);
   463 }
   466 klassOop Klass::array_klass_or_null(int rank) {
   467   EXCEPTION_MARK;
   468   // No exception can be thrown by array_klass_impl when called with or_null == true.
   469   // (In anycase, the execption mark will fail if it do so)
   470   return array_klass_impl(true, rank, THREAD);
   471 }
   474 klassOop Klass::array_klass_or_null() {
   475   EXCEPTION_MARK;
   476   // No exception can be thrown by array_klass_impl when called with or_null == true.
   477   // (In anycase, the execption mark will fail if it do so)
   478   return array_klass_impl(true, THREAD);
   479 }
   482 klassOop Klass::array_klass_impl(bool or_null, int rank, TRAPS) {
   483   fatal("array_klass should be dispatched to instanceKlass, objArrayKlass or typeArrayKlass");
   484   return NULL;
   485 }
   488 klassOop Klass::array_klass_impl(bool or_null, TRAPS) {
   489   fatal("array_klass should be dispatched to instanceKlass, objArrayKlass or typeArrayKlass");
   490   return NULL;
   491 }
   494 void Klass::with_array_klasses_do(void f(klassOop k)) {
   495   f(as_klassOop());
   496 }
   499 const char* Klass::external_name() const {
   500   if (oop_is_instance()) {
   501     instanceKlass* ik = (instanceKlass*) this;
   502     if (ik->is_anonymous()) {
   503       assert(AnonymousClasses, "");
   504       intptr_t hash = ik->java_mirror()->identity_hash();
   505       char     hash_buf[40];
   506       sprintf(hash_buf, "/" UINTX_FORMAT, (uintx)hash);
   507       size_t   hash_len = strlen(hash_buf);
   509       size_t result_len = name()->utf8_length();
   510       char*  result     = NEW_RESOURCE_ARRAY(char, result_len + hash_len + 1);
   511       name()->as_klass_external_name(result, (int) result_len + 1);
   512       assert(strlen(result) == result_len, "");
   513       strcpy(result + result_len, hash_buf);
   514       assert(strlen(result) == result_len + hash_len, "");
   515       return result;
   516     }
   517   }
   518   if (name() == NULL)  return "<unknown>";
   519   return name()->as_klass_external_name();
   520 }
   523 const char* Klass::signature_name() const {
   524   if (name() == NULL)  return "<unknown>";
   525   return name()->as_C_string();
   526 }
   528 // Unless overridden, modifier_flags is 0.
   529 jint Klass::compute_modifier_flags(TRAPS) const {
   530   return 0;
   531 }
   533 int Klass::atomic_incr_biased_lock_revocation_count() {
   534   return (int) Atomic::add(1, &_biased_lock_revocation_count);
   535 }
   537 // Unless overridden, jvmti_class_status has no flags set.
   538 jint Klass::jvmti_class_status() const {
   539   return 0;
   540 }
   542 // Printing
   544 void Klass::oop_print_on(oop obj, outputStream* st) {
   545   ResourceMark rm;
   546   // print title
   547   st->print_cr("%s ", internal_name());
   548   obj->print_address_on(st);
   550   if (WizardMode) {
   551      // print header
   552      obj->mark()->print_on(st);
   553   }
   555   // print class
   556   st->print(" - klass: ");
   557   obj->klass()->print_value_on(st);
   558   st->cr();
   559 }
   561 void Klass::oop_print_value_on(oop obj, outputStream* st) {
   562   // print title
   563   ResourceMark rm;              // Cannot print in debug mode without this
   564   st->print("%s", internal_name());
   565   obj->print_address_on(st);
   566 }
   568 // Verification
   570 void Klass::oop_verify_on(oop obj, outputStream* st) {
   571   guarantee(obj->is_oop(),  "should be oop");
   572   guarantee(obj->klass()->is_perm(),  "should be in permspace");
   573   guarantee(obj->klass()->is_klass(), "klass field is not a klass");
   574 }
   577 void Klass::oop_verify_old_oop(oop obj, oop* p, bool allow_dirty) {
   578   /* $$$ I think this functionality should be handled by verification of
   579   RememberedSet::verify_old_oop(obj, p, allow_dirty, false);
   580   the card table. */
   581 }
   582 void Klass::oop_verify_old_oop(oop obj, narrowOop* p, bool allow_dirty) { }
   584 #ifndef PRODUCT
   586 void Klass::verify_vtable_index(int i) {
   587   assert(oop_is_instance() || oop_is_array(), "only instanceKlass and arrayKlass have vtables");
   588   if (oop_is_instance()) {
   589     assert(i>=0 && i<((instanceKlass*)this)->vtable_length()/vtableEntry::size(), "index out of bounds");
   590   } else {
   591     assert(i>=0 && i<((arrayKlass*)this)->vtable_length()/vtableEntry::size(), "index out of bounds");
   592   }
   593 }
   595 #endif

mercurial