]> source.dussan.org Git - dcevm.git/commitdiff
Fixing MH's in case of instance fields swapping
authorIvan Dubrov <idubrov@guidewire.com>
Fri, 2 May 2014 02:10:33 +0000 (19:10 -0700)
committerIvan Dubrov <idubrov@guidewire.com>
Fri, 2 May 2014 02:10:33 +0000 (19:10 -0700)
Same fix as for static fields, update offset directly
in the DirectMethodHandle$Accessor.

dcevm/src/test/java7/com/github/dcevm/test/fields/InstanceFieldHandleTest.java [new file with mode: 0644]
dcevm/src/test/java7/com/github/dcevm/test/fields/StaticFieldHandleTest.java
hotspot/.hg/patches/light-jdk8u5-b13.patch

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 (file)
index 0000000..48f3f46
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * 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.Before;
+import org.junit.Ignore;
+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.
+ *
+ * @author Ivan Dubrov
+ */
+public class InstanceFieldHandleTest {
+
+  // Version 0
+  public static class A {
+    public int fieldA;
+    public int fieldB;
+  }
+
+  // Version 1 (fields swapped and new one is added)
+  public static class A___1 {
+    public String fieldC;
+    public int fieldB;
+    public int 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 handle = MethodHandles.publicLookup().findGetter(A.class, "fieldA", int.class);
+
+    a.fieldA = 3;
+    assertEquals(3, handle.invoke(a));
+
+    // Swap fields
+    __toVersion__(1);
+    assertEquals(3, handle.invoke(a));
+  }
+
+  @Test
+  @Ignore
+  public void testStaticFieldRemoved() throws Throwable {
+    MethodHandle handle = MethodHandles.publicLookup().findGetter(A.class, "fieldA", int.class);
+    A a = new A();
+    a.fieldA = 3;
+    assertEquals(3, handle.invoke(a));
+
+    // Remove fieldA
+    __toVersion__(2);
+
+    handle.invoke(a);
+  }
+
+  @Test
+  @Ignore
+  public void testStaticFieldTypeChange() throws Throwable {
+    MethodHandle handle = MethodHandles.publicLookup().findGetter(A.class, "fieldA", int.class);
+    A a = new A();
+    a.fieldA = 3;
+    assertEquals(3, handle.invoke(a));
+
+    // Remove fieldA
+    __toVersion__(3);
+
+    handle.invoke(a);
+  }
+}
\ No newline at end of file
index 7dee50d9264d983da52e621b4fb1f3cec909521d..6f5652523357e6525b20c14f0d078a221bcc86ec 100644 (file)
@@ -63,8 +63,8 @@ public class StaticFieldHandleTest {
 
   // Version 3 (field type changed)
   public static class A___3 {
-    public String fieldA;
-    public int fieldB;
+    public static String fieldA;
+    public static int fieldB;
   }
 
   @Before
index 58844702cae01a929742eb5c89d90dea2f566af3..f065525ffee5bd2b8dde5ddb5d237659283c1884 100644 (file)
@@ -1564,7 +1564,7 @@ diff --git a/src/share/vm/prims/jvmtiRedefineClasses2.cpp b/src/share/vm/prims/j
 new file mode 100644
 --- /dev/null
 +++ b/src/share/vm/prims/jvmtiRedefineClasses2.cpp
-@@ -0,0 +1,2100 @@
+@@ -0,0 +1,2101 @@
 +/*
 + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -2769,14 +2769,15 @@ new file mode 100644
 +        int flags    =       java_lang_invoke_MemberName::flags(mem_name);
 +        int ref_kind =       (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
 +        if (MethodHandles::ref_kind_is_field(ref_kind)) {
-+          if (java_lang_invoke_DirectMethodHandle_StaticAccessor::is_instance(obj)) {
-+            InstanceKlass* ik = InstanceKlass::cast(obj->klass());
-+            if (java_lang_invoke_MemberName::vmindex(mem_name) != 0) {
-+              // Note: we don't care about staticBase field (which is java.lang.Class)
-+              // It should be processed during normal object update.
-+              // Update offset in StaticAccessor
-+              int offset = java_lang_invoke_MemberName::vmindex(mem_name);
++          // Note: we don't care about staticBase field (which is java.lang.Class)
++          // It should be processed during normal object update.
++          // Update offset in StaticAccessor
++          int offset = java_lang_invoke_MemberName::vmindex(mem_name);
++          if (offset != 0) { // index of 0 means that field no longer exist
++            if (java_lang_invoke_DirectMethodHandle_StaticAccessor::is_instance(obj)) {
 +              java_lang_invoke_DirectMethodHandle_StaticAccessor::set_static_offset(obj, offset);
++            } else if (java_lang_invoke_DirectMethodHandle_Accessor::is_instance(obj)) {
++              java_lang_invoke_DirectMethodHandle_Accessor::set_field_offset(obj, offset);
 +            }
 +          }
 +        }