Implement join of single frame types
Change-Id: Id0ce02ad60956aa6a02b066de7df5d885a6f3a3a
diff --git a/src/main/java/com/android/tools/r8/cf/CfCodePrinter.java b/src/main/java/com/android/tools/r8/cf/CfCodePrinter.java
index 6fcc84a..cfa791d 100644
--- a/src/main/java/com/android/tools/r8/cf/CfCodePrinter.java
+++ b/src/main/java/com/android/tools/r8/cf/CfCodePrinter.java
@@ -542,7 +542,7 @@
}
} else {
assert frameType.isInitialized();
- if (frameType.isNull()) {
+ if (frameType.isNullType()) {
return frameTypeType() + ".initialized(" + dexItemFactoryType() + ".nullValueType)";
} else {
return frameTypeType()
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfFrame.java b/src/main/java/com/android/tools/r8/cf/code/CfFrame.java
index 642f492..94c2a25 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfFrame.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfFrame.java
@@ -75,11 +75,11 @@
return UninitializedThis.SINGLETON;
}
- public static FrameType top() {
+ public static Top top() {
return Top.SINGLETON;
}
- public static FrameType oneWord() {
+ public static OneWord oneWord() {
return OneWord.SINGLETON;
}
@@ -101,7 +101,7 @@
return false;
}
- public boolean isNull() {
+ public boolean isNullType() {
return false;
}
@@ -290,7 +290,33 @@
@Override
public SingleFrameType join(SingleFrameType frameType) {
- // TODO(b/214496607): Implement this.
+ if (equals(frameType)) {
+ return this;
+ }
+ if (frameType.isOneWord() || frameType.isTop()) {
+ return frameType;
+ }
+ if (frameType.isUninitializedObject()) {
+ return oneWord();
+ }
+ assert frameType.isInitialized();
+ DexType otherType = frameType.asSingleInitializedType().getInitializedType();
+ assert type != otherType;
+ if (type.isPrimitiveType()) {
+ // TODO(b/214496607): Should two different non-wide primitives join to int instead of
+ // OneWord?
+ return oneWord();
+ }
+ assert type.isReferenceType();
+ if (isNullType()) {
+ return otherType.isReferenceType() ? frameType : oneWord();
+ }
+ if (frameType.isNullType()) {
+ return this;
+ }
+ assert type.isArrayType() || type.isClassType();
+ assert otherType.isArrayType() || otherType.isClassType();
+ // TODO(b/214496607): Implement join of different reference types using class hierarchy.
throw new Unimplemented();
}
@@ -368,7 +394,7 @@
}
@Override
- public boolean isNull() {
+ public boolean isNullType() {
return type.isNullValueType();
}
@@ -475,8 +501,7 @@
@Override
public SingleFrameType join(SingleFrameType frameType) {
- // TODO(b/214496607): Implement this.
- throw new Unimplemented();
+ return this;
}
@Override
@@ -512,8 +537,14 @@
@Override
public SingleFrameType join(SingleFrameType frameType) {
- // TODO(b/214496607): Implement this.
- throw new Unimplemented();
+ if (equals(frameType)) {
+ return this;
+ }
+ // TODO(b/231126561): By unifying OneWord and Top, this could always return OneWord.
+ if (frameType.isTop()) {
+ return frameType;
+ }
+ return oneWord();
}
@Override
@@ -587,8 +618,14 @@
@Override
public SingleFrameType join(SingleFrameType frameType) {
- // TODO(b/214496607): Implement this.
- throw new Unimplemented();
+ if (this == frameType) {
+ return this;
+ }
+ // TODO(b/231126561): By unifying OneWord and Top, this could always return OneWord.
+ if (frameType.isTop()) {
+ return frameType;
+ }
+ return oneWord();
}
@Override
@@ -635,8 +672,8 @@
@Override
public SingleFrameType join(SingleFrameType frameType) {
- // TODO(b/214496607): Implement this.
- throw new Unimplemented();
+ // TODO(b/231126561): By unifying OneWord and Top this could always return `this`.
+ return frameType.isTop() ? frameType : this;
}
@Override
diff --git a/src/main/java/com/android/tools/r8/cf/code/frame/SingleFrameType.java b/src/main/java/com/android/tools/r8/cf/code/frame/SingleFrameType.java
index 2f1ead8..0bfde72 100644
--- a/src/main/java/com/android/tools/r8/cf/code/frame/SingleFrameType.java
+++ b/src/main/java/com/android/tools/r8/cf/code/frame/SingleFrameType.java
@@ -5,10 +5,25 @@
package com.android.tools.r8.cf.code.frame;
import com.android.tools.r8.cf.code.CfFrame.FrameType;
+import com.android.tools.r8.cf.code.CfFrame.SingleInitializedType;
public interface SingleFrameType {
FrameType asFrameType();
+ boolean isInitialized();
+
+ SingleInitializedType asSingleInitializedType();
+
+ boolean isNullType();
+
+ boolean isOneWord();
+
+ boolean isTop();
+
+ boolean isUninitializedObject();
+
+ boolean isUninitializedThis();
+
SingleFrameType join(SingleFrameType frameType);
}