Commit a56a3e2b authored by Lukáš Marek's avatar Lukáš Marek
Browse files

Introduced guard method caching

parent 7d86987b
......@@ -165,8 +165,9 @@ public class UnprocessedCode {
|| methodReturn.equals(Type.FLOAT_TYPE)
|| methodReturn.equals(Type.INT_TYPE)
|| methodReturn.equals(Type.LONG_TYPE)
|| methodReturn.equals(Type.SHORT_TYPE) || methodReturn
.equals(Type.getType(String.class)))) {
|| methodReturn.equals(Type.SHORT_TYPE)
|| methodReturn.equals(Type.getType(String.class))
)) {
throw new StaticContextGenException("Static context method "
+ methodInstr.name + " in the class " + methodInstr.owner
......
......@@ -7,14 +7,15 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import ch.usi.dag.disl.annotation.GuardMethod;
import ch.usi.dag.disl.exception.DiSLFatalException;
import ch.usi.dag.disl.exception.GuardException;
import ch.usi.dag.disl.exception.GuardRuntimeException;
import ch.usi.dag.disl.exception.ReflectionException;
import ch.usi.dag.disl.guardcontext.GuardContext;
import ch.usi.dag.disl.processorcontext.ArgumentContext;
import ch.usi.dag.disl.runtimecache.StConCache;
import ch.usi.dag.disl.resolver.GuardMethod;
import ch.usi.dag.disl.resolver.GuardResolver;
import ch.usi.dag.disl.resolver.StConResolver;
import ch.usi.dag.disl.snippet.Shadow;
import ch.usi.dag.disl.staticcontext.StaticContext;
import ch.usi.dag.disl.util.ReflectionHelper;
......@@ -28,72 +29,72 @@ public abstract class GuardHelper {
return null;
}
Method guardMethod = findGuardMethod(guardClass);
GuardMethod guardMethod =
GuardResolver.getInstance().getGuardMethod(guardClass);
validateGuardMethod(guardMethod, validArgs);
return guardMethod;
return guardMethod.getMethod();
}
// TODO ! guard - introduce caching for guardClass -> guardMethod using singleton hash map
// GuardMethod will not contain only method object but also all contexts set - for quick validation
private static Method findGuardMethod(Class<?> guardClass)
throws GuardException {
Method guardMethod = null;
private static void validateGuardMethod(GuardMethod guardMethod,
Set<Class<?>> validArgs) throws GuardException {
// check all methods
for(Method method : guardClass.getMethods()) {
// quick validation
if(guardMethod.getArgTypes() != null) {
if(method.isAnnotationPresent(GuardMethod.class)) {
// detect multiple annotations
if(guardMethod != null) {
throw new GuardException("Detected several "
+ GuardMethod.class.getName()
+ " annotations on guard class "
+ guardClass.getName());
}
guardMethod = method;
// only valid argument types are in the method - ok
if(validArgs.containsAll(guardMethod.getArgTypes())) {
return;
}
// we have some additional argument types then only valid ones
// prepare invalid argument type set
Set<Class<?>> invalidArgTypes =
new HashSet<Class<?>>(guardMethod.getArgTypes());
invalidArgTypes.removeAll(validArgs);
// construct the error massage
throw new GuardException("Guard "
+ guardMethod.getMethod().getDeclaringClass().getName()
+ " is using interface "
+ invalidArgTypes.iterator().next().getName()
+ " not allowed in this particular case (misused guard??)");
}
// detect no annotation
if(guardMethod == null) {
throw new GuardException("No "
+ GuardMethod.class.getName()
+ " annotation on guard class "
+ guardClass.getName());
}
return guardMethod;
}
private static void validateGuardMethod(Method guardMethod,
Set<Class<?>> validArgs) throws GuardException {
// validate properly
Method method = guardMethod.getMethod();
String guardMethodName = guardMethod.getDeclaringClass().getName()
+ "." + guardMethod.getName();
String guardMethodName = method.getDeclaringClass().getName()
+ "." + method.getName();
if(! guardMethod.getReturnType().equals(boolean.class)) {
if(! method.getReturnType().equals(boolean.class)) {
throw new GuardException("Guard method " + guardMethodName
+ " should return boolean type");
}
if(! Modifier.isStatic(guardMethod.getModifiers())) {
if(! Modifier.isStatic(method.getModifiers())) {
throw new GuardException("Guard method " + guardMethodName
+ " should be static");
}
// remember argument types for quick validation
Set<Class<?>> argTypes = new HashSet<Class<?>>();
// for all arguments
for(Class<?> argType : guardMethod.getParameterTypes()) {
for(Class<?> argType : method.getParameterTypes()) {
// throws exception in the case of invalidity
validateArgument(guardMethodName, argType, validArgs);
argTypes.add(validateArgument(guardMethodName, argType, validArgs));
}
// set argument types for quick validation
guardMethod.setArgTypes(argTypes);
}
private static void validateArgument(String guardMethodName,
private static Class<?> validateArgument(String guardMethodName,
Class<?> argClass, Set<Class<?>> validArgClasses)
throws GuardException {
......@@ -102,13 +103,13 @@ public abstract class GuardHelper {
// valid
if(argClass.equals(allowedInterface)) {
return;
return allowedInterface;
}
// valid - note that static context has to be implemented
if(allowedInterface.equals(StaticContext.class) && ReflectionHelper
.implementsInterface(argClass, allowedInterface)) {
return;
return allowedInterface;
}
}
......@@ -116,7 +117,8 @@ public abstract class GuardHelper {
StringBuilder sb = new StringBuilder("Guard argument "
+ argClass.getName()
+ " in " + guardMethodName
+ " does not implement any of the allowed interfaces: ");
+ " is not in the set of allowed interfaces"
+ " (misused guard??): ");
for(Class<?> allowedInterface : validArgClasses) {
......@@ -179,7 +181,8 @@ public abstract class GuardHelper {
ArgumentContext ac) throws GuardException {
// find and validate method first
Method guardMethod = findGuardMethod(guardClass);
GuardMethod guardMethod =
GuardResolver.getInstance().getGuardMethod(guardClass);
Set<Class<?>> validationSet;
......@@ -193,7 +196,8 @@ public abstract class GuardHelper {
validateGuardMethod(guardMethod, validationSet);
return invokeGuardMethod(guardMethod, shadow, ac);
// invoke method
return invokeGuardMethod(guardMethod.getMethod(), shadow, ac);
}
......@@ -236,7 +240,7 @@ public abstract class GuardHelper {
try {
// get static context
StaticContext scInst = StConCache.getInstance()
StaticContext scInst = StConResolver.getInstance()
.getStaticContextInstance(argType);
// populate with data
......
package ch.usi.dag.disl.resolver;
import java.lang.reflect.Method;
import java.util.Set;
public class GuardMethod {
private Method method;
private Set<Class<?>> argTypes;
public GuardMethod(Method method) {
super();
this.method = method;
}
public Method getMethod() {
return method;
}
public Set<Class<?>> getArgTypes() {
return argTypes;
}
public void setArgTypes(Set<Class<?>> argTypes) {
this.argTypes = argTypes;
}
}
\ No newline at end of file
package ch.usi.dag.disl.resolver;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import ch.usi.dag.disl.exception.GuardException;
public class GuardResolver {
private static GuardResolver instance = null;
// Guard to guard method map
private Map<Class<?>, GuardMethod> guardToMethod =
new HashMap<Class<?>, GuardMethod>();
public synchronized GuardMethod getGuardMethod(
Class<?> guardClass) throws GuardException {
GuardMethod guardMethod = guardToMethod.get(guardClass);
// resolved from cache
if(guardMethod != null) {
return guardMethod;
}
// no cache hit
// check all methods
for(Method method : guardClass.getMethods()) {
if(method.isAnnotationPresent(
ch.usi.dag.disl.annotation.GuardMethod.class)) {
// detect multiple annotations
if(guardMethod != null) {
throw new GuardException("Detected several "
+ GuardMethod.class.getName()
+ " annotations on guard class "
+ guardClass.getName());
}
guardMethod = new GuardMethod(method);
}
}
// detect no annotation
if(guardMethod == null) {
throw new GuardException("No "
+ ch.usi.dag.disl.annotation.GuardMethod.class.getName()
+ " annotation on guard class "
+ guardClass.getName());
}
// put into cache
guardToMethod.put(guardClass, guardMethod);
return guardMethod;
}
public static synchronized GuardResolver getInstance() {
if (instance == null) {
instance = new GuardResolver();
}
return instance;
}
}
package ch.usi.dag.disl.runtimecache;
package ch.usi.dag.disl.resolver;
import java.util.HashMap;
import java.util.Map;
......@@ -8,17 +8,19 @@ import ch.usi.dag.disl.staticcontext.StaticContext;
import ch.usi.dag.disl.util.ReflectionHelper;
public class StConCache {
public class StConResolver {
// NOTE: This is internal DiSL cache. For user static context cache see
// ch.usi.dag.disl.staticcontext.cache.StaticContextCache
private static StConResolver instance = null;
// list of static context instances
// validity of an instance is for whole instrumentation run
// instances are created lazily when needed
Map<Class<?>, Object> staticContextInstances =
private Map<Class<?>, Object> staticContextInstances =
new HashMap<Class<?>, Object>();
public synchronized StaticContext getStaticContextInstance(
Class<?> staticContextClass) throws ReflectionException {
......@@ -38,12 +40,10 @@ public class StConCache {
return (StaticContext) scInst;
}
private static StConCache instance = null;
public static synchronized StConCache getInstance() {
public static synchronized StConResolver getInstance() {
if (instance == null) {
instance = new StConCache();
instance = new StConResolver();
}
return instance;
}
......
package ch.usi.dag.disl.runtimecache;
public class GrdCache {
// TODO ! guard - cache
}
......@@ -10,7 +10,7 @@ import ch.usi.dag.disl.coderep.StaticContextMethod;
import ch.usi.dag.disl.exception.ReflectionException;
import ch.usi.dag.disl.exception.StaticContextGenException;
import ch.usi.dag.disl.processor.ProcMethod;
import ch.usi.dag.disl.runtimecache.StConCache;
import ch.usi.dag.disl.resolver.StConResolver;
import ch.usi.dag.disl.snippet.ProcInvocation;
import ch.usi.dag.disl.snippet.Shadow;
import ch.usi.dag.disl.snippet.Snippet;
......@@ -154,7 +154,7 @@ public class SCGenerator {
// get static context instance
StaticContext scInst =
StConCache.getInstance().getStaticContextInstance(
StConResolver.getInstance().getStaticContextInstance(
stConMth.getReferencedClass());
// populate static context instance with data
......
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