aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLiam Miller-Cushon <cushon@google.com>2016-12-05 11:58:11 -0800
committerColin Cross <ccross@android.com>2017-09-15 15:42:12 -0700
commitfe8ba49ea8854950d9d756b7b2ac937c4a3f9577 (patch)
tree47dbd419460a903756010a13c9512d76364d1e5d /src
parent01d8e643b65864b0078c06e0791ea36d2aa7b4b2 (diff)
downloadjdk8u_langtools-fe8ba49ea8854950d9d756b7b2ac937c4a3f9577.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). Ported from https://github.com/google/error-prone-javac/commit/87ec51a2de800c1bf58ddd5c885ec5f53cc4b81f Bug: 65645120 Change-Id: I30e7916e76791fea64115865486d845d60339155
Diffstat (limited to 'src')
-rw-r--r--src/share/classes/com/sun/tools/javac/comp/TransTypes.java41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/share/classes/com/sun/tools/javac/comp/TransTypes.java b/src/share/classes/com/sun/tools/javac/comp/TransTypes.java
index ad00b788..84118f1f 100644
--- a/src/share/classes/com/sun/tools/javac/comp/TransTypes.java
+++ b/src/share/classes/com/sun/tools/javac/comp/TransTypes.java
@@ -81,6 +81,8 @@ public class TransTypes extends TreeTranslator {
private final CompileStates compileStates;
+ private final boolean skipDuplicateBridges;
+
protected TransTypes(Context context) {
context.put(transTypesKey, this);
compileStates = CompileStates.instance(context);
@@ -93,6 +95,7 @@ public class TransTypes extends TreeTranslator {
allowEnums = source.allowEnums();
addBridges = source.addBridges();
allowInterfaceBridges = source.allowDefaultMethods();
+ skipDuplicateBridges = Options.instance(context).getBoolean("skipDuplicateBridges", false);
types = Types.instance(context);
make = TreeMaker.instance(context);
resolve = Resolve.instance(context);
@@ -405,6 +408,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);
@@ -445,6 +451,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,