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

     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 }

mercurial