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