Mercurial > hg > truffle
comparison src/share/vm/prims/methodHandles.cpp @ 20677:fe34c5ab0b35
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
author | coleenp |
---|---|
date | Wed, 19 Nov 2014 13:02:11 -0500 |
parents | 78bbf4d43a14 |
children | 7848fc12602b |
comparison
equal
deleted
inserted
replaced
20666:bee8095780db | 20677:fe34c5ab0b35 |
---|---|
27 #include "compiler/compileBroker.hpp" | 27 #include "compiler/compileBroker.hpp" |
28 #include "interpreter/interpreter.hpp" | 28 #include "interpreter/interpreter.hpp" |
29 #include "interpreter/oopMapCache.hpp" | 29 #include "interpreter/oopMapCache.hpp" |
30 #include "memory/allocation.inline.hpp" | 30 #include "memory/allocation.inline.hpp" |
31 #include "memory/oopFactory.hpp" | 31 #include "memory/oopFactory.hpp" |
32 #include "prims/jvmtiRedefineClassesTrace.hpp" | |
33 #include "prims/methodHandles.hpp" | 32 #include "prims/methodHandles.hpp" |
34 #include "runtime/compilationPolicy.hpp" | 33 #include "runtime/compilationPolicy.hpp" |
35 #include "runtime/javaCalls.hpp" | 34 #include "runtime/javaCalls.hpp" |
36 #include "runtime/reflection.hpp" | 35 #include "runtime/reflection.hpp" |
37 #include "runtime/signature.hpp" | 36 #include "runtime/signature.hpp" |
269 // root to help keep alive the Method*. | 268 // root to help keep alive the Method*. |
270 // If relevant, the vtable or itable value is stored as vmindex. | 269 // If relevant, the vtable or itable value is stored as vmindex. |
271 // This is done eagerly, since it is readily available without | 270 // This is done eagerly, since it is readily available without |
272 // constructing any new objects. | 271 // constructing any new objects. |
273 // TO DO: maybe intern mname_oop | 272 // TO DO: maybe intern mname_oop |
274 m->method_holder()->add_member_name(m->method_idnum(), mname); | 273 if (m->method_holder()->add_member_name(mname)) { |
275 | 274 return mname(); |
276 return mname(); | 275 } else { |
276 // Redefinition caused this to fail. Return NULL (and an exception?) | |
277 return NULL; | |
278 } | |
277 } | 279 } |
278 | 280 |
279 oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool is_setter) { | 281 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 ); | 282 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); | 283 flags |= IS_FIELD | ((fd.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT); |
944 jweak ref = this->at(idx); | 946 jweak ref = this->at(idx); |
945 JNIHandles::destroy_weak_global(ref); | 947 JNIHandles::destroy_weak_global(ref); |
946 } | 948 } |
947 } | 949 } |
948 | 950 |
949 void MemberNameTable::add_member_name(int index, jweak mem_name_wref) { | 951 void MemberNameTable::add_member_name(jweak mem_name_wref) { |
950 assert_locked_or_safepoint(MemberNameTable_lock); | 952 assert_locked_or_safepoint(MemberNameTable_lock); |
951 this->at_put_grow(index, mem_name_wref); | 953 this->push(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 } | 954 } |
962 | 955 |
963 #if INCLUDE_JVMTI | 956 #if INCLUDE_JVMTI |
964 oop MemberNameTable::find_member_name_by_method(Method* old_method) { | 957 // It is called at safepoint only for RedefineClasses |
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, | 958 void MemberNameTable::adjust_method_entries(Method** old_methods, Method** new_methods, |
985 int methods_length, bool *trace_name_printed) { | 959 int methods_length, bool *trace_name_printed) { |
986 assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint"); | 960 assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint"); |
987 // search the MemberNameTable for uses of either obsolete or EMCP methods | 961 // For each redefined method |
988 for (int j = 0; j < methods_length; j++) { | 962 for (int j = 0; j < methods_length; j++) { |
989 Method* old_method = old_methods[j]; | 963 Method* old_method = old_methods[j]; |
990 Method* new_method = new_methods[j]; | 964 Method* new_method = new_methods[j]; |
991 oop mem_name = find_member_name_by_method(old_method); | 965 |
992 if (mem_name != NULL) { | 966 // search the MemberNameTable for uses of either obsolete or EMCP methods |
993 java_lang_invoke_MemberName::adjust_vmtarget(mem_name, new_method); | 967 for (int idx = 0; idx < length(); idx++) { |
994 | 968 oop mem_name = JNIHandles::resolve(this->at(idx)); |
995 if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) { | 969 if (mem_name != NULL) { |
996 if (!(*trace_name_printed)) { | 970 java_lang_invoke_MemberName::adjust_vmtarget(mem_name, old_method, new_method, |
997 // RC_TRACE_MESG macro has an embedded ResourceMark | 971 trace_name_printed); |
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 } | 972 } |
1007 } | 973 } |
1008 } | 974 } |
1009 } | 975 } |
1010 #endif // INCLUDE_JVMTI | 976 #endif // INCLUDE_JVMTI |