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 "gc_implementation/shared/markSweep.inline.hpp"
28 #include "gc_interface/collectedHeap.inline.hpp"
29 #include "interpreter/interpreter.hpp"
30 #include "memory/gcLocker.hpp"
31 #include "memory/resourceArea.hpp"
32 #include "memory/universe.inline.hpp"
33 #include "oops/constMethodKlass.hpp"
34 #include "oops/klassOop.hpp"
35 #include "oops/methodDataOop.hpp"
36 #include "oops/methodKlass.hpp"
37 #include "oops/oop.inline.hpp"
38 #include "oops/oop.inline2.hpp"
39 #include "oops/symbol.hpp"
40 #include "runtime/handles.inline.hpp"
42 klassOop methodKlass::create_klass(TRAPS) {
43 methodKlass o;
44 KlassHandle h_this_klass(THREAD, Universe::klassKlassObj());
45 KlassHandle k = base_create_klass(h_this_klass, header_size(), o.vtbl_value(), CHECK_NULL);
46 // Make sure size calculation is right
47 assert(k()->size() == align_object_size(header_size()), "wrong size for object");
48 java_lang_Class::create_mirror(k, CHECK_NULL); // Allocate mirror
49 return k();
50 }
53 int methodKlass::oop_size(oop obj) const {
54 assert(obj->is_method(), "must be method oop");
55 return methodOop(obj)->object_size();
56 }
59 bool methodKlass::oop_is_parsable(oop obj) const {
60 assert(obj->is_method(), "must be method oop");
61 return methodOop(obj)->object_is_parsable();
62 }
65 methodOop methodKlass::allocate(constMethodHandle xconst,
66 AccessFlags access_flags, TRAPS) {
67 int size = methodOopDesc::object_size(access_flags.is_native());
68 KlassHandle h_k(THREAD, as_klassOop());
69 assert(xconst()->is_parsable(), "possible publication protocol violation");
70 methodOop m = (methodOop)CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL);
71 assert(!m->is_parsable(), "not expecting parsability yet.");
73 No_Safepoint_Verifier no_safepoint; // until m becomes parsable below
74 m->set_constMethod(xconst());
75 m->set_access_flags(access_flags);
76 m->set_method_size(size);
77 m->set_name_index(0);
78 m->set_signature_index(0);
79 #ifdef CC_INTERP
80 m->set_result_index(T_VOID);
81 #endif
82 m->set_constants(NULL);
83 m->set_max_stack(0);
84 m->set_max_locals(0);
85 m->set_intrinsic_id(vmIntrinsics::_none);
86 m->set_method_data(NULL);
87 m->set_interpreter_throwout_count(0);
88 m->set_vtable_index(methodOopDesc::garbage_vtable_index);
90 // Fix and bury in methodOop
91 m->set_interpreter_entry(NULL); // sets i2i entry and from_int
92 m->set_adapter_entry(NULL);
93 m->clear_code(); // from_c/from_i get set to c2i/i2i
95 if (access_flags.is_native()) {
96 m->clear_native_function();
97 m->set_signature_handler(NULL);
98 }
100 NOT_PRODUCT(m->set_compiled_invocation_count(0);)
101 m->set_interpreter_invocation_count(0);
102 m->invocation_counter()->init();
103 m->backedge_counter()->init();
104 m->clear_number_of_breakpoints();
106 #ifdef TIERED
107 m->set_rate(0);
108 m->set_prev_event_count(0);
109 m->set_prev_time(0);
110 #endif
112 assert(m->is_parsable(), "must be parsable here.");
113 assert(m->size() == size, "wrong size for object");
114 // We should not publish an uprasable object's reference
115 // into one that is parsable, since that presents problems
116 // for the concurrent parallel marking and precleaning phases
117 // of concurrent gc (CMS).
118 xconst->set_method(m);
119 return m;
120 }
123 void methodKlass::oop_follow_contents(oop obj) {
124 assert (obj->is_method(), "object must be method");
125 methodOop m = methodOop(obj);
126 // Performance tweak: We skip iterating over the klass pointer since we
127 // know that Universe::methodKlassObj never moves.
128 MarkSweep::mark_and_push(m->adr_constMethod());
129 MarkSweep::mark_and_push(m->adr_constants());
130 if (m->method_data() != NULL) {
131 MarkSweep::mark_and_push(m->adr_method_data());
132 }
133 }
135 #ifndef SERIALGC
136 void methodKlass::oop_follow_contents(ParCompactionManager* cm,
137 oop obj) {
138 assert (obj->is_method(), "object must be method");
139 methodOop m = methodOop(obj);
140 // Performance tweak: We skip iterating over the klass pointer since we
141 // know that Universe::methodKlassObj never moves.
142 PSParallelCompact::mark_and_push(cm, m->adr_constMethod());
143 PSParallelCompact::mark_and_push(cm, m->adr_constants());
144 #ifdef COMPILER2
145 if (m->method_data() != NULL) {
146 PSParallelCompact::mark_and_push(cm, m->adr_method_data());
147 }
148 #endif // COMPILER2
149 }
150 #endif // SERIALGC
152 int methodKlass::oop_oop_iterate(oop obj, OopClosure* blk) {
153 assert (obj->is_method(), "object must be method");
154 methodOop m = methodOop(obj);
155 // Get size before changing pointers.
156 // Don't call size() or oop_size() since that is a virtual call.
157 int size = m->object_size();
158 // Performance tweak: We skip iterating over the klass pointer since we
159 // know that Universe::methodKlassObj never moves
160 blk->do_oop(m->adr_constMethod());
161 blk->do_oop(m->adr_constants());
162 if (m->method_data() != NULL) {
163 blk->do_oop(m->adr_method_data());
164 }
165 return size;
166 }
169 int methodKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) {
170 assert (obj->is_method(), "object must be method");
171 methodOop m = methodOop(obj);
172 // Get size before changing pointers.
173 // Don't call size() or oop_size() since that is a virtual call.
174 int size = m->object_size();
175 // Performance tweak: We skip iterating over the klass pointer since we
176 // know that Universe::methodKlassObj never moves.
177 oop* adr;
178 adr = m->adr_constMethod();
179 if (mr.contains(adr)) blk->do_oop(adr);
180 adr = m->adr_constants();
181 if (mr.contains(adr)) blk->do_oop(adr);
182 if (m->method_data() != NULL) {
183 adr = m->adr_method_data();
184 if (mr.contains(adr)) blk->do_oop(adr);
185 }
186 return size;
187 }
190 int methodKlass::oop_adjust_pointers(oop obj) {
191 assert(obj->is_method(), "should be method");
192 methodOop m = methodOop(obj);
193 // Get size before changing pointers.
194 // Don't call size() or oop_size() since that is a virtual call.
195 int size = m->object_size();
196 // Performance tweak: We skip iterating over the klass pointer since we
197 // know that Universe::methodKlassObj never moves.
198 MarkSweep::adjust_pointer(m->adr_constMethod());
199 MarkSweep::adjust_pointer(m->adr_constants());
200 if (m->method_data() != NULL) {
201 MarkSweep::adjust_pointer(m->adr_method_data());
202 }
203 return size;
204 }
206 #ifndef SERIALGC
207 void methodKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
208 assert(obj->is_method(), "should be method");
209 }
211 int methodKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
212 assert(obj->is_method(), "should be method");
213 methodOop m = methodOop(obj);
214 PSParallelCompact::adjust_pointer(m->adr_constMethod());
215 PSParallelCompact::adjust_pointer(m->adr_constants());
216 #ifdef COMPILER2
217 if (m->method_data() != NULL) {
218 PSParallelCompact::adjust_pointer(m->adr_method_data());
219 }
220 #endif // COMPILER2
221 return m->object_size();
222 }
223 #endif // SERIALGC
225 #ifndef PRODUCT
227 // Printing
229 void methodKlass::oop_print_on(oop obj, outputStream* st) {
230 ResourceMark rm;
231 assert(obj->is_method(), "must be method");
232 Klass::oop_print_on(obj, st);
233 methodOop m = methodOop(obj);
234 // get the effect of PrintOopAddress, always, for methods:
235 st->print_cr(" - this oop: "INTPTR_FORMAT, (intptr_t)m);
236 st->print (" - method holder: "); m->method_holder()->print_value_on(st); st->cr();
237 st->print (" - constants: "INTPTR_FORMAT" ", (address)m->constants());
238 m->constants()->print_value_on(st); st->cr();
239 st->print (" - access: 0x%x ", m->access_flags().as_int()); m->access_flags().print_on(st); st->cr();
240 st->print (" - name: "); m->name()->print_value_on(st); st->cr();
241 st->print (" - signature: "); m->signature()->print_value_on(st); st->cr();
242 st->print_cr(" - max stack: %d", m->max_stack());
243 st->print_cr(" - max locals: %d", m->max_locals());
244 st->print_cr(" - size of params: %d", m->size_of_parameters());
245 st->print_cr(" - method size: %d", m->method_size());
246 if (m->intrinsic_id() != vmIntrinsics::_none)
247 st->print_cr(" - intrinsic id: %d %s", m->intrinsic_id(), vmIntrinsics::name_at(m->intrinsic_id()));
248 if (m->highest_comp_level() != CompLevel_none)
249 st->print_cr(" - highest level: %d", m->highest_comp_level());
250 st->print_cr(" - vtable index: %d", m->_vtable_index);
251 st->print_cr(" - i2i entry: " INTPTR_FORMAT, m->interpreter_entry());
252 st->print_cr(" - adapter: " INTPTR_FORMAT, m->adapter());
253 st->print_cr(" - compiled entry " INTPTR_FORMAT, m->from_compiled_entry());
254 st->print_cr(" - code size: %d", m->code_size());
255 if (m->code_size() != 0) {
256 st->print_cr(" - code start: " INTPTR_FORMAT, m->code_base());
257 st->print_cr(" - code end (excl): " INTPTR_FORMAT, m->code_base() + m->code_size());
258 }
259 if (m->method_data() != NULL) {
260 st->print_cr(" - method data: " INTPTR_FORMAT, (address)m->method_data());
261 }
262 st->print_cr(" - checked ex length: %d", m->checked_exceptions_length());
263 if (m->checked_exceptions_length() > 0) {
264 CheckedExceptionElement* table = m->checked_exceptions_start();
265 st->print_cr(" - checked ex start: " INTPTR_FORMAT, table);
266 if (Verbose) {
267 for (int i = 0; i < m->checked_exceptions_length(); i++) {
268 st->print_cr(" - throws %s", m->constants()->printable_name_at(table[i].class_cp_index));
269 }
270 }
271 }
272 if (m->has_linenumber_table()) {
273 u_char* table = m->compressed_linenumber_table();
274 st->print_cr(" - linenumber start: " INTPTR_FORMAT, table);
275 if (Verbose) {
276 CompressedLineNumberReadStream stream(table);
277 while (stream.read_pair()) {
278 st->print_cr(" - line %d: %d", stream.line(), stream.bci());
279 }
280 }
281 }
282 st->print_cr(" - localvar length: %d", m->localvariable_table_length());
283 if (m->localvariable_table_length() > 0) {
284 LocalVariableTableElement* table = m->localvariable_table_start();
285 st->print_cr(" - localvar start: " INTPTR_FORMAT, table);
286 if (Verbose) {
287 for (int i = 0; i < m->localvariable_table_length(); i++) {
288 int bci = table[i].start_bci;
289 int len = table[i].length;
290 const char* name = m->constants()->printable_name_at(table[i].name_cp_index);
291 const char* desc = m->constants()->printable_name_at(table[i].descriptor_cp_index);
292 int slot = table[i].slot;
293 st->print_cr(" - %s %s bci=%d len=%d slot=%d", desc, name, bci, len, slot);
294 }
295 }
296 }
297 if (m->code() != NULL) {
298 st->print (" - compiled code: ");
299 m->code()->print_value_on(st);
300 st->cr();
301 }
302 if (m->is_method_handle_invoke()) {
303 st->print_cr(" - invoke method type: " INTPTR_FORMAT, (address) m->method_handle_type());
304 // m is classified as native, but it does not have an interesting
305 // native_function or signature handler
306 } else if (m->is_native()) {
307 st->print_cr(" - native function: " INTPTR_FORMAT, m->native_function());
308 st->print_cr(" - signature handler: " INTPTR_FORMAT, m->signature_handler());
309 }
310 }
312 #endif //PRODUCT
314 void methodKlass::oop_print_value_on(oop obj, outputStream* st) {
315 assert(obj->is_method(), "must be method");
316 Klass::oop_print_value_on(obj, st);
317 methodOop m = methodOop(obj);
318 st->print(" ");
319 m->name()->print_value_on(st);
320 st->print(" ");
321 m->signature()->print_value_on(st);
322 st->print(" in ");
323 m->method_holder()->print_value_on(st);
324 if (WizardMode) st->print("[%d,%d]", m->size_of_parameters(), m->max_locals());
325 if (WizardMode && m->code() != NULL) st->print(" ((nmethod*)%p)", m->code());
326 }
328 const char* methodKlass::internal_name() const {
329 return "{method}";
330 }
333 // Verification
335 void methodKlass::oop_verify_on(oop obj, outputStream* st) {
336 Klass::oop_verify_on(obj, st);
337 guarantee(obj->is_method(), "object must be method");
338 if (!obj->partially_loaded()) {
339 methodOop m = methodOop(obj);
340 guarantee(m->is_perm(), "should be in permspace");
341 guarantee(m->constants()->is_perm(), "should be in permspace");
342 guarantee(m->constants()->is_constantPool(), "should be constant pool");
343 guarantee(m->constMethod()->is_constMethod(), "should be constMethodOop");
344 guarantee(m->constMethod()->is_perm(), "should be in permspace");
345 methodDataOop method_data = m->method_data();
346 guarantee(method_data == NULL ||
347 method_data->is_perm(), "should be in permspace");
348 guarantee(method_data == NULL ||
349 method_data->is_methodData(), "should be method data");
350 }
351 }
353 bool methodKlass::oop_partially_loaded(oop obj) const {
354 assert(obj->is_method(), "object must be method");
355 methodOop m = methodOop(obj);
356 constMethodOop xconst = m->constMethod();
357 assert(xconst != NULL, "const method must be set");
358 constMethodKlass* ck = constMethodKlass::cast(xconst->klass());
359 return ck->oop_partially_loaded(xconst);
360 }
363 void methodKlass::oop_set_partially_loaded(oop obj) {
364 assert(obj->is_method(), "object must be method");
365 methodOop m = methodOop(obj);
366 constMethodOop xconst = m->constMethod();
367 assert(xconst != NULL, "const method must be set");
368 constMethodKlass* ck = constMethodKlass::cast(xconst->klass());
369 ck->oop_set_partially_loaded(xconst);
370 }