src/share/vm/prims/methodHandles.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 8042235_8u40 Sdiff src/share/vm/prims

src/share/vm/prims/methodHandles.cpp

Print this page
rev 6917 : 8042235: redefining method used by multiple MethodHandles crashes VM
Summary: note all MemberNames created on internal list for adjusting method entries.
Reviewed-by: sspitsyn, dcubed, lfoltan


  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  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/symbolTable.hpp"
  27 #include "compiler/compileBroker.hpp"
  28 #include "interpreter/interpreter.hpp"
  29 #include "interpreter/oopMapCache.hpp"
  30 #include "memory/allocation.inline.hpp"
  31 #include "memory/oopFactory.hpp"
  32 #include "prims/jvmtiRedefineClassesTrace.hpp"
  33 #include "prims/methodHandles.hpp"
  34 #include "runtime/compilationPolicy.hpp"
  35 #include "runtime/javaCalls.hpp"
  36 #include "runtime/reflection.hpp"
  37 #include "runtime/signature.hpp"
  38 #include "runtime/stubRoutines.hpp"
  39 
  40 
  41 /*
  42  * JSR 292 reference implementation: method handles
  43  * The JDK 7 reference implementation represented method handle
  44  * combinations as chains.  Each link in the chain had a "vmentry"
  45  * field which pointed at a bit of assembly code which performed
  46  * one transformation before dispatching to the next link in the chain.
  47  *
  48  * The current reference implementation pushes almost all code generation
  49  * responsibility to (trusted) Java code.  A method handle contains a
  50  * pointer to its "LambdaForm", which embodies all details of the method
  51  * handle's behavior.  The LambdaForm is a normal Java object, managed
  52  * by a runtime coded in Java.


 254   }
 255 
 256   // @CallerSensitive annotation detected
 257   if (m->caller_sensitive()) {
 258     flags |= CALLER_SENSITIVE;
 259   }
 260 
 261   oop mname_oop = mname();
 262   java_lang_invoke_MemberName::set_flags(   mname_oop, flags);
 263   java_lang_invoke_MemberName::set_vmtarget(mname_oop, m());
 264   java_lang_invoke_MemberName::set_vmindex( mname_oop, vmindex);   // vtable/itable index
 265   java_lang_invoke_MemberName::set_clazz(   mname_oop, m_klass->java_mirror());
 266   // Note:  name and type can be lazily computed by resolve_MemberName,
 267   // if Java code needs them as resolved String and MethodType objects.
 268   // The clazz must be eagerly stored, because it provides a GC
 269   // root to help keep alive the Method*.
 270   // If relevant, the vtable or itable value is stored as vmindex.
 271   // This is done eagerly, since it is readily available without
 272   // constructing any new objects.
 273   // TO DO: maybe intern mname_oop
 274   m->method_holder()->add_member_name(m->method_idnum(), mname);
 275 
 276   return mname();




 277 }
 278 
 279 oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool is_setter) {
 280   int flags = (jushort)( fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS );
 281   flags |= IS_FIELD | ((fd.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT);
 282   if (is_setter)  flags += ((JVM_REF_putField - JVM_REF_getField) << REFERENCE_KIND_SHIFT);
 283   Metadata* vmtarget = fd.field_holder();
 284   int vmindex        = fd.offset();  // determines the field uniquely when combined with static bit
 285   oop mname_oop = mname();
 286   java_lang_invoke_MemberName::set_flags(mname_oop,    flags);
 287   java_lang_invoke_MemberName::set_vmtarget(mname_oop, vmtarget);
 288   java_lang_invoke_MemberName::set_vmindex(mname_oop,  vmindex);
 289   java_lang_invoke_MemberName::set_clazz(mname_oop,    fd.field_holder()->java_mirror());
 290   oop type = field_signature_type_or_null(fd.signature());
 291   oop name = field_name_or_null(fd.name());
 292   if (name != NULL)
 293     java_lang_invoke_MemberName::set_name(mname_oop,   name);
 294   if (type != NULL)
 295     java_lang_invoke_MemberName::set_type(mname_oop,   type);
 296   // Note:  name and type can be lazily computed by resolve_MemberName,


 929 
 930 //------------------------------------------------------------------------------
 931 // MemberNameTable
 932 //
 933 
 934 MemberNameTable::MemberNameTable(int methods_cnt)
 935                   : GrowableArray<jweak>(methods_cnt, true) {
 936   assert_locked_or_safepoint(MemberNameTable_lock);
 937 }
 938 
 939 MemberNameTable::~MemberNameTable() {
 940   assert_locked_or_safepoint(MemberNameTable_lock);
 941   int len = this->length();
 942 
 943   for (int idx = 0; idx < len; idx++) {
 944     jweak ref = this->at(idx);
 945     JNIHandles::destroy_weak_global(ref);
 946   }
 947 }
 948 
 949 void MemberNameTable::add_member_name(int index, jweak mem_name_wref) {
 950   assert_locked_or_safepoint(MemberNameTable_lock);
 951   this->at_put_grow(index, mem_name_wref);
 952 }
 953 
 954 // Return a member name oop or NULL.
 955 oop MemberNameTable::get_member_name(int index) {
 956   assert_locked_or_safepoint(MemberNameTable_lock);
 957 
 958   jweak ref = this->at(index);
 959   oop mem_name = JNIHandles::resolve(ref);
 960   return mem_name;
 961 }
 962 
 963 #if INCLUDE_JVMTI
 964 oop MemberNameTable::find_member_name_by_method(Method* old_method) {
 965   assert_locked_or_safepoint(MemberNameTable_lock);
 966   oop found = NULL;
 967   int len = this->length();
 968 
 969   for (int idx = 0; idx < len; idx++) {
 970     oop mem_name = JNIHandles::resolve(this->at(idx));
 971     if (mem_name == NULL) {
 972       continue;
 973     }
 974     Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(mem_name);
 975     if (method == old_method) {
 976       found = mem_name;
 977       break;
 978     }
 979   }
 980   return found;
 981 }
 982 
 983 // It is called at safepoint only
 984 void MemberNameTable::adjust_method_entries(Method** old_methods, Method** new_methods,
 985                                             int methods_length, bool *trace_name_printed) {
 986   assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
 987   // search the MemberNameTable for uses of either obsolete or EMCP methods
 988   for (int j = 0; j < methods_length; j++) {
 989     Method* old_method = old_methods[j];
 990     Method* new_method = new_methods[j];
 991     oop mem_name = find_member_name_by_method(old_method);
 992     if (mem_name != NULL) {
 993       java_lang_invoke_MemberName::adjust_vmtarget(mem_name, new_method);
 994 
 995       if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
 996         if (!(*trace_name_printed)) {
 997           // RC_TRACE_MESG macro has an embedded ResourceMark
 998           RC_TRACE_MESG(("adjust: name=%s",
 999                          old_method->method_holder()->external_name()));
1000           *trace_name_printed = true;
1001         }
1002         // RC_TRACE macro has an embedded ResourceMark
1003         RC_TRACE(0x00400000, ("MemberName method update: %s(%s)",
1004                               new_method->name()->as_C_string(),
1005                               new_method->signature()->as_C_string()));
1006       }
1007     }
1008   }
1009 }
1010 #endif // INCLUDE_JVMTI
1011 
1012 //
1013 // Here are the native methods in java.lang.invoke.MethodHandleNatives
1014 // They are the private interface between this JVM and the HotSpot-specific
1015 // Java code that implements JSR 292 method handles.
1016 //
1017 // Note:  We use a JVM_ENTRY macro to define each of these, for this is the way
1018 // that intrinsic (non-JNI) native methods are defined in HotSpot.
1019 //
1020 
1021 JVM_ENTRY(jint, MHN_getConstant(JNIEnv *env, jobject igcls, jint which)) {
1022   switch (which) {
1023   case MethodHandles::GC_COUNT_GWT:
1024 #ifdef COMPILER2
1025     return true;




  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  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/symbolTable.hpp"
  27 #include "compiler/compileBroker.hpp"
  28 #include "interpreter/interpreter.hpp"
  29 #include "interpreter/oopMapCache.hpp"
  30 #include "memory/allocation.inline.hpp"
  31 #include "memory/oopFactory.hpp"

  32 #include "prims/methodHandles.hpp"
  33 #include "runtime/compilationPolicy.hpp"
  34 #include "runtime/javaCalls.hpp"
  35 #include "runtime/reflection.hpp"
  36 #include "runtime/signature.hpp"
  37 #include "runtime/stubRoutines.hpp"
  38 
  39 
  40 /*
  41  * JSR 292 reference implementation: method handles
  42  * The JDK 7 reference implementation represented method handle
  43  * combinations as chains.  Each link in the chain had a "vmentry"
  44  * field which pointed at a bit of assembly code which performed
  45  * one transformation before dispatching to the next link in the chain.
  46  *
  47  * The current reference implementation pushes almost all code generation
  48  * responsibility to (trusted) Java code.  A method handle contains a
  49  * pointer to its "LambdaForm", which embodies all details of the method
  50  * handle's behavior.  The LambdaForm is a normal Java object, managed
  51  * by a runtime coded in Java.


 253   }
 254 
 255   // @CallerSensitive annotation detected
 256   if (m->caller_sensitive()) {
 257     flags |= CALLER_SENSITIVE;
 258   }
 259 
 260   oop mname_oop = mname();
 261   java_lang_invoke_MemberName::set_flags(   mname_oop, flags);
 262   java_lang_invoke_MemberName::set_vmtarget(mname_oop, m());
 263   java_lang_invoke_MemberName::set_vmindex( mname_oop, vmindex);   // vtable/itable index
 264   java_lang_invoke_MemberName::set_clazz(   mname_oop, m_klass->java_mirror());
 265   // Note:  name and type can be lazily computed by resolve_MemberName,
 266   // if Java code needs them as resolved String and MethodType objects.
 267   // The clazz must be eagerly stored, because it provides a GC
 268   // root to help keep alive the Method*.
 269   // If relevant, the vtable or itable value is stored as vmindex.
 270   // This is done eagerly, since it is readily available without
 271   // constructing any new objects.
 272   // TO DO: maybe intern mname_oop
 273   if (m->method_holder()->add_member_name(mname)) {

 274     return mname();
 275   } else {
 276     // Redefinition caused this to fail.  Return NULL (and an exception?)
 277     return NULL;
 278   }
 279 }
 280 
 281 oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool is_setter) {
 282   int flags = (jushort)( fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS );
 283   flags |= IS_FIELD | ((fd.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT);
 284   if (is_setter)  flags += ((JVM_REF_putField - JVM_REF_getField) << REFERENCE_KIND_SHIFT);
 285   Metadata* vmtarget = fd.field_holder();
 286   int vmindex        = fd.offset();  // determines the field uniquely when combined with static bit
 287   oop mname_oop = mname();
 288   java_lang_invoke_MemberName::set_flags(mname_oop,    flags);
 289   java_lang_invoke_MemberName::set_vmtarget(mname_oop, vmtarget);
 290   java_lang_invoke_MemberName::set_vmindex(mname_oop,  vmindex);
 291   java_lang_invoke_MemberName::set_clazz(mname_oop,    fd.field_holder()->java_mirror());
 292   oop type = field_signature_type_or_null(fd.signature());
 293   oop name = field_name_or_null(fd.name());
 294   if (name != NULL)
 295     java_lang_invoke_MemberName::set_name(mname_oop,   name);
 296   if (type != NULL)
 297     java_lang_invoke_MemberName::set_type(mname_oop,   type);
 298   // Note:  name and type can be lazily computed by resolve_MemberName,


 931 
 932 //------------------------------------------------------------------------------
 933 // MemberNameTable
 934 //
 935 
 936 MemberNameTable::MemberNameTable(int methods_cnt)
 937                   : GrowableArray<jweak>(methods_cnt, true) {
 938   assert_locked_or_safepoint(MemberNameTable_lock);
 939 }
 940 
 941 MemberNameTable::~MemberNameTable() {
 942   assert_locked_or_safepoint(MemberNameTable_lock);
 943   int len = this->length();
 944 
 945   for (int idx = 0; idx < len; idx++) {
 946     jweak ref = this->at(idx);
 947     JNIHandles::destroy_weak_global(ref);
 948   }
 949 }
 950 
 951 void MemberNameTable::add_member_name(jweak mem_name_wref) {
 952   assert_locked_or_safepoint(MemberNameTable_lock);
 953   this->push(mem_name_wref);









 954 }
 955 
 956 #if INCLUDE_JVMTI
 957 // It is called at safepoint only for RedefineClasses



















 958 void MemberNameTable::adjust_method_entries(Method** old_methods, Method** new_methods,
 959                                             int methods_length, bool *trace_name_printed) {
 960   assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
 961   // For each redefined method
 962   for (int j = 0; j < methods_length; j++) {
 963     Method* old_method = old_methods[j];
 964     Method* new_method = new_methods[j];



 965 
 966     // search the MemberNameTable for uses of either obsolete or EMCP methods
 967     for (int idx = 0; idx < length(); idx++) {
 968       oop mem_name = JNIHandles::resolve(this->at(idx));
 969       if (mem_name != NULL) {
 970         java_lang_invoke_MemberName::adjust_vmtarget(mem_name, old_method, new_method,
 971                                                      trace_name_printed);





 972       }
 973     }
 974   }
 975 }
 976 #endif // INCLUDE_JVMTI
 977 
 978 //
 979 // Here are the native methods in java.lang.invoke.MethodHandleNatives
 980 // They are the private interface between this JVM and the HotSpot-specific
 981 // Java code that implements JSR 292 method handles.
 982 //
 983 // Note:  We use a JVM_ENTRY macro to define each of these, for this is the way
 984 // that intrinsic (non-JNI) native methods are defined in HotSpot.
 985 //
 986 
 987 JVM_ENTRY(jint, MHN_getConstant(JNIEnv *env, jobject igcls, jint which)) {
 988   switch (which) {
 989   case MethodHandles::GC_COUNT_GWT:
 990 #ifdef COMPILER2
 991     return true;


src/share/vm/prims/methodHandles.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File