Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDennis Wagelaar2017-04-27 09:17:29 -0400
committerDennis Wagelaar2017-04-27 09:17:29 -0400
commitc8f39fd70b0f8d5f50fdc789cd0148da88e21483 (patch)
tree9526f0e4c248d18d111faaf5bd062124d48f18e8 /plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse
parentfc7cf94070cba2716d4967f636b26071d25ae56c (diff)
downloadorg.eclipse.atl-c8f39fd70b0f8d5f50fdc789cd0148da88e21483.tar.gz
org.eclipse.atl-c8f39fd70b0f8d5f50fdc789cd0148da88e21483.tar.xz
org.eclipse.atl-c8f39fd70b0f8d5f50fdc789cd0148da88e21483.zip
488223: EMFTVMUtil#getMethodSignature() causes method lookup collisions
Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=488223
Diffstat (limited to 'plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse')
-rw-r--r--plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/EMFTVMUtil.java402
-rw-r--r--plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/MethodSignature.java48
2 files changed, 270 insertions, 180 deletions
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/EMFTVMUtil.java b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/EMFTVMUtil.java
index dc67540c..67f09e76 100644
--- a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/EMFTVMUtil.java
+++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/EMFTVMUtil.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011-2015 Dennis Wagelaar, Vrije Universiteit Brussel.
+ * Copyright (c) 2011-2017 Dennis Wagelaar, Vrije Universiteit Brussel.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -17,6 +17,7 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
+import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -25,7 +26,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
@@ -34,6 +34,8 @@ import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.regex.Pattern;
import org.eclipse.emf.common.util.EList;
@@ -157,7 +159,12 @@ public final class EMFTVMUtil {
* @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
* @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
*/
- private static final Map<Class<?>, Map<MethodSignature, Method>> METHOD_CACHE = new WeakHashMap<Class<?>, Map<MethodSignature, Method>>();
+ private static final ConcurrentMap<MethodSignature, WeakReference<Method>> METHOD_CACHE = new ConcurrentHashMap<MethodSignature, WeakReference<Method>>();
+
+ /**
+ * Represents the <code>null</code> method reference for the {@link #METHOD_CACHE}.
+ */
+ private static final WeakReference<Method> NULL_METHOD_REFERENCE = new WeakReference<Method>(null);
/**
* Cache used to store the found root methods for native Java methods.
@@ -167,7 +174,8 @@ public final class EMFTVMUtil {
* @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
* @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
*/
- private static final Map<Method, Method> ROOT_METHOD_CACHE = Collections.synchronizedMap(new WeakHashMap<Method, Method>());
+ private static final Map<Method, WeakReference<Method>> ROOT_METHOD_CACHE = Collections
+ .synchronizedMap(new WeakHashMap<Method, WeakReference<Method>>());
/**
* Singleton {@link RegistryTypeSwitch} instance.
@@ -178,6 +186,11 @@ public final class EMFTVMUtil {
private static Metamodel emfTvmMetamodel;
private static Metamodel traceMetamodel;
+ private static volatile int MethodCacheAccesses;
+ private static volatile int MethodCacheHits;
+ private static volatile int RootMethodCacheAccesses;
+ private static volatile int RootMethodCacheHits;
+
/**
* Not used.
*/
@@ -1400,7 +1413,7 @@ public final class EMFTVMUtil {
* The class of the method
* @param opname
* The method name
- * @param argumentTypes
+ * @param argTypes
* The types of all arguments
* @param isStatic
* Whether to look for a static method or not
@@ -1410,18 +1423,108 @@ public final class EMFTVMUtil {
* @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
* @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
*/
- // TODO implement multi-methods in ExecEnv
public static Method findNativeMethod(final Class<?> context, final String opname, final Class<?>[] argTypes, final boolean isStatic) {
if (context == Void.TYPE) {
return null; // Java methods cannot be invoked on null, or defined on Void
}
- final MethodSignature sig = getMethodSignature(opname, argTypes, isStatic);
- Method ret = findCachedMethod(context, sig);
- if (ret != null || hasCachedMethod(context, sig)) {
+ final MethodSignature sig = getMethodSignature(context, opname, argTypes, isStatic);
+ MethodCacheAccesses++;
+ final WeakReference<Method> methodRef = METHOD_CACHE.get(sig);
+ final Method ret = methodRef != null ? methodRef.get() : null;
+ if (ret != null || methodRef == NULL_METHOD_REFERENCE) {
+ MethodCacheHits++;
+ return methodRef.get();
+ }
+
+ return findNativeMethodInternal(context, opname, argTypes, isStatic, sig);
+ }
+
+ /**
+ * Looks for a native Java method.
+ *
+ * @param context
+ * The class of the method
+ * @param opname
+ * The method name
+ * @param argumentType
+ * The type of the argument
+ * @param isStatic
+ * Whether to look for a static method or not
+ * @return the method if found, null otherwise
+ * @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic Jouault</a>
+ * @author <a href="mailto:william.piers@obeo.fr">William Piers</a>
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ * @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
+ */
+ public static Method findNativeMethod(final Class<?> context, final String opname, final Class<?> argType, final boolean isStatic) {
+ if (context == Void.TYPE) {
+ return null; // Java methods cannot be invoked on null, or defined on Void
+ }
+
+ final MethodSignature sig = getMethodSignature(context, opname, argType, isStatic);
+ MethodCacheAccesses++;
+ final WeakReference<Method> methodRef = METHOD_CACHE.get(sig);
+ final Method ret = methodRef != null ? methodRef.get() : null;
+ if (ret != null || methodRef == NULL_METHOD_REFERENCE) {
+ MethodCacheHits++;
return ret;
}
+ return findNativeMethodInternal(context, opname, argType, isStatic, sig);
+ }
+
+ /**
+ * Looks for a native Java method without arguments.
+ *
+ * @param context
+ * The class of the method
+ * @param opname
+ * The method name
+ * @param isStatic
+ * Whether to look for a static method or not
+ * @return the method if found, null otherwise
+ * @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic Jouault</a>
+ * @author <a href="mailto:william.piers@obeo.fr">William Piers</a>
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ * @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
+ */
+ public static Method findNativeMethod(final Class<?> context, final String opname, final boolean isStatic) {
+ if (context == Void.TYPE) {
+ return null; // Java methods cannot be invoked on null, or defined on Void
+ }
+
+ final MethodSignature sig = getMethodSignature(context, opname, isStatic);
+ MethodCacheAccesses++;
+ final WeakReference<Method> methodRef = METHOD_CACHE.get(sig);
+ Method ret = methodRef != null ? methodRef.get() : null;
+ if (ret != null || methodRef == NULL_METHOD_REFERENCE) {
+ MethodCacheHits++;
+ return ret;
+ }
+
+ return findNativeMethodInternal(context, opname, isStatic, sig);
+ }
+
+ /**
+ * Looks for a native Java method.
+ *
+ * @param context
+ * The class of the method
+ * @param opname
+ * The method name
+ * @param argTypes
+ * The types of all arguments
+ * @param isStatic
+ * Whether to look for a static method or not
+ * @param sig
+ * the method signature
+ * @return the method if found, null otherwise
+ */
+ private static Method findNativeMethodInternal(final Class<?> context, final String opname,
+ final Class<?>[] argTypes, final boolean isStatic, final MethodSignature sig) {
+ Method ret = null;
+
final Method[] methods = context.getDeclaredMethods();
METHODS: for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
@@ -1430,24 +1533,9 @@ public final class EMFTVMUtil {
if (pts.length == argTypes.length) {
boolean ok = true;
for (int j = 0; (j < pts.length) && ok; j++) {
- if (argTypes[j] == EnumLiteral.class && Enumerator.class.isAssignableFrom(pts[j])) {
- continue;
- }
- if (!pts[j].isAssignableFrom(argTypes[j])) {
- if (pts[j] == boolean.class)
- ok = argTypes[j] == Boolean.class;
- else if (pts[j] == int.class)
- ok = argTypes[j] == Integer.class;
- else if (pts[j] == char.class)
- ok = argTypes[j] == Character.class;
- else if (pts[j] == long.class)
- ok = argTypes[j] == Long.class;
- else if (pts[j] == float.class)
- ok = argTypes[j] == Float.class;
- else if (pts[j] == double.class)
- ok = argTypes[j] == Double.class;
- else
- ok = argTypes[j] == Void.TYPE; // any type
+ if (!checkParameterType(argTypes[j], pts[j])) {
+ ok = false;
+ break;
}
}
if (ok) {
@@ -1457,13 +1545,13 @@ public final class EMFTVMUtil {
}
}
}
-
+
if ((ret == null) && !isStatic && (context.getSuperclass() != null)) {
- ret = findNativeMethod(context.getSuperclass(), opname, argTypes, isStatic);
+ ret = findNativeMethodInternal(context.getSuperclass(), opname, argTypes, isStatic, sig);
+ } else {
+ METHOD_CACHE.put(sig, ret != null ? new WeakReference<Method>(ret) : NULL_METHOD_REFERENCE);
}
-
- cacheMethod(context, sig, ret);
-
+
return ret;
}
@@ -1474,70 +1562,38 @@ public final class EMFTVMUtil {
* The class of the method
* @param opname
* The method name
- * @param argumentType
+ * @param argType
* The type of the argument
* @param isStatic
* Whether to look for a static method or not
+ * @param sig
+ * the method signature
* @return the method if found, null otherwise
- * @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic Jouault</a>
- * @author <a href="mailto:william.piers@obeo.fr">William Piers</a>
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- * @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
*/
- // TODO implement multi-methods in ExecEnv
- public static Method findNativeMethod(final Class<?> context, final String opname, final Class<?> argType, final boolean isStatic) {
- if (context == Void.TYPE) {
- return null; // Java methods cannot be invoked on null, or defined on Void
- }
-
- final MethodSignature sig = getMethodSignature(opname, argType, isStatic);
- Method ret = findCachedMethod(context, sig);
- if (ret != null || hasCachedMethod(context, sig)) {
- return ret;
- }
-
+ private static Method findNativeMethodInternal(final Class<?> context, final String opname, final Class<?> argType,
+ final boolean isStatic, final MethodSignature sig) {
+ Method ret = null;
+
final Method[] methods = context.getDeclaredMethods();
METHODS: for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
if ((Modifier.isStatic(method.getModifiers()) == isStatic) && method.getName().equals(opname)) {
Class<?>[] pts = method.getParameterTypes();
if (pts.length == 1) {
- Class<?> pt = pts[0];
- if (argType == EnumLiteral.class && Enumerator.class.isAssignableFrom(pt)) {
- ret = method;
- break METHODS;
- }
- boolean ok = true;
- if (!pt.isAssignableFrom(argType)) {
- if (pt == boolean.class)
- ok = argType == Boolean.class;
- else if (pt == int.class)
- ok = argType == Integer.class;
- else if (pt == char.class)
- ok = argType == Character.class;
- else if (pt == long.class)
- ok = argType == Long.class;
- else if (pt == float.class)
- ok = argType == Float.class;
- else if (pt == double.class)
- ok = argType == Double.class;
- else
- ok = argType == Void.TYPE; // any type
- }
- if (ok) {
+ if (checkParameterType(argType, pts[0])) {
ret = method;
break METHODS;
}
}
}
}
-
+
if ((ret == null) && !isStatic && (context.getSuperclass() != null)) {
- ret = findNativeMethod(context.getSuperclass(), opname, argType, isStatic);
+ ret = findNativeMethodInternal(context.getSuperclass(), opname, argType, isStatic, sig);
+ } else {
+ METHOD_CACHE.put(sig, ret != null ? new WeakReference<Method>(ret) : NULL_METHOD_REFERENCE);
}
-
- cacheMethod(context, sig, ret);
-
+
return ret;
}
@@ -1550,22 +1606,13 @@ public final class EMFTVMUtil {
* The method name
* @param isStatic
* Whether to look for a static method or not
+ * @param sig
+ * the method signature
* @return the method if found, null otherwise
- * @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic Jouault</a>
- * @author <a href="mailto:william.piers@obeo.fr">William Piers</a>
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- * @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
*/
- public static Method findNativeMethod(final Class<?> context, final String opname, final boolean isStatic) {
- if (context == Void.TYPE) {
- return null; // Java methods cannot be invoked on null, or defined on Void
- }
-
- final MethodSignature sig = getMethodSignature(opname, isStatic);
- Method ret = findCachedMethod(context, sig);
- if (ret != null || hasCachedMethod(context, sig)) {
- return ret;
- }
+ private static Method findNativeMethodInternal(final Class<?> context, final String opname, final boolean isStatic,
+ final MethodSignature sig) {
+ Method ret = null;
final Method[] methods = context.getDeclaredMethods();
METHODS: for (int i = 0; i < methods.length; i++) {
@@ -1579,15 +1626,53 @@ public final class EMFTVMUtil {
}
if ((ret == null) && !isStatic && (context.getSuperclass() != null)) {
- ret = findNativeMethod(context.getSuperclass(), opname, isStatic);
+ ret = findNativeMethodInternal(context.getSuperclass(), opname, isStatic, sig);
+ } else {
+ METHOD_CACHE.put(sig, ret != null ? new WeakReference<Method>(ret) : NULL_METHOD_REFERENCE);
}
- cacheMethod(context, sig, ret);
-
return ret;
}
/**
+ * Checks whether the parameter type is compatible with the argument type
+ *
+ * @param argType
+ * the invocation argument type
+ * @param pt
+ * the method parameter type
+ * @return <code>true</code> if the parameter type is compatible,
+ * <code>false</code> otherwise
+ */
+ private static boolean checkParameterType(final Class<?> argType, final Class<?> pt) {
+ if (argType == EnumLiteral.class && Enumerator.class.isAssignableFrom(pt)) {
+ return true;
+ }
+ if (pt.isAssignableFrom(argType)) {
+ return true;
+ }
+ if (pt == boolean.class){
+ return argType == Boolean.class;
+ }
+ if (pt == int.class) {
+ return argType == Integer.class;
+ }
+ if (pt == char.class) {
+ return argType == Character.class;
+ }
+ if (pt == long.class) {
+ return argType == Long.class;
+ }
+ if (pt == float.class) {
+ return argType == Float.class;
+ }
+ if (pt == double.class) {
+ return argType == Double.class;
+ }
+ return argType == Void.TYPE; // any type
+ }
+
+ /**
* Compares 0-parameter <code>op</code> to <code>method</code>.
*
* @param op
@@ -1951,113 +2036,71 @@ public final class EMFTVMUtil {
}
/**
- * Returns <code>true</code> if the method cache contains the given caller and signature.
- *
- * @param caller
- * The class of the method
- * @param signature
- * The method signature
- * @return <code>true</code> if the method cache contains the given caller and signature
- */
- private static boolean hasCachedMethod(final Class<?> caller, final MethodSignature signature) {
- synchronized (METHOD_CACHE) {
- final Map<MethodSignature, Method> sigMap = METHOD_CACHE.get(caller);
- return (sigMap != null) && sigMap.containsKey(signature);
- }
- }
-
- /**
- * Find a method in the cache.
- *
- * @param caller
- * The class of the method
- * @param signature
- * The method signature
- * @return the method
- * @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic Jouault</a>
- * @author <a href="mailto:william.piers@obeo.fr">William Piers</a>
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- * @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
- */
- private static Method findCachedMethod(final Class<?> caller, final MethodSignature signature) {
- synchronized (METHOD_CACHE) {
- final Map<MethodSignature, Method> sigMap = METHOD_CACHE.get(caller);
- return (sigMap != null) ? sigMap.get(signature) : null;
- }
- }
-
- /**
- * Stores a method in a cache.
- *
- * @param caller
- * The class of the method
- * @param signature
- * The method signature
- * @param method
- * The method to store
- * @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic Jouault</a>
- * @author <a href="mailto:william.piers@obeo.fr">William Piers</a>
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- * @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
- */
- private static void cacheMethod(final Class<?> caller, final MethodSignature signature, final Method method) {
- synchronized (METHOD_CACHE) {
- Map<MethodSignature, Method> sigMap = METHOD_CACHE.get(caller);
- if (sigMap == null) {
- sigMap = new HashMap<MethodSignature, Method>();
- METHOD_CACHE.put(caller, sigMap);
- }
- sigMap.put(signature, method);
- }
- }
-
- /**
* Generates a signature to store methods.
*
+ * @param context
+ * the method declaring class
* @param name
+ * the method name
* @param argumentTypes
+ * the argument types
* @param isStatic
+ * whether the method is static
* @return The method signature
- * @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic Jouault</a>
+ * @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic
+ * Jouault</a>
* @author <a href="mailto:william.piers@obeo.fr">William Piers</a>
* @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
* @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
*/
- private static MethodSignature getMethodSignature(final String name, final Class<?>[] argumentTypes,
- final boolean isStatic) {
- return new MethodSignature(name, argumentTypes, isStatic);
+ private static MethodSignature getMethodSignature(final Class<?> context, final String name,
+ final Class<?>[] argumentTypes, final boolean isStatic) {
+ return new MethodSignature(context, name, argumentTypes, isStatic);
}
/**
* Generates a signature to store methods.
*
+ * @param context
+ * the method declaring class
* @param name
+ * the method name
* @param argumentType
+ * the (single) argument type
+ * @param isStatic
+ * whether the method is static
* @param isStatic
* @return The method signature
- * @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic Jouault</a>
+ * @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic
+ * Jouault</a>
* @author <a href="mailto:william.piers@obeo.fr">William Piers</a>
* @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
* @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
*/
- private static MethodSignature getMethodSignature(final String name, final Class<?> argumentType,
- final boolean isStatic) {
- return new MethodSignature(name, new Class<?>[] { argumentType }, isStatic);
+ private static MethodSignature getMethodSignature(final Class<?> context, final String name,
+ final Class<?> argumentType, final boolean isStatic) {
+ return new MethodSignature(context, name, new Class<?>[] { argumentType }, isStatic);
}
/**
* Generates a signature to store methods.
*
+ * @param context
+ * the method declaring class
* @param name
+ * the method name
* @param isStatic
+ * whether the method is static
* @return The method signature
- * @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic Jouault</a>
+ * @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic
+ * Jouault</a>
* @author <a href="mailto:william.piers@obeo.fr">William Piers</a>
* @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
* @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
*/
- private static MethodSignature getMethodSignature(final String name, final boolean isStatic) {
- return new MethodSignature(name, null, isStatic);
+ private static MethodSignature getMethodSignature(final Class<?> context, final String name,
+ final boolean isStatic) {
+ return new MethodSignature(context, name, null, isStatic);
}
/**
@@ -2460,12 +2503,15 @@ public final class EMFTVMUtil {
if (method == null) {
return null;
}
- Method rootMethod = ROOT_METHOD_CACHE.get(method);
+ RootMethodCacheAccesses++;
+ final WeakReference<Method> rootMethodReference = ROOT_METHOD_CACHE.get(method);
+ Method rootMethod = rootMethodReference != null ? rootMethodReference.get() : null;
if (rootMethod != null) {
+ RootMethodCacheHits++;
return rootMethod;
}
rootMethod = findRootMethodInner(method);
- ROOT_METHOD_CACHE.put(method, rootMethod);
+ ROOT_METHOD_CACHE.put(method, new WeakReference<Method>(rootMethod));
return rootMethod;
}
@@ -2521,4 +2567,24 @@ public final class EMFTVMUtil {
return methodModifiers & (Modifier.PRIVATE + Modifier.PROTECTED + Modifier.PUBLIC + Modifier.STATIC);
}
+ /**
+ * Returns the hit rate of the method cache.
+ *
+ * @return the hit rate of the method cache, or <code>-1.0</code> if no hits
+ * were recorded yet
+ */
+ public static double getMethodCacheHitRate() {
+ return MethodCacheAccesses > 0 ? (double) MethodCacheHits / (double) MethodCacheAccesses : -1.0;
+ }
+
+ /**
+ * Returns the hit rate of the root method cache.
+ *
+ * @return the hit rate of the root method cache, or <code>-1.0</code> if no
+ * hits were recorded yet
+ */
+ public static double getRootMethodCacheHitRate() {
+ return RootMethodCacheAccesses > 0 ? (double) RootMethodCacheHits / (double) RootMethodCacheAccesses : -1.0;
+ }
+
}
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/MethodSignature.java b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/MethodSignature.java
index 6c44da01..f150c0fb 100644
--- a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/MethodSignature.java
+++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/MethodSignature.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2016 Dennis Wagelaar.
+ * Copyright (c) 2016-2017 Dennis Wagelaar.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -21,8 +21,9 @@ import java.util.Arrays;
*/
public final class MethodSignature {
+ private final String context;
private final String name;
- private final Class<?>[] argumentTypes;
+ private final String[] argumentTypes;
private final boolean isStatic;
/**
@@ -35,14 +36,31 @@ public final class MethodSignature {
* @param isStatic
* whether the method is static
*/
- public MethodSignature(String name, Class<?>[] argumentTypes, boolean isStatic) {
+ public MethodSignature(Class<?> context, String name, Class<?>[] argumentTypes, boolean isStatic) {
super();
+ this.context = context.getName();
this.name = name;
- this.argumentTypes = argumentTypes;
+ if (argumentTypes != null) {
+ this.argumentTypes = new String[argumentTypes.length];
+ for (int i = 0; i < argumentTypes.length; i++) {
+ this.argumentTypes[i] = argumentTypes[i].getName();
+ }
+ } else {
+ this.argumentTypes = null;
+ }
this.isStatic = isStatic;
}
/**
+ * Returns the method context (i.e. declaring class).
+ *
+ * @return the context
+ */
+ public String getContext() {
+ return context;
+ }
+
+ /**
* Returns the method name.
*
* @return the name
@@ -56,7 +74,7 @@ public final class MethodSignature {
*
* @return the argumentTypes
*/
- public Class<?>[] getArgumentTypes() {
+ public String[] getArgumentTypes() {
return argumentTypes;
}
@@ -76,9 +94,10 @@ public final class MethodSignature {
public int hashCode() {
final int prime = 31;
int result = 1;
- result = prime * result + Arrays.hashCode(argumentTypes);
- result = prime * result + (isStatic ? 1231 : 1237);
+ result = prime * result + ((context == null) ? 0 : context.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
+ result = prime * result + (isStatic ? 1231 : 1237);
+ result = prime * result + Arrays.hashCode(argumentTypes);
return result;
}
@@ -94,15 +113,20 @@ public final class MethodSignature {
if (getClass() != obj.getClass())
return false;
MethodSignature other = (MethodSignature) obj;
- if (!Arrays.equals(argumentTypes, other.argumentTypes))
- return false;
- if (isStatic != other.isStatic)
+ if (context == null) {
+ if (other.context != null)
+ return false;
+ } else if (!context.equals(other.context))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
+ if (isStatic != other.isStatic)
+ return false;
+ if (!Arrays.equals(argumentTypes, other.argumentTypes))
+ return false;
return true;
}
@@ -111,8 +135,8 @@ public final class MethodSignature {
*/
@Override
public String toString() {
- return "MethodSignature [name=" + name + ", argumentTypes=" + Arrays.toString(argumentTypes) + ", isStatic="
- + isStatic + "]";
+ return "MethodSignature [context=" + context + ", name=" + name + ", argumentTypes="
+ + Arrays.toString(argumentTypes) + ", isStatic=" + isStatic + "]";
}
}

Back to the top