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,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());
}
}

View File

@ -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 = "";