Mercurial > hg > graal-compiler
changeset 23150:cda21cbf6ac0
Only generate a single NodeIntrinsicPluginFactory for all @NodeIntrinsic and @Fold methods in a top-level class.
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java Tue Dec 08 20:47:09 2015 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java Wed Dec 09 16:06:22 2015 +0100 @@ -131,7 +131,7 @@ StandardGraphBuilderPlugins.registerInvocationPlugins(metaAccess, invocationPlugins, true); for (NodeIntrinsicPluginFactory factory : Services.load(NodeIntrinsicPluginFactory.class)) { - factory.registerPlugin(invocationPlugins, nodeIntrinsificationProvider); + factory.registerPlugins(invocationPlugins, nodeIntrinsificationProvider); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/graphbuilderconf/NodeIntrinsicPluginFactory.java Tue Dec 08 20:47:09 2015 -0800 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/graphbuilderconf/NodeIntrinsicPluginFactory.java Wed Dec 09 16:06:22 2015 +0100 @@ -33,5 +33,5 @@ Stamp getReturnStamp(Class<?> type); } - void registerPlugin(InvocationPlugins plugins, InjectionProvider injection); + void registerPlugins(InvocationPlugins plugins, InjectionProvider injection); }
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/FoldTest.java Tue Dec 08 20:47:09 2015 -0800 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/FoldTest.java Wed Dec 09 16:06:22 2015 +0100 @@ -95,8 +95,7 @@ Plugins ret = super.getDefaultGraphBuilderPlugins(); // manually register generated factories, jvmci service providers don't work from unit tests InjectionProvider injection = new NodeIntrinsificationProvider(getMetaAccess(), getSnippetReflection(), getProviders().getForeignCalls(), null); - new FoldFactory_FoldTest_FoldUtils_getNumber().registerPlugin(ret.getInvocationPlugins(), injection); - new FoldFactory_FoldTest_FoldUtils_multiply_255f288().registerPlugin(ret.getInvocationPlugins(), injection); + new PluginFactory_FoldTest().registerPlugins(ret.getInvocationPlugins(), injection); return ret; }
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ReplacementsParseTest.java Tue Dec 08 20:47:09 2015 -0800 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ReplacementsParseTest.java Wed Dec 09 16:06:22 2015 +0100 @@ -48,7 +48,7 @@ protected Plugins getDefaultGraphBuilderPlugins() { Plugins ret = super.getDefaultGraphBuilderPlugins(); // manually register generated factory, jvmci service providers don't work from unit tests - new NodeIntrinsicFactory_ReplacementsParseTest_TestMethodsSubstitutions_asNonNullStringIntrinsic_2bfccb54().registerPlugin(ret.getInvocationPlugins(), null); + new PluginFactory_ReplacementsParseTest().registerPlugins(ret.getInvocationPlugins(), null); return ret; }
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/SubstitutionsTest.java Tue Dec 08 20:47:09 2015 -0800 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/SubstitutionsTest.java Wed Dec 09 16:06:22 2015 +0100 @@ -128,9 +128,7 @@ protected Plugins getDefaultGraphBuilderPlugins() { Plugins ret = super.getDefaultGraphBuilderPlugins(); // manually register generated factories, jvmci service providers don't work from unit tests - new NodeIntrinsicFactory_SubstitutionsTest_TestGuard_guard_1c2b7e8f().registerPlugin(ret.getInvocationPlugins(), null); - new NodeIntrinsicFactory_SubstitutionsTest_TestMemory_memory().registerPlugin(ret.getInvocationPlugins(), null); - new NodeIntrinsicFactory_SubstitutionsTest_TestValue_value_a22f0f5f().registerPlugin(ret.getInvocationPlugins(), null); + new PluginFactory_SubstitutionsTest().registerPlugins(ret.getInvocationPlugins(), null); return ret; }
--- a/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/APHotSpotSignature.java Tue Dec 08 20:47:09 2015 -0800 +++ b/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/APHotSpotSignature.java Wed Dec 09 16:06:22 2015 +0100 @@ -26,18 +26,9 @@ import java.util.List; import javax.annotation.processing.ProcessingEnvironment; -import javax.lang.model.element.Element; -import javax.lang.model.element.ElementKind; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; -import javax.lang.model.element.VariableElement; -import javax.lang.model.type.ArrayType; -import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; -import javax.lang.model.type.TypeVariable; -import javax.lang.model.type.WildcardType; import javax.tools.Diagnostic.Kind; /** @@ -105,81 +96,6 @@ return cur; } - private static void getSignatureName(StringBuilder ret, Element element) { - Element enclosing = element.getEnclosingElement(); - if (enclosing.getKind() == ElementKind.PACKAGE) { - ret.append(((PackageElement) enclosing).getQualifiedName().toString().replace('.', '/')); - ret.append('/'); - } else { - getSignatureName(ret, enclosing); - ret.append('$'); - } - ret.append(element.getSimpleName()); - } - - private static void getSignatureString(StringBuilder ret, TypeMirror type) { - switch (type.getKind()) { - case ARRAY: - ret.append('['); - getSignatureString(ret, ((ArrayType) type).getComponentType()); - break; - case BOOLEAN: - ret.append('Z'); - break; - case BYTE: - ret.append('B'); - break; - case SHORT: - ret.append('S'); - break; - case CHAR: - ret.append('C'); - break; - case INT: - ret.append('I'); - break; - case LONG: - ret.append('J'); - break; - case FLOAT: - ret.append('F'); - break; - case DOUBLE: - ret.append('D'); - break; - case VOID: - ret.append('V'); - break; - case DECLARED: - ret.append('L'); - getSignatureName(ret, ((DeclaredType) type).asElement()); - ret.append(';'); - break; - case TYPEVAR: - getSignatureString(ret, ((TypeVariable) type).getUpperBound()); - break; - case WILDCARD: - getSignatureString(ret, ((WildcardType) type).getExtendsBound()); - break; - case INTERSECTION: - ret.append("Ljava/lang/Object;"); - break; - default: - throw new IllegalArgumentException(type.toString()); - } - } - - public static String toSignature(ExecutableElement intrinsicMethod) { - StringBuilder ret = new StringBuilder(); - ret.append('('); - for (VariableElement param : intrinsicMethod.getParameters()) { - getSignatureString(ret, param.asType()); - } - ret.append(')'); - getSignatureString(ret, intrinsicMethod.getReturnType()); - return ret.toString(); - } - public int getParameterCount(boolean withReceiver) { return arguments.size() + (withReceiver ? 1 : 0); }
--- a/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/AbstractVerifier.java Tue Dec 08 20:47:09 2015 -0800 +++ b/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/AbstractVerifier.java Wed Dec 09 16:06:22 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ this.env = env; } - public abstract void verify(Element element, AnnotationMirror annotation); + public abstract void verify(Element element, AnnotationMirror annotation, PluginGenerator generator); public abstract Class<? extends Annotation> getAnnotationClass();
--- a/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/ClassSubstitutionVerifier.java Tue Dec 08 20:47:09 2015 -0800 +++ b/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/ClassSubstitutionVerifier.java Wed Dec 09 16:06:22 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ } @Override - public void verify(Element element, AnnotationMirror classSubstitution) { + public void verify(Element element, AnnotationMirror classSubstitution, PluginGenerator generator) { if (!element.getKind().isClass()) { assert false : "Element is guaranteed to be a class."; return;
--- a/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/FoldPluginGenerator.java Tue Dec 08 20:47:09 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,173 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.replacements.verifier; - -import java.io.PrintWriter; -import java.lang.annotation.Annotation; -import java.util.List; - -import javax.annotation.processing.ProcessingEnvironment; -import javax.lang.model.element.AnnotationMirror; -import javax.lang.model.element.Element; -import javax.lang.model.element.ElementKind; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.Modifier; -import javax.lang.model.element.TypeElement; -import javax.lang.model.element.VariableElement; -import javax.lang.model.type.TypeMirror; -import javax.tools.Diagnostic.Kind; - -import com.oracle.graal.api.replacements.Fold; -import com.oracle.graal.replacements.verifier.InjectedDependencies.WellKnownDependency; - -/** - * Create graph builder plugins for {@link Fold} methods. - */ -public class FoldPluginGenerator extends PluginGenerator { - - private class FoldVerifier extends AbstractVerifier { - - public FoldVerifier(ProcessingEnvironment env) { - super(env); - } - - @Override - public void verify(Element element, AnnotationMirror annotation) { - if (element.getKind() != ElementKind.METHOD) { - assert false : "Element is guaranteed to be a method."; - return; - } - - ExecutableElement intrinsicMethod = (ExecutableElement) element; - if (intrinsicMethod.getModifiers().contains(Modifier.PRIVATE)) { - env.getMessager().printMessage(Kind.ERROR, "@Fold method can not be private.", element); - } else { - FoldPluginGenerator.this.createPluginFactory(intrinsicMethod, null, null); - } - } - - @Override - public Class<? extends Annotation> getAnnotationClass() { - return Fold.class; - } - } - - private TypeMirror stringType() { - return env.getElementUtils().getTypeElement("java.lang.String").asType(); - } - - public FoldPluginGenerator(ProcessingEnvironment env) { - super(env); - } - - public AbstractVerifier getVerifier() { - return new FoldVerifier(env); - } - - @Override - protected String getBaseName() { - return "FoldFactory"; - } - - @Override - protected void createImports(PrintWriter out, ExecutableElement intrinsicMethod, ExecutableElement targetMethod) { - out.printf("import jdk.vm.ci.meta.JavaConstant;\n"); - out.printf("import jdk.vm.ci.meta.JavaKind;\n"); - out.printf("import com.oracle.graal.nodes.ConstantNode;\n"); - super.createImports(out, intrinsicMethod, targetMethod); - } - - @Override - protected InjectedDependencies createExecute(PrintWriter out, ExecutableElement intrinsicMethod, ExecutableElement constructor, TypeMirror[] signature) { - InjectedDependencies deps = new InjectedDependencies(); - List<? extends VariableElement> params = intrinsicMethod.getParameters(); - - int argCount = 0; - Object receiver; - if (intrinsicMethod.getModifiers().contains(Modifier.STATIC)) { - receiver = intrinsicMethod.getEnclosingElement(); - } else { - receiver = "arg0"; - TypeElement type = (TypeElement) intrinsicMethod.getEnclosingElement(); - constantArgument(out, deps, argCount, type.asType(), argCount); - argCount++; - } - - int firstArg = argCount; - for (VariableElement param : params) { - constantArgument(out, deps, argCount, param.asType(), argCount); - argCount++; - } - - if (intrinsicMethod.getAnnotation(Deprecated.class) != null) { - out.printf(" @SuppressWarnings(\"deprecation\")\n"); - } - out.printf(" %s result = %s.%s(", intrinsicMethod.getReturnType(), receiver, intrinsicMethod.getSimpleName()); - if (argCount > firstArg) { - out.printf("arg%d", firstArg); - for (int i = firstArg + 1; i < argCount; i++) { - out.printf(", arg%d", i); - } - } - out.printf(");\n"); - - TypeMirror returnType = intrinsicMethod.getReturnType(); - switch (returnType.getKind()) { - case BOOLEAN: - out.printf(" JavaConstant constant = JavaConstant.forInt(result ? 1 : 0);\n"); - break; - case BYTE: - case SHORT: - case CHAR: - case INT: - out.printf(" JavaConstant constant = JavaConstant.forInt(result);\n"); - break; - case LONG: - out.printf(" JavaConstant constant = JavaConstant.forLong(result);\n"); - break; - case FLOAT: - out.printf(" JavaConstant constant = JavaConstant.forFloat(result);\n"); - break; - case DOUBLE: - out.printf(" JavaConstant constant = JavaConstant.forDouble(result);\n"); - break; - case ARRAY: - case TYPEVAR: - case DECLARED: - if (returnType.equals(stringType())) { - out.printf(" JavaConstant constant = %s.forString(result);\n", deps.use(WellKnownDependency.CONSTANT_REFLECTION)); - } else { - out.printf(" JavaConstant constant = %s.forObject(result);\n", deps.use(WellKnownDependency.SNIPPET_REFLECTION)); - } - break; - default: - throw new IllegalArgumentException(returnType.toString()); - } - - out.printf(" ConstantNode node = ConstantNode.forConstant(constant, %s, %s);\n", deps.use(WellKnownDependency.META_ACCESS), deps.use(WellKnownDependency.STRUCTURED_GRAPH)); - out.printf(" b.push(JavaKind.%s, node);\n", getReturnKind(intrinsicMethod).name()); - out.printf(" return true;\n"); - - return deps; - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/FoldVerifier.java Wed Dec 09 16:06:22 2015 +0100 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.replacements.verifier; + +import java.lang.annotation.Annotation; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.tools.Diagnostic.Kind; + +import com.oracle.graal.api.replacements.Fold; + +public final class FoldVerifier extends AbstractVerifier { + + public FoldVerifier(ProcessingEnvironment env) { + super(env); + } + + @Override + public Class<? extends Annotation> getAnnotationClass() { + return Fold.class; + } + + @Override + public void verify(Element element, AnnotationMirror annotation, PluginGenerator generator) { + if (element.getKind() != ElementKind.METHOD) { + assert false : "Element is guaranteed to be a method."; + return; + } + + ExecutableElement foldMethod = (ExecutableElement) element; + if (foldMethod.getModifiers().contains(Modifier.PRIVATE)) { + env.getMessager().printMessage(Kind.ERROR, String.format("A @%s method must not be private.", Fold.class.getSimpleName()), element, annotation); + } else { + generator.addPlugin(new GeneratedFoldPlugin(foldMethod)); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/GeneratedFoldPlugin.java Wed Dec 09 16:06:22 2015 +0100 @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.replacements.verifier; + +import java.io.PrintWriter; +import java.util.List; +import java.util.Set; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.TypeMirror; + +import com.oracle.graal.api.replacements.Fold; +import com.oracle.graal.replacements.verifier.InjectedDependencies.WellKnownDependency; + +/** + * Create graph builder plugins for {@link Fold} methods. + */ +public class GeneratedFoldPlugin extends GeneratedPlugin { + + public GeneratedFoldPlugin(ExecutableElement intrinsicMethod) { + super(intrinsicMethod); + } + + private static TypeMirror stringType(ProcessingEnvironment env) { + return env.getElementUtils().getTypeElement("java.lang.String").asType(); + } + + @Override + public void extraImports(Set<String> imports) { + imports.add("jdk.vm.ci.meta.JavaConstant"); + imports.add("jdk.vm.ci.meta.JavaKind"); + imports.add("com.oracle.graal.nodes.ConstantNode"); + } + + @Override + protected InjectedDependencies createExecute(ProcessingEnvironment env, PrintWriter out) { + InjectedDependencies deps = new InjectedDependencies(); + List<? extends VariableElement> params = intrinsicMethod.getParameters(); + + int argCount = 0; + Object receiver; + if (intrinsicMethod.getModifiers().contains(Modifier.STATIC)) { + receiver = intrinsicMethod.getEnclosingElement(); + } else { + receiver = "arg0"; + TypeElement type = (TypeElement) intrinsicMethod.getEnclosingElement(); + constantArgument(env, out, deps, argCount, type.asType(), argCount); + argCount++; + } + + int firstArg = argCount; + for (VariableElement param : params) { + constantArgument(env, out, deps, argCount, param.asType(), argCount); + argCount++; + } + + if (intrinsicMethod.getAnnotation(Deprecated.class) != null) { + out.printf(" @SuppressWarnings(\"deprecation\")\n"); + } + out.printf(" %s result = %s.%s(", intrinsicMethod.getReturnType(), receiver, intrinsicMethod.getSimpleName()); + if (argCount > firstArg) { + out.printf("arg%d", firstArg); + for (int i = firstArg + 1; i < argCount; i++) { + out.printf(", arg%d", i); + } + } + out.printf(");\n"); + + TypeMirror returnType = intrinsicMethod.getReturnType(); + switch (returnType.getKind()) { + case BOOLEAN: + out.printf(" JavaConstant constant = JavaConstant.forInt(result ? 1 : 0);\n"); + break; + case BYTE: + case SHORT: + case CHAR: + case INT: + out.printf(" JavaConstant constant = JavaConstant.forInt(result);\n"); + break; + case LONG: + out.printf(" JavaConstant constant = JavaConstant.forLong(result);\n"); + break; + case FLOAT: + out.printf(" JavaConstant constant = JavaConstant.forFloat(result);\n"); + break; + case DOUBLE: + out.printf(" JavaConstant constant = JavaConstant.forDouble(result);\n"); + break; + case ARRAY: + case TYPEVAR: + case DECLARED: + if (returnType.equals(stringType(env))) { + out.printf(" JavaConstant constant = %s.forString(result);\n", deps.use(WellKnownDependency.CONSTANT_REFLECTION)); + } else { + out.printf(" JavaConstant constant = %s.forObject(result);\n", deps.use(WellKnownDependency.SNIPPET_REFLECTION)); + } + break; + default: + throw new IllegalArgumentException(returnType.toString()); + } + + out.printf(" ConstantNode node = ConstantNode.forConstant(constant, %s, %s);\n", deps.use(WellKnownDependency.META_ACCESS), deps.use(WellKnownDependency.STRUCTURED_GRAPH)); + out.printf(" b.push(JavaKind.%s, node);\n", getReturnKind(intrinsicMethod).name()); + out.printf(" return true;\n"); + + return deps; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/GeneratedNodeIntrinsicPlugin.java Wed Dec 09 16:06:22 2015 +0100 @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.replacements.verifier; + +import java.io.PrintWriter; +import java.util.List; +import java.util.Set; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeMirror; +import javax.tools.Diagnostic.Kind; + +import jdk.vm.ci.meta.JavaKind; + +import com.oracle.graal.graph.Node.ConstantNodeParameter; +import com.oracle.graal.graph.Node.InjectedNodeParameter; +import com.oracle.graal.graph.Node.NodeIntrinsic; +import com.oracle.graal.replacements.verifier.InjectedDependencies.WellKnownDependency; + +/** + * Create graph builder plugins for {@link NodeIntrinsic} methods. + */ +public abstract class GeneratedNodeIntrinsicPlugin extends GeneratedPlugin { + + private final TypeMirror[] signature; + + public GeneratedNodeIntrinsicPlugin(ExecutableElement intrinsicMethod, TypeMirror[] signature) { + super(intrinsicMethod); + this.signature = signature; + } + + private static TypeMirror valueNodeType(ProcessingEnvironment env) { + return env.getElementUtils().getTypeElement("com.oracle.graal.nodes.ValueNode").asType(); + } + + protected abstract List<? extends VariableElement> getParameters(); + + protected abstract void factoryCall(ProcessingEnvironment env, PrintWriter out, InjectedDependencies deps, int argCount); + + @Override + protected InjectedDependencies createExecute(ProcessingEnvironment env, PrintWriter out) { + InjectedDependencies deps = new InjectedDependencies(); + + List<? extends VariableElement> params = getParameters(); + + int idx = 0; + for (; idx < params.size(); idx++) { + VariableElement param = params.get(idx); + if (param.getAnnotation(InjectedNodeParameter.class) == null) { + break; + } + + out.printf(" %s arg%d = %s;\n", param.asType(), idx, deps.use(env, (DeclaredType) param.asType())); + } + + for (int i = 0; i < signature.length; i++, idx++) { + if (intrinsicMethod.getParameters().get(i).getAnnotation(ConstantNodeParameter.class) != null) { + constantArgument(env, out, deps, idx, signature[i], i); + } else { + if (signature[i].equals(valueNodeType(env))) { + out.printf(" ValueNode arg%d = args[%d];\n", idx, i); + } else { + out.printf(" %s arg%d = (%s) args[%d];\n", signature[i], idx, signature[i], i); + } + } + } + + factoryCall(env, out, deps, idx); + + return deps; + } + + public static class ConstructorPlugin extends GeneratedNodeIntrinsicPlugin { + + private final ExecutableElement constructor; + + public ConstructorPlugin(ExecutableElement intrinsicMethod, ExecutableElement constructor, TypeMirror[] signature) { + super(intrinsicMethod, signature); + this.constructor = constructor; + } + + @Override + public void extraImports(Set<String> imports) { + if (getReturnKind(intrinsicMethod) != JavaKind.Void) { + imports.add("jdk.vm.ci.meta.JavaKind"); + } + } + + @Override + protected List<? extends VariableElement> getParameters() { + return constructor.getParameters(); + } + + @Override + protected void factoryCall(ProcessingEnvironment env, PrintWriter out, InjectedDependencies deps, int argCount) { + out.printf(" %s node = new %s(", constructor.getEnclosingElement(), constructor.getEnclosingElement()); + if (argCount > 0) { + out.printf("arg0"); + for (int i = 1; i < argCount; i++) { + out.printf(", arg%d", i); + } + } + out.printf(");\n"); + + if (intrinsicMethod.getAnnotation(NodeIntrinsic.class).setStampFromReturnType()) { + out.printf(" node.setStamp(%s);\n", deps.use(WellKnownDependency.RETURN_STAMP)); + } + + JavaKind returnKind = getReturnKind(intrinsicMethod); + if (returnKind == JavaKind.Void) { + out.printf(" b.add(node);\n"); + } else { + out.printf(" b.addPush(JavaKind.%s, node);\n", returnKind.name()); + } + out.printf(" return true;\n"); + } + } + + public static class CustomFactoryPlugin extends GeneratedNodeIntrinsicPlugin { + + private final ExecutableElement customFactory; + + public CustomFactoryPlugin(ExecutableElement intrinsicMethod, ExecutableElement customFactory, TypeMirror[] signature) { + super(intrinsicMethod, signature); + this.customFactory = customFactory; + } + + @Override + public void extraImports(Set<String> imports) { + } + + @Override + protected List<? extends VariableElement> getParameters() { + List<? extends VariableElement> ret = customFactory.getParameters(); + // remove initial GraphBuilderContext parameter + return ret.subList(1, ret.size()); + } + + @Override + protected void factoryCall(ProcessingEnvironment env, PrintWriter out, InjectedDependencies deps, int argCount) { + out.printf(" return %s.%s(b", customFactory.getEnclosingElement(), customFactory.getSimpleName()); + for (int i = 0; i < argCount; i++) { + out.printf(", arg%d", i); + } + out.printf(");\n"); + + if (intrinsicMethod.getAnnotation(NodeIntrinsic.class).setStampFromReturnType()) { + env.getMessager().printMessage(Kind.WARNING, "Ignoring setStampFromReturnType because a custom 'intrinsify' method is used.", intrinsicMethod); + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/GeneratedPlugin.java Wed Dec 09 16:06:22 2015 +0100 @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.replacements.verifier; + +import java.io.PrintWriter; +import java.util.Set; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.ArrayType; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.type.TypeVariable; +import javax.lang.model.type.WildcardType; + +import jdk.vm.ci.meta.JavaKind; + +import com.oracle.graal.replacements.verifier.InjectedDependencies.Dependency; +import com.oracle.graal.replacements.verifier.InjectedDependencies.WellKnownDependency; + +public abstract class GeneratedPlugin { + + protected final ExecutableElement intrinsicMethod; + private boolean needInjectionProvider; + + public GeneratedPlugin(ExecutableElement intrinsicMethod) { + this.intrinsicMethod = intrinsicMethod; + this.needInjectionProvider = false; + } + + public void generate(ProcessingEnvironment env, PrintWriter out, int idx) { + out.printf(" // class: %s\n", intrinsicMethod.getEnclosingElement()); + out.printf(" // method: %s\n", intrinsicMethod); + out.printf(" private static final class Plugin%d extends GeneratedInvocationPlugin {\n", idx); + out.printf("\n"); + out.printf(" @Override\n"); + out.printf(" public boolean execute(GraphBuilderContext b, ResolvedJavaMethod targetMethod, InvocationPlugin.Receiver receiver, ValueNode[] args) {\n"); + out.printf(" if (!b.parsingIntrinsic()) {\n"); + out.printf(" return false;\n"); + out.printf(" }\n"); + InjectedDependencies deps = createExecute(env, out); + out.printf(" }\n"); + + createPrivateMembers(out, deps, idx); + + out.printf(" }\n"); + } + + public void register(PrintWriter out, int idx) { + out.printf(" plugins.register(new Plugin%d(", idx); + if (needInjectionProvider) { + out.printf("injection"); + } + out.printf("), %s.class, \"%s\"", intrinsicMethod.getEnclosingElement(), intrinsicMethod.getSimpleName()); + if (!intrinsicMethod.getModifiers().contains(Modifier.STATIC)) { + out.printf(", InvocationPlugin.Receiver.class"); + } + for (VariableElement arg : intrinsicMethod.getParameters()) { + out.printf(", %s.class", getErasedType(arg.asType())); + } + out.printf(");\n"); + } + + public abstract void extraImports(Set<String> imports); + + protected abstract InjectedDependencies createExecute(ProcessingEnvironment env, PrintWriter out); + + private static TypeMirror resolvedJavaTypeType(ProcessingEnvironment env) { + return env.getElementUtils().getTypeElement("jdk.vm.ci.meta.ResolvedJavaType").asType(); + } + + static String getErasedType(TypeMirror type) { + switch (type.getKind()) { + case DECLARED: + DeclaredType declared = (DeclaredType) type; + TypeElement element = (TypeElement) declared.asElement(); + return element.getQualifiedName().toString(); + case TYPEVAR: + return getErasedType(((TypeVariable) type).getUpperBound()); + case WILDCARD: + return getErasedType(((WildcardType) type).getExtendsBound()); + case ARRAY: + return getErasedType(((ArrayType) type).getComponentType()) + "[]"; + default: + return type.toString(); + } + } + + private void createPrivateMembers(PrintWriter out, InjectedDependencies deps, int idx) { + if (!deps.isEmpty()) { + out.printf("\n"); + for (Dependency dep : deps) { + out.printf(" private final %s %s;\n", dep.type, dep.name); + } + + out.printf("\n"); + out.printf(" private Plugin%d(InjectionProvider injection) {\n", idx); + for (Dependency dep : deps) { + out.printf(" this.%s = %s;\n", dep.name, dep.inject(intrinsicMethod)); + } + out.printf(" }\n"); + + needInjectionProvider = true; + } + } + + protected static JavaKind getReturnKind(ExecutableElement method) { + switch (method.getReturnType().getKind()) { + case BOOLEAN: + case BYTE: + case SHORT: + case CHAR: + case INT: + return JavaKind.Int; + case LONG: + return JavaKind.Long; + case FLOAT: + return JavaKind.Float; + case DOUBLE: + return JavaKind.Double; + case VOID: + return JavaKind.Void; + case ARRAY: + case TYPEVAR: + case DECLARED: + return JavaKind.Object; + default: + throw new IllegalArgumentException(method.getReturnType().toString()); + } + } + + protected static void constantArgument(ProcessingEnvironment env, PrintWriter out, InjectedDependencies deps, int argIdx, TypeMirror type, int nodeIdx) { + out.printf(" %s arg%d;\n", type, argIdx); + out.printf(" if (args[%d].isConstant()) {\n", nodeIdx); + if (type.equals(resolvedJavaTypeType(env))) { + out.printf(" arg%d = %s.asJavaType(args[%d].asConstant());\n", argIdx, deps.use(WellKnownDependency.CONSTANT_REFLECTION), nodeIdx); + } else { + switch (type.getKind()) { + case BOOLEAN: + out.printf(" arg%d = args[%d].asJavaConstant().asInt() != 0;\n", argIdx, nodeIdx); + break; + case BYTE: + out.printf(" arg%d = (byte) args[%d].asJavaConstant().asInt();\n", argIdx, nodeIdx); + break; + case CHAR: + out.printf(" arg%d = (char) args[%d].asJavaConstant().asInt();\n", argIdx, nodeIdx); + break; + case SHORT: + out.printf(" arg%d = (short) args[%d].asJavaConstant().asInt();\n", argIdx, nodeIdx); + break; + case INT: + out.printf(" arg%d = args[%d].asJavaConstant().asInt();\n", argIdx, nodeIdx); + break; + case LONG: + out.printf(" arg%d = args[%d].asJavaConstant().asLong();\n", argIdx, nodeIdx); + break; + case FLOAT: + out.printf(" arg%d = args[%d].asJavaConstant().asFloat();\n", argIdx, nodeIdx); + break; + case DOUBLE: + out.printf(" arg%d = args[%d].asJavaConstant().asDouble();\n", argIdx, nodeIdx); + break; + case DECLARED: + out.printf(" arg%d = %s.asObject(%s.class, args[%d].asJavaConstant());\n", argIdx, deps.use(WellKnownDependency.SNIPPET_REFLECTION), type, nodeIdx); + break; + default: + throw new IllegalArgumentException(); + } + } + out.printf(" } else {\n"); + out.printf(" return false;\n"); + out.printf(" }\n"); + } +}
--- a/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/InjectedDependencies.java Tue Dec 08 20:47:09 2015 -0800 +++ b/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/InjectedDependencies.java Wed Dec 09 16:06:22 2015 +0100 @@ -67,7 +67,7 @@ @Override public String inject(ExecutableElement inject) { - return String.format("injection.getReturnStamp(%s.class)", NodeIntrinsicPluginGenerator.getErasedType(inject.getReturnType())); + return String.format("injection.getReturnStamp(%s.class)", GeneratedPlugin.getErasedType(inject.getReturnType())); } }
--- a/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/MethodSubstitutionVerifier.java Tue Dec 08 20:47:09 2015 -0800 +++ b/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/MethodSubstitutionVerifier.java Wed Dec 09 16:06:22 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,7 +67,7 @@ @SuppressWarnings("unused") @Override - public void verify(Element element, AnnotationMirror annotation) { + public void verify(Element element, AnnotationMirror annotation, PluginGenerator generator) { if (element.getKind() != ElementKind.METHOD) { assert false : "Element is guaranteed to be a method."; return;
--- a/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/NodeIntrinsicPluginGenerator.java Tue Dec 08 20:47:09 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,133 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.replacements.verifier; - -import java.io.PrintWriter; -import java.util.List; - -import javax.annotation.processing.ProcessingEnvironment; -import javax.lang.model.element.ElementKind; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.VariableElement; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.TypeMirror; -import javax.tools.Diagnostic.Kind; - -import jdk.vm.ci.meta.JavaKind; - -import com.oracle.graal.graph.Node.ConstantNodeParameter; -import com.oracle.graal.graph.Node.InjectedNodeParameter; -import com.oracle.graal.graph.Node.NodeIntrinsic; -import com.oracle.graal.replacements.verifier.InjectedDependencies.WellKnownDependency; - -/** - * Create graph builder plugins for {@link NodeIntrinsic} methods. - */ -public class NodeIntrinsicPluginGenerator extends PluginGenerator { - - public NodeIntrinsicPluginGenerator(ProcessingEnvironment env) { - super(env); - } - - private TypeMirror valueNodeType() { - return env.getElementUtils().getTypeElement("com.oracle.graal.nodes.ValueNode").asType(); - } - - @Override - protected String getBaseName() { - return "NodeIntrinsicFactory"; - } - - @Override - protected void createImports(PrintWriter out, ExecutableElement intrinsicMethod, ExecutableElement targetMethod) { - if (targetMethod.getKind() == ElementKind.CONSTRUCTOR && getReturnKind(intrinsicMethod) != JavaKind.Void) { - out.printf("import jdk.vm.ci.meta.JavaKind;\n"); - } - super.createImports(out, intrinsicMethod, targetMethod); - } - - @Override - protected InjectedDependencies createExecute(PrintWriter out, ExecutableElement intrinsicMethod, ExecutableElement constructor, TypeMirror[] signature) { - InjectedDependencies deps = new InjectedDependencies(); - - List<? extends VariableElement> params = constructor.getParameters(); - - boolean customFactory = constructor.getKind() != ElementKind.CONSTRUCTOR; - int idx = customFactory ? 1 : 0; - for (; idx < params.size(); idx++) { - VariableElement param = params.get(idx); - if (param.getAnnotation(InjectedNodeParameter.class) == null) { - break; - } - - out.printf(" %s arg%d = %s;\n", param.asType(), idx, deps.use(env, (DeclaredType) param.asType())); - } - - for (int i = 0; i < signature.length; i++, idx++) { - if (intrinsicMethod.getParameters().get(i).getAnnotation(ConstantNodeParameter.class) != null) { - constantArgument(out, deps, idx, signature[i], i); - } else { - if (signature[i].equals(valueNodeType())) { - out.printf(" ValueNode arg%d = args[%d];\n", idx, i); - } else { - out.printf(" %s arg%d = (%s) args[%d];\n", signature[i], idx, signature[i], i); - } - } - } - - if (customFactory) { - out.printf(" return %s.%s(b", constructor.getEnclosingElement(), constructor.getSimpleName()); - for (int i = 1; i < idx; i++) { - out.printf(", arg%d", i); - } - out.printf(");\n"); - - if (intrinsicMethod.getAnnotation(NodeIntrinsic.class).setStampFromReturnType()) { - env.getMessager().printMessage(Kind.WARNING, "Ignoring setStampFromReturnType because a custom 'intrinsify' method is used.", intrinsicMethod); - } - } else { - out.printf(" %s node = new %s(", constructor.getEnclosingElement(), constructor.getEnclosingElement()); - if (idx > 0) { - out.printf("arg0"); - for (int i = 1; i < idx; i++) { - out.printf(", arg%d", i); - } - } - out.printf(");\n"); - - if (intrinsicMethod.getAnnotation(NodeIntrinsic.class).setStampFromReturnType()) { - out.printf(" node.setStamp(%s);\n", deps.use(WellKnownDependency.RETURN_STAMP)); - } - - JavaKind returnKind = getReturnKind(intrinsicMethod); - if (returnKind == JavaKind.Void) { - out.printf(" b.add(node);\n"); - } else { - out.printf(" b.addPush(JavaKind.%s, node);\n", returnKind.name()); - } - out.printf(" return true;\n"); - } - - return deps; - } -}
--- a/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/NodeIntrinsicVerifier.java Tue Dec 08 20:47:09 2015 -0800 +++ b/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/NodeIntrinsicVerifier.java Wed Dec 09 16:06:22 2015 +0100 @@ -77,11 +77,8 @@ return env.getElementUtils().getTypeElement("com.oracle.graal.nodes.graphbuilderconf.GraphBuilderContext").asType(); } - private final NodeIntrinsicPluginGenerator factoryGen; - public NodeIntrinsicVerifier(ProcessingEnvironment env) { super(env); - factoryGen = new NodeIntrinsicPluginGenerator(env); } @Override @@ -90,7 +87,7 @@ } @Override - public void verify(Element element, AnnotationMirror annotation) { + public void verify(Element element, AnnotationMirror annotation, PluginGenerator generator) { if (element.getKind() != ElementKind.METHOD) { assert false : "Element is guaranteed to be a method."; return; @@ -124,7 +121,7 @@ TypeMirror[] constructorSignature = constructorSignature(intrinsicMethod); ExecutableElement custom = findCustomIntrinsifyMethod(nodeClass, constructorSignature); if (custom != null) { - factoryGen.createPluginFactory(intrinsicMethod, custom, constructorSignature); + generator.addPlugin(new GeneratedNodeIntrinsicPlugin.CustomFactoryPlugin(intrinsicMethod, custom, constructorSignature)); } else { if (isNodeType(nodeClass)) { if (nodeClass.getModifiers().contains(Modifier.ABSTRACT)) { @@ -137,7 +134,7 @@ ExecutableElement constructor = findConstructor(nodeClass, constructorSignature, intrinsicMethod, annotation); if (constructor != null) { - factoryGen.createPluginFactory(intrinsicMethod, constructor, constructorSignature); + generator.addPlugin(new GeneratedNodeIntrinsicPlugin.ConstructorPlugin(intrinsicMethod, constructor, constructorSignature)); } } } else {
--- a/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/PluginGenerator.java Tue Dec 08 20:47:09 2015 -0800 +++ b/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/PluginGenerator.java Wed Dec 09 16:06:22 2015 +0100 @@ -24,38 +24,42 @@ import java.io.IOException; import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.Modifier; import javax.lang.model.element.PackageElement; -import javax.lang.model.element.TypeElement; -import javax.lang.model.element.VariableElement; -import javax.lang.model.type.ArrayType; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.TypeMirror; -import javax.lang.model.type.TypeVariable; -import javax.lang.model.type.WildcardType; import javax.tools.Diagnostic; import javax.tools.JavaFileObject; -import jdk.vm.ci.meta.JavaKind; - -import com.oracle.graal.replacements.verifier.InjectedDependencies.Dependency; -import com.oracle.graal.replacements.verifier.InjectedDependencies.WellKnownDependency; +public class PluginGenerator { -public abstract class PluginGenerator { + private final Map<Element, List<GeneratedPlugin>> plugins; - protected final ProcessingEnvironment env; - - public PluginGenerator(ProcessingEnvironment env) { - this.env = env; + public PluginGenerator() { + this.plugins = new HashMap<>(); } - private TypeMirror resolvedJavaTypeType() { - return env.getElementUtils().getTypeElement("jdk.vm.ci.meta.ResolvedJavaType").asType(); + public void addPlugin(GeneratedPlugin plugin) { + Element topLevel = getTopLevelClass(plugin.intrinsicMethod); + List<GeneratedPlugin> list = plugins.get(topLevel); + if (list == null) { + list = new ArrayList<>(); + plugins.put(topLevel, list); + } + list.add(plugin); + } + + public void generateAll(ProcessingEnvironment env) { + for (Entry<Element, List<GeneratedPlugin>> entry : plugins.entrySet()) { + createPluginFactory(env, entry.getKey(), entry.getValue()); + } } private static Element getTopLevelClass(Element element) { @@ -68,84 +72,30 @@ return prev; } - private static void mkClassName(StringBuilder ret, Element cls) { - Element enclosingClass = cls.getEnclosingElement(); - if (enclosingClass.getKind() == ElementKind.CLASS || enclosingClass.getKind() == ElementKind.INTERFACE) { - mkClassName(ret, enclosingClass); - ret.append('_'); - } - ret.append(cls.getSimpleName()); - } - - static String getErasedType(TypeMirror type) { - switch (type.getKind()) { - case DECLARED: - DeclaredType declared = (DeclaredType) type; - TypeElement element = (TypeElement) declared.asElement(); - return element.getQualifiedName().toString(); - case TYPEVAR: - return getErasedType(((TypeVariable) type).getUpperBound()); - case WILDCARD: - return getErasedType(((WildcardType) type).getExtendsBound()); - case ARRAY: - return getErasedType(((ArrayType) type).getComponentType()) + "[]"; - default: - return type.toString(); - } - } - - protected abstract String getBaseName(); - - private String mkFactoryClassName(ExecutableElement intrinsicMethod) { - StringBuilder ret = new StringBuilder(); - ret.append(getBaseName()); - ret.append('_'); - mkClassName(ret, intrinsicMethod.getEnclosingElement()); - ret.append('_'); - ret.append(intrinsicMethod.getSimpleName()); - if (!intrinsicMethod.getParameters().isEmpty()) { - ret.append('_'); - ret.append(Integer.toHexString(APHotSpotSignature.toSignature(intrinsicMethod).hashCode())); - } - return ret.toString(); - } - - void createPluginFactory(ExecutableElement intrinsicMethod, ExecutableElement targetMethod, TypeMirror[] constructorSignature) { - Element declaringClass = intrinsicMethod.getEnclosingElement(); - Element topLevelClass = getTopLevelClass(declaringClass); + private static void createPluginFactory(ProcessingEnvironment env, Element topLevelClass, List<GeneratedPlugin> plugins) { PackageElement pkg = (PackageElement) topLevelClass.getEnclosingElement(); - String genClassName = mkFactoryClassName(intrinsicMethod); + String genClassName = "PluginFactory_" + topLevelClass.getSimpleName(); try { - JavaFileObject factory = env.getFiler().createSourceFile(pkg.getQualifiedName() + "." + genClassName, topLevelClass, declaringClass, intrinsicMethod); + JavaFileObject factory = env.getFiler().createSourceFile(pkg.getQualifiedName() + "." + genClassName, topLevelClass); try (PrintWriter out = new PrintWriter(factory.openWriter())) { out.printf("// CheckStyle: stop header check\n"); out.printf("// CheckStyle: stop line length check\n"); out.printf("// GENERATED CONTENT - DO NOT EDIT\n"); out.printf("package %s;\n", pkg.getQualifiedName()); out.printf("\n"); - createImports(out, intrinsicMethod, targetMethod); + createImports(out, plugins); out.printf("\n"); out.printf("@ServiceProvider(NodeIntrinsicPluginFactory.class)\n"); out.printf("public class %s implements NodeIntrinsicPluginFactory {\n", genClassName); - out.printf("\n"); - out.printf(" private static final class Plugin extends GeneratedInvocationPlugin {\n"); + int idx = 0; + for (GeneratedPlugin plugin : plugins) { + out.printf("\n"); + plugin.generate(env, out, idx++); + } out.printf("\n"); - - out.printf(" @Override\n"); - out.printf(" public boolean execute(GraphBuilderContext b, ResolvedJavaMethod targetMethod, InvocationPlugin.Receiver receiver, ValueNode[] args) {\n"); - out.printf(" if (!b.parsingIntrinsic()) {\n"); - out.printf(" return false;\n"); - out.printf(" }\n"); - InjectedDependencies deps = createExecute(out, intrinsicMethod, targetMethod, constructorSignature); - out.printf(" }\n"); - - createPrivateMembers(out, intrinsicMethod, deps); - - out.printf(" }\n"); - out.printf("\n"); - createPluginFactoryMethod(out, intrinsicMethod, deps); + createPluginFactoryMethod(out, plugins); out.printf("}\n"); } } catch (IOException e) { @@ -153,9 +103,7 @@ } } - protected abstract InjectedDependencies createExecute(PrintWriter out, ExecutableElement intrinsicMethod, ExecutableElement constructor, TypeMirror[] signature); - - protected void createImports(PrintWriter out, @SuppressWarnings("unused") ExecutableElement intrinsicMethod, @SuppressWarnings("unused") ExecutableElement targetMethod) { + protected static void createImports(PrintWriter out, List<GeneratedPlugin> plugins) { out.printf("import jdk.vm.ci.meta.ResolvedJavaMethod;\n"); out.printf("import jdk.vm.ci.service.ServiceProvider;\n"); out.printf("\n"); @@ -165,103 +113,25 @@ out.printf("import com.oracle.graal.nodes.graphbuilderconf.InvocationPlugin;\n"); out.printf("import com.oracle.graal.nodes.graphbuilderconf.InvocationPlugins;\n"); out.printf("import com.oracle.graal.nodes.graphbuilderconf.NodeIntrinsicPluginFactory;\n"); - } - private static void createPrivateMembers(PrintWriter out, ExecutableElement intrinsicMethod, InjectedDependencies deps) { - if (!deps.isEmpty()) { + HashSet<String> extra = new HashSet<>(); + for (GeneratedPlugin plugin : plugins) { + plugin.extraImports(extra); + } + if (!extra.isEmpty()) { out.printf("\n"); - for (Dependency dep : deps) { - out.printf(" private final %s %s;\n", dep.type, dep.name); + for (String i : extra) { + out.printf("import %s;\n", i); } - - out.printf("\n"); - out.printf(" private Plugin(InjectionProvider injection) {\n"); - for (Dependency dep : deps) { - out.printf(" this.%s = %s;\n", dep.name, dep.inject(intrinsicMethod)); - } - out.printf(" }\n"); } } - private static void createPluginFactoryMethod(PrintWriter out, ExecutableElement intrinsicMethod, InjectedDependencies deps) { - out.printf(" public void registerPlugin(InvocationPlugins plugins, InjectionProvider injection) {\n"); - out.printf(" Plugin plugin = new Plugin(%s);\n", deps.isEmpty() ? "" : "injection"); - out.printf(" plugins.register(plugin, %s.class, \"%s\"", intrinsicMethod.getEnclosingElement(), intrinsicMethod.getSimpleName()); - if (!intrinsicMethod.getModifiers().contains(Modifier.STATIC)) { - out.printf(", InvocationPlugin.Receiver.class"); + private static void createPluginFactoryMethod(PrintWriter out, List<GeneratedPlugin> plugins) { + out.printf(" public void registerPlugins(InvocationPlugins plugins, InjectionProvider injection) {\n"); + int idx = 0; + for (GeneratedPlugin plugin : plugins) { + plugin.register(out, idx++); } - for (VariableElement arg : intrinsicMethod.getParameters()) { - out.printf(", %s.class", getErasedType(arg.asType())); - } - out.printf(");\n"); out.printf(" }\n"); } - - protected static JavaKind getReturnKind(ExecutableElement method) { - switch (method.getReturnType().getKind()) { - case BOOLEAN: - case BYTE: - case SHORT: - case CHAR: - case INT: - return JavaKind.Int; - case LONG: - return JavaKind.Long; - case FLOAT: - return JavaKind.Float; - case DOUBLE: - return JavaKind.Double; - case VOID: - return JavaKind.Void; - case ARRAY: - case TYPEVAR: - case DECLARED: - return JavaKind.Object; - default: - throw new IllegalArgumentException(method.getReturnType().toString()); - } - } - - protected void constantArgument(PrintWriter out, InjectedDependencies deps, int argIdx, TypeMirror type, int nodeIdx) { - out.printf(" %s arg%d;\n", type, argIdx); - out.printf(" if (args[%d].isConstant()) {\n", nodeIdx); - if (type.equals(resolvedJavaTypeType())) { - out.printf(" arg%d = %s.asJavaType(args[%d].asConstant());\n", argIdx, deps.use(WellKnownDependency.CONSTANT_REFLECTION), nodeIdx); - } else { - switch (type.getKind()) { - case BOOLEAN: - out.printf(" arg%d = args[%d].asJavaConstant().asInt() != 0;\n", argIdx, nodeIdx); - break; - case BYTE: - out.printf(" arg%d = (byte) args[%d].asJavaConstant().asInt();\n", argIdx, nodeIdx); - break; - case CHAR: - out.printf(" arg%d = (char) args[%d].asJavaConstant().asInt();\n", argIdx, nodeIdx); - break; - case SHORT: - out.printf(" arg%d = (short) args[%d].asJavaConstant().asInt();\n", argIdx, nodeIdx); - break; - case INT: - out.printf(" arg%d = args[%d].asJavaConstant().asInt();\n", argIdx, nodeIdx); - break; - case LONG: - out.printf(" arg%d = args[%d].asJavaConstant().asLong();\n", argIdx, nodeIdx); - break; - case FLOAT: - out.printf(" arg%d = args[%d].asJavaConstant().asFloat();\n", argIdx, nodeIdx); - break; - case DOUBLE: - out.printf(" arg%d = args[%d].asJavaConstant().asDouble();\n", argIdx, nodeIdx); - break; - case DECLARED: - out.printf(" arg%d = %s.asObject(%s.class, args[%d].asJavaConstant());\n", argIdx, deps.use(WellKnownDependency.SNIPPET_REFLECTION), type, nodeIdx); - break; - default: - throw new IllegalArgumentException(); - } - } - out.printf(" } else {\n"); - out.printf(" return false;\n"); - out.printf(" }\n"); - } }
--- a/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/VerifierAnnotationProcessor.java Tue Dec 08 20:47:09 2015 -0800 +++ b/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/VerifierAnnotationProcessor.java Wed Dec 09 16:06:22 2015 +0100 @@ -49,6 +49,7 @@ @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { if (!roundEnv.processingOver()) { + PluginGenerator generator = new PluginGenerator(); for (AbstractVerifier verifier : getVerifiers()) { Class<? extends Annotation> annotationClass = verifier.getAnnotationClass(); for (Element e : roundEnv.getElementsAnnotatedWith(annotationClass)) { @@ -57,9 +58,11 @@ assert false : "Annotation mirror always expected."; continue; } - verifier.verify(e, annotationMirror); + verifier.verify(e, annotationMirror, generator); } } + + generator.generateAll(processingEnv); } return false; } @@ -84,7 +87,7 @@ verifiers.add(new ClassSubstitutionVerifier(this.processingEnv)); verifiers.add(new MethodSubstitutionVerifier(this.processingEnv)); verifiers.add(new NodeIntrinsicVerifier(this.processingEnv)); - verifiers.add(new FoldPluginGenerator(this.processingEnv).getVerifier()); + verifiers.add(new FoldVerifier(this.processingEnv)); } return verifiers; }