Mercurial > hg > graal-compiler
changeset 22111:3f83cc877a0e
Add support so methods for invocation plugins can be optional; add support for new unaligned Unsafe methods in JDK 9.
author | twisti |
---|---|
date | Fri, 26 Jun 2015 17:11:34 -0700 |
parents | e11e05cc0f2e |
children | 91b8a0d1abc5 |
files | graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugin.java graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugins.java graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64GraphBuilderPlugins.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/MethodIdMap.java |
diffstat | 5 files changed, 94 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugin.java Fri Jun 26 20:35:08 2015 +0200 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugin.java Fri Jun 26 17:11:34 2015 -0700 @@ -38,8 +38,8 @@ /** * The receiver in a non-static method. The class literal for this interface must be used with - * {@link MethodIdMap#put(Object, boolean, Class, String, Class...)} to denote the receiver - * argument for such a non-static method. + * {@link MethodIdMap#put(Object, boolean, boolean, Class, String, Class...)} to denote the + * receiver argument for such a non-static method. */ public interface Receiver { /**
--- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugins.java Fri Jun 26 20:35:08 2015 +0200 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugins.java Fri Jun 26 17:11:34 2015 -0700 @@ -159,6 +159,26 @@ } /** + * Registers a plugin for an optional method with 3 arguments. + * + * @param name the name of the method + * @param plugin the plugin to be registered + */ + public void registerOptional3(String name, Class<?> arg1, Class<?> arg2, Class<?> arg3, InvocationPlugin plugin) { + plugins.registerOptional(plugin, declaringClass, name, arg1, arg2, arg3); + } + + /** + * Registers a plugin for an optional method with 4 arguments. + * + * @param name the name of the method + * @param plugin the plugin to be registered + */ + public void registerOptional4(String name, Class<?> arg1, Class<?> arg2, Class<?> arg3, Class<?> arg4, InvocationPlugin plugin) { + plugins.registerOptional(plugin, declaringClass, name, arg1, arg2, arg3, arg4); + } + + /** * Registers a plugin that implements a method based on the bytecode of a substitute method. * * @param substituteDeclaringClass the class declaring the substitute method @@ -203,6 +223,15 @@ this(null, metaAccess); } + private void register(InvocationPlugin plugin, boolean isOptional, Class<?> declaringClass, String name, Class<?>... argumentTypes) { + boolean isStatic = argumentTypes.length == 0 || argumentTypes[0] != InvocationPlugin.Receiver.class; + if (!isStatic) { + argumentTypes[0] = declaringClass; + } + MethodKey<InvocationPlugin> methodInfo = plugins.put(plugin, isStatic, isOptional, declaringClass, name, argumentTypes); + assert Checker.check(this, methodInfo, plugin); + } + /** * Registers an invocation plugin for a given method. There must be no plugin currently * registered for {@code method}. @@ -213,12 +242,20 @@ * {@code declaringClass} */ public void register(InvocationPlugin plugin, Class<?> declaringClass, String name, Class<?>... argumentTypes) { - boolean isStatic = argumentTypes.length == 0 || argumentTypes[0] != InvocationPlugin.Receiver.class; - if (!isStatic) { - argumentTypes[0] = declaringClass; - } - MethodKey<InvocationPlugin> methodInfo = plugins.put(plugin, isStatic, declaringClass, name, argumentTypes); - assert Checker.check(this, methodInfo, plugin); + register(plugin, false, declaringClass, name, argumentTypes); + } + + /** + * Registers an invocation plugin for a given, optional method. There must be no plugin + * currently registered for {@code method}. + * + * @param argumentTypes the argument types of the method. Element 0 of this array must be the + * {@link Class} value for {@link InvocationPlugin.Receiver} iff the method is + * non-static. Upon returning, element 0 will have been rewritten to + * {@code declaringClass} + */ + public void registerOptional(InvocationPlugin plugin, Class<?> declaringClass, String name, Class<?>... argumentTypes) { + register(plugin, true, declaringClass, name, argumentTypes); } /** @@ -265,6 +302,7 @@ * The set of all {@link InvocationPlugin#apply} method signatures. */ static final Class<?>[][] SIGS; + static { ArrayList<Class<?>[]> sigs = new ArrayList<>(MAX_ARITY); for (Method method : InvocationPlugin.class.getDeclaredMethods()) {
--- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64GraphBuilderPlugins.java Fri Jun 26 20:35:08 2015 +0200 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64GraphBuilderPlugins.java Fri Jun 26 17:11:34 2015 -0700 @@ -37,6 +37,7 @@ import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.replacements.*; +import com.oracle.graal.replacements.StandardGraphBuilderPlugins.*; public class AMD64GraphBuilderPlugins { @@ -133,5 +134,11 @@ }); } } + + for (Kind kind : new Kind[]{Kind.Char, Kind.Short, Kind.Int, Kind.Long}) { + Class<?> javaClass = kind.toJavaClass(); + r.registerOptional3("get" + kind.name() + "Unaligned", Receiver.class, Object.class, long.class, new UnsafeGetPlugin(kind, false)); + r.registerOptional4("put" + kind.name() + "Unaligned", Receiver.class, Object.class, long.class, javaClass, new UnsafePutPlugin(kind, false)); + } } }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java Fri Jun 26 20:35:08 2015 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java Fri Jun 26 17:11:34 2015 -0700 @@ -555,7 +555,7 @@ } } - static class UnsafePutPlugin implements InvocationPlugin { + public static class UnsafePutPlugin implements InvocationPlugin { private final Kind kind; private final boolean isVolatile;
--- a/jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/MethodIdMap.java Fri Jun 26 20:35:08 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/MethodIdMap.java Fri Jun 26 17:11:34 2015 -0700 @@ -48,20 +48,28 @@ */ public static class MethodKey<T> { final boolean isStatic; + + /** + * This method is optional. This is used for new API methods not present in previous JDK + * versions. + */ + final boolean isOptional; + final Class<?> declaringClass; final String name; final Class<?>[] argumentTypes; final T value; int id; - MethodKey(T data, boolean isStatic, Class<?> declaringClass, String name, Class<?>... argumentTypes) { + MethodKey(T data, boolean isStatic, boolean isOptional, Class<?> declaringClass, String name, Class<?>... argumentTypes) { assert isStatic || argumentTypes[0] == declaringClass; this.value = data; this.isStatic = isStatic; + this.isOptional = isOptional; this.declaringClass = declaringClass; this.name = name; this.argumentTypes = argumentTypes; - assert resolveJava() != null; + assert isOptional || resolveJava() != null; } @Override @@ -86,7 +94,11 @@ } private MethodIdHolder resolve(MetaAccessProvider metaAccess) { - return (MethodIdHolder) metaAccess.lookupJavaMethod(resolveJava()); + Executable method = resolveJava(); + if (method == null) { + return null; + } + return (MethodIdHolder) metaAccess.lookupJavaMethod(method); } private Executable resolveJava() { @@ -101,6 +113,9 @@ assert Modifier.isStatic(res.getModifiers()) == isStatic; return res; } catch (NoSuchMethodException | SecurityException e) { + if (isOptional) { + return null; + } throw new InternalError(e); } } @@ -149,15 +164,16 @@ * * @param value value to be associated with the specified method * @param isStatic specifies if the method is static + * @param isOptional specifies if the method is optional * @param declaringClass the class declaring the method * @param name the name of the method * @param argumentTypes the argument types of the method. Element 0 of this array must be * {@code declaringClass} iff the method is non-static. * @return an object representing the method */ - public MethodKey<V> put(V value, boolean isStatic, Class<?> declaringClass, String name, Class<?>... argumentTypes) { + public MethodKey<V> put(V value, boolean isStatic, boolean isOptional, Class<?> declaringClass, String name, Class<?>... argumentTypes) { assert isStatic || argumentTypes[0] == declaringClass; - MethodKey<V> methodKey = new MethodKey<>(value, isStatic, declaringClass, name, argumentTypes); + MethodKey<V> methodKey = new MethodKey<>(value, isStatic, isOptional, declaringClass, name, argumentTypes); assert entries == null : "registration is closed"; assert !registrations.contains(methodKey) : "a value is already registered for " + methodKey; registrations.add(methodKey); @@ -199,21 +215,30 @@ int max = Integer.MIN_VALUE; for (MethodKey<V> methodKey : registrations) { MethodIdHolder m = methodKey.resolve(metaAccess); - int id = idAllocator.assignId(m); - if (id < minId) { - minId = id; + if (m == null) { + assert methodKey.isOptional; + methodKey.id = -1; + } else { + int id = idAllocator.assignId(m); + if (id < minId) { + minId = id; + } + if (id > max) { + max = id; + } + methodKey.id = id; } - if (id > max) { - max = id; - } - methodKey.id = id; } int length = (max - minId) + 1; entries = allocateEntries(length); - for (MethodKey<V> m : registrations) { - int index = m.id - minId; - entries[index] = m.value; + for (MethodKey<V> methodKey : registrations) { + if (methodKey.id == -1) { + assert methodKey.isOptional; + } else { + int index = methodKey.id - minId; + entries[index] = methodKey.value; + } } } }