aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiam Miller-Cushon <cushon@google.com>2016-12-05 11:58:11 -0800
committerColin Cross <ccross@android.com>2017-10-05 16:37:50 -0700
commit21d5ec9f070a5709fd8183c106840c13c0182a29 (patch)
tree192612420ec92e6b1b90ad5bbf598638b52db141
parent0ff2930b76dd2dad0c4183945b7104b0f7b55930 (diff)
downloadjdk9_langtools-21d5ec9f070a5709fd8183c106840c13c0182a29.tar.gz
ANDROID: Avoid some duplicate bridge methods
Work around a long-standing compilation ordering bridge method generation bug, and pave the way for ignoring bridges across compilation boundaries during separation compilation (which is good news for ijar and turbine). Cherry-picked from https://github.com/google/error-prone-javac/commit/87ec51a2de800c1bf58ddd5c885ec5f53cc4b81f Bug: 65645120 Change-Id: Ifec36900d0183781d826040bfddff06650fe215c
-rw-r--r--src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java
index 3e9b2ae41..b045ca2f9 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java
@@ -80,6 +80,8 @@ public class TransTypes extends TreeTranslator {
/** Switch: are default methods supported? */
private final boolean allowInterfaceBridges;
+ private final boolean skipDuplicateBridges;
+
protected TransTypes(Context context) {
context.put(transTypesKey, this);
compileStates = CompileStates.instance(context);
@@ -94,6 +96,7 @@ public class TransTypes extends TreeTranslator {
Source source = Source.instance(context);
allowInterfaceBridges = source.allowDefaultMethods();
allowGraphInference = source.allowGraphInference();
+ skipDuplicateBridges = Options.instance(context).getBoolean("skipDuplicateBridges", false);
annotate = Annotate.instance(context);
}
@@ -406,6 +409,9 @@ public class TransTypes extends TreeTranslator {
MethodSymbol impl,
Type dest) {
if (impl != method) {
+ if (skipBridge(method, impl, dest)) {
+ return false;
+ }
// If either method or impl have different erasures as
// members of dest, a bridge is needed.
Type method_erasure = method.erasure(types);
@@ -446,6 +452,41 @@ public class TransTypes extends TreeTranslator {
return types.isSameType(erasure(types.memberType(type, method)),
erasure);
}
+ /**
+ * Returns true if a bridge should be skipped because we expect it to be declared in
+ * a super-type.
+ *
+ * @param method The symbol for which a bridge might have to be added
+ * @param impl The implementation of method
+ * @param dest The type in which the bridge would go
+ */
+ private boolean skipBridge(MethodSymbol method,
+ MethodSymbol impl,
+ Type dest) {
+ if (!skipDuplicateBridges) {
+ return false;
+ }
+ if (dest.tsym == impl.owner) {
+ // the method is implemented in the current class; we need to bridge it here
+ return false;
+ }
+ if (!types.isSubtype(
+ types.erasure(impl.owner.type), types.erasure(method.owner.type))) {
+ // the method is implemented in some supertype that is not a subtype of
+ // the declaring type, so the bridge will not have been created in the
+ // implementing class
+ return false;
+ }
+ if (!impl.overrides(method, (TypeSymbol) impl.owner, types, true)) {
+ // the method is implementing in a supertype that is also a subtype
+ // of the declaring type, but the method's signature in the implementing
+ // class does not override its signature in the declaring class
+ return false;
+ }
+ // we don't need to consider visibility for accessibility bridges, because
+ // that happens on a separate code path
+ return true;
+ }
void addBridges(DiagnosticPosition pos,
TypeSymbol i,