org.eclipse.dltk.core.mixin.MixinModel is only partially synchronized.
We have multiple threads attempting to use the index and they get into strife calling get(String) on MixinModel. The reason is simple:
public IMixinElement get(String key) {
if (DLTKCore.VERBOSE) {
System.out.println("MixinModel.get(" + key + ')'); //$NON-NLS-1$
}
if (notExistKeysCache.contains(key)) {
return null;
}
if (removes == 0) {
if (cache.get(key) == null) {
return null;
}
}
MixinElement element = getCreateEmpty(key);
if (DLTKCore.VERBOSE) {
System.out.println("Filling ratio:" + this.cache.fillingRatio()); //$NON-NLS-1$
this.cache.printStats();
}
buildElementTree(element);
if (element.isFinal() && element.sourceModules.size() > 0) {
existKeysCache.add(key);
return element;
}
notExistKeysCache.add(key);
synchronized (this.cache) {
cache.remove(element.key);
cache.resetSpaceLimit(CACHE_LIMIT, element);
}
return null;
}
The class members existKeysCache and notExistKeysCache are not synchronized. Multiple threads can access them. The calls to add(key) on the HashMap result in two threads trying to modify the map simultaneously. Specifically a rehash(). This seems to cause the HashMap to either blow up or infinitely loop inside AnalyzeMap().
The solution would be to synchronize these other members as well as the cache.
- Carl.