Commit fd70b486 authored by Lukáš Marek's avatar Lukáš Marek

Removed static context caches - problem with concurrency

parent 03bc775b
package ch.usi.dag.disl.staticcontext;
import java.util.HashMap;
import java.util.Map;
import ch.usi.dag.disl.snippet.Shadow;
import ch.usi.dag.disl.staticcontext.cache.CacheableStaticContext;
import ch.usi.dag.disl.staticcontext.cache.StaticContextCache;
public abstract class AbstractStaticContext implements StaticContext,
CacheableStaticContext {
public abstract class AbstractStaticContext implements StaticContext {
protected Shadow staticContextData;
private Map<String, StaticContextCache> retValCache =
new HashMap<String, StaticContextCache>();
protected <T extends Shadow> void registerCache(
String methodName, Class<T> keyCacheClass) {
retValCache.put(methodName, new StaticContextCache(keyCacheClass));
}
public StaticContextCache getRetValCache(String method) {
return retValCache.get(method);
}
public void staticContextData(Shadow sa) {
staticContextData = sa;
......
package ch.usi.dag.disl.staticcontext;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.objectweb.asm.tree.AbstractInsnNode;
import ch.usi.dag.disl.staticcontext.customdatacache.MethodCDCache;
import ch.usi.dag.disl.snippet.Shadow;
import ch.usi.dag.disl.util.AsmHelper;
import ch.usi.dag.disl.util.cfg.CtrlFlowGraph;
public class BasicBlockStaticContext extends
MethodCDCache<CtrlFlowGraph> {
public class BasicBlockStaticContext extends AbstractStaticContext {
private Map<String, CtrlFlowGraph> cache = new HashMap<String, CtrlFlowGraph>();
protected CtrlFlowGraph customData;
public void staticContextData(Shadow sa) {
super.staticContextData(sa);
String key = staticContextData.getClassNode().name
+ staticContextData.getMethodNode().name
+ staticContextData.getMethodNode().desc;
customData = cache.get(key);
if (customData == null) {
customData = produceCustomData();
cache.put(key, customData);
}
}
public int getTotBBs() {
return customData.getNodes().size();
}
......@@ -40,7 +61,6 @@ public class BasicBlockStaticContext extends
return customData.getIndex(staticContextData.getRegionStart());
}
@Override
protected CtrlFlowGraph produceCustomData() {
return new CtrlFlowGraph(staticContextData.getMethodNode());
}
......
......@@ -2,47 +2,10 @@ package ch.usi.dag.disl.staticcontext;
import org.objectweb.asm.Opcodes;
import ch.usi.dag.disl.staticcontext.cache.ClassCache;
import ch.usi.dag.disl.staticcontext.cache.MethodCache;
import ch.usi.dag.disl.util.Constants;
public class MethodStaticContext extends AbstractStaticContext {
public MethodStaticContext() {
registerCache("thisClassName", ClassCache.class);
registerCache("thisClassOuterClass", ClassCache.class);
registerCache("thisClassOuterMethod", ClassCache.class);
registerCache("thisClassOuterMethodDesc", ClassCache.class);
registerCache("thisClassSignature", ClassCache.class);
registerCache("thisClassSourceFile", ClassCache.class);
registerCache("thisClassSuperName", ClassCache.class);
registerCache("thisClassVersion", ClassCache.class);
registerCache("thisClassName", ClassCache.class);
registerCache("isClassAbstract", ClassCache.class);
registerCache("isClassAnnotation", ClassCache.class);
registerCache("isClassEnum", ClassCache.class);
registerCache("isClassFinal", ClassCache.class);
registerCache("isClassInterface", ClassCache.class);
registerCache("isClassPrivate", ClassCache.class);
registerCache("isClassProtected", ClassCache.class);
registerCache("isClassPublic", ClassCache.class);
registerCache("isClassSynthetic", ClassCache.class);
registerCache("thisMethodName", MethodCache.class);
registerCache("thisMethodFullName", MethodCache.class);
registerCache("thisMethodDescriptor", MethodCache.class);
registerCache("thisMethodSignature", MethodCache.class);
registerCache("isMethodBridge", MethodCache.class);
registerCache("isMethodFinal", MethodCache.class);
registerCache("isMethodPrivate", MethodCache.class);
registerCache("isMethodProtected", MethodCache.class);
registerCache("isMethodPublic", MethodCache.class);
registerCache("isMethodStatic", MethodCache.class);
registerCache("isMethodSynchronized", MethodCache.class);
registerCache("isMethodVarArgs", MethodCache.class);
}
// *** Class ***
public String thisClassName() {
......
package ch.usi.dag.disl.staticcontext.cache;
public interface CacheableStaticContext {
public StaticContextCache getRetValCache(String method);
}
package ch.usi.dag.disl.staticcontext.cache;
import ch.usi.dag.disl.snippet.Shadow;
public class ClassCache extends Shadow {
public ClassCache(Shadow sa) {
super(sa);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((classNode == null) ? 0 : classNode.hashCode());
// ignored for this cache type
//result = prime * result + ((methodNode == null) ? 0 : methodNode.hashCode());
// ignored for this cache type
//result = prime * result + ((snippet == null) ? 0 : snippet.hashCode());
// ignored for this cache type
//result = prime * result + ((marking == null) ? 0 : marking.hashCode());
// ignored for this cache type
//result = prime * result + ((markedRegion == null) ? 0 : markedRegion.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ClassCache other = (ClassCache) obj;
if (classNode == null) {
if (other.classNode != null)
return false;
} else if (!classNode.equals(other.classNode))
return false;
// ignored for this cache type
//if (methodNode == null) {
// if (other.methodNode != null)
// return false;
//} else if (!methodNode.equals(other.methodNode))
// return false;
// ignored for this cache type
//if (snippet == null) {
// if (other.snippet != null)
// return false;
//} else if (!snippet.equals(other.snippet))
// return false;
// ignored for this cache type
//if (marking == null) {
// if (other.marking != null)
// return false;
//} else if (!marking.equals(other.marking))
// return false;
// ignored for this cache type
//if (markedRegion == null) {
// if (other.markedRegion != null)
// return false;
//} else if (!markedRegion.equals(other.markedRegion))
// return false;
return true;
}
}
package ch.usi.dag.disl.staticcontext.cache;
import ch.usi.dag.disl.snippet.Shadow;
public class MethodCache extends Shadow {
public MethodCache(Shadow sa) {
super(sa);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((classNode == null) ? 0 : classNode.hashCode());
result = prime * result
+ ((methodNode == null) ? 0 : methodNode.hashCode());
// ignored for this cache type
//result = prime * result + ((snippet == null) ? 0 : snippet.hashCode());
// ignored for this cache type
//result = prime * result + ((marking == null) ? 0 : marking.hashCode());
// ignored for this cache type
//result = prime * result + ((markedRegion == null) ? 0 : markedRegion.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
MethodCache other = (MethodCache) obj;
if (classNode == null) {
if (other.classNode != null)
return false;
} else if (!classNode.equals(other.classNode))
return false;
if (methodNode == null) {
if (other.methodNode != null)
return false;
} else if (!methodNode.equals(other.methodNode))
return false;
// ignored for this cache type
//if (snippet == null) {
// if (other.snippet != null)
// return false;
//} else if (!snippet.equals(other.snippet))
// return false;
// ignored for this cache type
//if (marking == null) {
// if (other.marking != null)
// return false;
//} else if (!marking.equals(other.marking))
// return false;
// ignored for this cache type
//if (markedRegion == null) {
// if (other.markedRegion != null)
// return false;
//} else if (!markedRegion.equals(other.markedRegion))
// return false;
return true;
}
}
package ch.usi.dag.disl.staticcontext.cache;
import ch.usi.dag.disl.snippet.Shadow;
public class SnippetCache extends Shadow {
public SnippetCache(Shadow sa) {
super(sa);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((classNode == null) ? 0 : classNode.hashCode());
result = prime * result
+ ((methodNode == null) ? 0 : methodNode.hashCode());
result = prime * result + ((snippet == null) ? 0 : snippet.hashCode());
// ignored for this cache type
//result = prime * result + ((marking == null) ? 0 : marking.hashCode());
// ignored for this cache type
//result = prime * result + ((markedRegion == null) ? 0 : markedRegion.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SnippetCache other = (SnippetCache) obj;
if (classNode == null) {
if (other.classNode != null)
return false;
} else if (!classNode.equals(other.classNode))
return false;
if (methodNode == null) {
if (other.methodNode != null)
return false;
} else if (!methodNode.equals(other.methodNode))
return false;
if (snippet == null) {
if (other.snippet != null)
return false;
} else if (!snippet.equals(other.snippet))
return false;
// ignored for this cache type
//if (marking == null) {
// if (other.marking != null)
// return false;
//} else if (!marking.equals(other.marking))
// return false;
// ignored for this cache type
//if (markedRegion == null) {
// if (other.markedRegion != null)
// return false;
//} else if (!markedRegion.equals(other.markedRegion))
// return false;
return true;
}
}
package ch.usi.dag.disl.staticcontext.cache;
import java.util.HashMap;
import java.util.Map;
import ch.usi.dag.disl.exception.ReflectionException;
import ch.usi.dag.disl.snippet.Shadow;
import ch.usi.dag.disl.util.ReflectionHelper;
public class StaticContextCache {
private Class<? extends Shadow> cacheClass;
// this could be Map<Shadow, Object> but
// we don't have to cast it for usage if we put there object
// - valid class is checked already in constructor
private Map<Object, Object> cachedData = new HashMap<Object, Object>();
public StaticContextCache(Class<? extends Shadow> cacheClass) {
this.cacheClass = cacheClass;
}
private Object createCacheObject(Shadow sa)
throws ReflectionException {
// create cache object using "copy" constructor
return ReflectionHelper.createInstance(cacheClass, sa);
}
public Object getCachedResult(Shadow sa)
throws ReflectionException {
return cachedData.get(createCacheObject(sa));
}
public void cacheResult(Shadow sa, Object result)
throws ReflectionException {
cachedData.put(createCacheObject(sa), result);
}
}
package ch.usi.dag.disl.staticcontext.customdatacache;
public abstract class ClassCDCache<V> extends CustomDataCache<String, V> {
@Override
protected final String key() {
return staticContextData.getClassNode().name;
}
}
package ch.usi.dag.disl.staticcontext.customdatacache;
import java.util.HashMap;
import java.util.Map;
import ch.usi.dag.disl.snippet.Shadow;
import ch.usi.dag.disl.staticcontext.AbstractStaticContext;
public abstract class CustomDataCache<K, V> extends AbstractStaticContext {
private Map<K, V> cache = new HashMap<K, V>();
protected V customData;
public void staticContextData(Shadow sa) {
super.staticContextData(sa);
customData = cache.get(key());
if (customData == null) {
customData = produceCustomData();
cache.put(key(), customData);
}
}
protected abstract K key();
protected abstract V produceCustomData();
}
package ch.usi.dag.disl.staticcontext.customdatacache;
public abstract class MethodCDCache<V> extends CustomDataCache<String, V> {
@Override
protected final String key() {
return staticContextData.getClassNode().name
+ staticContextData.getMethodNode().name
+ staticContextData.getMethodNode().desc;
}
}
......@@ -15,8 +15,6 @@ import ch.usi.dag.disl.snippet.ProcInvocation;
import ch.usi.dag.disl.snippet.Shadow;
import ch.usi.dag.disl.snippet.Snippet;
import ch.usi.dag.disl.staticcontext.StaticContext;
import ch.usi.dag.disl.staticcontext.cache.CacheableStaticContext;
import ch.usi.dag.disl.staticcontext.cache.StaticContextCache;
import ch.usi.dag.disl.util.Constants;
public class SCGenerator {
......@@ -175,33 +173,6 @@ public class SCGenerator {
Shadow shadow) throws StaticContextGenException,
ReflectionException {
// NOTE: default cache
// some default cache is not needed because for each marked region,
// the computation is called only once
StaticContextCache cache = null;
// cacheable static context data - try to query cache first
if(scInst instanceof CacheableStaticContext) {
CacheableStaticContext cacheableSC =
(CacheableStaticContext) scInst;
cache = cacheableSC.getRetValCache(method.getName());
// static context has cache for this method
if(cache != null) {
Object result = cache.getCachedResult(shadow);
// cache is valid - return cache hit
if(result != null) {
return result;
}
}
}
// if cache wasn't hit...
try {
// populate static context instance with data
......@@ -210,11 +181,6 @@ public class SCGenerator {
// get static data by invoking static context method
Object result = method.invoke(scInst);
// cache result if applicable
if (cache != null) {
cache.cacheResult(shadow, result);
}
return result;
} catch (Exception e) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment