src/share/vm/oops/objArrayKlassKlass.cpp

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

author
johnc
date
Thu, 07 Apr 2011 09:53:20 -0700
changeset 2781
e1162778c1c8
parent 2658
c7f3d0b4570f
child 3682
fc9d8850ab8b
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, 2011, 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/javaClasses.hpp"
    27 #include "classfile/systemDictionary.hpp"
    28 #include "gc_implementation/shared/markSweep.inline.hpp"
    29 #include "gc_interface/collectedHeap.inline.hpp"
    30 #include "oops/instanceKlass.hpp"
    31 #include "oops/objArrayKlassKlass.hpp"
    32 #include "oops/oop.inline.hpp"
    33 #include "oops/oop.inline2.hpp"
    34 #ifndef SERIALGC
    35 #include "gc_implementation/parNew/parOopClosures.inline.hpp"
    36 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
    37 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
    38 #include "memory/cardTableRS.hpp"
    39 #include "oops/oop.pcgc.inline.hpp"
    40 #endif
    42 klassOop objArrayKlassKlass::create_klass(TRAPS) {
    43   objArrayKlassKlass o;
    44   KlassHandle h_this_klass(THREAD, Universe::klassKlassObj());
    45   KlassHandle k = base_create_klass(h_this_klass, header_size(), o.vtbl_value(), CHECK_0);
    46   assert(k()->size() == align_object_size(header_size()), "wrong size for object");
    47   java_lang_Class::create_mirror(k, CHECK_0); // Allocate mirror
    48   return k();
    49 }
    51 klassOop objArrayKlassKlass::allocate_system_objArray_klass(TRAPS) {
    52   // system_objArrays have no instance klass, so allocate with fake class, then reset to NULL
    53   KlassHandle kk(THREAD, Universe::intArrayKlassObj());
    54   klassOop k = allocate_objArray_klass(1, kk, CHECK_0);
    55   objArrayKlass* tk = (objArrayKlass*) k->klass_part();
    56   tk->set_element_klass(NULL);
    57   tk->set_bottom_klass(NULL);
    58   return k;
    59 }
    62 klassOop objArrayKlassKlass::allocate_objArray_klass(int n, KlassHandle element_klass, TRAPS) {
    63   objArrayKlassKlassHandle this_oop(THREAD, as_klassOop());
    64   return allocate_objArray_klass_impl(this_oop, n, element_klass, THREAD);
    65 }
    67 klassOop objArrayKlassKlass::allocate_objArray_klass_impl(objArrayKlassKlassHandle this_oop,
    68                                                           int n, KlassHandle element_klass, TRAPS) {
    70   // Eagerly allocate the direct array supertype.
    71   KlassHandle super_klass = KlassHandle();
    72   if (!Universe::is_bootstrapping()) {
    73     KlassHandle element_super (THREAD, element_klass->super());
    74     if (element_super.not_null()) {
    75       // The element type has a direct super.  E.g., String[] has direct super of Object[].
    76       super_klass = KlassHandle(THREAD, element_super->array_klass_or_null());
    77       bool supers_exist = super_klass.not_null();
    78       // Also, see if the element has secondary supertypes.
    79       // We need an array type for each.
    80       objArrayHandle element_supers = objArrayHandle(THREAD,
    81                                             element_klass->secondary_supers());
    82       for( int i = element_supers->length()-1; i >= 0; i-- ) {
    83         klassOop elem_super = (klassOop) element_supers->obj_at(i);
    84         if (Klass::cast(elem_super)->array_klass_or_null() == NULL) {
    85           supers_exist = false;
    86           break;
    87         }
    88       }
    89       if (!supers_exist) {
    90         // Oops.  Not allocated yet.  Back out, allocate it, and retry.
    91 #ifndef PRODUCT
    92         if (WizardMode) {
    93           tty->print_cr("Must retry array klass creation for depth %d",n);
    94         }
    95 #endif
    96         KlassHandle ek;
    97         {
    98           MutexUnlocker mu(MultiArray_lock);
    99           MutexUnlocker mc(Compile_lock);   // for vtables
   100           klassOop sk = element_super->array_klass(CHECK_0);
   101           super_klass = KlassHandle(THREAD, sk);
   102           for( int i = element_supers->length()-1; i >= 0; i-- ) {
   103             KlassHandle elem_super (THREAD, element_supers->obj_at(i));
   104             elem_super->array_klass(CHECK_0);
   105           }
   106           // Now retry from the beginning
   107           klassOop klass_oop = element_klass->array_klass(n, CHECK_0);
   108           // Create a handle because the enclosing brace, when locking
   109           // can cause a gc.  Better to have this function return a Handle.
   110           ek = KlassHandle(THREAD, klass_oop);
   111         }  // re-lock
   112         return ek();
   113       }
   114     } else {
   115       // The element type is already Object.  Object[] has direct super of Object.
   116       super_klass = KlassHandle(THREAD, SystemDictionary::Object_klass());
   117     }
   118   }
   120   // Create type name for klass.
   121   Symbol* name = NULL;
   122   if (!element_klass->oop_is_instance() ||
   123       (name = instanceKlass::cast(element_klass())->array_name()) == NULL) {
   125     ResourceMark rm(THREAD);
   126     char *name_str = element_klass->name()->as_C_string();
   127     int len = element_klass->name()->utf8_length();
   128     char *new_str = NEW_RESOURCE_ARRAY(char, len + 4);
   129     int idx = 0;
   130     new_str[idx++] = '[';
   131     if (element_klass->oop_is_instance()) { // it could be an array or simple type
   132       new_str[idx++] = 'L';
   133     }
   134     memcpy(&new_str[idx], name_str, len * sizeof(char));
   135     idx += len;
   136     if (element_klass->oop_is_instance()) {
   137       new_str[idx++] = ';';
   138     }
   139     new_str[idx++] = '\0';
   140     name = SymbolTable::new_symbol(new_str, CHECK_0);
   141     if (element_klass->oop_is_instance()) {
   142       instanceKlass* ik = instanceKlass::cast(element_klass());
   143       ik->set_array_name(name);
   144     }
   145   }
   147   objArrayKlass o;
   148   arrayKlassHandle k = arrayKlass::base_create_array_klass(o.vtbl_value(),
   149                                                            objArrayKlass::header_size(),
   150                                                           this_oop,
   151                                                            CHECK_0);
   153   // Initialize instance variables
   154   objArrayKlass* oak = objArrayKlass::cast(k());
   155   oak->set_dimension(n);
   156   oak->set_element_klass(element_klass());
   157   oak->set_name(name);
   158   // decrement refcount because object arrays are not explicitly freed.  The
   159   // instanceKlass array_name() keeps the name counted while the klass is
   160   // loaded.
   161   name->decrement_refcount();
   163   klassOop bk;
   164   if (element_klass->oop_is_objArray()) {
   165     bk = objArrayKlass::cast(element_klass())->bottom_klass();
   166   } else {
   167     bk = element_klass();
   168   }
   169   assert(bk != NULL && (Klass::cast(bk)->oop_is_instance() || Klass::cast(bk)->oop_is_typeArray()), "invalid bottom klass");
   170   oak->set_bottom_klass(bk);
   172   oak->set_layout_helper(array_layout_helper(T_OBJECT));
   173   assert(oak->oop_is_javaArray(), "sanity");
   174   assert(oak->oop_is_objArray(), "sanity");
   176   // Call complete_create_array_klass after all instance variables has been initialized.
   177   arrayKlass::complete_create_array_klass(k, super_klass, CHECK_0);
   179   return k();
   180 }
   183 void objArrayKlassKlass::oop_follow_contents(oop obj) {
   184   assert(obj->is_klass(), "must be klass");
   185   assert(klassOop(obj)->klass_part()->oop_is_objArray_slow(), "must be obj array");
   187   objArrayKlass* oak = objArrayKlass::cast((klassOop)obj);
   188   MarkSweep::mark_and_push(oak->element_klass_addr());
   189   MarkSweep::mark_and_push(oak->bottom_klass_addr());
   191   arrayKlassKlass::oop_follow_contents(obj);
   192 }
   194 #ifndef SERIALGC
   195 void objArrayKlassKlass::oop_follow_contents(ParCompactionManager* cm,
   196                                              oop obj) {
   197   assert(obj->is_klass(), "must be klass");
   198   assert(klassOop(obj)->klass_part()->oop_is_objArray_slow(), "must be obj array");
   200   objArrayKlass* oak = objArrayKlass::cast((klassOop)obj);
   201   PSParallelCompact::mark_and_push(cm, oak->element_klass_addr());
   202   PSParallelCompact::mark_and_push(cm, oak->bottom_klass_addr());
   204   arrayKlassKlass::oop_follow_contents(cm, obj);
   205 }
   206 #endif // SERIALGC
   209 int objArrayKlassKlass::oop_adjust_pointers(oop obj) {
   210   assert(obj->is_klass(), "must be klass");
   211   assert(klassOop(obj)->klass_part()->oop_is_objArray_slow(), "must be obj array");
   213   objArrayKlass* oak = objArrayKlass::cast((klassOop)obj);
   214   MarkSweep::adjust_pointer(oak->element_klass_addr());
   215   MarkSweep::adjust_pointer(oak->bottom_klass_addr());
   217   return arrayKlassKlass::oop_adjust_pointers(obj);
   218 }
   222 int objArrayKlassKlass::oop_oop_iterate(oop obj, OopClosure* blk) {
   223   assert(obj->is_klass(), "must be klass");
   224   assert(klassOop(obj)->klass_part()->oop_is_objArray_slow(), "must be obj array");
   226   objArrayKlass* oak = objArrayKlass::cast((klassOop)obj);
   227   blk->do_oop(oak->element_klass_addr());
   228   blk->do_oop(oak->bottom_klass_addr());
   230   return arrayKlassKlass::oop_oop_iterate(obj, blk);
   231 }
   234 int
   235 objArrayKlassKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) {
   236   assert(obj->is_klass(), "must be klass");
   237   assert(klassOop(obj)->klass_part()->oop_is_objArray_slow(), "must be obj array");
   239   objArrayKlass* oak = objArrayKlass::cast((klassOop)obj);
   240   oop* addr;
   241   addr = oak->element_klass_addr();
   242   if (mr.contains(addr)) blk->do_oop(addr);
   243   addr = oak->bottom_klass_addr();
   244   if (mr.contains(addr)) blk->do_oop(addr);
   246   return arrayKlassKlass::oop_oop_iterate_m(obj, blk, mr);
   247 }
   249 #ifndef SERIALGC
   250 void objArrayKlassKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
   251   assert(obj->blueprint()->oop_is_objArrayKlass(),"must be an obj array klass");
   252   objArrayKlass* oak = objArrayKlass::cast((klassOop)obj);
   253   oop* p = oak->element_klass_addr();
   254   if (PSScavenge::should_scavenge(p)) {
   255     pm->claim_or_forward_depth(p);
   256   }
   257   p = oak->bottom_klass_addr();
   258   if (PSScavenge::should_scavenge(p)) {
   259     pm->claim_or_forward_depth(p);
   260   }
   262   arrayKlassKlass::oop_push_contents(pm, obj);
   263 }
   265 int objArrayKlassKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
   266   assert(obj->is_klass(), "must be klass");
   267   assert(klassOop(obj)->klass_part()->oop_is_objArray_slow(), "must be obj array");
   269   objArrayKlass* oak = objArrayKlass::cast((klassOop)obj);
   270   PSParallelCompact::adjust_pointer(oak->element_klass_addr());
   271   PSParallelCompact::adjust_pointer(oak->bottom_klass_addr());
   273   return arrayKlassKlass::oop_update_pointers(cm, obj);
   274 }
   275 #endif // SERIALGC
   277 #ifndef PRODUCT
   279 // Printing
   281 void objArrayKlassKlass::oop_print_on(oop obj, outputStream* st) {
   282   assert(obj->is_klass(), "must be klass");
   283   objArrayKlass* oak = (objArrayKlass*) klassOop(obj)->klass_part();
   284   klassKlass::oop_print_on(obj, st);
   285   st->print(" - instance klass: ");
   286   oak->element_klass()->print_value_on(st);
   287   st->cr();
   288 }
   290 #endif //PRODUCT
   292 void objArrayKlassKlass::oop_print_value_on(oop obj, outputStream* st) {
   293   assert(obj->is_klass(), "must be klass");
   294   objArrayKlass* oak = (objArrayKlass*) klassOop(obj)->klass_part();
   296   oak->element_klass()->print_value_on(st);
   297   st->print("[]");
   298 }
   300 const char* objArrayKlassKlass::internal_name() const {
   301   return "{object array class}";
   302 }
   305 // Verification
   307 void objArrayKlassKlass::oop_verify_on(oop obj, outputStream* st) {
   308   arrayKlassKlass::oop_verify_on(obj, st);
   309   objArrayKlass* oak = objArrayKlass::cast((klassOop)obj);
   310   guarantee(oak->element_klass()->is_perm(),  "should be in permspace");
   311   guarantee(oak->element_klass()->is_klass(), "should be klass");
   312   guarantee(oak->bottom_klass()->is_perm(),   "should be in permspace");
   313   guarantee(oak->bottom_klass()->is_klass(),  "should be klass");
   314   Klass* bk = Klass::cast(oak->bottom_klass());
   315   guarantee(bk->oop_is_instance() || bk->oop_is_typeArray(),  "invalid bottom klass");
   316 }

mercurial