Make clinit optimization weaker in order to properly handle case

when clinit method reads state that was set somewhere in main method
This commit is contained in:
Alexey Andreev 2019-03-27 19:34:30 +03:00
parent d2a7e31eca
commit 45d31da85c
2 changed files with 21 additions and 7 deletions

View File

@ -210,13 +210,18 @@ public class ClassInitializerAnalysis implements ClassInitializerInfo {
public void getField(VariableReader receiver, VariableReader instance, FieldReference field, public void getField(VariableReader receiver, VariableReader instance, FieldReference field,
ValueType fieldType) { ValueType fieldType) {
if (instance == null) { if (instance == null) {
analyzeInitializer(field.getClassName()); touchField(field);
} }
} }
@Override @Override
public void putField(VariableReader instance, FieldReference field, VariableReader value, ValueType fieldType) { public void putField(VariableReader instance, FieldReference field, VariableReader value, ValueType fieldType) {
if (instance == null) { if (instance == null) {
touchField(field);
}
}
private void touchField(FieldReference field) {
analyzeInitializer(field.getClassName()); analyzeInitializer(field.getClassName());
if (!methodInfo.anyFieldModified && !field.getClassName().equals(currentClass)) { if (!methodInfo.anyFieldModified && !field.getClassName().equals(currentClass)) {
if (methodInfo.classesWithModifiedFields == null) { if (methodInfo.classesWithModifiedFields == null) {
@ -225,7 +230,6 @@ public class ClassInitializerAnalysis implements ClassInitializerInfo {
methodInfo.classesWithModifiedFields.add(field.getClassName()); methodInfo.classesWithModifiedFields.add(field.getClassName());
} }
} }
}
@Override @Override
public void invoke(VariableReader receiver, VariableReader instance, MethodReference method, public void invoke(VariableReader receiver, VariableReader instance, MethodReference method,

View File

@ -303,6 +303,12 @@ public class VMTest {
assertEquals("default,A;default,B;overridden,C;", sb.toString()); assertEquals("default,A;default,B;overridden,C;", sb.toString());
} }
@Test
public void clinitReadsState() {
initCount = 23;
assertEquals(23, ReadingStateInClinit.state);
}
interface WithDefaultMethod { interface WithDefaultMethod {
default String foo() { default String foo() {
return "default"; return "default";
@ -342,6 +348,10 @@ public class VMTest {
static int initCount; static int initCount;
private static class ReadingStateInClinit {
public static final int state = initCount;
}
private static class AsyncClinitClass { private static class AsyncClinitClass {
static String state = ""; static String state = "";
String instanceState = ""; String instanceState = "";