# HG changeset patch # User Doug Simon # Date 1426140858 -3600 # Node ID 4545e180658c0a60e4c7f67e9cd5dbbc03fdf93f # Parent 2e6e20ac56b4ac953f31ec4e986e9e285babe764# Parent deab43a789ad8086672a2863b5b7b7f1892fa67a Merge. diff -r deab43a789ad -r 4545e180658c graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java Wed Mar 11 17:45:21 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java Thu Mar 12 07:14:18 2015 +0100 @@ -43,7 +43,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.options.*; import com.oracle.graal.replacements.*; -import com.oracle.graal.word.phases.*; +import com.oracle.graal.word.*; /** * Defines the {@link Plugins} used when running on HotSpot. diff -r deab43a789ad -r 4545e180658c graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotParameterPlugin.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotParameterPlugin.java Wed Mar 11 17:45:21 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotParameterPlugin.java Thu Mar 12 07:14:18 2015 +0100 @@ -29,7 +29,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.type.*; -import com.oracle.graal.word.phases.*; +import com.oracle.graal.word.*; public final class HotSpotParameterPlugin implements ParameterPlugin { private final WordTypes wordTypes; diff -r deab43a789ad -r 4545e180658c graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSnippetReflectionProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSnippetReflectionProvider.java Wed Mar 11 17:45:21 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSnippetReflectionProvider.java Thu Mar 12 07:14:18 2015 +0100 @@ -73,6 +73,9 @@ } public Object getInjectedNodeIntrinsicParameter(ResolvedJavaType type) { + if (type.isInstance(forObject(runtime.getHostProviders().getWordTypes()))) { + return runtime.getHostProviders().getWordTypes(); + } if (type.isInstance(forObject(runtime))) { return runtime; } diff -r deab43a789ad -r 4545e180658c graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotWordOperationPlugin.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotWordOperationPlugin.java Wed Mar 11 17:45:21 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotWordOperationPlugin.java Thu Mar 12 07:14:18 2015 +0100 @@ -39,7 +39,7 @@ import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.replacements.*; -import com.oracle.graal.word.phases.*; +import com.oracle.graal.word.*; /** * Extends {@link WordOperationPlugin} to handle {@linkplain HotSpotOperation HotSpot word diff -r deab43a789ad -r 4545e180658c 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 17:45:21 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/NativeCallStubGraphBuilder.java Thu Mar 12 07:14:18 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 deab43a789ad -r 4545e180658c graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java Wed Mar 11 17:45:21 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java Thu Mar 12 07:14:18 2015 +0100 @@ -24,6 +24,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.nodeinfo.*; @@ -44,8 +45,8 @@ public static final NodeClass TYPE = NodeClass.create(BeginLockScopeNode.class); protected int lockDepth; - public BeginLockScopeNode(int lockDepth) { - super(TYPE, null); + public BeginLockScopeNode(@InjectedNodeParameter WordTypes wordTypes, int lockDepth) { + super(TYPE, StampFactory.forKind(wordTypes.getWordKind())); this.lockDepth = lockDepth; } @@ -68,6 +69,6 @@ gen.setResult(this, result); } - @NodeIntrinsic(setStampFromReturnType = true) + @NodeIntrinsic public static native Word beginLockScope(@ConstantNodeParameter int lockDepth); } diff -r deab43a789ad -r 4545e180658c graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CStringNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CStringNode.java Wed Mar 11 17:45:21 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CStringNode.java Thu Mar 12 07:14:18 2015 +0100 @@ -23,6 +23,7 @@ package com.oracle.graal.hotspot.nodes; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.calc.*; @@ -38,8 +39,8 @@ public static final NodeClass TYPE = NodeClass.create(CStringNode.class); protected final String string; - public CStringNode(String string) { - super(TYPE, null); + public CStringNode(@InjectedNodeParameter WordTypes wordTypes, String string) { + super(TYPE, StampFactory.forKind(wordTypes.getWordKind())); this.string = string; } @@ -68,6 +69,6 @@ return bytes; } - @NodeIntrinsic(setStampFromReturnType = true) + @NodeIntrinsic public static native Word cstring(@ConstantNodeParameter String string); } diff -r deab43a789ad -r 4545e180658c graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentJavaThreadNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentJavaThreadNode.java Wed Mar 11 17:45:21 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentJavaThreadNode.java Thu Mar 12 07:14:18 2015 +0100 @@ -42,8 +42,8 @@ protected LIRKind wordKind; - public CurrentJavaThreadNode(@InjectedNodeParameter HotSpotGraalRuntimeProvider runtime) { - this(runtime.getTarget().wordKind); + public CurrentJavaThreadNode(@InjectedNodeParameter WordTypes wordTypes) { + this(wordTypes.getWordKind()); } public CurrentJavaThreadNode(Kind wordKind) { @@ -65,6 +65,6 @@ } } - @NodeIntrinsic(setStampFromReturnType = true) + @NodeIntrinsic public static native Word get(); } diff -r deab43a789ad -r 4545e180658c graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentLockNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentLockNode.java Wed Mar 11 17:45:21 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentLockNode.java Thu Mar 12 07:14:18 2015 +0100 @@ -24,6 +24,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.nodeinfo.*; @@ -40,8 +41,8 @@ protected int lockDepth; - public CurrentLockNode(int lockDepth) { - super(TYPE, null); + public CurrentLockNode(@InjectedNodeParameter WordTypes wordTypes, int lockDepth) { + super(TYPE, StampFactory.forKind(wordTypes.getWordKind())); this.lockDepth = lockDepth; } @@ -55,6 +56,6 @@ gen.setResult(this, result); } - @NodeIntrinsic(setStampFromReturnType = true) + @NodeIntrinsic public static native Word currentLock(@ConstantNodeParameter int lockDepth); } diff -r deab43a789ad -r 4545e180658c graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DimensionsNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DimensionsNode.java Wed Mar 11 17:45:21 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DimensionsNode.java Thu Mar 12 07:14:18 2015 +0100 @@ -28,6 +28,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodeinfo.*; @@ -45,8 +46,8 @@ public static final NodeClass TYPE = NodeClass.create(DimensionsNode.class); protected final int rank; - public DimensionsNode(int rank) { - super(TYPE, null); + public DimensionsNode(@InjectedNodeParameter WordTypes wordTypes, int rank) { + super(TYPE, StampFactory.forKind(wordTypes.getWordKind())); this.rank = rank; } @@ -61,6 +62,6 @@ gen.setResult(this, result); } - @NodeIntrinsic(setStampFromReturnType = true) + @NodeIntrinsic public static native Word allocaDimsArray(@ConstantNodeParameter int rank); } diff -r deab43a789ad -r 4545e180658c graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorCounterNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorCounterNode.java Wed Mar 11 17:45:21 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorCounterNode.java Thu Mar 12 07:14:18 2015 +0100 @@ -26,6 +26,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.calc.*; @@ -39,8 +40,8 @@ public final class MonitorCounterNode extends FloatingNode implements LIRLowerable { public static final NodeClass TYPE = NodeClass.create(MonitorCounterNode.class); - public MonitorCounterNode() { - super(TYPE, null); + public MonitorCounterNode(@InjectedNodeParameter WordTypes wordTypes) { + super(TYPE, StampFactory.forKind(wordTypes.getWordKind())); } @Override @@ -51,6 +52,6 @@ gen.setResult(this, result); } - @NodeIntrinsic(setStampFromReturnType = true) + @NodeIntrinsic public static native Word counter(); } diff -r deab43a789ad -r 4545e180658c graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java Wed Mar 11 17:45:21 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java Thu Mar 12 07:14:18 2015 +0100 @@ -38,7 +38,6 @@ import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.nodes.*; import com.oracle.graal.word.*; -import com.oracle.graal.word.phases.*; /** * A {@linkplain #getGraph() generated} stub for a {@link Transition non-leaf} foreign call from diff -r deab43a789ad -r 4545e180658c 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 17:45:21 2015 -0700 +++ /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 deab43a789ad -r 4545e180658c graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/word/HotSpotWordTypes.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/word/HotSpotWordTypes.java Wed Mar 11 17:45:21 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/word/HotSpotWordTypes.java Thu Mar 12 07:14:18 2015 +0100 @@ -25,7 +25,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.hotspot.nodes.type.*; -import com.oracle.graal.word.phases.*; +import com.oracle.graal.word.*; /** * Extends {@link WordTypes} with information about HotSpot metaspace pointer types. diff -r deab43a789ad -r 4545e180658c 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 17:45:21 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/word/PointerCastNode.java Thu Mar 12 07:14:18 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 deab43a789ad -r 4545e180658c graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultGenericInvocationPlugin.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultGenericInvocationPlugin.java Wed Mar 11 17:45:21 2015 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultGenericInvocationPlugin.java Thu Mar 12 07:14:18 2015 +0100 @@ -35,7 +35,7 @@ import com.oracle.graal.java.GraphBuilderPlugin.GenericInvocationPlugin; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.word.phases.*; +import com.oracle.graal.word.*; /** * An {@link GenericInvocationPlugin} that handles methods annotated by {@link Fold}, @@ -108,8 +108,11 @@ } res = b.append(res); - if (res.getKind().getStackKind() != Kind.Void) { + if (returnKind != Kind.Void) { + assert res.getKind().getStackKind() != Kind.Void; b.push(returnKind.getStackKind(), res); + } else { + assert res.getKind().getStackKind() == Kind.Void; } return true; diff -r deab43a789ad -r 4545e180658c graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraphKit.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraphKit.java Wed Mar 11 17:45:21 2015 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraphKit.java Thu Mar 12 07:14:18 2015 +0100 @@ -38,7 +38,7 @@ import com.oracle.graal.phases.common.inlining.*; import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.ReplacementsImpl.FrameStateProcessing; -import com.oracle.graal.word.phases.*; +import com.oracle.graal.word.*; /** * A utility for manually creating a graph. This will be expanded as necessary to support all diff -r deab43a789ad -r 4545e180658c graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java Wed Mar 11 17:45:21 2015 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java Thu Mar 12 07:14:18 2015 +0100 @@ -42,7 +42,6 @@ import com.oracle.graal.word.Word.Opcode; import com.oracle.graal.word.Word.Operation; import com.oracle.graal.word.nodes.*; -import com.oracle.graal.word.phases.*; /** * A {@link GenericInvocationPlugin} for calls to {@linkplain Operation word operations}. diff -r deab43a789ad -r 4545e180658c graal/com.oracle.graal.word/src/com/oracle/graal/word/WordTypes.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/WordTypes.java Thu Mar 12 07:14:18 2015 +0100 @@ -0,0 +1,139 @@ +/* + * 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; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.graal.word.Word.Operation; + +/** + * Encapsulates information for Java types representing raw words (as opposed to Objects). + */ +public class WordTypes { + + /** + * Resolved type for {@link WordBase}. + */ + private final ResolvedJavaType wordBaseType; + + /** + * Resolved type for {@link Word}. + */ + private final ResolvedJavaType wordImplType; + + /** + * Resolved type for {@link ObjectAccess}. + */ + private final ResolvedJavaType objectAccessType; + + /** + * Resolved type for {@link BarrieredAccess}. + */ + private final ResolvedJavaType barrieredAccessType; + + private final Kind wordKind; + + public WordTypes(MetaAccessProvider metaAccess, Kind wordKind) { + this.wordKind = wordKind; + this.wordBaseType = metaAccess.lookupJavaType(WordBase.class); + this.wordImplType = metaAccess.lookupJavaType(Word.class); + this.objectAccessType = metaAccess.lookupJavaType(ObjectAccess.class); + this.barrieredAccessType = metaAccess.lookupJavaType(BarrieredAccess.class); + } + + /** + * Determines if a given method denotes a word operation. + */ + public boolean isWordOperation(ResolvedJavaMethod targetMethod) { + final boolean isObjectAccess = objectAccessType.equals(targetMethod.getDeclaringClass()); + final boolean isBarrieredAccess = barrieredAccessType.equals(targetMethod.getDeclaringClass()); + if (isObjectAccess || isBarrieredAccess) { + assert targetMethod.getAnnotation(Operation.class) != null : targetMethod + " should be annotated with @" + Operation.class.getSimpleName(); + return true; + } + return isWord(targetMethod.getDeclaringClass()); + } + + /** + * Gets the method annotated with {@link Operation} based on a given method that represents a + * word operation (but may not necessarily have the annotation). + * + * @param callingContextType the {@linkplain ResolvedJavaType type} from which + * {@code targetMethod} is invoked + * @return the {@link Operation} method resolved for {@code targetMethod} if any + */ + public ResolvedJavaMethod getWordOperation(ResolvedJavaMethod targetMethod, ResolvedJavaType callingContextType) { + final boolean isWordBase = wordBaseType.isAssignableFrom(targetMethod.getDeclaringClass()); + ResolvedJavaMethod wordMethod = targetMethod; + if (isWordBase && !targetMethod.isStatic()) { + assert wordImplType.isLinked(); + wordMethod = wordImplType.resolveConcreteMethod(targetMethod, callingContextType); + } + assert wordMethod.getAnnotation(Operation.class) != null : wordMethod; + return wordMethod; + } + + /** + * Determines if a given node has a word type. + */ + public boolean isWord(ValueNode node) { + return isWord(StampTool.typeOrNull(node)); + } + + /** + * Determines if a given type is a word type. + */ + public boolean isWord(ResolvedJavaType type) { + return type != null && wordBaseType.isAssignableFrom(type); + } + + /** + * Gets the kind for a given type, returning the {@linkplain #getWordKind() word kind} if + * {@code type} is a {@linkplain #isWord(ResolvedJavaType) word type}. + */ + public Kind asKind(JavaType type) { + if (type instanceof ResolvedJavaType && isWord((ResolvedJavaType) type)) { + return wordKind; + } else { + return type.getKind(); + } + } + + public Kind getWordKind() { + return wordKind; + } + + /** + * Gets the stamp for a given {@linkplain #isWord(ResolvedJavaType) word type}. + */ + public Stamp getWordStamp(ResolvedJavaType type) { + assert isWord(type); + return StampFactory.forKind(wordKind); + } + + public ResolvedJavaType getWordImplType() { + return wordImplType; + } +} diff -r deab43a789ad -r 4545e180658c 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 17:45:21 2015 -0700 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java Thu Mar 12 07:14:18 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 deab43a789ad -r 4545e180658c 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 17:45:21 2015 -0700 +++ /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 deab43a789ad -r 4545e180658c 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 17:45:21 2015 -0700 +++ /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 deab43a789ad -r 4545e180658c graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypes.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypes.java Wed Mar 11 17:45:21 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,140 +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 com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.type.*; -import com.oracle.graal.word.*; -import com.oracle.graal.word.Word.Operation; - -/** - * Encapsulates information for Java types representing raw words (as opposed to Objects). - */ -public class WordTypes { - - /** - * Resolved type for {@link WordBase}. - */ - private final ResolvedJavaType wordBaseType; - - /** - * Resolved type for {@link Word}. - */ - private final ResolvedJavaType wordImplType; - - /** - * Resolved type for {@link ObjectAccess}. - */ - private final ResolvedJavaType objectAccessType; - - /** - * Resolved type for {@link BarrieredAccess}. - */ - private final ResolvedJavaType barrieredAccessType; - - private final Kind wordKind; - - public WordTypes(MetaAccessProvider metaAccess, Kind wordKind) { - this.wordKind = wordKind; - this.wordBaseType = metaAccess.lookupJavaType(WordBase.class); - this.wordImplType = metaAccess.lookupJavaType(Word.class); - this.objectAccessType = metaAccess.lookupJavaType(ObjectAccess.class); - this.barrieredAccessType = metaAccess.lookupJavaType(BarrieredAccess.class); - } - - /** - * Determines if a given method denotes a word operation. - */ - public boolean isWordOperation(ResolvedJavaMethod targetMethod) { - final boolean isObjectAccess = objectAccessType.equals(targetMethod.getDeclaringClass()); - final boolean isBarrieredAccess = barrieredAccessType.equals(targetMethod.getDeclaringClass()); - if (isObjectAccess || isBarrieredAccess) { - assert targetMethod.getAnnotation(Operation.class) != null : targetMethod + " should be annotated with @" + Operation.class.getSimpleName(); - return true; - } - return isWord(targetMethod.getDeclaringClass()); - } - - /** - * Gets the method annotated with {@link Operation} based on a given method that represents a - * word operation (but may not necessarily have the annotation). - * - * @param callingContextType the {@linkplain ResolvedJavaType type} from which - * {@code targetMethod} is invoked - * @return the {@link Operation} method resolved for {@code targetMethod} if any - */ - public ResolvedJavaMethod getWordOperation(ResolvedJavaMethod targetMethod, ResolvedJavaType callingContextType) { - final boolean isWordBase = wordBaseType.isAssignableFrom(targetMethod.getDeclaringClass()); - ResolvedJavaMethod wordMethod = targetMethod; - if (isWordBase && !targetMethod.isStatic()) { - assert wordImplType.isLinked(); - wordMethod = wordImplType.resolveConcreteMethod(targetMethod, callingContextType); - } - assert wordMethod.getAnnotation(Operation.class) != null : wordMethod; - return wordMethod; - } - - /** - * Determines if a given node has a word type. - */ - public boolean isWord(ValueNode node) { - return isWord(StampTool.typeOrNull(node)); - } - - /** - * Determines if a given type is a word type. - */ - public boolean isWord(ResolvedJavaType type) { - return type != null && wordBaseType.isAssignableFrom(type); - } - - /** - * Gets the kind for a given type, returning the {@linkplain #getWordKind() word kind} if - * {@code type} is a {@linkplain #isWord(ResolvedJavaType) word type}. - */ - public Kind asKind(JavaType type) { - if (type instanceof ResolvedJavaType && isWord((ResolvedJavaType) type)) { - return wordKind; - } else { - return type.getKind(); - } - } - - public Kind getWordKind() { - return wordKind; - } - - /** - * Gets the stamp for a given {@linkplain #isWord(ResolvedJavaType) word type}. - */ - public Stamp getWordStamp(ResolvedJavaType type) { - assert isWord(type); - return StampFactory.forKind(wordKind); - } - - public ResolvedJavaType getWordImplType() { - return wordImplType; - } -} diff -r deab43a789ad -r 4545e180658c 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 17:45:21 2015 -0700 +++ b/graal/com.oracle.nfi.test/test/com/oracle/nfi/test/NativeFunctionInterfaceTest.java Thu Mar 12 07:14:18 2015 +0100 @@ -36,7 +36,6 @@ import com.oracle.nfi.*; import com.oracle.nfi.api.*; -@Ignore public class NativeFunctionInterfaceTest { public final NativeFunctionInterface nfi; diff -r deab43a789ad -r 4545e180658c mx/mx_graal.py --- a/mx/mx_graal.py Wed Mar 11 17:45:21 2015 -0700 +++ b/mx/mx_graal.py Thu Mar 12 07:14:18 2015 +0100 @@ -2203,6 +2203,9 @@ includedirs = set() for p in mx.projects(): + projsetting = getattr(p, 'jacoco', '') + if projsetting == 'exclude': + continue for include in includes: if include in p.dir: includedirs.add(p.dir)