src/share/vm/oops/cpCacheKlass.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 3092
baf763f388e6
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) 1998, 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 "gc_implementation/shared/markSweep.inline.hpp"
    28 #include "gc_interface/collectedHeap.hpp"
    29 #include "interpreter/bytecodes.hpp"
    30 #include "memory/genOopClosures.inline.hpp"
    31 #include "memory/permGen.hpp"
    32 #include "oops/constantPoolOop.hpp"
    33 #include "oops/cpCacheKlass.hpp"
    34 #include "oops/oop.inline.hpp"
    35 #include "runtime/handles.inline.hpp"
    36 #ifndef SERIALGC
    37 #include "gc_implementation/parNew/parOopClosures.inline.hpp"
    38 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
    39 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
    40 #include "memory/cardTableRS.hpp"
    41 #include "oops/oop.pcgc.inline.hpp"
    42 #endif
    45 int constantPoolCacheKlass::oop_size(oop obj) const {
    46   assert(obj->is_constantPoolCache(), "must be constantPool");
    47   return constantPoolCacheOop(obj)->object_size();
    48 }
    51 constantPoolCacheOop constantPoolCacheKlass::allocate(int length,
    52                                                       TRAPS) {
    53   // allocate memory
    54   int size = constantPoolCacheOopDesc::object_size(length);
    56   KlassHandle klass (THREAD, as_klassOop());
    58   // Commented out below is the original code.  The code from
    59   // permanent_obj_allocate() was in-lined so that we could
    60   // set the _length field, necessary to correctly compute its
    61   // size(), before setting its klass word further below.
    62   // constantPoolCacheOop cache = (constantPoolCacheOop)
    63   //   CollectedHeap::permanent_obj_allocate(klass, size, CHECK_NULL);
    65   oop obj = CollectedHeap::permanent_obj_allocate_no_klass_install(klass, size, CHECK_NULL);
    66   NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value((HeapWord*) obj,
    67                                                               size));
    68   constantPoolCacheOop cache = (constantPoolCacheOop) obj;
    69   assert(!UseConcMarkSweepGC || obj->klass_or_null() == NULL,
    70          "klass should be NULL here when using CMS");
    71   cache->set_length(length);  // should become visible before klass is set below.
    72   cache->set_constant_pool(NULL);
    74   OrderAccess::storestore();
    75   obj->set_klass(klass());
    76   assert(cache->size() == size, "Incorrect cache->size()");
    77   return cache;
    78 }
    80 klassOop constantPoolCacheKlass::create_klass(TRAPS) {
    81   constantPoolCacheKlass o;
    82   KlassHandle h_this_klass(THREAD, Universe::klassKlassObj());
    83   KlassHandle k = base_create_klass(h_this_klass, header_size(), o.vtbl_value(), CHECK_NULL);
    84   // Make sure size calculation is right
    85   assert(k()->size() == align_object_size(header_size()), "wrong size for object");
    86   java_lang_Class::create_mirror(k, CHECK_NULL); // Allocate mirror
    87   return k();
    88 }
    91 void constantPoolCacheKlass::oop_follow_contents(oop obj) {
    92   assert(obj->is_constantPoolCache(), "obj must be constant pool cache");
    93   constantPoolCacheOop cache = (constantPoolCacheOop)obj;
    94   // Performance tweak: We skip iterating over the klass pointer since we
    95   // know that Universe::constantPoolCacheKlassObj never moves.
    96   // gc of constant pool cache instance variables
    97   MarkSweep::mark_and_push((oop*)cache->constant_pool_addr());
    98   // gc of constant pool cache entries
    99   int i = cache->length();
   100   while (i-- > 0) cache->entry_at(i)->follow_contents();
   101 }
   103 #ifndef SERIALGC
   104 void constantPoolCacheKlass::oop_follow_contents(ParCompactionManager* cm,
   105                                                  oop obj) {
   106   assert(obj->is_constantPoolCache(), "obj must be constant pool cache");
   107   constantPoolCacheOop cache = (constantPoolCacheOop)obj;
   108   // Performance tweak: We skip iterating over the klass pointer since we
   109   // know that Universe::constantPoolCacheKlassObj never moves.
   110   // gc of constant pool cache instance variables
   111   PSParallelCompact::mark_and_push(cm, (oop*)cache->constant_pool_addr());
   112   // gc of constant pool cache entries
   113   int i = cache->length();
   114   while (i-- > 0) cache->entry_at(i)->follow_contents(cm);
   115 }
   116 #endif // SERIALGC
   119 int constantPoolCacheKlass::oop_oop_iterate(oop obj, OopClosure* blk) {
   120   assert(obj->is_constantPoolCache(), "obj must be constant pool cache");
   121   constantPoolCacheOop cache = (constantPoolCacheOop)obj;
   122   // Get size before changing pointers.
   123   // Don't call size() or oop_size() since that is a virtual call.
   124   int size = cache->object_size();
   125   // Performance tweak: We skip iterating over the klass pointer since we
   126   // know that Universe::constantPoolCacheKlassObj never moves.
   127   // iteration over constant pool cache instance variables
   128   blk->do_oop((oop*)cache->constant_pool_addr());
   129   // iteration over constant pool cache entries
   130   for (int i = 0; i < cache->length(); i++) cache->entry_at(i)->oop_iterate(blk);
   131   return size;
   132 }
   135 int constantPoolCacheKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) {
   136   assert(obj->is_constantPoolCache(), "obj must be constant pool cache");
   137   constantPoolCacheOop cache = (constantPoolCacheOop)obj;
   138   // Get size before changing pointers.
   139   // Don't call size() or oop_size() since that is a virtual call.
   140   int size = cache->object_size();
   141   // Performance tweak: We skip iterating over the klass pointer since we
   142   // know that Universe::constantPoolCacheKlassObj never moves.
   143   // iteration over constant pool cache instance variables
   144   oop* addr = (oop*)cache->constant_pool_addr();
   145   if (mr.contains(addr)) blk->do_oop(addr);
   146   // iteration over constant pool cache entries
   147   for (int i = 0; i < cache->length(); i++) cache->entry_at(i)->oop_iterate_m(blk, mr);
   148   return size;
   149 }
   151 int constantPoolCacheKlass::oop_adjust_pointers(oop obj) {
   152   assert(obj->is_constantPoolCache(), "obj must be constant pool cache");
   153   constantPoolCacheOop cache = (constantPoolCacheOop)obj;
   154   // Get size before changing pointers.
   155   // Don't call size() or oop_size() since that is a virtual call.
   156   int size = cache->object_size();
   157   // Performance tweak: We skip iterating over the klass pointer since we
   158   // know that Universe::constantPoolCacheKlassObj never moves.
   159   // Iteration over constant pool cache instance variables
   160   MarkSweep::adjust_pointer((oop*)cache->constant_pool_addr());
   161   // iteration over constant pool cache entries
   162   for (int i = 0; i < cache->length(); i++)
   163     cache->entry_at(i)->adjust_pointers();
   164   return size;
   165 }
   167 #ifndef SERIALGC
   168 void constantPoolCacheKlass::oop_push_contents(PSPromotionManager* pm,
   169                                                oop obj) {
   170   assert(obj->is_constantPoolCache(), "should be constant pool");
   171   if (ScavengeRootsInCode) {
   172     constantPoolCacheOop cache = (constantPoolCacheOop)obj;
   173     // during a scavenge, it is safe to inspect my pool, since it is perm
   174     constantPoolOop pool = cache->constant_pool();
   175     assert(pool->is_constantPool(), "should be constant pool");
   176     for (int i = 0; i < cache->length(); i++) {
   177       ConstantPoolCacheEntry* e = cache->entry_at(i);
   178       oop* p = (oop*)&e->_f1;
   179       if (PSScavenge::should_scavenge(p))
   180         pm->claim_or_forward_depth(p);
   181       assert(!(e->is_vfinal() && PSScavenge::should_scavenge((oop*)&e->_f2)),
   182              "no live oops here");
   183     }
   184   }
   185 }
   187 int
   188 constantPoolCacheKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
   189   assert(obj->is_constantPoolCache(), "obj must be constant pool cache");
   190   constantPoolCacheOop cache = (constantPoolCacheOop)obj;
   192   // Iteration over constant pool cache instance variables
   193   PSParallelCompact::adjust_pointer((oop*)cache->constant_pool_addr());
   195   // iteration over constant pool cache entries
   196   for (int i = 0; i < cache->length(); ++i) {
   197     cache->entry_at(i)->update_pointers();
   198   }
   200   return cache->object_size();
   201 }
   202 #endif // SERIALGC
   204 void constantPoolCacheKlass::oop_print_on(oop obj, outputStream* st) {
   205   assert(obj->is_constantPoolCache(), "obj must be constant pool cache");
   206   constantPoolCacheOop cache = (constantPoolCacheOop)obj;
   207   // super print
   208   Klass::oop_print_on(obj, st);
   209   // print constant pool cache entries
   210   for (int i = 0; i < cache->length(); i++) cache->entry_at(i)->print(st, i);
   211 }
   213 void constantPoolCacheKlass::oop_print_value_on(oop obj, outputStream* st) {
   214   assert(obj->is_constantPoolCache(), "obj must be constant pool cache");
   215   constantPoolCacheOop cache = (constantPoolCacheOop)obj;
   216   st->print("cache [%d]", cache->length());
   217   cache->print_address_on(st);
   218   st->print(" for ");
   219   cache->constant_pool()->print_value_on(st);
   220 }
   222 void constantPoolCacheKlass::oop_verify_on(oop obj, outputStream* st) {
   223   guarantee(obj->is_constantPoolCache(), "obj must be constant pool cache");
   224   constantPoolCacheOop cache = (constantPoolCacheOop)obj;
   225   // super verify
   226   Klass::oop_verify_on(obj, st);
   227   // print constant pool cache entries
   228   for (int i = 0; i < cache->length(); i++) cache->entry_at(i)->verify(st);
   229 }
   232 const char* constantPoolCacheKlass::internal_name() const {
   233   return "{constant pool cache}";
   234 }

mercurial