# HG changeset patch # User Doug Simon # Date 1426119082 -3600 # Node ID c59d8ba9ced5c506dc3f01e0ba964e7a65b891c5 # Parent c70ef0d09be9510675746513d2dcd1eb79c9e7a2 removed WordTypeRewriterPhase diff -r c70ef0d09be9 -r c59d8ba9ced5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/NativeCallStubGraphBuilder.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/NativeCallStubGraphBuilder.java Wed Mar 11 23:36:38 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/NativeCallStubGraphBuilder.java Thu Mar 12 01:11:22 2015 +0100 @@ -30,7 +30,6 @@ import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.hotspot.word.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; import com.oracle.graal.nodes.extended.*; @@ -91,7 +90,6 @@ ReturnNode returnNode = g.add(new ReturnNode(boxedResult)); callNode.setNext(returnNode); - (new HotSpotWordTypeRewriterPhase(providers.getMetaAccess(), providers.getSnippetReflection(), providers.getConstantReflection(), Kind.Long)).apply(g); return g; } catch (NoSuchMethodException e) { throw GraalInternalError.shouldNotReachHere("Call Stub method not found"); @@ -121,7 +119,7 @@ ConstantNode index = ConstantNode.forInt(0, g); int indexScaling = runtime().getArrayIndexScale(arrayElementKind); IndexedLocationNode locationNode = g.unique(new IndexedLocationNode(locationIdentity, displacement, index, indexScaling)); - Stamp wordStamp = StampFactory.forKind(providers.getCodeCache().getTarget().wordKind); + Stamp wordStamp = StampFactory.forKind(providers.getWordTypes().getWordKind()); ComputeAddressNode arrayAddress = g.unique(new ComputeAddressNode(boxedElement, locationNode, wordStamp)); args.add(arrayAddress); } else { diff -r c70ef0d09be9 -r c59d8ba9ced5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/word/HotSpotWordTypeRewriterPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/word/HotSpotWordTypeRewriterPhase.java Wed Mar 11 23:36:38 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2014, 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.hotspot.word; - -import static com.oracle.graal.api.meta.LocationIdentity.*; -import static com.oracle.graal.hotspot.word.HotSpotOperation.HotspotOpcode.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.replacements.*; -import com.oracle.graal.compiler.common.*; -import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.hotspot.nodes.*; -import com.oracle.graal.hotspot.nodes.type.*; -import com.oracle.graal.hotspot.word.HotSpotOperation.HotspotOpcode; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.HeapAccess.BarrierType; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.java.*; -import com.oracle.graal.word.Word.Operation; -import com.oracle.graal.word.phases.*; - -public class HotSpotWordTypeRewriterPhase extends WordTypeRewriterPhase { - - public HotSpotWordTypeRewriterPhase(MetaAccessProvider metaAccess, SnippetReflectionProvider snippetReflection, ConstantReflectionProvider constantReflection, Kind wordKind) { - super(metaAccess, snippetReflection, constantReflection, new HotSpotWordTypes(metaAccess, wordKind)); - } - - @Override - protected void rewriteAccessIndexed(StructuredGraph graph, AccessIndexedNode node) { - if (node.stamp() instanceof MetaspacePointerStamp && node instanceof LoadIndexedNode && node.elementKind() != Kind.Illegal) { - /* - * Prevent rewriting of the MetaspacePointerStamp in the CanonicalizerPhase. - */ - graph.replaceFixedWithFixed(node, graph.add(new LoadIndexedPointerNode(node.stamp(), node.array(), node.index()))); - } else { - super.rewriteAccessIndexed(graph, node); - } - } - - /** - * Intrinsification of methods that are annotated with {@link Operation} or - * {@link HotSpotOperation}. - */ - @Override - protected void rewriteInvoke(StructuredGraph graph, MethodCallTargetNode callTargetNode) { - ResolvedJavaMethod targetMethod = callTargetNode.targetMethod(); - HotSpotOperation operation = targetMethod.getAnnotation(HotSpotOperation.class); - if (operation == null) { - super.rewriteInvoke(graph, callTargetNode); - } else { - Invoke invoke = callTargetNode.invoke(); - NodeInputList arguments = callTargetNode.arguments(); - - switch (operation.opcode()) { - case POINTER_EQ: - case POINTER_NE: - assert arguments.size() == 2; - replace(invoke, pointerComparisonOp(graph, operation.opcode(), arguments.get(0), arguments.get(1))); - break; - - case IS_NULL: - assert arguments.size() == 1; - replace(invoke, pointerIsNullOp(graph, arguments.get(0))); - break; - - case FROM_POINTER: - assert arguments.size() == 1; - replace(invoke, graph.unique(new PointerCastNode(StampFactory.forKind(wordTypes.getWordKind()), arguments.get(0)))); - break; - - case TO_KLASS_POINTER: - assert arguments.size() == 1; - replace(invoke, graph.unique(new PointerCastNode(KlassPointerStamp.klass(), arguments.get(0)))); - break; - - case TO_METHOD_POINTER: - assert arguments.size() == 1; - replace(invoke, graph.unique(new PointerCastNode(MethodPointerStamp.method(), arguments.get(0)))); - break; - - case READ_KLASS_POINTER: - assert arguments.size() == 2 || arguments.size() == 3; - Stamp readStamp = KlassPointerStamp.klass(); - LocationNode location; - if (arguments.size() == 2) { - location = makeLocation(graph, arguments.get(1), ANY_LOCATION); - } else { - location = makeLocation(graph, arguments.get(1), arguments.get(2)); - } - replace(invoke, readKlassOp(graph, arguments.get(0), invoke, location, readStamp, operation.opcode())); - break; - - default: - throw GraalInternalError.shouldNotReachHere("unknown operation: " + operation.opcode()); - } - } - } - - protected ValueNode readKlassOp(StructuredGraph graph, ValueNode base, Invoke invoke, LocationNode location, Stamp readStamp, HotspotOpcode op) { - assert op == READ_KLASS_POINTER; - final BarrierType barrier = BarrierType.NONE; - - ReadNode read = graph.add(new ReadNode(base, location, readStamp, barrier)); - graph.addBeforeFixed(invoke.asNode(), read); - /* - * The read must not float outside its block otherwise it may float above an explicit zero - * check on its base address. - */ - read.setGuard(AbstractBeginNode.prevBegin(invoke.asNode())); - return read; - } - - private static ValueNode pointerComparisonOp(StructuredGraph graph, HotspotOpcode opcode, ValueNode left, ValueNode right) { - assert left.stamp() instanceof MetaspacePointerStamp && right.stamp() instanceof MetaspacePointerStamp; - assert opcode == POINTER_EQ || opcode == POINTER_NE; - - PointerEqualsNode comparison = graph.unique(new PointerEqualsNode(left, right)); - ValueNode eqValue = ConstantNode.forBoolean(opcode == POINTER_EQ, graph); - ValueNode neValue = ConstantNode.forBoolean(opcode == POINTER_NE, graph); - return graph.unique(new ConditionalNode(comparison, eqValue, neValue)); - } - - private static ValueNode pointerIsNullOp(StructuredGraph graph, ValueNode pointer) { - assert pointer.stamp() instanceof MetaspacePointerStamp; - - IsNullNode isNull = graph.unique(new IsNullNode(pointer)); - return graph.unique(new ConditionalNode(isNull, ConstantNode.forBoolean(true, graph), ConstantNode.forBoolean(false, graph))); - } -} diff -r c70ef0d09be9 -r c59d8ba9ced5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/word/PointerCastNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/word/PointerCastNode.java Wed Mar 11 23:36:38 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/word/PointerCastNode.java Thu Mar 12 01:11:22 2015 +0100 @@ -25,14 +25,15 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.word.HotSpotOperation.HotspotOpcode; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; /** - * Cast between Word and metaspace pointers that is introduced by the - * {@link HotSpotWordTypeRewriterPhase}. + * Cast between Word and metaspace pointers exposed by the {@link HotspotOpcode#FROM_POINTER} and + * {@link HotspotOpcode#TO_KLASS_POINTER} operations. */ @NodeInfo public final class PointerCastNode extends FloatingNode implements LIRLowerable { diff -r c70ef0d09be9 -r c59d8ba9ced5 graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java Wed Mar 11 23:36:38 2015 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java Thu Mar 12 01:11:22 2015 +0100 @@ -29,11 +29,12 @@ import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.word.phases.*; +import com.oracle.graal.word.Word.Opcode; /** - * Cast between Word and Object that is introduced by the {@link WordTypeRewriterPhase}. It has an - * impact on the pointer maps for the GC, so it must not be scheduled or optimized away. + * Casts between Word and Object exposed by the {@link Opcode#FROM_OBJECT} and + * {@link Opcode#TO_OBJECT} operations. It has an impact on the pointer maps for the GC, so it must + * not be scheduled or optimized away. */ @NodeInfo public final class WordCastNode extends FixedWithNextNode implements LIRLowerable, Canonicalizable { diff -r c70ef0d09be9 -r c59d8ba9ced5 graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Wed Mar 11 23:36:38 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,420 +0,0 @@ -/* - * Copyright (c) 2012, 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.word.phases; - -import static com.oracle.graal.api.meta.LocationIdentity.*; - -import java.lang.reflect.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.replacements.*; -import com.oracle.graal.compiler.common.*; -import com.oracle.graal.compiler.common.calc.*; -import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.HeapAccess.BarrierType; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.type.*; -import com.oracle.graal.nodes.util.*; -import com.oracle.graal.phases.*; -import com.oracle.graal.phases.graph.*; -import com.oracle.graal.word.*; -import com.oracle.graal.word.Word.Opcode; -import com.oracle.graal.word.Word.Operation; -import com.oracle.graal.word.nodes.*; - -/** - * Transforms all uses of the {@link Word} class into unsigned operations on {@code int} or - * {@code long} values, depending on the word kind of the underlying platform. - */ -public class WordTypeRewriterPhase extends Phase { - - protected final MetaAccessProvider metaAccess; - protected final SnippetReflectionProvider snippetReflection; - protected final ConstantReflectionProvider constantReflection; - protected final WordTypes wordTypes; - - public WordTypeRewriterPhase(MetaAccessProvider metaAccess, SnippetReflectionProvider snippetReflection, ConstantReflectionProvider constantReflection, WordTypes wordTypes) { - this.metaAccess = metaAccess; - this.wordTypes = wordTypes; - this.snippetReflection = snippetReflection; - this.constantReflection = constantReflection; - } - - @Override - protected void run(StructuredGraph graph) { - InferStamps.inferStamps(graph); - - for (Node n : graph.getNodes()) { - if (n instanceof ValueNode) { - changeToWord(graph, (ValueNode) n); - } - } - - for (Node node : graph.getNodes()) { - rewriteNode(graph, node); - } - } - - /** - * Change the stamp for word nodes from the object stamp ({@link WordBase} or anything extending - * or implementing that interface) to the primitive word stamp. - */ - private void changeToWord(StructuredGraph graph, ValueNode node) { - if (wordTypes.isWord(node)) { - if (node.isConstant()) { - ConstantNode oldConstant = (ConstantNode) node; - assert oldConstant.asJavaConstant().getKind() == Kind.Object; - WordBase value = snippetReflection.asObject(WordBase.class, oldConstant.asJavaConstant()); - ConstantNode newConstant = ConstantNode.forIntegerKind(wordTypes.getWordKind(), value.rawValue(), node.graph()); - graph.replaceFloating(oldConstant, newConstant); - - } else { - node.setStamp(wordTypes.getWordStamp(StampTool.typeOrNull(node))); - } - } - } - - /** - * Clean up nodes that are no longer necessary or valid after the stamp change, and perform - * intrinsification of all methods called on word types. - */ - protected void rewriteNode(StructuredGraph graph, Node node) { - if (node instanceof CheckCastNode) { - rewriteCheckCast(graph, (CheckCastNode) node); - } else if (node instanceof PiNode) { - rewritePi(graph, (PiNode) node); - } else if (node instanceof LoadFieldNode) { - rewriteLoadField(graph, (LoadFieldNode) node); - } else if (node instanceof AccessIndexedNode) { - rewriteAccessIndexed(graph, (AccessIndexedNode) node); - } else if (node instanceof MethodCallTargetNode) { - rewriteInvoke(graph, (MethodCallTargetNode) node); - } - } - - /** - * Remove casts between word types (which by now no longer have kind Object). - */ - protected void rewriteCheckCast(StructuredGraph graph, CheckCastNode node) { - if (node.getKind() == wordTypes.getWordKind()) { - node.replaceAtUsages(node.object()); - graph.removeFixed(node); - } - } - - /** - * Remove casts between word types (which by now no longer have kind Object). - */ - protected void rewritePi(StructuredGraph graph, PiNode node) { - if (node.getKind() == wordTypes.getWordKind()) { - node.replaceAtUsages(node.object()); - graph.removeFloating(node); - } - } - - /** - * Fold constant field reads, e.g. enum constants. - */ - protected void rewriteLoadField(StructuredGraph graph, LoadFieldNode node) { - ConstantNode constant = node.asConstant(metaAccess, constantReflection, node.object()); - if (constant != null) { - node.replaceAtUsages(graph.unique(constant)); - graph.removeFixed(node); - } - } - - /** - * Change loads and stores of word-arrays. Since the element kind is managed by the node on its - * own and not in the stamp, {@link #changeToWord} does not perform all necessary changes. - */ - protected void rewriteAccessIndexed(StructuredGraph graph, AccessIndexedNode node) { - ResolvedJavaType arrayType = StampTool.typeOrNull(node.array()); - /* - * There are cases where the array does not have a known type yet, i.e., the type is null. - * In that case we assume it is not a word type. - */ - if (arrayType != null && wordTypes.isWord(arrayType.getComponentType()) && node.elementKind() != wordTypes.getWordKind()) { - /* - * The elementKind of the node is a final field, and other information such as the stamp - * depends on elementKind. Therefore, just create a new node and replace the old one. - */ - if (node instanceof LoadIndexedNode) { - graph.replaceFixedWithFixed(node, graph.add(new LoadIndexedNode(node.array(), node.index(), wordTypes.getWordKind()))); - } else if (node instanceof StoreIndexedNode) { - graph.replaceFixedWithFixed(node, graph.add(new StoreIndexedNode(node.array(), node.index(), wordTypes.getWordKind(), ((StoreIndexedNode) node).value()))); - } else { - throw GraalInternalError.shouldNotReachHere(); - } - } - } - - /** - * Intrinsification of methods that are annotated with {@link Operation}. - */ - protected void rewriteInvoke(StructuredGraph graph, MethodCallTargetNode callTargetNode) { - ResolvedJavaMethod targetMethod = callTargetNode.targetMethod(); - if (wordTypes.isWordOperation(targetMethod)) { - ResolvedJavaMethod wordMethod = wordTypes.getWordOperation(targetMethod, callTargetNode.invoke().getContextType()); - rewriteWordOperation(graph, callTargetNode, wordMethod); - } - } - - protected void rewriteWordOperation(StructuredGraph graph, MethodCallTargetNode callTargetNode, ResolvedJavaMethod targetMethod) throws GraalInternalError { - Invoke invoke = callTargetNode.invoke(); - Operation operation = targetMethod.getAnnotation(Word.Operation.class); - assert operation != null : targetMethod; - - NodeInputList arguments = callTargetNode.arguments(); - - switch (operation.opcode()) { - case NODE_CLASS: - assert arguments.size() == 2; - ValueNode left = arguments.get(0); - ValueNode right = operation.rightOperandIsInt() ? toUnsigned(graph, arguments.get(1), Kind.Int) : fromSigned(graph, arguments.get(1)); - - ValueNode replacement = graph.addOrUnique(createBinaryNodeInstance(operation.node(), left, right)); - if (replacement instanceof FixedWithNextNode) { - graph.addBeforeFixed(invoke.asNode(), (FixedWithNextNode) replacement); - } - replace(invoke, replacement); - break; - - case COMPARISON: - assert arguments.size() == 2; - replace(invoke, comparisonOp(graph, operation.condition(), arguments.get(0), fromSigned(graph, arguments.get(1)))); - break; - - case NOT: - assert arguments.size() == 1; - replace(invoke, graph.unique(new XorNode(arguments.get(0), ConstantNode.forIntegerKind(wordTypes.getWordKind(), -1, graph)))); - break; - - case READ_POINTER: - case READ_OBJECT: - case READ_BARRIERED: { - assert arguments.size() == 2 || arguments.size() == 3; - Kind readKind = wordTypes.asKind(callTargetNode.returnType()); - LocationNode location; - if (arguments.size() == 2) { - location = makeLocation(graph, arguments.get(1), ANY_LOCATION); - } else { - location = makeLocation(graph, arguments.get(1), arguments.get(2)); - } - replace(invoke, readOp(graph, readKind, arguments.get(0), invoke, location, operation.opcode())); - break; - } - case READ_HEAP: { - assert arguments.size() == 3; - Kind readKind = wordTypes.asKind(callTargetNode.returnType()); - LocationNode location = makeLocation(graph, arguments.get(1), ANY_LOCATION); - BarrierType barrierType = snippetReflection.asObject(BarrierType.class, arguments.get(2).asJavaConstant()); - replace(invoke, readOp(graph, readKind, arguments.get(0), invoke, location, barrierType, true)); - break; - } - case WRITE_POINTER: - case WRITE_OBJECT: - case WRITE_BARRIERED: - case INITIALIZE: { - assert arguments.size() == 3 || arguments.size() == 4; - Kind writeKind = wordTypes.asKind(targetMethod.getSignature().getParameterType(targetMethod.isStatic() ? 2 : 1, targetMethod.getDeclaringClass())); - LocationNode location; - if (arguments.size() == 3) { - location = makeLocation(graph, arguments.get(1), LocationIdentity.ANY_LOCATION); - } else { - location = makeLocation(graph, arguments.get(1), arguments.get(3)); - } - replace(invoke, writeOp(graph, writeKind, arguments.get(0), arguments.get(2), invoke, location, operation.opcode())); - break; - } - case ZERO: - assert arguments.size() == 0; - replace(invoke, ConstantNode.forIntegerKind(wordTypes.getWordKind(), 0L, graph)); - break; - - case FROM_UNSIGNED: - assert arguments.size() == 1; - replace(invoke, fromUnsigned(graph, arguments.get(0))); - break; - - case FROM_SIGNED: - assert arguments.size() == 1; - replace(invoke, fromSigned(graph, arguments.get(0))); - break; - - case TO_RAW_VALUE: - assert arguments.size() == 1; - replace(invoke, toUnsigned(graph, arguments.get(0), Kind.Long)); - break; - - case FROM_OBJECT: - assert arguments.size() == 1; - WordCastNode objectToWord = graph.add(WordCastNode.objectToWord(arguments.get(0), wordTypes.getWordKind())); - graph.addBeforeFixed(invoke.asNode(), objectToWord); - replace(invoke, objectToWord); - break; - - case FROM_ARRAY: - assert arguments.size() == 2; - replace(invoke, graph.unique(new ComputeAddressNode(arguments.get(0), arguments.get(1), StampFactory.forKind(wordTypes.getWordKind())))); - break; - - case TO_OBJECT: - assert arguments.size() == 1; - WordCastNode wordToObject = graph.add(WordCastNode.wordToObject(arguments.get(0), wordTypes.getWordKind())); - graph.addBeforeFixed(invoke.asNode(), wordToObject); - replace(invoke, wordToObject); - break; - - default: - throw new GraalInternalError("Unknown opcode: %s", operation.opcode()); - } - } - - protected ValueNode fromUnsigned(StructuredGraph graph, ValueNode value) { - return convert(graph, value, wordTypes.getWordKind(), true); - } - - private ValueNode fromSigned(StructuredGraph graph, ValueNode value) { - return convert(graph, value, wordTypes.getWordKind(), false); - } - - protected ValueNode toUnsigned(StructuredGraph graph, ValueNode value, Kind toKind) { - return convert(graph, value, toKind, true); - } - - private static ValueNode convert(StructuredGraph graph, ValueNode value, Kind toKind, boolean unsigned) { - if (value.getKind() == toKind) { - return value; - } - - if (toKind == Kind.Int) { - assert value.getKind() == Kind.Long; - return graph.unique(new NarrowNode(value, 32)); - } else { - assert toKind == Kind.Long; - assert value.getKind().getStackKind() == Kind.Int; - if (unsigned) { - return graph.unique(new ZeroExtendNode(value, 64)); - } else { - return graph.unique(new SignExtendNode(value, 64)); - } - } - } - - /** - * Create an instance of a binary node which is used to lower Word operations. This method is - * called for all Word operations which are annotated with @Operation(node = ...) and - * encapsulates the reflective allocation of the node. - */ - private static ValueNode createBinaryNodeInstance(Class nodeClass, ValueNode left, ValueNode right) { - try { - Constructor cons = nodeClass.getDeclaredConstructor(ValueNode.class, ValueNode.class); - return (ValueNode) cons.newInstance(left, right); - } catch (Throwable ex) { - throw new GraalInternalError(ex).addContext(nodeClass.getName()); - } - } - - private ValueNode comparisonOp(StructuredGraph graph, Condition condition, ValueNode left, ValueNode right) { - assert left.getKind() == wordTypes.getWordKind() && right.getKind() == wordTypes.getWordKind(); - - // mirroring gets the condition into canonical form - boolean mirror = condition.canonicalMirror(); - - ValueNode a = mirror ? right : left; - ValueNode b = mirror ? left : right; - - CompareNode comparison; - if (condition == Condition.EQ || condition == Condition.NE) { - comparison = new IntegerEqualsNode(a, b); - } else if (condition.isUnsigned()) { - comparison = new IntegerBelowNode(a, b); - } else { - comparison = new IntegerLessThanNode(a, b); - } - - ConstantNode trueValue = ConstantNode.forInt(1, graph); - ConstantNode falseValue = ConstantNode.forInt(0, graph); - - if (condition.canonicalNegate()) { - ConstantNode temp = trueValue; - trueValue = falseValue; - falseValue = temp; - } - ConditionalNode materialize = graph.unique(new ConditionalNode(graph.unique(comparison), trueValue, falseValue)); - return materialize; - } - - protected LocationNode makeLocation(StructuredGraph graph, ValueNode offset, ValueNode locationIdentity) { - if (locationIdentity.isConstant()) { - return makeLocation(graph, offset, snippetReflection.asObject(LocationIdentity.class, locationIdentity.asJavaConstant())); - } - return graph.unique(new SnippetLocationNode(snippetReflection, locationIdentity, ConstantNode.forLong(0, graph), fromSigned(graph, offset), ConstantNode.forInt(1, graph))); - } - - protected LocationNode makeLocation(StructuredGraph graph, ValueNode offset, LocationIdentity locationIdentity) { - return graph.unique(new IndexedLocationNode(locationIdentity, 0, fromSigned(graph, offset), 1)); - } - - protected ValueNode readOp(StructuredGraph graph, Kind readKind, ValueNode base, Invoke invoke, LocationNode location, Opcode op) { - assert op == Opcode.READ_POINTER || op == Opcode.READ_OBJECT || op == Opcode.READ_BARRIERED; - final BarrierType barrier = (op == Opcode.READ_BARRIERED ? BarrierType.PRECISE : BarrierType.NONE); - final boolean compressible = (op == Opcode.READ_OBJECT || op == Opcode.READ_BARRIERED); - - return readOp(graph, readKind, base, invoke, location, barrier, compressible); - } - - protected ValueNode readOp(StructuredGraph graph, Kind readKind, ValueNode base, Invoke invoke, LocationNode location, BarrierType barrierType, boolean compressible) { - JavaReadNode read = graph.add(new JavaReadNode(readKind, base, location, barrierType, compressible)); - graph.addBeforeFixed(invoke.asNode(), read); - /* - * The read must not float outside its block otherwise it may float above an explicit zero - * check on its base address. - */ - read.setGuard(AbstractBeginNode.prevBegin(invoke.asNode())); - return read; - } - - protected ValueNode writeOp(StructuredGraph graph, Kind writeKind, ValueNode base, ValueNode value, Invoke invoke, LocationNode location, Opcode op) { - assert op == Opcode.WRITE_POINTER || op == Opcode.WRITE_OBJECT || op == Opcode.WRITE_BARRIERED || op == Opcode.INITIALIZE; - final BarrierType barrier = (op == Opcode.WRITE_BARRIERED ? BarrierType.PRECISE : BarrierType.NONE); - final boolean compressible = (op == Opcode.WRITE_OBJECT || op == Opcode.WRITE_BARRIERED); - final boolean initialize = (op == Opcode.INITIALIZE); - JavaWriteNode write = graph.add(new JavaWriteNode(writeKind, base, value, location, barrier, compressible, initialize)); - write.setStateAfter(invoke.stateAfter()); - graph.addBeforeFixed(invoke.asNode(), write); - return write; - } - - protected void replace(Invoke invoke, ValueNode value) { - FixedNode next = invoke.next(); - invoke.setNext(null); - invoke.asNode().replaceAtPredecessor(next); - invoke.asNode().replaceAtUsages(value); - GraphUtil.killCFG(invoke.asNode()); - } -} diff -r c70ef0d09be9 -r c59d8ba9ced5 graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java Wed Mar 11 23:36:38 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,165 +0,0 @@ -/* - * Copyright (c) 2011, 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.word.phases; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.graph.Node.NodeIntrinsic; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.util.*; -import com.oracle.graal.phases.*; -import com.oracle.graal.phases.graph.*; -import com.oracle.graal.word.*; -import com.oracle.graal.word.Word.Operation; - -/** - * Verifies invariants that must hold for code that uses the {@link WordBase word type} above and - * beyond normal bytecode verification. - */ -public class WordTypeVerificationPhase extends Phase { - - private final WordTypes wordAccess; - - public WordTypeVerificationPhase(MetaAccessProvider metaAccess, Kind wordKind) { - this.wordAccess = new WordTypes(metaAccess, wordKind); - } - - @Override - protected void run(StructuredGraph graph) { - assert verify(graph); - } - - protected boolean verify(StructuredGraph inputGraph) { - /* - * This is a verification phase, so we do not want to have side effects. Since inferStamps() - * modifies the stamp of nodes, we copy the graph before running the verification. - */ - StructuredGraph graph = inputGraph.copy(); - InferStamps.inferStamps(graph); - - for (ValueNode node : graph.getNodes().filter(ValueNode.class)) { - for (Node usage : node.usages()) { - if (usage instanceof AccessMonitorNode) { - verify(!isWord(node), node, usage, "word value has no monitor"); - } else if (usage instanceof LoadFieldNode) { - verify(!isWord(node) || ((LoadFieldNode) usage).object() != node, node, usage, "cannot load from word value"); - } else if (usage instanceof StoreFieldNode) { - verify(!isWord(node) || ((StoreFieldNode) usage).object() != node, node, usage, "cannot store to word value"); - } else if (usage instanceof CheckCastNode) { - verify(isWord(((CheckCastNode) usage).type()) == isWord(node), node, usage, "word cannot be cast to object, and vice versa"); - } else if (usage instanceof LoadIndexedNode) { - verify(!isWord(node) || ((LoadIndexedNode) usage).array() != node, node, usage, "cannot load from word value"); - verify(!isWord(node) || ((LoadIndexedNode) usage).index() != node, node, usage, "cannot use word value as index"); - } else if (usage instanceof StoreIndexedNode) { - verify(!isWord(node) || ((StoreIndexedNode) usage).array() != node, node, usage, "cannot store to word value"); - verify(!isWord(node) || ((StoreIndexedNode) usage).index() != node, node, usage, "cannot use word value as index"); - } else if (usage instanceof MethodCallTargetNode) { - MethodCallTargetNode callTarget = (MethodCallTargetNode) usage; - verifyInvoke(node, callTarget); - } else if (usage instanceof ObjectEqualsNode) { - verify(!isWord(node) || ((ObjectEqualsNode) usage).getX() != node, node, usage, "cannot use word type in comparison"); - verify(!isWord(node) || ((ObjectEqualsNode) usage).getY() != node, node, usage, "cannot use word type in comparison"); - } else if (usage instanceof ArrayLengthNode) { - verify(!isWord(node) || ((ArrayLengthNode) usage).array() != node, node, usage, "cannot get array length from word value"); - } else if (usage instanceof ValuePhiNode) { - if (!(node instanceof AbstractMergeNode)) { - ValuePhiNode phi = (ValuePhiNode) usage; - for (ValueNode input : phi.values()) { - verify(isWord(node) == isWord(input), node, input, "cannot merge word and non-word values"); - } - } - } - } - } - return true; - } - - protected void verifyInvoke(ValueNode node, MethodCallTargetNode callTarget) { - ResolvedJavaMethod method = callTarget.targetMethod(); - if (method.getAnnotation(NodeIntrinsic.class) == null) { - Invoke invoke = (Invoke) callTarget.usages().first(); - NodeInputList arguments = callTarget.arguments(); - boolean isStatic = method.isStatic(); - int argc = 0; - if (!isStatic) { - ValueNode receiver = arguments.get(argc); - if (receiver == node && isWord(node)) { - ResolvedJavaMethod resolvedMethod = wordAccess.getWordImplType().resolveConcreteMethod(method, invoke.getContextType()); - verify(resolvedMethod != null, node, invoke.asNode(), "cannot resolve method on Word class: " + method.format("%H.%n(%P) %r")); - Operation operation = resolvedMethod.getAnnotation(Word.Operation.class); - verify(operation != null, node, invoke.asNode(), "cannot dispatch on word value to non @Operation annotated method " + resolvedMethod); - } - argc++; - } - Signature signature = method.getSignature(); - for (int i = 0; i < signature.getParameterCount(false); i++) { - ValueNode argument = arguments.get(argc); - if (argument == node) { - ResolvedJavaType type = (ResolvedJavaType) signature.getParameterType(i, method.getDeclaringClass()); - verify(isWord(type) == isWord(argument), node, invoke.asNode(), "cannot pass word value to non-word parameter " + i + " or vice-versa"); - } - argc++; - } - } - } - - private boolean isWord(ValueNode node) { - return wordAccess.isWord(node); - } - - private boolean isWord(ResolvedJavaType type) { - return wordAccess.isWord(type); - } - - private static void verify(boolean condition, Node node, Node usage, String message) { - if (!condition) { - error(node, usage, message); - } - } - - private static void error(Node node, Node usage, String message) { - throw new GraalInternalError(String.format("Snippet verification error: %s" + "%n node: %s (%s)" + "%n usage: %s (%s)", message, node, sourceLocation(node), usage, sourceLocation(usage))); - } - - private static String sourceLocation(Node n) { - if (n instanceof PhiNode) { - StringBuilder buf = new StringBuilder(); - for (Node usage : n.usages()) { - String loc = sourceLocation(usage); - if (!loc.equals("")) { - if (buf.length() != 0) { - buf.append(", "); - } - buf.append(loc); - } - } - return buf.toString(); - } else { - String loc = GraphUtil.approxSourceLocation(n); - return loc == null ? ((StructuredGraph) n.graph()).method().format("method %h.%n") : loc; - } - } -} diff -r c70ef0d09be9 -r c59d8ba9ced5 graal/com.oracle.nfi.test/test/com/oracle/nfi/test/NativeFunctionInterfaceTest.java --- a/graal/com.oracle.nfi.test/test/com/oracle/nfi/test/NativeFunctionInterfaceTest.java Wed Mar 11 23:36:38 2015 +0100 +++ b/graal/com.oracle.nfi.test/test/com/oracle/nfi/test/NativeFunctionInterfaceTest.java Thu Mar 12 01:11:22 2015 +0100 @@ -36,7 +36,6 @@ import com.oracle.nfi.*; import com.oracle.nfi.api.*; -@Ignore public class NativeFunctionInterfaceTest { public final NativeFunctionInterface nfi;