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

duke@435 1 /*
stefank@2534 2 * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
duke@435 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@435 4 *
duke@435 5 * This code is free software; you can redistribute it and/or modify it
duke@435 6 * under the terms of the GNU General Public License version 2 only, as
duke@435 7 * published by the Free Software Foundation.
duke@435 8 *
duke@435 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@435 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@435 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@435 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@435 13 * accompanied this code).
duke@435 14 *
duke@435 15 * You should have received a copy of the GNU General Public License version
duke@435 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@435 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@435 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
duke@435 22 *
duke@435 23 */
duke@435 24
stefank@2314 25 #include "precompiled.hpp"
stefank@2314 26 #include "classfile/javaClasses.hpp"
stefank@2314 27 #include "gc_implementation/shared/markSweep.inline.hpp"
stefank@2314 28 #include "gc_interface/collectedHeap.hpp"
stefank@2314 29 #include "interpreter/bytecodes.hpp"
stefank@2314 30 #include "memory/genOopClosures.inline.hpp"
stefank@2314 31 #include "memory/permGen.hpp"
stefank@2314 32 #include "oops/constantPoolOop.hpp"
stefank@2314 33 #include "oops/cpCacheKlass.hpp"
stefank@2314 34 #include "oops/oop.inline.hpp"
stefank@2314 35 #include "runtime/handles.inline.hpp"
stefank@2314 36 #ifndef SERIALGC
stefank@2314 37 #include "gc_implementation/parNew/parOopClosures.inline.hpp"
stefank@2314 38 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
stefank@2314 39 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
stefank@2314 40 #include "memory/cardTableRS.hpp"
stefank@2314 41 #include "oops/oop.pcgc.inline.hpp"
stefank@2314 42 #endif
duke@435 43
duke@435 44
duke@435 45 int constantPoolCacheKlass::oop_size(oop obj) const {
duke@435 46 assert(obj->is_constantPoolCache(), "must be constantPool");
duke@435 47 return constantPoolCacheOop(obj)->object_size();
duke@435 48 }
duke@435 49
duke@435 50
jmasa@977 51 constantPoolCacheOop constantPoolCacheKlass::allocate(int length,
jmasa@977 52 TRAPS) {
duke@435 53 // allocate memory
duke@435 54 int size = constantPoolCacheOopDesc::object_size(length);
jmasa@977 55
duke@435 56 KlassHandle klass (THREAD, as_klassOop());
jmasa@977 57
ysr@2533 58 // Commented out below is the original code. The code from
ysr@2533 59 // permanent_obj_allocate() was in-lined so that we could
ysr@2533 60 // set the _length field, necessary to correctly compute its
ysr@2533 61 // size(), before setting its klass word further below.
jmasa@977 62 // constantPoolCacheOop cache = (constantPoolCacheOop)
jmasa@977 63 // CollectedHeap::permanent_obj_allocate(klass, size, CHECK_NULL);
jmasa@977 64
jmasa@977 65 oop obj = CollectedHeap::permanent_obj_allocate_no_klass_install(klass, size, CHECK_NULL);
jmasa@977 66 NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value((HeapWord*) obj,
jmasa@977 67 size));
ysr@2533 68 constantPoolCacheOop cache = (constantPoolCacheOop) obj;
ysr@2533 69 assert(!UseConcMarkSweepGC || obj->klass_or_null() == NULL,
ysr@2533 70 "klass should be NULL here when using CMS");
ysr@2533 71 cache->set_length(length); // should become visible before klass is set below.
ysr@2533 72 cache->set_constant_pool(NULL);
jmasa@977 73
ysr@2533 74 OrderAccess::storestore();
ysr@2533 75 obj->set_klass(klass());
ysr@2533 76 assert(cache->size() == size, "Incorrect cache->size()");
duke@435 77 return cache;
duke@435 78 }
duke@435 79
duke@435 80 klassOop constantPoolCacheKlass::create_klass(TRAPS) {
duke@435 81 constantPoolCacheKlass o;
coleenp@548 82 KlassHandle h_this_klass(THREAD, Universe::klassKlassObj());
coleenp@548 83 KlassHandle k = base_create_klass(h_this_klass, header_size(), o.vtbl_value(), CHECK_NULL);
coleenp@548 84 // Make sure size calculation is right
coleenp@548 85 assert(k()->size() == align_object_size(header_size()), "wrong size for object");
coleenp@548 86 java_lang_Class::create_mirror(k, CHECK_NULL); // Allocate mirror
duke@435 87 return k();
duke@435 88 }
duke@435 89
duke@435 90
duke@435 91 void constantPoolCacheKlass::oop_follow_contents(oop obj) {
duke@435 92 assert(obj->is_constantPoolCache(), "obj must be constant pool cache");
duke@435 93 constantPoolCacheOop cache = (constantPoolCacheOop)obj;
duke@435 94 // Performance tweak: We skip iterating over the klass pointer since we
duke@435 95 // know that Universe::constantPoolCacheKlassObj never moves.
duke@435 96 // gc of constant pool cache instance variables
duke@435 97 MarkSweep::mark_and_push((oop*)cache->constant_pool_addr());
duke@435 98 // gc of constant pool cache entries
duke@435 99 int i = cache->length();
duke@435 100 while (i-- > 0) cache->entry_at(i)->follow_contents();
duke@435 101 }
duke@435 102
duke@435 103 #ifndef SERIALGC
duke@435 104 void constantPoolCacheKlass::oop_follow_contents(ParCompactionManager* cm,
duke@435 105 oop obj) {
duke@435 106 assert(obj->is_constantPoolCache(), "obj must be constant pool cache");
duke@435 107 constantPoolCacheOop cache = (constantPoolCacheOop)obj;
duke@435 108 // Performance tweak: We skip iterating over the klass pointer since we
duke@435 109 // know that Universe::constantPoolCacheKlassObj never moves.
duke@435 110 // gc of constant pool cache instance variables
duke@435 111 PSParallelCompact::mark_and_push(cm, (oop*)cache->constant_pool_addr());
duke@435 112 // gc of constant pool cache entries
duke@435 113 int i = cache->length();
duke@435 114 while (i-- > 0) cache->entry_at(i)->follow_contents(cm);
duke@435 115 }
duke@435 116 #endif // SERIALGC
duke@435 117
duke@435 118
duke@435 119 int constantPoolCacheKlass::oop_oop_iterate(oop obj, OopClosure* blk) {
duke@435 120 assert(obj->is_constantPoolCache(), "obj must be constant pool cache");
duke@435 121 constantPoolCacheOop cache = (constantPoolCacheOop)obj;
duke@435 122 // Get size before changing pointers.
duke@435 123 // Don't call size() or oop_size() since that is a virtual call.
duke@435 124 int size = cache->object_size();
duke@435 125 // Performance tweak: We skip iterating over the klass pointer since we
duke@435 126 // know that Universe::constantPoolCacheKlassObj never moves.
duke@435 127 // iteration over constant pool cache instance variables
duke@435 128 blk->do_oop((oop*)cache->constant_pool_addr());
duke@435 129 // iteration over constant pool cache entries
duke@435 130 for (int i = 0; i < cache->length(); i++) cache->entry_at(i)->oop_iterate(blk);
duke@435 131 return size;
duke@435 132 }
duke@435 133
duke@435 134
duke@435 135 int constantPoolCacheKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) {
duke@435 136 assert(obj->is_constantPoolCache(), "obj must be constant pool cache");
duke@435 137 constantPoolCacheOop cache = (constantPoolCacheOop)obj;
duke@435 138 // Get size before changing pointers.
duke@435 139 // Don't call size() or oop_size() since that is a virtual call.
duke@435 140 int size = cache->object_size();
duke@435 141 // Performance tweak: We skip iterating over the klass pointer since we
duke@435 142 // know that Universe::constantPoolCacheKlassObj never moves.
duke@435 143 // iteration over constant pool cache instance variables
duke@435 144 oop* addr = (oop*)cache->constant_pool_addr();
duke@435 145 if (mr.contains(addr)) blk->do_oop(addr);
duke@435 146 // iteration over constant pool cache entries
duke@435 147 for (int i = 0; i < cache->length(); i++) cache->entry_at(i)->oop_iterate_m(blk, mr);
duke@435 148 return size;
duke@435 149 }
duke@435 150
duke@435 151 int constantPoolCacheKlass::oop_adjust_pointers(oop obj) {
duke@435 152 assert(obj->is_constantPoolCache(), "obj must be constant pool cache");
duke@435 153 constantPoolCacheOop cache = (constantPoolCacheOop)obj;
duke@435 154 // Get size before changing pointers.
duke@435 155 // Don't call size() or oop_size() since that is a virtual call.
duke@435 156 int size = cache->object_size();
duke@435 157 // Performance tweak: We skip iterating over the klass pointer since we
duke@435 158 // know that Universe::constantPoolCacheKlassObj never moves.
duke@435 159 // Iteration over constant pool cache instance variables
duke@435 160 MarkSweep::adjust_pointer((oop*)cache->constant_pool_addr());
duke@435 161 // iteration over constant pool cache entries
duke@435 162 for (int i = 0; i < cache->length(); i++)
duke@435 163 cache->entry_at(i)->adjust_pointers();
duke@435 164 return size;
duke@435 165 }
duke@435 166
duke@435 167 #ifndef SERIALGC
duke@435 168 void constantPoolCacheKlass::oop_push_contents(PSPromotionManager* pm,
duke@435 169 oop obj) {
duke@435 170 assert(obj->is_constantPoolCache(), "should be constant pool");
never@2658 171 if (ScavengeRootsInCode) {
jrose@1161 172 constantPoolCacheOop cache = (constantPoolCacheOop)obj;
jrose@1161 173 // during a scavenge, it is safe to inspect my pool, since it is perm
jrose@1161 174 constantPoolOop pool = cache->constant_pool();
jrose@1161 175 assert(pool->is_constantPool(), "should be constant pool");
never@2658 176 for (int i = 0; i < cache->length(); i++) {
never@2658 177 ConstantPoolCacheEntry* e = cache->entry_at(i);
never@2658 178 oop* p = (oop*)&e->_f1;
never@2658 179 if (PSScavenge::should_scavenge(p))
never@2658 180 pm->claim_or_forward_depth(p);
never@2658 181 assert(!(e->is_vfinal() && PSScavenge::should_scavenge((oop*)&e->_f2)),
never@2658 182 "no live oops here");
jrose@1161 183 }
jrose@1161 184 }
duke@435 185 }
duke@435 186
duke@435 187 int
duke@435 188 constantPoolCacheKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
duke@435 189 assert(obj->is_constantPoolCache(), "obj must be constant pool cache");
duke@435 190 constantPoolCacheOop cache = (constantPoolCacheOop)obj;
duke@435 191
duke@435 192 // Iteration over constant pool cache instance variables
duke@435 193 PSParallelCompact::adjust_pointer((oop*)cache->constant_pool_addr());
duke@435 194
duke@435 195 // iteration over constant pool cache entries
duke@435 196 for (int i = 0; i < cache->length(); ++i) {
duke@435 197 cache->entry_at(i)->update_pointers();
duke@435 198 }
duke@435 199
duke@435 200 return cache->object_size();
duke@435 201 }
duke@435 202 #endif // SERIALGC
duke@435 203
duke@435 204 void constantPoolCacheKlass::oop_print_on(oop obj, outputStream* st) {
duke@435 205 assert(obj->is_constantPoolCache(), "obj must be constant pool cache");
duke@435 206 constantPoolCacheOop cache = (constantPoolCacheOop)obj;
duke@435 207 // super print
coleenp@548 208 Klass::oop_print_on(obj, st);
duke@435 209 // print constant pool cache entries
duke@435 210 for (int i = 0; i < cache->length(); i++) cache->entry_at(i)->print(st, i);
duke@435 211 }
duke@435 212
jrose@1590 213 void constantPoolCacheKlass::oop_print_value_on(oop obj, outputStream* st) {
jrose@1590 214 assert(obj->is_constantPoolCache(), "obj must be constant pool cache");
jrose@1590 215 constantPoolCacheOop cache = (constantPoolCacheOop)obj;
jrose@1590 216 st->print("cache [%d]", cache->length());
jrose@1590 217 cache->print_address_on(st);
jrose@1590 218 st->print(" for ");
jrose@1590 219 cache->constant_pool()->print_value_on(st);
jrose@1590 220 }
jrose@1590 221
duke@435 222 void constantPoolCacheKlass::oop_verify_on(oop obj, outputStream* st) {
duke@435 223 guarantee(obj->is_constantPoolCache(), "obj must be constant pool cache");
duke@435 224 constantPoolCacheOop cache = (constantPoolCacheOop)obj;
duke@435 225 // super verify
coleenp@548 226 Klass::oop_verify_on(obj, st);
duke@435 227 // print constant pool cache entries
duke@435 228 for (int i = 0; i < cache->length(); i++) cache->entry_at(i)->verify(st);
duke@435 229 }
duke@435 230
duke@435 231
duke@435 232 const char* constantPoolCacheKlass::internal_name() const {
duke@435 233 return "{constant pool cache}";
duke@435 234 }

mercurial