import com.github.dcevm.HotSwapTool;
import org.junit.Assert;
+import java.lang.reflect.Field;
/**
* Utility methods for unit testing.
});
}
+ 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);
+ }
+ }
+
}
--- /dev/null
+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));
+ }
+
+
+
+}
--- /dev/null
+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));
+ }
+}
--- /dev/null
+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));
+ }
+
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