6827648: Extremely slow compilation time for visitor pattern code + generics
Javac unnecessarily recomputates type-substitutions multiple times Reviewed-by: jjg
This commit is contained in:
parent
54b80cfe2a
commit
59b2cbc448
@ -1197,21 +1197,9 @@ public abstract class Symbol implements Element {
|
|||||||
* as possible implementations.
|
* as possible implementations.
|
||||||
*/
|
*/
|
||||||
public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
|
public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
|
||||||
for (Type t = origin.type; t.tag == CLASS || t.tag == TYPEVAR; t = types.supertype(t)) {
|
MethodSymbol res = types.implementation(this, origin, types, checkResult);
|
||||||
while (t.tag == TYPEVAR)
|
if (res != null)
|
||||||
t = t.getUpperBound();
|
return res;
|
||||||
TypeSymbol c = t.tsym;
|
|
||||||
for (Scope.Entry e = c.members().lookup(name);
|
|
||||||
e.scope != null;
|
|
||||||
e = e.next()) {
|
|
||||||
if (e.sym.kind == MTH) {
|
|
||||||
MethodSymbol m = (MethodSymbol) e.sym;
|
|
||||||
if (m.overrides(this, origin, types, checkResult) &&
|
|
||||||
(m.flags() & SYNTHETIC) == 0)
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if origin is derived from a raw type, we might have missed
|
// if origin is derived from a raw type, we might have missed
|
||||||
// an implementation because we do not know enough about instantiations.
|
// an implementation because we do not know enough about instantiations.
|
||||||
// in this case continue with the supertype as origin.
|
// in this case continue with the supertype as origin.
|
||||||
|
@ -25,10 +25,9 @@
|
|||||||
|
|
||||||
package com.sun.tools.javac.code;
|
package com.sun.tools.javac.code;
|
||||||
|
|
||||||
|
import java.lang.ref.SoftReference;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import com.sun.tools.javac.api.Messages;
|
|
||||||
|
|
||||||
import com.sun.tools.javac.util.*;
|
import com.sun.tools.javac.util.*;
|
||||||
import com.sun.tools.javac.util.List;
|
import com.sun.tools.javac.util.List;
|
||||||
|
|
||||||
@ -1442,7 +1441,7 @@ public class Types {
|
|||||||
return (sym.flags() & STATIC) != 0
|
return (sym.flags() & STATIC) != 0
|
||||||
? sym.type
|
? sym.type
|
||||||
: memberType.visit(t, sym);
|
: memberType.visit(t, sym);
|
||||||
}
|
}
|
||||||
// where
|
// where
|
||||||
private SimpleVisitor<Type,Symbol> memberType = new SimpleVisitor<Type,Symbol>() {
|
private SimpleVisitor<Type,Symbol> memberType = new SimpleVisitor<Type,Symbol>() {
|
||||||
|
|
||||||
@ -1552,7 +1551,7 @@ public class Types {
|
|||||||
return t; /* fast special case */
|
return t; /* fast special case */
|
||||||
else
|
else
|
||||||
return erasure.visit(t, recurse);
|
return erasure.visit(t, recurse);
|
||||||
}
|
}
|
||||||
// where
|
// where
|
||||||
private SimpleVisitor<Type, Boolean> erasure = new SimpleVisitor<Type, Boolean>() {
|
private SimpleVisitor<Type, Boolean> erasure = new SimpleVisitor<Type, Boolean>() {
|
||||||
public Type visitType(Type t, Boolean recurse) {
|
public Type visitType(Type t, Boolean recurse) {
|
||||||
@ -1946,6 +1945,45 @@ public class Types {
|
|||||||
hasSameArgs(t, erasure(s)) || hasSameArgs(erasure(t), s);
|
hasSameArgs(t, erasure(s)) || hasSameArgs(erasure(t), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, MethodSymbol>>> implCache_check =
|
||||||
|
new WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, MethodSymbol>>>();
|
||||||
|
|
||||||
|
private WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, MethodSymbol>>> implCache_nocheck =
|
||||||
|
new WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, MethodSymbol>>>();
|
||||||
|
|
||||||
|
public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, Types types, boolean checkResult) {
|
||||||
|
Map<MethodSymbol, SoftReference<Map<TypeSymbol, MethodSymbol>>> implCache = checkResult ?
|
||||||
|
implCache_check : implCache_nocheck;
|
||||||
|
SoftReference<Map<TypeSymbol, MethodSymbol>> ref_cache = implCache.get(ms);
|
||||||
|
Map<TypeSymbol, MethodSymbol> cache = ref_cache != null ? ref_cache.get() : null;
|
||||||
|
if (cache == null) {
|
||||||
|
cache = new HashMap<TypeSymbol, MethodSymbol>();
|
||||||
|
implCache.put(ms, new SoftReference<Map<TypeSymbol, MethodSymbol>>(cache));
|
||||||
|
}
|
||||||
|
MethodSymbol impl = cache.get(origin);
|
||||||
|
if (impl == null) {
|
||||||
|
for (Type t = origin.type; t.tag == CLASS || t.tag == TYPEVAR; t = types.supertype(t)) {
|
||||||
|
while (t.tag == TYPEVAR)
|
||||||
|
t = t.getUpperBound();
|
||||||
|
TypeSymbol c = t.tsym;
|
||||||
|
for (Scope.Entry e = c.members().lookup(ms.name);
|
||||||
|
e.scope != null;
|
||||||
|
e = e.next()) {
|
||||||
|
if (e.sym.kind == Kinds.MTH) {
|
||||||
|
MethodSymbol m = (MethodSymbol) e.sym;
|
||||||
|
if (m.overrides(ms, origin, types, checkResult) &&
|
||||||
|
(m.flags() & SYNTHETIC) == 0) {
|
||||||
|
impl = m;
|
||||||
|
cache.put(origin, m);
|
||||||
|
return impl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return impl;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does t have the same arguments as s? It is assumed that both
|
* Does t have the same arguments as s? It is assumed that both
|
||||||
* types are (possibly polymorphic) method types. Monomorphic
|
* types are (possibly polymorphic) method types. Monomorphic
|
||||||
|
Loading…
x
Reference in New Issue
Block a user