From 220d2d53e0ca62efe7e8cd325445cd9eef8619b7 Mon Sep 17 00:00:00 2001 From: Ivan Dubrov Date: Fri, 10 Jul 2015 14:22:07 -0700 Subject: [PATCH] Fixing fields handling --- .../test/fields/InstanceFieldHandleTest.java | 154 ++++++++++++++ .../test/fields/StaticFieldHandleTest.java | 154 ++++++++++++++ .../light-jdk7u79-b15-method-handles.patch | 201 +++++++++--------- 3 files changed, 413 insertions(+), 96 deletions(-) create mode 100644 dcevm/src/test/java7/com/github/dcevm/test/fields/InstanceFieldHandleTest.java create mode 100644 dcevm/src/test/java7/com/github/dcevm/test/fields/StaticFieldHandleTest.java diff --git a/dcevm/src/test/java7/com/github/dcevm/test/fields/InstanceFieldHandleTest.java b/dcevm/src/test/java7/com/github/dcevm/test/fields/InstanceFieldHandleTest.java new file mode 100644 index 00000000..a47ce5c5 --- /dev/null +++ b/dcevm/src/test/java7/com/github/dcevm/test/fields/InstanceFieldHandleTest.java @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +package com.github.dcevm.test.fields; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; + +import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__; +import static org.junit.Assert.assertEquals; + +/** + * Test for replacing field with MethodHandle pointing to it. + * + * Technically, should work for Java 7, but currently is not supported in Java 7. + * + * @author Ivan Dubrov + */ +public class InstanceFieldHandleTest { + + // Version 0 + public static class A { + public int fieldA; + public int fieldB; + + public int getFieldA() { + return -1; + } + } + + // Version 1 (fields swapped and new one is added) + public static class A___1 { + public int fieldB; + public int fieldA; + public String fieldC; + + public int getFieldA() { + return fieldA; + } + } + + // Version 2 (fields removed) + public static class A___2 { + } + + // Version 3 (field type changed) + public static class A___3 { + public String fieldA; + public int fieldB; + } + + @Before + @After + public void setUp() throws Exception { + __toVersion__(0); + } + + @Test + public void testFieldChangeOrder() throws Throwable { + A a = new A(); + MethodHandle getter = MethodHandles.publicLookup().findGetter(A.class, "fieldA", int.class); + MethodHandle setter = MethodHandles.publicLookup().findSetter(A.class, "fieldA", int.class); + + a.fieldA = 3; + assertEquals(3, getter.invoke(a)); + + // Swap fields + __toVersion__(1); + + assertEquals(3, getter.invoke(a)); + setter.invoke(a, 53); + assertEquals(53, a.getFieldA()); + assertEquals(53, getter.invoke(a)); + } + + @Test + public void testFieldRemoved() throws Throwable { + A a = new A(); + MethodHandle getter = MethodHandles.publicLookup().findGetter(A.class, "fieldA", int.class); + MethodHandle setter = MethodHandles.publicLookup().findSetter(A.class, "fieldA", int.class); + + a.fieldA = 3; + assertEquals(3, getter.invoke(a)); + + // Remove fieldA + __toVersion__(2); + + try { + getter.invoke(a); + Assert.fail("Handle should have been cleared!"); + } catch (NullPointerException e) { + // Handle was cleared! + } + + try { + setter.invoke(a, 10); + Assert.fail("Handle should have been cleared!"); + } catch (NullPointerException e) { + // Handle was cleared! + } + } + + @Test + public void testFieldTypeChange() throws Throwable { + A a = new A(); + MethodHandle getter = MethodHandles.publicLookup().findGetter(A.class, "fieldA", int.class); + MethodHandle setter = MethodHandles.publicLookup().findSetter(A.class, "fieldA", int.class); + + a.fieldA = 3; + assertEquals(3, getter.invoke(a)); + + // Remove fieldA + __toVersion__(3); + + try { + getter.invoke(a); + Assert.fail("Handle should have been cleared!"); + } catch (NullPointerException e) { + // Handle was cleared! + } + + try { + setter.invoke(a, 10); + Assert.fail("Handle should have been cleared!"); + } catch (NullPointerException e) { + // Handle was cleared! + } + } +} \ No newline at end of file diff --git a/dcevm/src/test/java7/com/github/dcevm/test/fields/StaticFieldHandleTest.java b/dcevm/src/test/java7/com/github/dcevm/test/fields/StaticFieldHandleTest.java new file mode 100644 index 00000000..ee669917 --- /dev/null +++ b/dcevm/src/test/java7/com/github/dcevm/test/fields/StaticFieldHandleTest.java @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +package com.github.dcevm.test.fields; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; + +import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__; +import static org.junit.Assert.assertEquals; + +/** + * Test for replacing field with MethodHandle pointing to it. + * + * Technically, should work for Java 7, but currently is not supported in Java 7. + * + * @author Ivan Dubrov + */ +public class StaticFieldHandleTest { + + // Version 0 + public static class A { + public static int fieldA; + public static int fieldB; + + public static int getFieldA() { + return -1; + } + } + + // Version 1 (fields swapped) + public static class A___1 { + public static int fieldB; + public static int fieldA; + public static String fieldC; + + public static int getFieldA() { + return fieldA; + } + } + + // Version 2 (fields removed) + public static class A___2 { + } + + // Version 3 (field type changed) + public static class A___3 { + public static String fieldA; + public static int fieldB; + } + + @Before + @After + public void setUp() throws Exception { + __toVersion__(0); + } + + @Test + public void testStaticFieldChangeOrder() throws Throwable { + MethodHandle getter = MethodHandles.publicLookup().findStaticGetter(A.class, "fieldA", int.class); + MethodHandle setter = MethodHandles.publicLookup().findStaticSetter(A.class, "fieldA", int.class); + + A.fieldA = 3; + A.fieldB = 5; + assertEquals(3, getter.invoke()); + + // Swap fields A and B + __toVersion__(1); + + assertEquals(3, getter.invoke()); + setter.invoke(12); + assertEquals(12, A.getFieldA()); + assertEquals(12, getter.invoke()); + } + + @Test + public void testStaticFieldRemoved() throws Throwable { + MethodHandle getter = MethodHandles.publicLookup().findStaticGetter(A.class, "fieldA", int.class); + MethodHandle setter = MethodHandles.publicLookup().findStaticSetter(A.class, "fieldA", int.class); + + A.fieldA = 3; + A.fieldB = 5; + assertEquals(3, getter.invoke()); + + // Remove fieldA + __toVersion__(2); + + try { + getter.invoke(); + Assert.fail("Handle should have been cleared!"); + } catch (NullPointerException e) { + // Handle was cleared! + } + + try { + setter.invoke(15); + Assert.fail("Handle should have been cleared!"); + } catch (NullPointerException e) { + // Handle was cleared! + } + } + + @Test + public void testStaticFieldTypeChange() throws Throwable { + MethodHandle getter = MethodHandles.publicLookup().findStaticGetter(A.class, "fieldA", int.class); + MethodHandle setter = MethodHandles.publicLookup().findStaticSetter(A.class, "fieldA", int.class); + + A.fieldA = 3; + A.fieldB = 5; + assertEquals(3, getter.invoke()); + + // Remove fieldA + __toVersion__(3); + + try { + getter.invoke(); + Assert.fail("Handle should have been cleared!"); + } catch (NullPointerException e) { + // Handle was cleared! + } + + try { + setter.invoke(15); + Assert.fail("Handle should have been cleared!"); + } catch (NullPointerException e) { + // Handle was cleared! + } + } +} \ No newline at end of file diff --git a/hotspot/.hg/patches/light-jdk7u79-b15-method-handles.patch b/hotspot/.hg/patches/light-jdk7u79-b15-method-handles.patch index ef7b85ba..b50a11a8 100644 --- a/hotspot/.hg/patches/light-jdk7u79-b15-method-handles.patch +++ b/hotspot/.hg/patches/light-jdk7u79-b15-method-handles.patch @@ -1,9 +1,9 @@ # HG changeset patch # Parent 6858a68213bfb26e2a246f0014b921ecab5ac750 -diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/classfile/javaClasses.cpp +diff -r 6858a68213bf src/share/vm/classfile/javaClasses.cpp --- a/src/share/vm/classfile/javaClasses.cpp Fri Jul 10 13:18:18 2015 -0700 -+++ b/src/share/vm/classfile/javaClasses.cpp Fri Jul 10 13:59:26 2015 -0700 ++++ b/src/share/vm/classfile/javaClasses.cpp Fri Jul 10 14:20:20 2015 -0700 @@ -2414,6 +2414,49 @@ } } @@ -63,9 +63,9 @@ diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/classfile/javaClasses.cpp java_lang_invoke_MemberName::compute_offsets(); java_lang_invoke_LambdaForm::compute_offsets(); java_lang_invoke_MethodType::compute_offsets(); -diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/classfile/javaClasses.hpp +diff -r 6858a68213bf src/share/vm/classfile/javaClasses.hpp --- a/src/share/vm/classfile/javaClasses.hpp Fri Jul 10 13:18:18 2015 -0700 -+++ b/src/share/vm/classfile/javaClasses.hpp Fri Jul 10 13:59:26 2015 -0700 ++++ b/src/share/vm/classfile/javaClasses.hpp Fri Jul 10 14:20:20 2015 -0700 @@ -942,6 +942,55 @@ static int member_offset_in_bytes() { return _member_offset; } }; @@ -122,9 +122,9 @@ diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/classfile/javaClasses.hpp // Interface to java.lang.invoke.LambdaForm objects // (These are a private interface for managing adapter code generation.) -diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/classfile/systemDictionary.hpp +diff -r 6858a68213bf src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Fri Jul 10 13:18:18 2015 -0700 -+++ b/src/share/vm/classfile/systemDictionary.hpp Fri Jul 10 13:59:26 2015 -0700 ++++ b/src/share/vm/classfile/systemDictionary.hpp Fri Jul 10 14:20:20 2015 -0700 @@ -148,6 +148,8 @@ do_klass(reflect_UnsafeStaticFieldAccessorImpl_klass, sun_reflect_UnsafeStaticFieldAccessorImpl, Opt_Only_JDK15 ) \ \ @@ -134,9 +134,9 @@ diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/classfile/systemDictionary.hpp do_klass(MethodHandle_klass, java_lang_invoke_MethodHandle, Pre_JSR292 ) \ do_klass(MemberName_klass, java_lang_invoke_MemberName, Pre_JSR292 ) \ do_klass(MethodHandleNatives_klass, java_lang_invoke_MethodHandleNatives, Pre_JSR292 ) \ -diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/classfile/vmSymbols.hpp +diff -r 6858a68213bf src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Fri Jul 10 13:18:18 2015 -0700 -+++ b/src/share/vm/classfile/vmSymbols.hpp Fri Jul 10 13:59:26 2015 -0700 ++++ b/src/share/vm/classfile/vmSymbols.hpp Fri Jul 10 14:20:20 2015 -0700 @@ -244,6 +244,8 @@ /* Support for JSR 292 & invokedynamic (JDK 1.7 and above) */ \ template(java_lang_invoke_CallSite, "java/lang/invoke/CallSite") \ @@ -157,99 +157,103 @@ diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/classfile/vmSymbols.hpp /* signature symbols needed by intrinsics */ \ VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, template, VM_ALIAS_IGNORE) \ \ -diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/prims/jvmtiRedefineClasses.cpp +diff -r 6858a68213bf src/share/vm/prims/jvmtiRedefineClasses.cpp --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Jul 10 13:18:18 2015 -0700 -+++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Jul 10 13:59:26 2015 -0700 -@@ -1400,6 +1400,120 @@ ++++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Jul 10 14:20:20 2015 -0700 +@@ -1398,8 +1398,124 @@ + template static void oop_store(T* p, oop v) { oopDesc::encode_store_heap_oop_not_null(p, v); } + }; - template - class ChangePointersOopClosure : public OopClosureNoHeader { -+ // import java_lang_invoke_MemberName.* -+ enum { -+ REFERENCE_KIND_SHIFT = java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT, -+ REFERENCE_KIND_MASK = java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK, -+ }; -+ -+ static oop field_name_or_null(Symbol* s) { -+ if (s == NULL) return NULL; -+ return StringTable::lookup(s); -+ } ++// import java_lang_invoke_MemberName.* ++enum { ++ REFERENCE_KIND_SHIFT = java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT, ++ REFERENCE_KIND_MASK = java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK, ++}; + -+ static oop object_java_mirror() { -+ return Klass::cast(SystemDictionary::Object_klass())->java_mirror(); -+ } ++static oop field_name_or_null(Symbol* s) { ++ if (s == NULL) return NULL; ++ return StringTable::lookup(s); ++} + -+ static oop field_signature_type_or_null(Symbol* s) { -+ if (s == NULL) return NULL; -+ BasicType bt = FieldType::basic_type(s); -+ if (is_java_primitive(bt)) { -+ assert(s->utf8_length() == 1, ""); -+ return java_lang_Class::primitive_mirror(bt); -+ } -+ // Here are some more short cuts for common types. -+ // They are optional, since reference types can be resolved lazily. -+ if (bt == T_OBJECT) { -+ if (s == vmSymbols::object_signature()) { -+ return object_java_mirror(); -+ } else if (s == vmSymbols::class_signature()) { -+ return Klass::cast(SystemDictionary::Class_klass())->java_mirror(); -+ } else if (s == vmSymbols::string_signature()) { -+ return Klass::cast(SystemDictionary::String_klass())->java_mirror(); -+ } ++static oop object_java_mirror() { ++ return Klass::cast(SystemDictionary::Object_klass())->java_mirror(); ++} ++ ++static oop field_signature_type_or_null(Symbol* s) { ++ if (s == NULL) return NULL; ++ BasicType bt = FieldType::basic_type(s); ++ if (is_java_primitive(bt)) { ++ assert(s->utf8_length() == 1, ""); ++ return java_lang_Class::primitive_mirror(bt); ++ } ++ // Here are some more short cuts for common types. ++ // They are optional, since reference types can be resolved lazily. ++ if (bt == T_OBJECT) { ++ if (s == vmSymbols::object_signature()) { ++ return object_java_mirror(); ++ } else if (s == vmSymbols::class_signature()) { ++ return Klass::cast(SystemDictionary::Class_klass())->java_mirror(); ++ } else if (s == vmSymbols::string_signature()) { ++ return Klass::cast(SystemDictionary::String_klass())->java_mirror(); + } -+ return NULL; + } ++ return NULL; ++} + -+ bool update_member_name(oop obj) { -+ int flags = java_lang_invoke_MemberName::flags(obj); -+ int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK; -+ if (MethodHandles::ref_kind_is_method(ref_kind)) { -+ methodOop m = (methodOop) java_lang_invoke_MemberName::vmtarget(obj); -+ if (m != NULL && !instanceKlass::cast(m->method_holder())->is_newest_version()) { -+ // Let's try to re-resolve method -+ KlassHandle newest = instanceKlass::cast(m->method_holder())->newest_version(); -+ methodOop new_method = instanceKlass::cast(newest())->find_method(m->name(), m->signature()); -+ -+ // Note: we might set NULL at this point, which should force AbstractMethodError at runtime -+ bool do_dispatch = (ref_kind != JVM_REF_invokeSpecial); -+ MethodHandles::init_method_MemberName(obj, new_method, do_dispatch, newest); -+ } -+ } else if (MethodHandles::ref_kind_is_field(ref_kind)) { -+ klassOop k = (klassOop) java_lang_invoke_MemberName::vmtarget(obj); -+ if (k == NULL) { -+ return false; // Was cleared before, this MemberName is invalid. -+ } ++bool update_member_name(oop obj) { ++ int flags = java_lang_invoke_MemberName::flags(obj); ++ int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK; ++ if (MethodHandles::ref_kind_is_method(ref_kind)) { ++ methodOop m = (methodOop) java_lang_invoke_MemberName::vmtarget(obj); ++ if (m != NULL && !instanceKlass::cast(m->method_holder())->is_newest_version()) { ++ // Let's try to re-resolve method ++ KlassHandle newest = instanceKlass::cast(m->method_holder())->newest_version(); ++ methodOop new_method = instanceKlass::cast(newest())->find_method(m->name(), m->signature()); ++ ++ // Note: we might set NULL at this point, which should force AbstractMethodError at runtime ++ bool do_dispatch = (ref_kind != JVM_REF_invokeSpecial); ++ MethodHandles::init_method_MemberName(obj, new_method, do_dispatch, newest); ++ } ++ } else if (MethodHandles::ref_kind_is_field(ref_kind)) { ++ klassOop k = (klassOop) java_lang_invoke_MemberName::vmtarget(obj); ++ if (k == NULL) { ++ return false; // Was cleared before, this MemberName is invalid. ++ } + -+ if (k != NULL && !Klass::cast(k)->is_newest_version()) { -+ // Let's try to re-resolve field -+ fieldDescriptor fd; -+ int offset = java_lang_invoke_MemberName::vmindex(obj); -+ bool is_static = MethodHandles::ref_kind_is_static(ref_kind); -+ instanceKlass *ik = instanceKlass::cast(k); -+ if (ik->find_local_field_from_offset(offset, is_static, &fd)) { -+ KlassHandle newest = Klass::cast(k)->newest_version(); -+ fieldDescriptor fd_new; -+ if (instanceKlass::cast(newest())->find_local_field(fd.name(), fd.signature(), &fd_new)) { -+ bool is_setter = MethodHandles::ref_kind_is_setter(ref_kind); -+ oop type = field_signature_type_or_null(fd_new.signature()); -+ oop name = field_name_or_null(fd_new.name()); -+ MethodHandles::init_field_MemberName(obj, newest, fd_new.access_flags(), type, name, fd_new.offset(), is_setter); -+ } else { -+ // Matching field is not found in new version, not much we can do here. -+ // JVM will crash once faulty MH is invoked. -+ // However, to avoid that all DMH's using this faulty MH are cleared (set to NULL) -+ // Eventually, we probably want to replace them with something more meaningful, -+ // like instance throwing NoSuchFieldError or DMH that will resort to dynamic -+ // field resolution (with possibility of type conversion) -+ java_lang_invoke_MemberName::set_vmtarget(obj, NULL); -+ java_lang_invoke_MemberName::set_vmindex(obj, 0); -+ return false; -+ } ++ if (k != NULL && !Klass::cast(k)->is_newest_version()) { ++ // Let's try to re-resolve field ++ fieldDescriptor fd; ++ int offset = java_lang_invoke_MemberName::vmindex(obj); ++ bool is_static = MethodHandles::ref_kind_is_static(ref_kind); ++ instanceKlass *ik = instanceKlass::cast(k); ++ if (ik->find_local_field_from_offset(offset, is_static, &fd)) { ++ KlassHandle newest = Klass::cast(k)->newest_version(); ++ fieldDescriptor fd_new; ++ if (instanceKlass::cast(newest())->find_local_field(fd.name(), fd.signature(), &fd_new)) { ++ bool is_setter = MethodHandles::ref_kind_is_setter(ref_kind); ++ oop type = field_signature_type_or_null(fd_new.signature()); ++ oop name = field_name_or_null(fd_new.name()); ++ MethodHandles::init_field_MemberName(obj, newest, fd_new.access_flags(), type, name, fd_new.offset(), is_setter); ++ } else { ++ // Matching field is not found in new version, not much we can do here. ++ // JVM will crash once faulty MH is invoked. ++ // However, to avoid that all DMH's using this faulty MH are cleared (set to NULL) ++ // Eventually, we probably want to replace them with something more meaningful, ++ // like instance throwing NoSuchFieldError or DMH that will resort to dynamic ++ // field resolution (with possibility of type conversion) ++ java_lang_invoke_MemberName::set_vmtarget(obj, NULL); ++ java_lang_invoke_MemberName::set_vmindex(obj, 0); ++ return false; + } + } + } -+ return true; + } ++ return true; ++} ++ ++ + template + class ChangePointersOopClosure : public OopClosureNoHeader { + + bool update_direct_method_handle(oop obj) { + // Always update member name first. @@ -281,12 +285,10 @@ diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/prims/jvmtiRedefineClasses.cpp // Forward pointers to instanceKlass and mirror class to new versions template inline void do_oop_work(T* p) { -@@ -1422,6 +1536,14 @@ +@@ -1422,6 +1538,12 @@ S::oop_store(p, oop); } } -+ } else if (java_lang_invoke_MemberName::is_instance(oop)) { -+ update_member_name(oop); + } else if (java_lang_invoke_DirectMethodHandle::is_instance(oop)) { + if (!update_direct_method_handle(oop)) { + // DMH is no longer valid, replace it with null reference. @@ -296,7 +298,14 @@ diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/prims/jvmtiRedefineClasses.cpp } } -@@ -1504,22 +1626,6 @@ +@@ -1501,25 +1623,13 @@ + // Causes SIGSEGV? + //instanceMirrorKlass::oop_fields_iterate(obj, _closure); + } else { ++ // Update member name before its klass pointer is updated! ++ if (java_lang_invoke_MemberName::is_instance(obj)) { ++ update_member_name(obj); ++ } obj->oop_iterate(_closure); } @@ -319,7 +328,7 @@ diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/prims/jvmtiRedefineClasses.cpp if (obj->blueprint()->new_version() != NULL) { Klass* new_klass = obj->blueprint()->new_version()->klass_part(); if (obj->is_perm()) { -@@ -1989,6 +2095,11 @@ +@@ -1989,6 +2099,11 @@ transfer_old_native_function_registrations(the_old_class); @@ -331,9 +340,9 @@ diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/prims/jvmtiRedefineClasses.cpp #ifdef ASSERT -diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/runtime/mutexLocker.cpp +diff -r 6858a68213bf src/share/vm/runtime/mutexLocker.cpp --- a/src/share/vm/runtime/mutexLocker.cpp Fri Jul 10 13:18:18 2015 -0700 -+++ b/src/share/vm/runtime/mutexLocker.cpp Fri Jul 10 13:59:26 2015 -0700 ++++ b/src/share/vm/runtime/mutexLocker.cpp Fri Jul 10 14:20:20 2015 -0700 @@ -265,7 +265,7 @@ def(Heap_lock , Monitor, nonleaf+1, false); def(JfieldIdCreation_lock , Mutex , nonleaf+1, true ); // jfieldID, Used in VM_Operation -- 2.39.5