Prevent unbounded / double cache growth.

This commit is contained in:
md_5 2015-01-12 20:32:03 +11:00
parent 8c2527e413
commit 4ae1176157
3 changed files with 10 additions and 14 deletions

View File

@ -65,7 +65,6 @@ public class Jar {
private final String filename; private final String filename;
private final LinkedHashMap<String, JarFile> jarForResource; private final LinkedHashMap<String, JarFile> jarForResource;
private final Set<String> contains = new HashSet<String>(); private final Set<String> contains = new HashSet<String>();
private final Map<String, ClassNode> classes = new HashMap<String, ClassNode>();
/** /**
* Check if this jar contains the given class. Takes the internal name of a * Check if this jar contains the given class. Takes the internal name of a
@ -124,12 +123,6 @@ public class Jar {
* @return * @return
*/ */
public ClassNode getNode(String clazz) { public ClassNode getNode(String clazz) {
// Lets try a cache hit
ClassNode cache = classes.get(clazz);
if (cache != null) {
return cache;
}
// No luck, so lets try read it // No luck, so lets try read it
try { try {
InputStream is = getClass(clazz); InputStream is = getClass(clazz);
@ -138,8 +131,7 @@ public class Jar {
ClassReader cr = new ClassReader(is); ClassReader cr = new ClassReader(is);
ClassNode node = new ClassNode(); ClassNode node = new ClassNode();
cr.accept(node, 0); cr.accept(node, 0);
// Add it to the cache
classes.put(clazz, node);
return node; return node;
} }
} catch (IOException ex) { } catch (IOException ex) {

View File

@ -33,6 +33,8 @@ import java.util.Collection;
import java.util.Map; import java.util.Map;
import net.md_5.specialsource.provider.InheritanceProvider; import net.md_5.specialsource.provider.InheritanceProvider;
import net.md_5.specialsource.provider.JarProvider; import net.md_5.specialsource.provider.JarProvider;
import net.md_5.specialsource.repo.ClassRepo;
import net.md_5.specialsource.repo.JarRepo;
import net.md_5.specialsource.util.NoDupeList; import net.md_5.specialsource.util.NoDupeList;
import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.FieldVisitor;
@ -47,6 +49,7 @@ public class JarComparer extends ClassVisitor {
private final MethodReferenceFinder methodVisitor = new MethodReferenceFinder(); private final MethodReferenceFinder methodVisitor = new MethodReferenceFinder();
public final Jar jar; public final Jar jar;
private final ClassRepo jarRepo;
private final InheritanceProvider inheritance; private final InheritanceProvider inheritance;
private String myName; private String myName;
public int iterDepth; public int iterDepth;
@ -70,6 +73,7 @@ public class JarComparer extends ClassVisitor {
public JarComparer(Jar jar) { public JarComparer(Jar jar) {
super(Opcodes.ASM5); super(Opcodes.ASM5);
this.jar = jar; this.jar = jar;
this.jarRepo = new JarRepo(jar);
this.inheritance = new JarProvider(jar); this.inheritance = new JarProvider(jar);
} }
@ -116,7 +120,7 @@ public class JarComparer extends ClassVisitor {
String newParent = null; String newParent = null;
ClassNode n = jar.getNode(currentParent); ClassNode n = jarRepo.findClass(currentParent);
if (n == null) { if (n == null) {
return newParent; return newParent;
} }

View File

@ -28,17 +28,17 @@
*/ */
package net.md_5.specialsource.repo; package net.md_5.specialsource.repo;
import java.util.Map; import com.google.common.cache.Cache;
import java.util.WeakHashMap; import com.google.common.cache.CacheBuilder;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
public abstract class CachingRepo implements ClassRepo { public abstract class CachingRepo implements ClassRepo {
private final Map<String, ClassNode> cache = new WeakHashMap<String, ClassNode>(); private final Cache<String, ClassNode> cache = CacheBuilder.newBuilder().maximumSize(4096).build();
@Override @Override
public final ClassNode findClass(String internalName) { public final ClassNode findClass(String internalName) {
ClassNode fromCache = cache.get(internalName); ClassNode fromCache = cache.getIfPresent(internalName);
if (fromCache != null) { if (fromCache != null) {
return fromCache; return fromCache;
} }