src/share/vm/oops/methodKlass.cpp

Thu, 07 Apr 2011 09:53:20 -0700

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

mercurial