diff options
author | Liam Miller-Cushon <cushon@google.com> | 2016-12-05 11:58:11 -0800 |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2017-10-05 16:37:50 -0700 |
commit | 21d5ec9f070a5709fd8183c106840c13c0182a29 (patch) | |
tree | 192612420ec92e6b1b90ad5bbf598638b52db141 | |
parent | 0ff2930b76dd2dad0c4183945b7104b0f7b55930 (diff) | |
download | jdk9_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.java | 41 |
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, |