]> source.dussan.org Git - dcevm.git/commitdiff
fix for proper incrementation of classRedefinedCount, till now we were updating value... 140/head
authorPrzemysław Rumik <przemelek@gmail.com>
Sat, 24 Mar 2018 15:36:29 +0000 (16:36 +0100)
committerPrzemysław Rumik <przemelek@gmail.com>
Sat, 24 Mar 2018 15:36:29 +0000 (16:36 +0100)
dcevm/src/test/java7/com/github/dcevm/test/TestUtil.java
dcevm/src/test/java7/com/github/dcevm/test/fields/FieldOperationsUpdateClassRedefinedCount.java [new file with mode: 0644]
dcevm/src/test/java7/com/github/dcevm/test/methods/OperationsOnMethodsUpdateClassRedefinedCount.java [new file with mode: 0644]
hotspot/.hg/patches/light-updateClassRedefinedCount-java8.patch [new file with mode: 0644]
hotspot/.hg/patches/series

index 7208af208ce815cff0b9837694512da9de7f631f..41d9b0bc9ad6985ed9013b7db6adede57cc8a1f6 100644 (file)
@@ -26,6 +26,7 @@ package com.github.dcevm.test;
 
 import com.github.dcevm.HotSwapTool;
 import org.junit.Assert;
+import java.lang.reflect.Field;
 
 /**
  * Utility methods for unit testing.
@@ -71,4 +72,17 @@ public class TestUtil {
     });
   }
 
+  public static int getClassRedefinedCount(Class type) {
+    try {
+      Field field = Class.class.getDeclaredField("classRedefinedCount");
+      boolean accessibility = field.isAccessible();
+      field.setAccessible(true);
+      int classRedefinedCount = (Integer) field.get(type);
+      field.setAccessible(accessibility);
+      return  classRedefinedCount;
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+  }
+
 }
diff --git a/dcevm/src/test/java7/com/github/dcevm/test/fields/FieldOperationsUpdateClassRedefinedCount.java b/dcevm/src/test/java7/com/github/dcevm/test/fields/FieldOperationsUpdateClassRedefinedCount.java
new file mode 100644 (file)
index 0000000..ff7ddaa
--- /dev/null
@@ -0,0 +1,86 @@
+package com.github.dcevm.test.fields;
+
+import com.github.dcevm.HotSwapTool;
+import com.github.dcevm.test.TestUtil;
+import com.github.dcevm.test.category.Light;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__;
+import static org.junit.Assert.assertEquals;
+
+
+@Category(Light.class)
+public class FieldOperationsUpdateClassRedefinedCount {
+
+    // Version 0
+    public static class A {
+
+        public int x;
+
+        int getFieldInOldCode() {
+
+            __toVersion__(1);
+
+            // This field does no longer exist
+            return x;
+        }
+        int getVer() {
+            return 0;
+        }
+    }
+
+    // Version 1
+    public static class A___1 {
+        public int x;
+        public int y;
+        int getVer() {
+            return 1;
+        }
+    }
+
+    public static class A___2 {
+        int getVer() {
+            return 2;
+        }
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        __toVersion__(0);
+    }
+
+    @Test
+    public void addingFieldUpdatesClassRedifinedCount() throws NoSuchFieldException, IllegalAccessException {
+        // setup
+        A a = new A();
+        __toVersion__(0);
+        int prevVersion = TestUtil.getClassRedefinedCount(A.class);
+        // examine
+        __toVersion__(1);
+
+        Object y = A.class.getDeclaredField("y").get(a);
+        // verify
+        assertEquals(0,y);
+        assertEquals(1, a.getVer());
+        assertEquals(prevVersion+1, TestUtil.getClassRedefinedCount(A.class));
+    }
+
+    @Test
+    public void deletingFieldUpdatesClassRedifinedCount() {
+        // setup
+        A a= new A();
+        __toVersion__(0);
+        int prevVersion = TestUtil.getClassRedefinedCount(A.class);
+        // examine
+        __toVersion__(2);
+
+        // verify
+        assertEquals(2, a.getVer());
+        assertEquals(prevVersion+1, TestUtil.getClassRedefinedCount(A.class));
+    }
+
+
+
+}
diff --git a/dcevm/src/test/java7/com/github/dcevm/test/methods/OperationsOnMethodsUpdateClassRedefinedCount.java b/dcevm/src/test/java7/com/github/dcevm/test/methods/OperationsOnMethodsUpdateClassRedefinedCount.java
new file mode 100644 (file)
index 0000000..9652291
--- /dev/null
@@ -0,0 +1,111 @@
+package com.github.dcevm.test.methods;
+
+import com.github.dcevm.test.TestUtil;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__;
+import static org.junit.Assert.assertEquals;
+
+public class OperationsOnMethodsUpdateClassRedefinedCount {
+    // Version 0
+    public static class A {
+        public int value(int newVersion) {
+            return newVersion;
+        }
+    }
+
+    // Version 1
+    public static class A___1 {
+
+        public int value(int newVersion) {
+
+            int x = 1;
+            try {
+                x = 2;
+            } catch (NumberFormatException e) {
+                x = 3;
+            } catch (Exception e) {
+                x = 4;
+            } finally {
+                x = x * 2;
+            }
+            __toVersion__(newVersion);
+            throw new IllegalArgumentException();
+        }
+    }
+
+    // Version 2
+    public static class A___2 {
+
+        public int value2() {
+            return 2;
+        }
+
+        public int value(int newVersion) {
+
+            int x = 1;
+            try {
+                x = 2;
+            } catch (NumberFormatException e) {
+                x = 3;
+            } catch (Exception e) {
+                x = 4;
+            } finally {
+                x = x * 2;
+            }
+            __toVersion__(newVersion);
+            throw new IllegalArgumentException();
+        }
+
+        public int value3() {
+            return 3;
+        }
+
+        public int value4() {
+            return 4;
+        }
+
+        public int value5() {
+            return 5;
+        }
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        __toVersion__(0);
+    }
+
+    @Test
+    public void changingMethodUpdatesClassRedefinedCount() {
+        // setup
+        __toVersion__(0);
+        int prevVersion = TestUtil.getClassRedefinedCount(A.class);
+        // examine
+        __toVersion__(1);
+        // verify
+        assertEquals(prevVersion+1, TestUtil.getClassRedefinedCount(A.class));
+    }
+
+    @Test
+    public void addingMethodUpdatesClassRedefinedCount() {
+        // setup
+        __toVersion__(0);
+        int prevVersion = TestUtil.getClassRedefinedCount(A.class);
+        // examine
+        __toVersion__(2);
+        // verify
+        assertEquals(prevVersion+1, TestUtil.getClassRedefinedCount(A.class));
+    }
+
+    @Test
+    public void deletingMethodUpdatesClassRedefinedCount() {
+        // setup
+        __toVersion__(2);
+        int prevVersion = TestUtil.getClassRedefinedCount(A.class);
+        // examine
+        __toVersion__(0);
+        // verify
+        assertEquals(prevVersion+1, TestUtil.getClassRedefinedCount(A.class));
+    }
+}
diff --git a/hotspot/.hg/patches/light-updateClassRedefinedCount-java8.patch b/hotspot/.hg/patches/light-updateClassRedefinedCount-java8.patch
new file mode 100644 (file)
index 0000000..31ca895
--- /dev/null
@@ -0,0 +1,28 @@
+diff -r 7bb5278e8ce7 src/share/vm/prims/jvmtiRedefineClasses2.cpp
+--- a/src/share/vm/prims/jvmtiRedefineClasses2.cpp     Fri Mar 23 15:32:54 2018 +0100
++++ b/src/share/vm/prims/jvmtiRedefineClasses2.cpp     Sat Mar 24 15:49:52 2018 +0100
+@@ -1763,8 +1763,8 @@
+   // increment the classRedefinedCount field in the_class and in any
+   // direct and indirect subclasses of the_class
+-  increment_class_counter((InstanceKlass *)the_old_class(), THREAD);
+-
++  increment_class_counter((InstanceKlass *)the_new_class(), THREAD);
++  
+ }
+@@ -1864,10 +1864,10 @@
+ // Increment the classRedefinedCount field in the specific InstanceKlass
+ // and in all direct and indirect subclasses.
+-void VM_EnhancedRedefineClasses::increment_class_counter(Klass* klass, TRAPS) {
+-  oop class_mirror = klass->java_mirror();
++void VM_EnhancedRedefineClasses::increment_class_counter(Klass* klass, TRAPS) {      
++  oop class_mirror = klass->old_version()->java_mirror();
+   int new_count = java_lang_Class::classRedefinedCount(class_mirror) + 1;
+-  java_lang_Class::set_classRedefinedCount(class_mirror, new_count);
++  java_lang_Class::set_classRedefinedCount(klass->java_mirror(), new_count);
+   RC_TRACE(0x00000008, ("updated count for class=%s to %d", klass->external_name(), new_count));
+ }
index 59b6058338d3a8c9b081aec136cc7e2adff7edfd..97875a8cb7aec400e9b8057f4d7a668f6d26ea26 100644 (file)
@@ -56,3 +56,4 @@ jvmti-lockRedefine-java8.patch #+light-jdk8u144-b01delete
 light-jdk8u20-deopt-cp.patch #+light-jdk8u20-b22 #+light-jdk8u31-b13 #+light-jdk8u40-b25 #+light-jdk8u45-b14 #+light-jdk8u51-b16
 light-jdk8u66-b17-deopt-cp.patch #+light-jdk8u66-b17 #+light-jdk8u74-b02 #+light-jdk8u92-b14 #+light-jdk8u102-b31 #+light-jdk8u111-b14 #+light-jdk8u112-b16 #+light-jdk8u144-b01 #+light-jdk8u152-b16
 dont-clear-f1.patch #+light-jdk8u74-b02 #+light-jdk8u92-b14 #+light-jdk8u102-b31 #+light-jdk8u111-b14 #+light-jdk8u112-b16 #+light-jdk8u144-b01 #+light-jdk8u152-b16
+light-updateClassRedefinedCount-java8.patch #+light-jdk8u112-b16 #+light-jdk8u144-b01 #+light-jdk8u152-b16