From 45d31da85cc38ea3a7adeb01372be3edb2a0bcc7 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Wed, 27 Mar 2019 19:34:30 +0300 Subject: [PATCH] Make clinit optimization weaker in order to properly handle case when clinit method reads state that was set somewhere in main method --- .../analysis/ClassInitializerAnalysis.java | 18 +++++++++++------- tests/src/test/java/org/teavm/vm/VMTest.java | 10 ++++++++++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/org/teavm/model/analysis/ClassInitializerAnalysis.java b/core/src/main/java/org/teavm/model/analysis/ClassInitializerAnalysis.java index 6ad234198..83c813d31 100644 --- a/core/src/main/java/org/teavm/model/analysis/ClassInitializerAnalysis.java +++ b/core/src/main/java/org/teavm/model/analysis/ClassInitializerAnalysis.java @@ -210,20 +210,24 @@ public class ClassInitializerAnalysis implements ClassInitializerInfo { public void getField(VariableReader receiver, VariableReader instance, FieldReference field, ValueType fieldType) { if (instance == null) { - analyzeInitializer(field.getClassName()); + touchField(field); } } @Override public void putField(VariableReader instance, FieldReference field, VariableReader value, ValueType fieldType) { if (instance == null) { - analyzeInitializer(field.getClassName()); - if (!methodInfo.anyFieldModified && !field.getClassName().equals(currentClass)) { - if (methodInfo.classesWithModifiedFields == null) { - methodInfo.classesWithModifiedFields = new HashSet<>(); - } - methodInfo.classesWithModifiedFields.add(field.getClassName()); + touchField(field); + } + } + + private void touchField(FieldReference field) { + analyzeInitializer(field.getClassName()); + if (!methodInfo.anyFieldModified && !field.getClassName().equals(currentClass)) { + if (methodInfo.classesWithModifiedFields == null) { + methodInfo.classesWithModifiedFields = new HashSet<>(); } + methodInfo.classesWithModifiedFields.add(field.getClassName()); } } diff --git a/tests/src/test/java/org/teavm/vm/VMTest.java b/tests/src/test/java/org/teavm/vm/VMTest.java index 4dfdc06fb..c3f698587 100644 --- a/tests/src/test/java/org/teavm/vm/VMTest.java +++ b/tests/src/test/java/org/teavm/vm/VMTest.java @@ -303,6 +303,12 @@ public class VMTest { assertEquals("default,A;default,B;overridden,C;", sb.toString()); } + @Test + public void clinitReadsState() { + initCount = 23; + assertEquals(23, ReadingStateInClinit.state); + } + interface WithDefaultMethod { default String foo() { return "default"; @@ -342,6 +348,10 @@ public class VMTest { static int initCount; + private static class ReadingStateInClinit { + public static final int state = initCount; + } + private static class AsyncClinitClass { static String state = ""; String instanceState = "";