# HG changeset patch # User Andreas Woess # Date 1416490838 -3600 # Node ID 54b0c8ab466818f7433172ac5c4d2bb08db5355c # Parent de179c27cad3b21aaa408ec41f87a3f0c0cee281 Refactor PartialEvaluatorCanonicalizer into custom ConstantReflectionProvider diff -r de179c27cad3 -r 54b0c8ab4668 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Thu Nov 20 13:22:12 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Thu Nov 20 14:40:38 2014 +0100 @@ -45,7 +45,6 @@ import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; -import com.oracle.graal.phases.common.CanonicalizerPhase.CustomCanonicalizer; import com.oracle.graal.phases.common.inlining.*; import com.oracle.graal.phases.common.inlining.info.*; import com.oracle.graal.phases.tiers.*; @@ -75,8 +74,7 @@ public PartialEvaluator(Providers providers, TruffleCache truffleCache) { this.providers = providers; - CustomCanonicalizer customCanonicalizer = new PartialEvaluatorCanonicalizer(providers.getMetaAccess(), providers.getConstantReflection()); - this.canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue(), customCanonicalizer); + this.canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue()); this.snippetReflection = Graal.getRequiredCapability(SnippetReflectionProvider.class); this.truffleCache = truffleCache; this.callDirectMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.getCallDirectMethod()); diff -r de179c27cad3 -r 54b0c8ab4668 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java Thu Nov 20 13:22:12 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2013, 2014, 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.truffle; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.Node; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.java.*; -import com.oracle.graal.phases.common.*; -import com.oracle.graal.truffle.nodes.*; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.nodes.Node.Child; -import com.oracle.truffle.api.nodes.Node.Children; - -final class PartialEvaluatorCanonicalizer extends CanonicalizerPhase.CustomCanonicalizer { - - private final MetaAccessProvider metaAccess; - private final ConstantReflectionProvider constantReflection; - - PartialEvaluatorCanonicalizer(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) { - this.metaAccess = metaAccess; - this.constantReflection = constantReflection; - } - - @Override - public Node canonicalize(Node node) { - if (node instanceof LoadFieldNode) { - return canonicalizeLoadField((LoadFieldNode) node); - } else if (node instanceof LoadIndexedNode) { - return canonicalizeLoadIndex((LoadIndexedNode) node); - } - return node; - } - - private Node canonicalizeLoadField(LoadFieldNode loadFieldNode) { - if (!loadFieldNode.isStatic() && loadFieldNode.object().isConstant() && !loadFieldNode.object().isNullConstant()) { - ResolvedJavaField field = loadFieldNode.field(); - JavaType fieldType = field.getType(); - if (field.isFinal() || field.getAnnotation(CompilationFinal.class) != null || - (fieldType.getKind() == Kind.Object && (field.getAnnotation(Child.class) != null || field.getAnnotation(Children.class) != null))) { - JavaConstant constant = constantReflection.readFieldValue(field, loadFieldNode.object().asJavaConstant()); - assert verifyFieldValue(field, constant); - if (constant.isNonNull() && fieldType.getKind() == Kind.Object && fieldType.getComponentType() != null && - (field.getAnnotation(CompilationFinal.class) != null || field.getAnnotation(Children.class) != null)) { - int stableDimensions = getDeclaredArrayDimensions(fieldType); - return StableArrayConstantNode.forStableArrayConstant(constant, stableDimensions, true, metaAccess); - } else { - return ConstantNode.forConstant(constant, metaAccess); - } - } - } - return loadFieldNode; - } - - private Node canonicalizeLoadIndex(LoadIndexedNode loadIndexedNode) { - if (loadIndexedNode.array() instanceof StableArrayConstantNode && loadIndexedNode.index().isConstant()) { - StableArrayConstantNode stableArray = (StableArrayConstantNode) loadIndexedNode.array(); - int index = loadIndexedNode.index().asJavaConstant().asInt(); - - JavaConstant constant = constantReflection.readArrayElement(loadIndexedNode.array().asJavaConstant(), index); - if (constant != null) { - if (stableArray.getStableDimensions() > 1 && constant.isNonNull()) { - return StableArrayConstantNode.forStableArrayConstant(constant, stableArray.getStableDimensions() - 1, stableArray.isCompilationFinal(), metaAccess); - } else if (constant.isNonNull() || stableArray.isCompilationFinal()) { - return ConstantNode.forConstant(constant, metaAccess); - } - } - } - return loadIndexedNode; - } - - private static int getDeclaredArrayDimensions(JavaType type) { - int dimensions = 0; - JavaType componentType = type; - while ((componentType = componentType.getComponentType()) != null) { - dimensions++; - } - return dimensions; - } - - private boolean verifyFieldValue(ResolvedJavaField field, JavaConstant constant) { - assert field.getAnnotation(Child.class) == null || constant.isNull() || - metaAccess.lookupJavaType(com.oracle.truffle.api.nodes.Node.class).isAssignableFrom(metaAccess.lookupJavaType(constant)) : "@Child field value must be a Node: " + field + - ", but was: " + constant; - assert field.getAnnotation(Children.class) == null || constant.isNull() || metaAccess.lookupJavaType(constant).isArray() : "@Children field value must be an array: " + field + ", but was: " + - constant; - return true; - } -} diff -r de179c27cad3 -r 54b0c8ab4668 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Thu Nov 20 13:22:12 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Thu Nov 20 14:40:38 2014 +0100 @@ -75,7 +75,8 @@ this.compilationNotify = graalTruffleRuntime.getCompilationNotify(); this.backend = runtime.getHostBackend(); Replacements truffleReplacements = graalTruffleRuntime.getReplacements(); - this.providers = backend.getProviders().copyWith(truffleReplacements); + ConstantReflectionProvider constantReflection = new TruffleConstantReflectionProvider(backend.getProviders().getConstantReflection(), backend.getProviders().getMetaAccess()); + this.providers = backend.getProviders().copyWith(truffleReplacements).copyWith(constantReflection); this.suites = backend.getSuites().getDefaultSuites(); ResolvedJavaType[] skippedExceptionTypes = getSkippedExceptionTypes(providers.getMetaAccess()); diff -r de179c27cad3 -r 54b0c8ab4668 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleConstantReflectionProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleConstantReflectionProvider.java Thu Nov 20 14:40:38 2014 +0100 @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2013, 2014, 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.truffle; + +import com.oracle.graal.api.meta.*; +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; +import com.oracle.truffle.api.nodes.Node.Child; +import com.oracle.truffle.api.nodes.Node.Children; + +public class TruffleConstantReflectionProvider implements ConstantReflectionProvider { + private final ConstantReflectionProvider graalConstantReflection; + private final MetaAccessProvider metaAccess; + + public TruffleConstantReflectionProvider(ConstantReflectionProvider graalConstantReflection, MetaAccessProvider metaAccess) { + this.graalConstantReflection = graalConstantReflection; + this.metaAccess = metaAccess; + } + + public Boolean constantEquals(Constant x, Constant y) { + return graalConstantReflection.constantEquals(x, y); + } + + public Integer readArrayLength(JavaConstant array) { + return graalConstantReflection.readArrayLength(array); + } + + public JavaConstant readArrayElement(JavaConstant array, int index) { + return graalConstantReflection.readArrayElement(array, index); + } + + public JavaConstant readConstantArrayElement(JavaConstant array, int index) { + return graalConstantReflection.readConstantArrayElement(array, index); + } + + public JavaConstant readConstantFieldValue(JavaField field0, JavaConstant receiver) { + ResolvedJavaField field = (ResolvedJavaField) field0; + if (!field.isStatic() && receiver.isNonNull()) { + JavaType fieldType = field.getType(); + if (field.isFinal() || field.getAnnotation(CompilationFinal.class) != null || + (fieldType.getKind() == Kind.Object && (field.getAnnotation(Child.class) != null || field.getAnnotation(Children.class) != null))) { + JavaConstant constant = graalConstantReflection.readFieldValue(field, receiver); + assert verifyFieldValue(field, constant); + if (constant.isNonNull() && fieldType.getKind() == Kind.Object && fieldType.getComponentType() != null && + (field.getAnnotation(CompilationFinal.class) != null || field.getAnnotation(Children.class) != null)) { + return graalConstantReflection.readStableFieldValue(field, receiver, true); + } else { + return graalConstantReflection.readFieldValue(field, receiver); + } + } + } + return graalConstantReflection.readConstantFieldValue(field, receiver); + } + + private boolean verifyFieldValue(ResolvedJavaField field, JavaConstant constant) { + assert field.getAnnotation(Child.class) == null || constant.isNull() || + metaAccess.lookupJavaType(com.oracle.truffle.api.nodes.Node.class).isAssignableFrom(metaAccess.lookupJavaType(constant)) : "@Child field value must be a Node: " + field + + ", but was: " + constant; + assert field.getAnnotation(Children.class) == null || constant.isNull() || metaAccess.lookupJavaType(constant).isArray() : "@Children field value must be an array: " + field + ", but was: " + + constant; + return true; + } + + public JavaConstant readFieldValue(JavaField field, JavaConstant receiver) { + return graalConstantReflection.readFieldValue(field, receiver); + } + + public JavaConstant readStableFieldValue(JavaField field, JavaConstant receiver, boolean isDefaultStable) { + return graalConstantReflection.readStableFieldValue(field, receiver, isDefaultStable); + } + + public JavaConstant readUnsafeConstant(Kind kind, JavaConstant base, long displacement) { + return graalConstantReflection.readUnsafeConstant(kind, base, displacement); + } + + public JavaConstant readRawConstant(Kind kind, Constant base, long displacement, int bits) { + return graalConstantReflection.readRawConstant(kind, base, displacement, bits); + } + + public Constant readPointerConstant(PointerType type, Constant base, long displacement) { + return graalConstantReflection.readPointerConstant(type, base, displacement); + } + + public JavaConstant boxPrimitive(JavaConstant source) { + return graalConstantReflection.boxPrimitive(source); + } + + public JavaConstant unboxPrimitive(JavaConstant source) { + return graalConstantReflection.unboxPrimitive(source); + } + + public JavaConstant forString(String value) { + return graalConstantReflection.forString(value); + } + + public ResolvedJavaType asJavaType(JavaConstant constant) { + return graalConstantReflection.asJavaType(constant); + } + + public MethodHandleAccessProvider getMethodHandleAccess() { + return graalConstantReflection.getMethodHandleAccess(); + } +} diff -r de179c27cad3 -r 54b0c8ab4668 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/StableArrayConstantNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/StableArrayConstantNode.java Thu Nov 20 13:22:12 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2013, 2014, 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.truffle.nodes; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.nodeinfo.*; -import com.oracle.graal.nodes.*; - -/** - * The {@code StableArrayConstantNode} represents a stable or compilation final array constant. - */ -@NodeInfo(shortName = "StableConst", nameTemplate = "StableConst({p#rawvalue})") -public class StableArrayConstantNode extends ConstantNode { - protected final int stableDimensions; - protected final boolean compilationFinal; - - /** - * Constructs a new node representing the specified stable array constant. - * - * @param value the constant - * @param stableDimensions number of array dimensions that are to be considered as stable - * @param compilationFinal if {@code true}, default values are considered constant as well - */ - public static StableArrayConstantNode create(JavaConstant value, Stamp stamp, int stableDimensions, boolean compilationFinal) { - return new StableArrayConstantNode(value, stamp, stableDimensions, compilationFinal); - } - - protected StableArrayConstantNode(JavaConstant value, Stamp stamp, int stableDimensions, boolean compilationFinal) { - super(value, stamp); - assert value.getKind() == Kind.Object && value.isNonNull(); - assert stableDimensions <= 255; - this.stableDimensions = stableDimensions; - this.compilationFinal = compilationFinal; - } - - public static ConstantNode forStableArrayConstant(JavaConstant constant, int stableDimensions, boolean compilationFinal, MetaAccessProvider metaAccess, StructuredGraph graph) { - return graph.unique(forStableArrayConstant(constant, stableDimensions, compilationFinal, metaAccess)); - } - - public static ConstantNode forStableArrayConstant(JavaConstant constant, int stableDimensions, boolean compilationFinal, MetaAccessProvider metaAccess) { - if (constant.getKind() == Kind.Object && constant.isNonNull()) { - Stamp stamp = StampFactory.forConstant(constant, metaAccess); - assert stamp.javaType(metaAccess).isArray(); - return StableArrayConstantNode.create(constant, stamp, stableDimensions, compilationFinal); - } else { - throw new IllegalArgumentException(constant.toString()); - } - } - - public int getStableDimensions() { - return stableDimensions; - } - - public boolean isCompilationFinal() { - return compilationFinal; - } -}