Thu, 07 Apr 2011 09:53:20 -0700
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 }