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 "gc_interface/collectedHeap.inline.hpp"
30 #include "memory/permGen.hpp"
31 #include "memory/universe.inline.hpp"
32 #include "oops/compiledICHolderKlass.hpp"
33 #include "oops/oop.inline.hpp"
34 #include "oops/oop.inline2.hpp"
35 #include "runtime/handles.inline.hpp"
36 #ifndef SERIALGC
37 #include "oops/oop.pcgc.inline.hpp"
38 #endif
40 klassOop compiledICHolderKlass::create_klass(TRAPS) {
41 compiledICHolderKlass o;
42 KlassHandle h_this_klass(THREAD, Universe::klassKlassObj());
43 KlassHandle k = base_create_klass(h_this_klass, header_size(), o.vtbl_value(), CHECK_NULL);
44 // Make sure size calculation is right
45 assert(k()->size() == align_object_size(header_size()), "wrong size for object");
46 java_lang_Class::create_mirror(k, CHECK_NULL); // Allocate mirror
47 return k();
48 }
51 compiledICHolderOop compiledICHolderKlass::allocate(TRAPS) {
52 KlassHandle h_k(THREAD, as_klassOop());
53 int size = compiledICHolderOopDesc::object_size();
54 compiledICHolderOop c = (compiledICHolderOop)
55 CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL);
56 c->set_holder_method(NULL);
57 c->set_holder_klass(NULL);
58 return c;
59 }
62 int compiledICHolderKlass::oop_size(oop obj) const {
63 assert(obj->is_compiledICHolder(), "must be compiledICHolder");
64 return compiledICHolderOop(obj)->object_size();
65 }
67 void compiledICHolderKlass::oop_follow_contents(oop obj) {
68 assert(obj->is_compiledICHolder(), "must be compiledICHolder");
69 compiledICHolderOop c = compiledICHolderOop(obj);
71 obj->follow_header();
72 MarkSweep::mark_and_push(c->adr_holder_method());
73 MarkSweep::mark_and_push(c->adr_holder_klass());
74 }
76 #ifndef SERIALGC
77 void compiledICHolderKlass::oop_follow_contents(ParCompactionManager* cm,
78 oop obj) {
79 assert(obj->is_compiledICHolder(), "must be compiledICHolder");
80 compiledICHolderOop c = compiledICHolderOop(obj);
82 obj->follow_header(cm);
83 PSParallelCompact::mark_and_push(cm, c->adr_holder_method());
84 PSParallelCompact::mark_and_push(cm, c->adr_holder_klass());
85 }
86 #endif // SERIALGC
89 int compiledICHolderKlass::oop_oop_iterate(oop obj, OopClosure* blk) {
90 assert(obj->is_compiledICHolder(), "must be compiledICHolder");
91 compiledICHolderOop c = compiledICHolderOop(obj);
92 // Get size before changing pointers.
93 // Don't call size() or oop_size() since that is a virtual call.
94 int size = c->object_size();
96 obj->oop_iterate_header(blk);
97 blk->do_oop(c->adr_holder_method());
98 blk->do_oop(c->adr_holder_klass());
99 return size;
100 }
102 int compiledICHolderKlass::oop_oop_iterate_m(oop obj, OopClosure* blk,
103 MemRegion mr) {
104 assert(obj->is_compiledICHolder(), "must be compiledICHolder");
105 compiledICHolderOop c = compiledICHolderOop(obj);
106 // Get size before changing pointers.
107 // Don't call size() or oop_size() since that is a virtual call.
108 int size = c->object_size();
110 obj->oop_iterate_header(blk, mr);
112 oop* adr;
113 adr = c->adr_holder_method();
114 if (mr.contains(adr)) blk->do_oop(adr);
115 adr = c->adr_holder_klass();
116 if (mr.contains(adr)) blk->do_oop(adr);
117 return size;
118 }
121 int compiledICHolderKlass::oop_adjust_pointers(oop obj) {
122 assert(obj->is_compiledICHolder(), "must be compiledICHolder");
123 compiledICHolderOop c = compiledICHolderOop(obj);
124 // Get size before changing pointers.
125 // Don't call size() or oop_size() since that is a virtual call.
126 int size = c->object_size();
128 MarkSweep::adjust_pointer(c->adr_holder_method());
129 MarkSweep::adjust_pointer(c->adr_holder_klass());
130 obj->adjust_header();
131 return size;
132 }
134 #ifndef SERIALGC
135 void compiledICHolderKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
136 assert(obj->is_compiledICHolder(), "must be compiledICHolder");
137 }
139 int compiledICHolderKlass::oop_update_pointers(ParCompactionManager* cm,
140 oop obj) {
141 assert(obj->is_compiledICHolder(), "must be compiledICHolder");
142 compiledICHolderOop c = compiledICHolderOop(obj);
144 PSParallelCompact::adjust_pointer(c->adr_holder_method());
145 PSParallelCompact::adjust_pointer(c->adr_holder_klass());
146 return c->object_size();
147 }
148 #endif // SERIALGC
150 // Printing
152 void compiledICHolderKlass::oop_print_on(oop obj, outputStream* st) {
153 assert(obj->is_compiledICHolder(), "must be compiledICHolder");
154 Klass::oop_print_on(obj, st);
155 compiledICHolderOop c = compiledICHolderOop(obj);
156 st->print(" - method: "); c->holder_method()->print_value_on(st); st->cr();
157 st->print(" - klass: "); c->holder_klass()->print_value_on(st); st->cr();
158 }
160 void compiledICHolderKlass::oop_print_value_on(oop obj, outputStream* st) {
161 assert(obj->is_compiledICHolder(), "must be compiledICHolder");
162 Klass::oop_print_value_on(obj, st);
163 }
165 const char* compiledICHolderKlass::internal_name() const {
166 return "{compiledICHolder}";
167 }
169 // Verification
171 void compiledICHolderKlass::oop_verify_on(oop obj, outputStream* st) {
172 Klass::oop_verify_on(obj, st);
173 guarantee(obj->is_compiledICHolder(), "must be compiledICHolder");
174 compiledICHolderOop c = compiledICHolderOop(obj);
175 guarantee(c->is_perm(), "should be in permspace");
176 guarantee(c->holder_method()->is_perm(), "should be in permspace");
177 guarantee(c->holder_method()->is_method(), "should be method");
178 guarantee(c->holder_klass()->is_perm(), "should be in permspace");
179 guarantee(c->holder_klass()->is_klass(), "should be klass");
180 }