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) 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 }