--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Mon Sep 06 12:55:09 2010 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Tue Sep 07 17:31:54 2010 +0100
@@ -1974,45 +1974,74 @@
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));
+ // <editor-fold defaultstate="collapsed" desc="Determining method implementation in given site">
+ class ImplementationCache {
+
+ private WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, Entry>>> _map =
+ new WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, Entry>>>();
+
+ class Entry {
+ final MethodSymbol cachedImpl;
+ final Filter<Symbol> implFilter;
+ final boolean checkResult;
+
+ public Entry(MethodSymbol cachedImpl,
+ Filter<Symbol> scopeFilter,
+ boolean checkResult) {
+ this.cachedImpl = cachedImpl;
+ this.implFilter = scopeFilter;
+ this.checkResult = checkResult;
+ }
+
+ boolean matches(Filter<Symbol> scopeFilter, boolean checkResult) {
+ return this.implFilter == scopeFilter &&
+ this.checkResult == checkResult;
+ }
}
- MethodSymbol impl = cache.get(origin);
- if (impl == null) {
+
+ MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
+ SoftReference<Map<TypeSymbol, Entry>> ref_cache = _map.get(ms);
+ Map<TypeSymbol, Entry> cache = ref_cache != null ? ref_cache.get() : null;
+ if (cache == null) {
+ cache = new HashMap<TypeSymbol, Entry>();
+ _map.put(ms, new SoftReference<Map<TypeSymbol, Entry>>(cache));
+ }
+ Entry e = cache.get(origin);
+ if (e == null ||
+ !e.matches(implFilter, checkResult)) {
+ MethodSymbol impl = implementationInternal(ms, origin, Types.this, checkResult, implFilter);
+ cache.put(origin, new Entry(impl, implFilter, checkResult));
+ return impl;
+ }
+ else {
+ return e.cachedImpl;
+ }
+ }
+
+ private MethodSymbol implementationInternal(MethodSymbol ms, TypeSymbol origin, Types types, boolean checkResult, Filter<Symbol> implFilter) {
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);
+ for (Scope.Entry e = c.members().lookup(ms.name, implFilter);
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;
- }
- }
+ if (e.sym != null &&
+ e.sym.overrides(ms, origin, types, checkResult))
+ return (MethodSymbol)e.sym;
}
}
+ return null;
}
- return impl;
}
+ private ImplementationCache implCache = new ImplementationCache();
+
+ public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, Types types, boolean checkResult, Filter<Symbol> implFilter) {
+ return implCache.get(ms, origin, checkResult, implFilter);
+ }
+ // </editor-fold>
+
/**
* Does t have the same arguments as s? It is assumed that both
* types are (possibly polymorphic) method types. Monomorphic