# HG changeset patch # User Gilles Duboscq # Date 1375978667 -7200 # Node ID ef6915cf1e59f0c45472d326eb6bd77682d06d19 # Parent 7894695caee6bc0657a1b50d2f1719db180dc86a Add illegal stamp Remove ValueNode.(object|integer)Stamp: use explicit tests/casts Fix ObjectStamp.join Introduce ObjectStamp.castTo Add some tests for ObjectStamp.join diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILCompilationResult.java --- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILCompilationResult.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILCompilationResult.java Thu Aug 08 18:17:47 2013 +0200 @@ -126,8 +126,8 @@ @Override protected void run(StructuredGraph graph) { for (LocalNode local : graph.getNodes(LocalNode.class)) { - if (local.kind() == Kind.Object) { - local.setStamp(StampFactory.declaredNonNull(local.objectStamp().type())); + if (local.stamp() instanceof ObjectStamp) { + local.setStamp(StampFactory.declaredNonNull(((ObjectStamp) local.stamp()).type())); } } } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXPhase.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXPhase.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXPhase.java Thu Aug 08 18:17:47 2013 +0200 @@ -22,23 +22,21 @@ */ package com.oracle.graal.compiler.ptx.test; -import com.oracle.graal.api.meta.Kind; -import com.oracle.graal.nodes.LocalNode; -import com.oracle.graal.nodes.StructuredGraph; -import com.oracle.graal.nodes.type.StampFactory; -import com.oracle.graal.phases.Phase; - +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.graal.phases.*; public class PTXPhase extends Phase { + @Override protected void run(StructuredGraph graph) { /* - * Assume that null checks would be done on the CPU caller side prior - * to copying data onto the GPU. + * Assume that null checks would be done on the CPU caller side prior to copying data onto + * the GPU. */ for (LocalNode local : graph.getNodes(LocalNode.class)) { - if (local.kind() == Kind.Object) { - local.setStamp(StampFactory.declaredNonNull(local.objectStamp().type())); + if (local.stamp() instanceof ObjectStamp) { + local.setStamp(StampFactory.declaredNonNull(((ObjectStamp) local.stamp()).type())); } } } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IntegerStampTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IntegerStampTest.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IntegerStampTest.java Thu Aug 08 18:17:47 2013 +0200 @@ -42,51 +42,51 @@ @Test public void testBooleanConstant() { - assertEquals(new IntegerStamp(Kind.Int, 1, 1, 0x1), ConstantNode.forBoolean(true, graph).integerStamp()); - assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0), ConstantNode.forBoolean(false, graph).integerStamp()); + assertEquals(new IntegerStamp(Kind.Int, 1, 1, 0x1), ConstantNode.forBoolean(true, graph).stamp()); + assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0), ConstantNode.forBoolean(false, graph).stamp()); } @Test public void testByteConstant() { - assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0), ConstantNode.forByte((byte) 0, graph).integerStamp()); - assertEquals(new IntegerStamp(Kind.Int, 16, 16, 0x10), ConstantNode.forByte((byte) 16, graph).integerStamp()); - assertEquals(new IntegerStamp(Kind.Int, -16, -16, 0xf0), ConstantNode.forByte((byte) -16, graph).integerStamp()); - assertEquals(new IntegerStamp(Kind.Int, 127, 127, 0x7f), ConstantNode.forByte((byte) 127, graph).integerStamp()); - assertEquals(new IntegerStamp(Kind.Int, -128, -128, 0x80), ConstantNode.forByte((byte) -128, graph).integerStamp()); + assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0), ConstantNode.forByte((byte) 0, graph).stamp()); + assertEquals(new IntegerStamp(Kind.Int, 16, 16, 0x10), ConstantNode.forByte((byte) 16, graph).stamp()); + assertEquals(new IntegerStamp(Kind.Int, -16, -16, 0xf0), ConstantNode.forByte((byte) -16, graph).stamp()); + assertEquals(new IntegerStamp(Kind.Int, 127, 127, 0x7f), ConstantNode.forByte((byte) 127, graph).stamp()); + assertEquals(new IntegerStamp(Kind.Int, -128, -128, 0x80), ConstantNode.forByte((byte) -128, graph).stamp()); } @Test public void testShortConstant() { - assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0), ConstantNode.forShort((short) 0, graph).integerStamp()); - assertEquals(new IntegerStamp(Kind.Int, 128, 128, 0x80), ConstantNode.forShort((short) 128, graph).integerStamp()); - assertEquals(new IntegerStamp(Kind.Int, -128, -128, 0xff80), ConstantNode.forShort((short) -128, graph).integerStamp()); - assertEquals(new IntegerStamp(Kind.Int, 32767, 32767, 0x7fff), ConstantNode.forShort((short) 32767, graph).integerStamp()); - assertEquals(new IntegerStamp(Kind.Int, -32768, -32768, 0x8000), ConstantNode.forShort((short) -32768, graph).integerStamp()); + assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0), ConstantNode.forShort((short) 0, graph).stamp()); + assertEquals(new IntegerStamp(Kind.Int, 128, 128, 0x80), ConstantNode.forShort((short) 128, graph).stamp()); + assertEquals(new IntegerStamp(Kind.Int, -128, -128, 0xff80), ConstantNode.forShort((short) -128, graph).stamp()); + assertEquals(new IntegerStamp(Kind.Int, 32767, 32767, 0x7fff), ConstantNode.forShort((short) 32767, graph).stamp()); + assertEquals(new IntegerStamp(Kind.Int, -32768, -32768, 0x8000), ConstantNode.forShort((short) -32768, graph).stamp()); } @Test public void testCharConstant() { - assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0), ConstantNode.forChar((char) 0, graph).integerStamp()); - assertEquals(new IntegerStamp(Kind.Int, 'A', 'A', 'A'), ConstantNode.forChar('A', graph).integerStamp()); - assertEquals(new IntegerStamp(Kind.Int, 128, 128, 0x80), ConstantNode.forChar((char) 128, graph).integerStamp()); - assertEquals(new IntegerStamp(Kind.Int, 65535, 65535, 0xffff), ConstantNode.forChar((char) 65535, graph).integerStamp()); + assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0), ConstantNode.forChar((char) 0, graph).stamp()); + assertEquals(new IntegerStamp(Kind.Int, 'A', 'A', 'A'), ConstantNode.forChar('A', graph).stamp()); + assertEquals(new IntegerStamp(Kind.Int, 128, 128, 0x80), ConstantNode.forChar((char) 128, graph).stamp()); + assertEquals(new IntegerStamp(Kind.Int, 65535, 65535, 0xffff), ConstantNode.forChar((char) 65535, graph).stamp()); } @Test public void testIntConstant() { - assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0), ConstantNode.forInt(0, graph).integerStamp()); - assertEquals(new IntegerStamp(Kind.Int, 128, 128, 0x80), ConstantNode.forInt(128, graph).integerStamp()); - assertEquals(new IntegerStamp(Kind.Int, -128, -128, 0xffffff80L), ConstantNode.forInt(-128, graph).integerStamp()); - assertEquals(new IntegerStamp(Kind.Int, Integer.MAX_VALUE, Integer.MAX_VALUE, 0x7fffffff), ConstantNode.forInt(Integer.MAX_VALUE, graph).integerStamp()); - assertEquals(new IntegerStamp(Kind.Int, Integer.MIN_VALUE, Integer.MIN_VALUE, 0x80000000L), ConstantNode.forInt(Integer.MIN_VALUE, graph).integerStamp()); + assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0), ConstantNode.forInt(0, graph).stamp()); + assertEquals(new IntegerStamp(Kind.Int, 128, 128, 0x80), ConstantNode.forInt(128, graph).stamp()); + assertEquals(new IntegerStamp(Kind.Int, -128, -128, 0xffffff80L), ConstantNode.forInt(-128, graph).stamp()); + assertEquals(new IntegerStamp(Kind.Int, Integer.MAX_VALUE, Integer.MAX_VALUE, 0x7fffffff), ConstantNode.forInt(Integer.MAX_VALUE, graph).stamp()); + assertEquals(new IntegerStamp(Kind.Int, Integer.MIN_VALUE, Integer.MIN_VALUE, 0x80000000L), ConstantNode.forInt(Integer.MIN_VALUE, graph).stamp()); } @Test public void testLongConstant() { - assertEquals(new IntegerStamp(Kind.Long, 0, 0, 0x0), ConstantNode.forLong(0, graph).integerStamp()); - assertEquals(new IntegerStamp(Kind.Long, 128, 128, 0x80), ConstantNode.forLong(128, graph).integerStamp()); - assertEquals(new IntegerStamp(Kind.Long, -128, -128, 0xffffffffffffff80L), ConstantNode.forLong(-128, graph).integerStamp()); - assertEquals(new IntegerStamp(Kind.Long, Long.MAX_VALUE, Long.MAX_VALUE, 0x7fffffffffffffffL), ConstantNode.forLong(Long.MAX_VALUE, graph).integerStamp()); - assertEquals(new IntegerStamp(Kind.Long, Long.MIN_VALUE, Long.MIN_VALUE, 0x8000000000000000L), ConstantNode.forLong(Long.MIN_VALUE, graph).integerStamp()); + assertEquals(new IntegerStamp(Kind.Long, 0, 0, 0x0), ConstantNode.forLong(0, graph).stamp()); + assertEquals(new IntegerStamp(Kind.Long, 128, 128, 0x80), ConstantNode.forLong(128, graph).stamp()); + assertEquals(new IntegerStamp(Kind.Long, -128, -128, 0xffffffffffffff80L), ConstantNode.forLong(-128, graph).stamp()); + assertEquals(new IntegerStamp(Kind.Long, Long.MAX_VALUE, Long.MAX_VALUE, 0x7fffffffffffffffL), ConstantNode.forLong(Long.MAX_VALUE, graph).stamp()); + assertEquals(new IntegerStamp(Kind.Long, Long.MIN_VALUE, Long.MIN_VALUE, 0x8000000000000000L), ConstantNode.forLong(Long.MIN_VALUE, graph).stamp()); } } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java Thu Aug 08 18:17:47 2013 +0200 @@ -68,7 +68,7 @@ for (ReadNode rn : graph.getNodes().filter(ReadNode.class)) { if (rn.location() instanceof ConstantLocationNode && rn.object().stamp() instanceof ObjectStamp) { long disp = ((ConstantLocationNode) rn.location()).getDisplacement(); - ResolvedJavaType receiverType = rn.object().objectStamp().type(); + ResolvedJavaType receiverType = ObjectStamp.typeOrNull(rn.object()); ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(disp); if (field != null) { diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Thu Aug 08 18:17:47 2013 +0200 @@ -46,6 +46,7 @@ import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.util.*; @@ -365,6 +366,9 @@ } protected void emitNode(ValueNode node) { + if (Debug.isLogEnabled() && node.stamp() == StampFactory.illegal()) { + Debug.log("This node has invalid type, we are emitting dead code(?): %s", node); + } ((LIRLowerable) node).generate(this); } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Thu Aug 08 18:17:47 2013 +0200 @@ -513,7 +513,7 @@ NodeInputList parameters = callTarget.arguments(); ValueNode receiver = parameters.size() <= 0 ? null : parameters.get(0); GuardingNode receiverNullCheck = null; - if (!callTarget.isStatic() && receiver.kind() == Kind.Object && !receiver.objectStamp().nonNull()) { + if (!callTarget.isStatic() && receiver.stamp() instanceof ObjectStamp && !ObjectStamp.isObjectNonNull(receiver)) { receiverNullCheck = tool.createNullCheckGuard(invoke, receiver); } JavaType[] signature = MetaUtil.signatureToTypes(callTarget.targetMethod().getSignature(), callTarget.isStatic() ? null : callTarget.targetMethod().getDeclaringClass()); @@ -608,10 +608,10 @@ LocationNode arrayLocation = createArrayLocation(graph, elementKind, storeIndexed.index()); ValueNode value = storeIndexed.value(); ValueNode array = storeIndexed.array(); - if (elementKind == Kind.Object && !value.objectStamp().alwaysNull()) { + if (elementKind == Kind.Object && !ObjectStamp.isObjectAlwaysNull(value)) { // Store check! - ResolvedJavaType arrayType = array.objectStamp().type(); - if (arrayType != null && array.objectStamp().isExactType()) { + ResolvedJavaType arrayType = ObjectStamp.typeOrNull(array); + if (arrayType != null && ObjectStamp.isExactType(array)) { ResolvedJavaType elementType = arrayType.getComponentType(); if (!MetaUtil.isJavaLangObject(elementType)) { CheckCastNode checkcast = graph.add(new CheckCastNode(elementType, value, null, true)); @@ -854,8 +854,15 @@ } private static boolean addReadBarrier(UnsafeLoadNode load) { - return useG1GC() && load.object().kind() == Kind.Object && load.accessKind() == Kind.Object && !load.object().objectStamp().alwaysNull() && load.object().objectStamp().type() != null && - !(load.object().objectStamp().type().isArray()); + if (useG1GC()) { + if (load.object().kind() == Kind.Object && load.accessKind() == Kind.Object && !ObjectStamp.isObjectAlwaysNull(load.object())) { + ResolvedJavaType type = ObjectStamp.typeOrNull(load.object()); + if (type != null && !type.isArray()) { + return true; + } + } + } + return false; } private static ReadNode createReadVirtualMethod(StructuredGraph graph, Kind wordKind, ValueNode hub, ResolvedJavaMethod method) { @@ -910,7 +917,7 @@ private static BarrierType getUnsafeStoreBarrierType(UnsafeStoreNode store) { BarrierType barrierType = BarrierType.NONE; if (store.value().kind() == Kind.Object) { - ResolvedJavaType type = store.object().objectStamp().type(); + ResolvedJavaType type = ObjectStamp.typeOrNull(store.object()); if (type != null && !type.isArray()) { barrierType = BarrierType.IMPRECISE; } else { @@ -923,7 +930,7 @@ private static BarrierType getCompareAndSwapBarrier(CompareAndSwapNode cas) { BarrierType barrierType = BarrierType.NONE; if (cas.expected().kind() == Kind.Object) { - ResolvedJavaType type = cas.object().objectStamp().type(); + ResolvedJavaType type = ObjectStamp.typeOrNull(cas.object()); if (type != null && !type.isArray()) { barrierType = BarrierType.IMPRECISE; } else { diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -44,7 +44,7 @@ import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; import com.oracle.graal.nodes.java.SelfReplacingMethodCallTargetNode; import com.oracle.graal.nodes.spi.Canonicalizable; -import com.oracle.graal.nodes.type.StampFactory; +import com.oracle.graal.nodes.type.*; import com.oracle.graal.replacements.nodes.MacroNode; /** @@ -200,7 +200,7 @@ // Try to get the most accurate receiver type if (this instanceof MethodHandleLinkToVirtualNode || this instanceof MethodHandleLinkToInterfaceNode) { - ResolvedJavaType receiverType = getReceiver().objectStamp().type(); + ResolvedJavaType receiverType = ObjectStamp.typeOrNull(getReceiver().stamp()); if (receiverType != null) { ResolvedJavaMethod concreteMethod = receiverType.findUniqueConcreteMethod(targetMethod); if (concreteMethod != null) { @@ -233,7 +233,7 @@ ResolvedJavaType targetType = (ResolvedJavaType) type; if (!targetType.isPrimitive()) { ValueNode argument = arguments.get(index); - ResolvedJavaType argumentType = argument.objectStamp().type(); + ResolvedJavaType argumentType = ObjectStamp.typeOrNull(argument.stamp()); if (argumentType == null || (argumentType.isAssignableFrom(targetType) && !argumentType.equals(targetType))) { PiNode piNode = graph().unique(new PiNode(argument, StampFactory.declared(targetType))); arguments.set(index, piNode); diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -30,6 +30,7 @@ import com.oracle.graal.loop.phases.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; @@ -62,13 +63,13 @@ } private StructuredGraph selectSnippet(LoweringTool tool, Replacements replacements) { - ResolvedJavaType srcType = getSource().objectStamp().type(); - ResolvedJavaType destType = getDestination().objectStamp().type(); + ResolvedJavaType srcType = ObjectStamp.typeOrNull(getSource().stamp()); + ResolvedJavaType destType = ObjectStamp.typeOrNull(getDestination().stamp()); if (srcType == null || !srcType.isArray() || destType == null || !destType.isArray()) { return null; } - if (!destType.getComponentType().isAssignableFrom(srcType.getComponentType()) || !getDestination().objectStamp().isExactType()) { + if (!destType.getComponentType().isAssignableFrom(srcType.getComponentType()) || !ObjectStamp.isExactType(getDestination().stamp())) { return null; } Kind componentKind = srcType.getComponentType().getKind(); @@ -126,10 +127,10 @@ if (state.getState() == EscapeState.Virtual) { type = state.getVirtualObject().type(); } else { - type = state.getMaterializedValue().objectStamp().type(); + type = ObjectStamp.typeOrNull(state.getMaterializedValue()); } } else { - type = entry.objectStamp().type(); + type = ObjectStamp.typeOrNull(entry); } if (type == null || !destComponentType.isAssignableFrom(type)) { return false; diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastDynamicSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastDynamicSnippets.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastDynamicSnippets.java Thu Aug 08 18:17:47 2013 +0200 @@ -78,7 +78,7 @@ Arguments args = new Arguments(dynamic); args.add("hub", checkcast.hub()); args.add("object", object); - args.addConst("checkNull", !object.stamp().nonNull()); + args.addConst("checkNull", !ObjectStamp.isObjectNonNull(object.stamp())); SnippetTemplate template = template(args); Debug.log("Lowering dynamic checkcast in %s: node=%s, template=%s, arguments=%s", graph, checkcast, template, args); diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Thu Aug 08 18:17:47 2013 +0200 @@ -242,7 +242,7 @@ } args.add("trueValue", replacer.trueValue); args.add("falseValue", replacer.falseValue); - args.addConst("checkNull", !object.stamp().nonNull()); + args.addConst("checkNull", !ObjectStamp.isObjectNonNull(object.stamp())); if (hintInfo.hintHitProbability >= hintHitProbabilityThresholdForDeoptimizingSnippet()) { args.addConst("nullSeen", hintInfo.profile.getNullSeen() != TriState.FALSE); } @@ -258,7 +258,7 @@ args.add("object", object); args.add("trueValue", replacer.trueValue); args.add("falseValue", replacer.falseValue); - args.addConst("checkNull", !object.stamp().nonNull()); + args.addConst("checkNull", !ObjectStamp.isObjectNonNull(object.stamp())); return args; } } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Thu Aug 08 18:17:47 2013 +0200 @@ -44,6 +44,7 @@ import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; @@ -409,7 +410,7 @@ } args.add("object", monitorenterNode.object()); args.addConst("lockDepth", monitorenterNode.getLockDepth()); - args.addConst("checkNull", !monitorenterNode.object().stamp().nonNull()); + args.addConst("checkNull", !ObjectStamp.isObjectNonNull(monitorenterNode.object().stamp())); boolean tracingEnabledForMethod = stateAfter != null && (isTracingEnabledForMethod(stateAfter.method()) || isTracingEnabledForMethod(graph.method())); args.addConst("trace", isTracingEnabledForType(monitorenterNode.object()) || tracingEnabledForMethod); @@ -448,7 +449,7 @@ } static boolean isTracingEnabledForType(ValueNode object) { - ResolvedJavaType type = object.objectStamp().type(); + ResolvedJavaType type = ObjectStamp.typeOrNull(object.stamp()); if (TRACE_TYPE_FILTER == null) { return false; } else { diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -56,7 +56,7 @@ return null; } - ResolvedJavaType type = getObject().objectStamp().type(); + ResolvedJavaType type = ObjectStamp.typeOrNull(getObject()); Method method; /* * The first condition tests if the parameter is an array, the second condition tests if the @@ -81,13 +81,17 @@ return type != null && metaAccess.lookupJavaType(Cloneable.class).isAssignableFrom(type); } - private static ResolvedJavaType getConcreteType(ObjectStamp stamp, Assumptions assumptions) { - if (stamp.isExactType() || stamp.type() == null) { - return stamp.type(); + private static ResolvedJavaType getConcreteType(Stamp stamp, Assumptions assumptions) { + if (!(stamp instanceof ObjectStamp)) { + return null; + } + ObjectStamp objectStamp = (ObjectStamp) stamp; + if (objectStamp.isExactType() || objectStamp.type() == null) { + return objectStamp.type(); } else { - ResolvedJavaType type = stamp.type().findUniqueConcreteSubtype(); + ResolvedJavaType type = objectStamp.type().findUniqueConcreteSubtype(); if (type != null) { - assumptions.recordConcreteSubtype(stamp.type(), type); + assumptions.recordConcreteSubtype(objectStamp.type(), type); } return type; } @@ -114,7 +118,7 @@ } else { obj = tool.getReplacedValue(getObject()); } - ResolvedJavaType type = getConcreteType(obj.objectStamp(), tool.getAssumptions()); + ResolvedJavaType type = getConcreteType(obj.stamp(), tool.getAssumptions()); if (isCloneableType(type, tool.getMetaAccessProvider())) { if (!type.isArray()) { VirtualInstanceNode newVirtual = new VirtualInstanceNode(type); diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectGetClassNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectGetClassNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectGetClassNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -64,13 +64,15 @@ if (usages().isEmpty()) { return null; } else { - ObjectStamp stamp = getObject().objectStamp(); - if (stamp.isExactType()) { - Constant clazz = stamp.type().getEncoding(Representation.JavaClass); - return ConstantNode.forConstant(clazz, tool.runtime(), graph()); - } else { - return this; + Stamp stamp = getObject().stamp(); + if (stamp instanceof ObjectStamp) { + ObjectStamp objectStamp = (ObjectStamp) stamp; + if (objectStamp.isExactType()) { + Constant clazz = objectStamp.type().getEncoding(Representation.JavaClass); + return ConstantNode.forConstant(clazz, tool.runtime(), graph()); + } } + return this; } } } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Thu Aug 08 18:17:47 2013 +0200 @@ -36,6 +36,7 @@ import com.oracle.graal.nodes.HeapAccess.BarrierType; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; @@ -343,7 +344,7 @@ args.add("object", writeBarrier.getObject()); args.add("location", writeBarrier.getLocation()); args.addConst("usePrecise", writeBarrier.usePrecise()); - args.addConst("alwaysNull", writeBarrier.getValue().objectStamp().alwaysNull()); + args.addConst("alwaysNull", ObjectStamp.isObjectAlwaysNull(writeBarrier.getValue())); template(args).instantiate(runtime, writeBarrier, DEFAULT_REPLACER, args); } @@ -383,7 +384,7 @@ args.add("value", writeBarrierPost.getValue()); args.add("location", writeBarrierPost.getLocation()); args.addConst("usePrecise", writeBarrierPost.usePrecise()); - args.addConst("alwaysNull", writeBarrierPost.getValue().objectStamp().alwaysNull()); + args.addConst("alwaysNull", ObjectStamp.isObjectAlwaysNull(writeBarrierPost.getValue())); args.addConst("trace", traceBarrier()); template(args).instantiate(runtime, writeBarrierPost, DEFAULT_REPLACER, args); } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Thu Aug 08 18:17:47 2013 +0200 @@ -914,7 +914,7 @@ } private void emitNullCheck(ValueNode receiver) { - if (receiver.stamp().nonNull()) { + if (ObjectStamp.isObjectNonNull(receiver.stamp())) { return; } BlockPlaceholderNode trueSucc = currentGraph.add(new BlockPlaceholderNode()); @@ -1103,8 +1103,11 @@ } // 1. check if the exact type of the receiver can be determined ResolvedJavaType exact = klass.asExactType(); - if (exact == null && receiver.objectStamp().isExactType()) { - exact = receiver.objectStamp().type(); + if (exact == null && receiver.stamp() instanceof ObjectStamp) { + ObjectStamp receiverStamp = (ObjectStamp) receiver.stamp(); + if (receiverStamp.isExactType()) { + exact = receiverStamp.type(); + } } if (exact != null) { // either the holder class is exact, or the receiver object has an exact type diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/StampTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/StampTest.java Thu Aug 08 18:17:47 2013 +0200 @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2013, 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.nodes.test; + +import org.junit.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.test.*; +import com.oracle.graal.nodes.type.*; + +public class StampTest extends GraalCompilerTest { + + private static class A { + + } + + private static class B extends A { + + } + + private static class C extends B implements I { + + } + + private static class D extends A { + + } + + private interface I { + + } + + @Test + public void testJoin0() { + Stamp a = StampFactory.declared(getType(A.class)); + Stamp b = StampFactory.declared(getType(B.class)); + Assert.assertEquals(b, join(a, b)); + } + + @Test + public void testJoin1() { + Stamp aNonNull = StampFactory.declaredNonNull(getType(A.class)); + Stamp b = StampFactory.declared(getType(B.class)); + Stamp bNonNull = StampFactory.declaredNonNull(getType(B.class)); + Assert.assertEquals(bNonNull, join(aNonNull, b)); + } + + @Test + public void testJoin2() { + Stamp aExact = StampFactory.exactNonNull(getType(A.class)); + Stamp b = StampFactory.declared(getType(B.class)); + Assert.assertEquals(StampFactory.illegal(), join(aExact, b)); + } + + @Test + public void testJoin3() { + Stamp d = StampFactory.declared(getType(D.class)); + Stamp c = StampFactory.declared(getType(C.class)); + Assert.assertTrue(ObjectStamp.isObjectAlwaysNull(join(c, d))); + } + + @Test + public void testJoin4() { + Stamp dExactNonNull = StampFactory.exactNonNull(getType(D.class)); + Stamp c = StampFactory.declared(getType(C.class)); + Assert.assertEquals(StampFactory.illegal(), join(c, dExactNonNull)); + } + + @Test + public void testJoin5() { + Stamp dExact = StampFactory.exact(getType(D.class)); + Stamp c = StampFactory.declared(getType(C.class)); + Assert.assertTrue(ObjectStamp.isObjectAlwaysNull(join(c, dExact))); + } + + @Test + public void testJoin6() { + Stamp dExactNonNull = StampFactory.exactNonNull(getType(D.class)); + Stamp allwaysNull = StampFactory.alwaysNull(); + Stamp join = join(allwaysNull, dExactNonNull); + Assert.assertFalse(ObjectStamp.isObjectNonNull(join)); + Assert.assertFalse(ObjectStamp.isObjectAlwaysNull(join)); + } + + @Test + public void testJoinInterface0() { + Stamp a = StampFactory.declared(getType(A.class)); + Stamp b = StampFactory.declared(getType(I.class)); + Assert.assertNotSame(StampFactory.illegal(), join(a, b)); + } + + @Test + public void testJoinInterface1() { + Stamp aNonNull = StampFactory.declaredNonNull(getType(A.class)); + Stamp i = StampFactory.declared(getType(I.class)); + Stamp join = join(aNonNull, i); + Assert.assertTrue(join instanceof ObjectStamp); + Assert.assertTrue(((ObjectStamp) join).nonNull()); + } + + @Test + public void testJoinInterface2() { + Stamp bExact = StampFactory.exactNonNull(getType(B.class)); + Stamp i = StampFactory.declared(getType(I.class)); + Stamp join = join(i, bExact); + Assert.assertEquals(StampFactory.illegal(), join); + } + + private static Stamp join(Stamp a, Stamp b) { + Stamp ab = a.join(b); + Stamp ba = b.join(a); + Assert.assertEquals(ab, ba); + return ab; + } + + private ResolvedJavaType getType(Class clazz) { + return runtime().lookupJavaType(clazz); + } +} diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java Thu Aug 08 18:17:47 2013 +0200 @@ -381,7 +381,7 @@ public boolean verify() { for (ValueNode value : values) { assert assertTrue(value == null || !value.isDeleted(), "frame state must not contain deleted nodes"); - assert assertTrue(value == null || value instanceof VirtualObjectNode || (value.kind() != Kind.Void && value.kind() != Kind.Illegal), "unexpected value: %s", value); + assert assertTrue(value == null || value instanceof VirtualObjectNode || (value.kind() != Kind.Void), "unexpected value: %s", value); } return super.verify(); } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardedValueNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardedValueNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardedValueNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -60,7 +60,10 @@ @Override public boolean inferStamp() { - return updateStamp(stamp().join(object().stamp())); + if (stamp() instanceof ObjectStamp && object().stamp() instanceof ObjectStamp) { + return updateStamp(((ObjectStamp) object().stamp()).castTo((ObjectStamp) stamp())); + } + return updateStamp(object().stamp().join(stamp())); } @Override diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -124,11 +124,6 @@ public boolean verify() { assertTrue(merge() != null, "missing merge"); assertTrue(merge().phiPredecessorCount() == valueCount(), "mismatch between merge predecessor count and phi value count: %d != %d", merge().phiPredecessorCount(), valueCount()); - if (type == PhiType.Value) { - for (ValueNode v : values()) { - assertTrue(v.kind() == kind(), "all phi values must have same kind"); - } - } return super.verify(); } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -27,6 +27,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; /** * A node that attaches a type profile to a proxied input node. @@ -71,7 +72,7 @@ @Override public ValueNode canonical(CanonicalizerTool tool) { - if (object.objectStamp().isExactType()) { + if (ObjectStamp.isExactType(object)) { // The profile is useless - we know the type! return object; } else if (object instanceof TypeProfileProxyNode) { @@ -92,8 +93,8 @@ Debug.log("Improved profile via other profile."); return TypeProfileProxyNode.create(object, newProfile); } - } else if (object.objectStamp().type() != null) { - ResolvedJavaType type = object.objectStamp().type(); + } else if (ObjectStamp.typeOrNull(object) != null) { + ResolvedJavaType type = ObjectStamp.typeOrNull(object); ResolvedJavaType uniqueConcrete = type.findUniqueConcreteSubtype(); if (uniqueConcrete != null) { // Profile is useless => remove. @@ -105,7 +106,7 @@ return this; } lastCheckedType = type; - JavaTypeProfile newProfile = this.profile.restrict(type, object.objectStamp().nonNull()); + JavaTypeProfile newProfile = this.profile.restrict(type, ObjectStamp.isObjectNonNull(object)); if (newProfile != this.profile) { Debug.log("Improved profile via static type information."); if (newProfile.getTypes().length == 0) { diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -134,21 +134,6 @@ return true; } - public final ObjectStamp objectStamp() { - assert verifyStamp(ObjectStamp.class); - return (ObjectStamp) stamp(); - } - - public final IntegerStamp integerStamp() { - assert verifyStamp(IntegerStamp.class); - return (IntegerStamp) stamp(); - } - - public final FloatStamp floatStamp() { - assert verifyStamp(FloatStamp.class); - return (FloatStamp) stamp(); - } - @Override public boolean verify() { assertTrue(kind() != null, "Should have a valid kind"); diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -37,7 +37,7 @@ @Override public boolean inferStamp() { - return updateStamp(StampTool.and(x().integerStamp(), y().integerStamp())); + return updateStamp(StampTool.and(x().stamp(), y().stamp())); } @Override diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -66,10 +66,8 @@ if (x().isConstant() && y().isConstant() && condition instanceof IntegerEqualsNode) { IntegerEqualsNode equals = (IntegerEqualsNode) condition; if (equals.y().isConstant() && equals.y().asConstant().equals(Constant.INT_0)) { - if (equals.x().integerStamp().mask() == 1) { - if (x().asConstant().equals(Constant.INT_0) && y().asConstant().equals(Constant.INT_1)) { - return equals.x(); - } + if (x().asConstant().equals(Constant.INT_0) && y().asConstant().equals(Constant.INT_1)) { + return equals.x(); } } } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -202,22 +202,30 @@ @Override public boolean inferStamp() { + Stamp stamp = value.stamp(); + if (!(stamp instanceof IntegerStamp)) { + if (stamp instanceof FloatStamp) { + return false; + } + return updateStamp(StampFactory.illegal()); + } Stamp newStamp; + IntegerStamp integerStamp = (IntegerStamp) stamp; switch (opcode) { case I2L: - newStamp = StampTool.intToLong(value().integerStamp()); + newStamp = StampTool.intToLong(integerStamp); break; case L2I: - newStamp = StampTool.longToInt(value().integerStamp()); + newStamp = StampTool.longToInt(integerStamp); break; case I2B: - newStamp = StampTool.intToByte(value().integerStamp()); + newStamp = StampTool.intToByte(integerStamp); break; case I2C: - newStamp = StampTool.intToChar(value().integerStamp()); + newStamp = StampTool.intToChar(integerStamp); break; case I2S: - newStamp = StampTool.intToShort(value().integerStamp()); + newStamp = StampTool.intToShort(integerStamp); break; default: return false; diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -37,7 +37,7 @@ @Override public boolean inferStamp() { - return updateStamp(StampTool.add(x().integerStamp(), y().integerStamp())); + return updateStamp(StampTool.add(x().stamp(), y().stamp())); } @Override diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -58,13 +58,15 @@ if (x() == y()) { return LogicConstantNode.contradiction(graph()); } else { - IntegerStamp xStamp = x().integerStamp(); - IntegerStamp yStamp = y().integerStamp(); - if (yStamp.isPositive()) { - if (xStamp.isPositive() && xStamp.upperBound() < yStamp.lowerBound()) { - return LogicConstantNode.tautology(graph()); - } else if (xStamp.isStrictlyNegative() || xStamp.lowerBound() >= yStamp.upperBound()) { - return LogicConstantNode.contradiction(graph()); + if (x().stamp() instanceof IntegerStamp && y().stamp() instanceof IntegerStamp) { + IntegerStamp xStamp = (IntegerStamp) x().stamp(); + IntegerStamp yStamp = (IntegerStamp) y().stamp(); + if (yStamp.isPositive()) { + if (xStamp.isPositive() && xStamp.upperBound() < yStamp.lowerBound()) { + return LogicConstantNode.tautology(graph()); + } else if (xStamp.isStrictlyNegative() || xStamp.lowerBound() >= yStamp.upperBound()) { + return LogicConstantNode.contradiction(graph()); + } } } } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -38,7 +38,7 @@ @Override public boolean inferStamp() { - return updateStamp(StampTool.div(x().integerStamp(), y().integerStamp())); + return updateStamp(StampTool.div(x().stamp(), y().stamp())); } @Override @@ -63,9 +63,9 @@ return graph().unique(new NegateNode(x())); } long abs = Math.abs(c); - if (CodeUtil.isPowerOf2(abs)) { + if (CodeUtil.isPowerOf2(abs) && x().stamp() instanceof IntegerStamp) { ValueNode dividend = x(); - IntegerStamp stampX = x().integerStamp(); + IntegerStamp stampX = (IntegerStamp) x().stamp(); int log2 = CodeUtil.log2(abs); // no rounding if dividend is positive or if its low bits are always 0 if (stampX.canBeNegative() || (stampX.mask() & (abs - 1)) != 0) { @@ -121,6 +121,6 @@ @Override public boolean canDeoptimize() { - return y().integerStamp().contains(0); + return !(y().stamp() instanceof IntegerStamp) || ((IntegerStamp) y().stamp()).contains(0); } } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -71,7 +71,7 @@ public LogicNode canonical(CanonicalizerTool tool) { if (x() == y()) { return LogicConstantNode.tautology(graph()); - } else if (x().integerStamp().alwaysDistinct(y().integerStamp())) { + } else if (x().stamp().alwaysDistinct(y().stamp())) { return LogicConstantNode.contradiction(graph()); } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -73,13 +73,18 @@ public LogicNode canonical(CanonicalizerTool tool) { if (x() == y()) { return LogicConstantNode.contradiction(graph()); - } else if (x().integerStamp().upperBound() < y().integerStamp().lowerBound()) { - return LogicConstantNode.tautology(graph()); - } else if (x().integerStamp().lowerBound() >= y().integerStamp().upperBound()) { - return LogicConstantNode.contradiction(graph()); } - if (IntegerStamp.sameSign(x().integerStamp(), y().integerStamp())) { - return graph().unique(new IntegerBelowThanNode(x(), y())); + if (x().stamp() instanceof IntegerStamp && y().stamp() instanceof IntegerStamp) { + IntegerStamp xStamp = (IntegerStamp) x().stamp(); + IntegerStamp yStamp = (IntegerStamp) y().stamp(); + if (xStamp.upperBound() < yStamp.lowerBound()) { + return LogicConstantNode.tautology(graph()); + } else if (xStamp.lowerBound() >= yStamp.upperBound()) { + return LogicConstantNode.contradiction(graph()); + } + if (IntegerStamp.sameSign(xStamp, yStamp)) { + return graph().unique(new IntegerBelowThanNode(x(), y())); + } } return super.canonical(tool); } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -27,6 +27,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; @NodeInfo(shortName = "%") public class IntegerRemNode extends FixedBinaryNode implements Canonicalizable, Lowerable, LIRLowerable { @@ -52,7 +53,7 @@ long c = y().asConstant().asLong(); if (c == 1 || c == -1) { return ConstantNode.forIntegerKind(kind(), 0, graph()); - } else if (c > 0 && CodeUtil.isPowerOf2(c) && x().integerStamp().isPositive()) { + } else if (c > 0 && CodeUtil.isPowerOf2(c) && x().stamp() instanceof IntegerStamp && ((IntegerStamp) x().stamp()).isPositive()) { return graph().unique(new AndNode(kind(), x(), ConstantNode.forIntegerKind(kind(), c - 1, graph()))); } } @@ -71,6 +72,6 @@ @Override public boolean canDeoptimize() { - return y().integerStamp().contains(0); + return !(y().stamp() instanceof IntegerStamp) || ((IntegerStamp) y().stamp()).contains(0); } } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -37,7 +37,7 @@ @Override public boolean inferStamp() { - return updateStamp(StampTool.sub(x().integerStamp(), y().integerStamp())); + return updateStamp(StampTool.sub(x().stamp(), y().stamp())); } @Override diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; /** * This node will perform a "test" operation on its arguments. Its result is equivalent to the @@ -64,8 +65,12 @@ if (x().isConstant() && y().isConstant()) { return LogicConstantNode.forBoolean((x().asConstant().asLong() & y().asConstant().asLong()) == 0, graph()); } - if ((x().integerStamp().mask() & y().integerStamp().mask()) == 0) { - return LogicConstantNode.tautology(graph()); + if (x().stamp() instanceof IntegerStamp && y().stamp() instanceof IntegerStamp) { + IntegerStamp xStamp = (IntegerStamp) x().stamp(); + IntegerStamp yStamp = (IntegerStamp) y().stamp(); + if ((xStamp.mask() & yStamp.mask()) == 0) { + return LogicConstantNode.tautology(graph()); + } } return this; } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -44,7 +44,6 @@ * @param object the instruction producing the object to check against null */ public IsNullNode(ValueNode object) { - assert object.kind() == Kind.Object : object; this.object = object; } @@ -56,7 +55,7 @@ @Override public boolean verify() { assertTrue(object() != null, "is null input must not be null"); - assertTrue(object().kind() == Kind.Object, "is null input must be an object"); + assertTrue(object().stamp() instanceof ObjectStamp || object().stamp() == StampFactory.illegal(), "is null input must be an object"); return super.verify(); } @@ -67,7 +66,7 @@ assert constant.getKind() == Kind.Object; return LogicConstantNode.forBoolean(constant.isNull(), graph()); } - if (object.objectStamp().nonNull()) { + if (ObjectStamp.isObjectNonNull(object.stamp())) { return LogicConstantNode.contradiction(graph()); } return this; @@ -82,9 +81,9 @@ @Override public boolean push(PiNode parent) { - ObjectStamp piStamp = parent.objectStamp(); - if (parent.object().kind() == Kind.Object) { - ObjectStamp piValueStamp = parent.object().objectStamp(); + if (parent.stamp() instanceof ObjectStamp && parent.object().stamp() instanceof ObjectStamp) { + ObjectStamp piStamp = (ObjectStamp) parent.stamp(); + ObjectStamp piValueStamp = (ObjectStamp) parent.object().stamp(); if (piStamp.nonNull() == piValueStamp.nonNull() && piStamp.alwaysNull() == piValueStamp.alwaysNull()) { replaceFirstInput(parent, parent.object()); return true; diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -37,7 +37,7 @@ @Override public boolean inferStamp() { - return updateStamp(StampTool.leftShift(x().integerStamp(), y().integerStamp())); + return updateStamp(StampTool.leftShift(x().stamp(), y().stamp())); } @Override diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -26,6 +26,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; @NodeInfo(shortName = "==") public final class ObjectEqualsNode extends CompareNode implements Virtualizable { @@ -58,9 +59,9 @@ return LogicConstantNode.tautology(graph()); } - if (x().objectStamp().alwaysNull()) { + if (ObjectStamp.isObjectAlwaysNull(x())) { return graph().unique(new IsNullNode(y())); - } else if (y().objectStamp().alwaysNull()) { + } else if (ObjectStamp.isObjectAlwaysNull(y())) { return graph().unique(new IsNullNode(x())); } if (x().stamp().alwaysDistinct(y().stamp())) { diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -37,7 +37,7 @@ @Override public boolean inferStamp() { - return updateStamp(StampTool.or(x().integerStamp(), y().integerStamp())); + return updateStamp(StampTool.or(x().stamp(), y().stamp())); } @Override diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -37,7 +37,7 @@ @Override public ValueNode canonical(CanonicalizerTool tool) { - if (x().integerStamp().isPositive()) { + if (x().stamp() instanceof IntegerStamp && ((IntegerStamp) x().stamp()).isPositive()) { return graph().unique(new UnsignedRightShiftNode(kind(), x(), y())); } if (y().isConstant()) { diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -27,6 +27,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; @NodeInfo(shortName = "|/|") public class UnsignedDivNode extends FixedBinaryNode implements Canonicalizable, Lowerable, LIRLowerable { @@ -72,6 +73,6 @@ @Override public boolean canDeoptimize() { - return y().integerStamp().contains(0); + return !(y().stamp() instanceof IntegerStamp) || ((IntegerStamp) y().stamp()).contains(0); } } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -27,6 +27,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; @NodeInfo(shortName = "|%|") public class UnsignedRemNode extends FixedBinaryNode implements Canonicalizable, Lowerable, LIRLowerable { @@ -71,6 +72,6 @@ @Override public boolean canDeoptimize() { - return y().integerStamp().contains(0); + return !(y().stamp() instanceof IntegerStamp) || ((IntegerStamp) y().stamp()).contains(0); } } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -37,7 +37,7 @@ @Override public boolean inferStamp() { - return updateStamp(StampTool.unsignedRightShift(x().integerStamp(), y().integerStamp())); + return updateStamp(StampTool.unsignedRightShift(x().stamp(), y().stamp())); } @Override diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -37,7 +37,7 @@ @Override public boolean inferStamp() { - return updateStamp(StampTool.xor(x().integerStamp(), y().integerStamp())); + return updateStamp(StampTool.xor(x().stamp(), y().stamp())); } @Override diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -72,7 +72,7 @@ @Override public void virtualize(VirtualizerTool tool) { ValueNode v = tool.getReplacedValue(getValue()); - ResolvedJavaType type = objectStamp().type(); + ResolvedJavaType type = ObjectStamp.typeOrNull(stamp()); VirtualBoxingNode newVirtual = new VirtualBoxingNode(type, boxingKind); assert newVirtual.getFields().length == 1; diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -111,8 +111,8 @@ } tool.addToWorkList(blockSuccessor(survivingEdge)); graph().removeSplit(this, blockSuccessor(survivingEdge)); - } else if (value() != null) { - IntegerStamp stamp = value().integerStamp(); + } else if (value().stamp() instanceof IntegerStamp) { + IntegerStamp stamp = (IntegerStamp) value().stamp(); if (!stamp.isUnrestricted()) { int validKeys = 0; for (int i = 0; i < keyCount(); i++) { diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -65,8 +65,8 @@ @Override public ValueNode canonical(CanonicalizerTool tool) { MetaAccessProvider runtime = tool.runtime(); - if (runtime != null) { - ObjectStamp stamp = object.objectStamp(); + if (runtime != null && object.stamp() instanceof ObjectStamp) { + ObjectStamp stamp = (ObjectStamp) object.stamp(); ResolvedJavaType exactType; if (stamp.isExactType()) { diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -107,15 +107,15 @@ if (location() instanceof ConstantLocationNode) { long displacement = ((ConstantLocationNode) location()).getDisplacement(); if (parent.stamp() instanceof ObjectStamp) { - ObjectStamp piStamp = parent.objectStamp(); + ObjectStamp piStamp = (ObjectStamp) parent.stamp(); ResolvedJavaType receiverType = piStamp.type(); if (receiverType != null) { ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(displacement); if (field != null) { ResolvedJavaType declaringClass = field.getDeclaringClass(); - if (declaringClass.isAssignableFrom(receiverType) && declaringClass != receiverType) { - ObjectStamp piValueStamp = parent.object().objectStamp(); + if (declaringClass.isAssignableFrom(receiverType) && declaringClass != receiverType && parent.object().stamp() instanceof ObjectStamp) { + ObjectStamp piValueStamp = (ObjectStamp) parent.object().stamp(); if (piStamp.nonNull() == piValueStamp.nonNull() && piStamp.alwaysNull() == piValueStamp.alwaysNull()) { replaceFirstInput(parent, parent.object()); return true; diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeAccessNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeAccessNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeAccessNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -65,18 +65,14 @@ long constantOffset = offset().asConstant().asLong(); // Try to canonicalize to a field access. - if (object().stamp() instanceof ObjectStamp) { - // TODO (gd) remove that once UnsafeAccess only have an object base - ObjectStamp receiverStamp = object().objectStamp(); - ResolvedJavaType receiverType = receiverStamp.type(); - if (receiverType != null) { - ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(displacement() + constantOffset); - // No need for checking that the receiver is non-null. The field access includes - // the null check and if a field is found, the offset is so small that this is - // never a valid access of an arbitrary address. - if (field != null && field.getKind() == this.accessKind()) { - return cloneAsFieldAccess(field); - } + ResolvedJavaType receiverType = ObjectStamp.typeOrNull(object()); + if (receiverType != null) { + ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(displacement() + constantOffset); + // No need for checking that the receiver is non-null. The field access includes + // the null check and if a field is found, the offset is so small that this is + // never a valid access of an arbitrary address. + if (field != null && field.getKind() == this.accessKind()) { + return cloneAsFieldAccess(field); } } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -45,18 +45,18 @@ } public UnsafeCastNode(ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) { - this(object, toType.getKind() == Kind.Object ? StampFactory.object(toType, exactType, nonNull || object.stamp().nonNull()) : StampFactory.forKind(toType.getKind())); + this(object, toType.getKind() == Kind.Object ? StampFactory.object(toType, exactType, nonNull || ObjectStamp.isObjectNonNull(object.stamp())) : StampFactory.forKind(toType.getKind())); } @Override public boolean inferStamp() { - if (kind() != Kind.Object || object().kind() != Kind.Object) { - return false; - } if (stamp() == StampFactory.forNodeIntrinsic()) { return false; } - return updateStamp(stamp().join(object().stamp())); + if (stamp() instanceof ObjectStamp && object().stamp() instanceof ObjectStamp) { + return updateStamp(((ObjectStamp) object().stamp()).castTo((ObjectStamp) stamp())); + } + return false; } @Override @@ -65,9 +65,9 @@ return this; } - if (kind() == Kind.Object) { - ObjectStamp my = objectStamp(); - ObjectStamp other = object().objectStamp(); + if (stamp() instanceof ObjectStamp && object().stamp() instanceof ObjectStamp) { + ObjectStamp my = (ObjectStamp) stamp(); + ObjectStamp other = (ObjectStamp) object().stamp(); if (my.type() == null || other.type() == null) { return this; diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewArrayNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewArrayNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -78,11 +78,13 @@ @Override public ValueNode canonical(CanonicalizerTool tool) { - if (usages().isEmpty() && length.integerStamp().isPositive()) { - return null; - } else { - return this; + if (usages().isEmpty()) { + Stamp stamp = length.stamp(); + if (stamp instanceof IntegerStamp && ((IntegerStamp) stamp).isPositive()) { + return null; + } } + return this; } @Override diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -65,18 +65,14 @@ @Override public boolean inferStamp() { - if (object().stamp().nonNull() && !stamp().nonNull()) { - setStamp(StampFactory.objectNonNull()); - return true; - } - return super.inferStamp(); + return updateStamp(object().stamp()); } @Override public ValueNode canonical(CanonicalizerTool tool) { assert object() != null : this; - if (object().objectStamp().alwaysNull()) { + if (ObjectStamp.isObjectAlwaysNull(object())) { return object(); } if (hub.isConstant() && hub.kind() == Kind.Object && hub.asConstant().asObject() instanceof Class) { diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -98,13 +98,16 @@ @Override public void lower(LoweringTool tool, LoweringType loweringType) { InstanceOfNode typeTest = graph().add(new InstanceOfNode(type, object, profile)); - Stamp stamp = StampFactory.declared(type).join(object.stamp()); + Stamp stamp = StampFactory.declared(type); + if (stamp() instanceof ObjectStamp && object().stamp() instanceof ObjectStamp) { + stamp = ((ObjectStamp) object().stamp()).castTo((ObjectStamp) stamp); + } ValueNode condition; - if (stamp == null) { + if (stamp == StampFactory.illegal()) { // This is a check cast that will always fail condition = LogicConstantNode.contradiction(graph()); stamp = StampFactory.declared(type); - } else if (object.stamp().nonNull()) { + } else if (ObjectStamp.isObjectNonNull(object)) { condition = typeTest; } else { if (profile != null && profile.getNullSeen() == TriState.FALSE) { @@ -124,14 +127,17 @@ @Override public boolean inferStamp() { - return updateStamp(stamp().join(object().stamp())); + if (stamp() instanceof ObjectStamp && object().stamp() instanceof ObjectStamp) { + return updateStamp(((ObjectStamp) object().stamp()).castTo((ObjectStamp) stamp())); + } + return false; } @Override public ValueNode canonical(CanonicalizerTool tool) { assert object() != null : this; - ResolvedJavaType objectType = object().objectStamp().type(); + ResolvedJavaType objectType = ObjectStamp.typeOrNull(object()); if (objectType != null && type.isAssignableFrom(objectType)) { // we don't have to check for null types here because they will also pass the // checkcast. @@ -150,7 +156,7 @@ } } - if (object().objectStamp().alwaysNull()) { + if (ObjectStamp.isObjectAlwaysNull(object())) { return object(); } if (tool.assumptions().useOptimisticAssumptions()) { diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -27,6 +27,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; /** * The {@code InstanceOfDynamicNode} represents a type check where the type being checked is not @@ -46,8 +47,8 @@ this.mirror = mirror; this.object = object; assert mirror.kind() == Kind.Object : mirror.kind(); - assert mirror.objectStamp().isExactType(); - assert mirror.objectStamp().type().getName().equals("Ljava/lang/Class;"); + assert mirror.stamp() instanceof ObjectStamp; + assert ((ObjectStamp) mirror.stamp()).type().getName().equals("Ljava/lang/Class;"); } @Override diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -58,19 +58,20 @@ @Override public LogicNode canonical(CanonicalizerTool tool) { - assert object() != null : this; - - ObjectStamp stamp = object().objectStamp(); - if (object().objectStamp().alwaysNull()) { + Stamp stamp = object().stamp(); + if (!(stamp instanceof ObjectStamp)) { + return this; + } + ObjectStamp objectStamp = (ObjectStamp) stamp; + if (objectStamp.alwaysNull()) { return LogicConstantNode.contradiction(graph()); } - ResolvedJavaType stampType = stamp.type(); - if (stamp.isExactType() || stampType != null) { + ResolvedJavaType stampType = objectStamp.type(); + if (stampType != null) { boolean subType = type().isAssignableFrom(stampType); - if (subType) { - if (stamp.nonNull()) { + if (objectStamp.nonNull()) { // the instanceOf matches, so return true return LogicConstantNode.tautology(graph()); } else { @@ -80,7 +81,7 @@ return graph().unique(new IsNullNode(object())); } } else { - if (stamp.isExactType()) { + if (objectStamp.isExactType()) { // since this type check failed for an exact type we know that it can never // succeed at run time. we also don't care about null values, since they will // also make the check fail. diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -45,8 +45,9 @@ } private static Stamp createStamp(ValueNode array, Kind kind) { - if (kind == Kind.Object && array.objectStamp().type() != null) { - return StampFactory.declared(array.objectStamp().type().getComponentType()); + ResolvedJavaType type = ObjectStamp.typeOrNull(array); + if (kind == Kind.Object && type != null) { + return StampFactory.declared(type.getComponentType()); } else { return StampFactory.forKind(kind); } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -128,9 +128,9 @@ public ValueNode canonical(CanonicalizerTool tool) { if (!isStatic()) { ValueNode receiver = receiver(); - if (receiver != null && receiver.objectStamp().isExactType()) { + if (receiver != null && ObjectStamp.isExactType(receiver)) { if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) { - ResolvedJavaMethod method = receiver.objectStamp().type().resolveMethod(targetMethod); + ResolvedJavaMethod method = ObjectStamp.typeOrNull(receiver).resolveMethod(targetMethod); if (method != null) { invokeKind = InvokeKind.Special; targetMethod = method; diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -56,7 +56,11 @@ @Override public ValueNode canonical(CanonicalizerTool tool) { - ObjectStamp stamp = object.objectStamp(); + if (!(object.stamp() instanceof ObjectStamp)) { + return this; + } + + ObjectStamp stamp = (ObjectStamp) object.stamp(); boolean needsCheck = true; if (stamp.isExactType()) { diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -74,7 +74,7 @@ int index = indexValue.isConstant() ? indexValue.asConstant().asInt() : -1; if (index >= 0 && index < arrayState.getVirtualObject().entryCount()) { ResolvedJavaType componentType = arrayState.getVirtualObject().type().getComponentType(); - if (componentType.isPrimitive() || value.objectStamp().alwaysNull() || (value.objectStamp().type() != null && componentType.isAssignableFrom(value.objectStamp().type()))) { + if (componentType.isPrimitive() || ObjectStamp.isObjectAlwaysNull(value) || (ObjectStamp.typeOrNull(value) != null && componentType.isAssignableFrom(ObjectStamp.typeOrNull(value)))) { tool.setVirtualEntry(arrayState, index, value()); tool.delete(); } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -97,8 +97,8 @@ tool.addToWorkList(blockSuccessor(survivingEdge)); graph().removeSplit(this, blockSuccessor(survivingEdge)); } - if (value() instanceof LoadHubNode) { - ObjectStamp stamp = ((LoadHubNode) value()).object().objectStamp(); + if (value() instanceof LoadHubNode && ((LoadHubNode) value()).object().stamp() instanceof ObjectStamp) { + ObjectStamp stamp = (ObjectStamp) ((LoadHubNode) value()).object().stamp(); if (stamp.type() != null) { int validKeys = 0; for (int i = 0; i < keyCount(); i++) { diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/FloatStamp.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/FloatStamp.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/FloatStamp.java Thu Aug 08 18:17:47 2013 +0200 @@ -95,6 +95,15 @@ @Override public Stamp meet(Stamp otherStamp) { + if (otherStamp == this) { + return this; + } + if (otherStamp instanceof IllegalStamp) { + return otherStamp.meet(this); + } + if (!(otherStamp instanceof FloatStamp)) { + return StampFactory.illegal(); + } FloatStamp other = (FloatStamp) otherStamp; assert kind() == other.kind(); double meetUpperBound = Math.max(upperBound, other.upperBound); @@ -111,6 +120,15 @@ @Override public Stamp join(Stamp otherStamp) { + if (otherStamp == this) { + return this; + } + if (otherStamp instanceof IllegalStamp) { + return otherStamp.join(this); + } + if (!(otherStamp instanceof FloatStamp)) { + return StampFactory.illegal(); + } FloatStamp other = (FloatStamp) otherStamp; assert kind() == other.kind(); double joinUpperBound = Math.min(upperBound, other.upperBound); @@ -120,6 +138,8 @@ return this; } else if (joinLowerBound == other.lowerBound && joinUpperBound == other.upperBound && joinNonNaN == other.nonNaN) { return other; + } else if (joinLowerBound > joinUpperBound) { + return StampFactory.illegal(); } else { return new FloatStamp(kind(), joinLowerBound, joinUpperBound, joinNonNaN); } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/GenericStamp.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/GenericStamp.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/GenericStamp.java Thu Aug 08 18:17:47 2013 +0200 @@ -58,13 +58,23 @@ @Override public Stamp meet(Stamp other) { - assert ((GenericStamp) other).type == type; + if (other instanceof IllegalStamp) { + return other.join(this); + } + if (!(other instanceof GenericStamp) || ((GenericStamp) other).type != type) { + return StampFactory.illegal(); + } return this; } @Override public Stamp join(Stamp other) { - assert ((GenericStamp) other).type == type; + if (other instanceof IllegalStamp) { + return other.join(this); + } + if (!(other instanceof GenericStamp) || ((GenericStamp) other).type != type) { + return StampFactory.illegal(); + } return this; } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IllegalStamp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IllegalStamp.java Thu Aug 08 18:17:47 2013 +0200 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2012, 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.nodes.type; + +import com.oracle.graal.api.meta.*; + +public final class IllegalStamp extends Stamp { + + public static final IllegalStamp ILLEGAL = new IllegalStamp(); + + private IllegalStamp() { + super(Kind.Illegal); + } + + @Override + public ResolvedJavaType javaType(MetaAccessProvider metaAccess) { + return null; + } + + @Override + public boolean alwaysDistinct(Stamp other) { + return true; + } + + @Override + public Stamp meet(Stamp other) { + return other; + } + + @Override + public Stamp join(Stamp other) { + return this; + } + + @Override + public String toString() { + return "ILLEGAL"; + } +} diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java Thu Aug 08 18:17:47 2013 +0200 @@ -143,6 +143,15 @@ @Override public Stamp meet(Stamp otherStamp) { + if (otherStamp == this) { + return this; + } + if (otherStamp instanceof IllegalStamp) { + return otherStamp.meet(this); + } + if (!(otherStamp instanceof IntegerStamp)) { + return StampFactory.illegal(); + } IntegerStamp other = (IntegerStamp) otherStamp; assert kind() == other.kind(); long meetUpperBound = Math.max(upperBound, other.upperBound); @@ -159,6 +168,15 @@ @Override public Stamp join(Stamp otherStamp) { + if (otherStamp == this) { + return this; + } + if (otherStamp instanceof IllegalStamp) { + return otherStamp.join(this); + } + if (!(otherStamp instanceof IntegerStamp)) { + return StampFactory.illegal(); + } IntegerStamp other = (IntegerStamp) otherStamp; assert kind() == other.kind(); long joinUpperBound = Math.min(upperBound, other.upperBound); @@ -168,6 +186,8 @@ return this; } else if (joinLowerBound == other.lowerBound && joinUpperBound == other.upperBound && joinMask == other.mask) { return other; + } else if (joinLowerBound > joinUpperBound) { + return StampFactory.illegal(); } else { return new IntegerStamp(kind(), joinLowerBound, joinUpperBound, joinMask); } @@ -237,4 +257,11 @@ return s1.isPositive() && s2.isPositive() || s1.isStrictlyNegative() && s2.isStrictlyNegative(); } + @Override + public Constant asConstant() { + if (lowerBound == upperBound) { + return Constant.forIntegerKind(kind(), lowerBound, null); + } + return null; + } } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/ObjectStamp.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/ObjectStamp.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/ObjectStamp.java Thu Aug 08 18:17:47 2013 +0200 @@ -25,6 +25,7 @@ import java.lang.reflect.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; public class ObjectStamp extends Stamp { @@ -35,29 +36,12 @@ public ObjectStamp(ResolvedJavaType type, boolean exactType, boolean nonNull, boolean alwaysNull) { super(Kind.Object); - assert isValid(type, exactType, nonNull, alwaysNull); this.type = type; this.exactType = exactType; this.nonNull = nonNull; this.alwaysNull = alwaysNull; } - public static boolean isValid(ResolvedJavaType type, boolean exactType, boolean nonNull, boolean alwaysNull) { - if (exactType && type == null) { - return false; - } - - if (exactType && Modifier.isAbstract(type.getModifiers()) && !type.isArray()) { - return false; - } - - if (nonNull && alwaysNull) { - return false; - } - - return true; - } - @Override public ResolvedJavaType javaType(MetaAccessProvider metaAccess) { if (type != null) { @@ -66,7 +50,6 @@ return metaAccess.lookupJavaType(Object.class); } - @Override public boolean nonNull() { return nonNull; } @@ -92,26 +75,16 @@ } @Override - public boolean alwaysDistinct(Stamp otherStamp) { - ObjectStamp other = (ObjectStamp) otherStamp; - if ((alwaysNull && other.nonNull) || (nonNull && other.alwaysNull)) { - return true; - } - if (other.type == null || type == null) { - // We have no type information for one of the values. - return false; - } else if (other.nonNull || nonNull) { - // One of the two values cannot be null. - return !other.type.isInterface() && !type.isInterface() && !type.isAssignableFrom(other.type) && !other.type.isAssignableFrom(type); - } - return false; - } - - @Override public Stamp meet(Stamp otherStamp) { if (this == otherStamp) { return this; } + if (otherStamp instanceof IllegalStamp) { + return otherStamp.meet(this); + } + if (!(otherStamp instanceof ObjectStamp)) { + return StampFactory.illegal(); + } ObjectStamp other = (ObjectStamp) otherStamp; ResolvedJavaType meetType; boolean meetExactType; @@ -144,44 +117,82 @@ } @Override - public ObjectStamp join(Stamp otherStamp) { + public Stamp join(Stamp otherStamp) { + return join0(otherStamp, false); + } + + public Stamp castTo(ObjectStamp to) { + return join0(to, true); + } + + public Stamp join0(Stamp otherStamp, boolean castToOther) { if (this == otherStamp) { return this; } + if (otherStamp instanceof IllegalStamp) { + return otherStamp.join(this); + } + if (!(otherStamp instanceof ObjectStamp)) { + return StampFactory.illegal(); + } ObjectStamp other = (ObjectStamp) otherStamp; ResolvedJavaType joinType; - boolean joinExactType = exactType || other.exactType; + boolean joinAlwaysNull = alwaysNull || other.alwaysNull; boolean joinNonNull = nonNull || other.nonNull; - boolean joinAlwaysNull = alwaysNull || other.alwaysNull; + if (joinAlwaysNull && joinNonNull) { + return StampFactory.illegal(); + } + boolean joinExactType = exactType || other.exactType; if (type == other.type) { joinType = type; } else if (type == null && other.type == null) { joinType = null; + if (joinExactType) { + return StampFactory.illegal(); + } } else if (type == null) { joinType = other.type; } else if (other.type == null) { joinType = type; } else { - // both types are != null + // both types are != null and different if (type.isAssignableFrom(other.type)) { joinType = other.type; + if (exactType) { + joinAlwaysNull = true; + } + } else if (other.type.isAssignableFrom(type)) { + joinType = type; + if (other.exactType) { + joinAlwaysNull = true; + } } else { - joinType = type; + if (castToOther) { + joinType = other.type; + joinExactType = other.exactType; + } else { + joinType = null; + if (joinExactType || (!type.isInterface() && !other.type.isInterface())) { + joinAlwaysNull = true; + } + } } } - + if (joinAlwaysNull) { + if (joinNonNull) { + return StampFactory.illegal(); + } + joinExactType = false; + joinType = null; + } else if (joinExactType && Modifier.isAbstract(joinType.getModifiers()) && !joinType.isArray()) { + return StampFactory.illegal(); + } if (joinType == type && joinExactType == exactType && joinNonNull == nonNull && joinAlwaysNull == alwaysNull) { return this; } else if (joinType == other.type && joinExactType == other.exactType && joinNonNull == other.nonNull && joinAlwaysNull == other.alwaysNull) { return other; } else { - if (isValid(joinType, joinExactType, joinNonNull, joinAlwaysNull)) { - return new ObjectStamp(joinType, joinExactType, joinNonNull, joinAlwaysNull); - } else { - // This situation can happen in case the compiler wants to join two contradicting - // stamps. - return null; - } + return new ObjectStamp(joinType, joinExactType, joinNonNull, joinAlwaysNull); } } @@ -201,6 +212,7 @@ int result = 1; result = prime * result + (exactType ? 1231 : 1237); result = prime * result + (nonNull ? 1231 : 1237); + result = prime * result + (alwaysNull ? 1231 : 1237); result = prime * result + ((type == null) ? 0 : type.hashCode()); return result; } @@ -214,7 +226,7 @@ return false; } ObjectStamp other = (ObjectStamp) obj; - if (exactType != other.exactType || nonNull != other.nonNull) { + if (exactType != other.exactType || nonNull != other.nonNull || alwaysNull != other.alwaysNull) { return false; } if (type == null) { @@ -226,4 +238,42 @@ } return true; } + + public static boolean isObjectAlwaysNull(ValueNode node) { + return isObjectAlwaysNull(node.stamp()); + } + + public static boolean isObjectAlwaysNull(Stamp stamp) { + return (stamp instanceof ObjectStamp && ((ObjectStamp) stamp).alwaysNull()); + } + + public static boolean isObjectNonNull(ValueNode node) { + return isObjectNonNull(node.stamp()); + } + + public static boolean isObjectNonNull(Stamp stamp) { + return (stamp instanceof ObjectStamp && ((ObjectStamp) stamp).nonNull()); + } + + public static ResolvedJavaType typeOrNull(ValueNode node) { + return typeOrNull(node.stamp()); + } + + public static ResolvedJavaType typeOrNull(Stamp stamp) { + if (stamp instanceof ObjectStamp) { + return ((ObjectStamp) stamp).type(); + } + return null; + } + + public static boolean isExactType(ValueNode node) { + return isExactType(node.stamp()); + } + + public static boolean isExactType(Stamp stamp) { + if (stamp instanceof ObjectStamp) { + return ((ObjectStamp) stamp).isExactType(); + } + return false; + } } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/Stamp.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/Stamp.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/Stamp.java Thu Aug 08 18:17:47 2013 +0200 @@ -46,15 +46,10 @@ */ public abstract ResolvedJavaType javaType(MetaAccessProvider metaAccess); - /** - * Determines if the stamped value is guaranteed to be non-null. - */ - public boolean nonNull() { - return false; + public boolean alwaysDistinct(Stamp other) { + return join(other) == StampFactory.illegal(); } - public abstract boolean alwaysDistinct(Stamp other); - /** * Returns the union of this stamp and the given stamp. Typically used to create stamps for * {@link PhiNode}s. @@ -71,4 +66,15 @@ * @return The intersection of this stamp and the given stamp. */ public abstract Stamp join(Stamp other); + + /** + * If this stamp represents a single value, the methods returns this single value. It returns + * null otherwise. + * + * @return the constant corresponding to the single value of this stamp and null if this tamp + * can represent less or more than one value. + */ + public Constant asConstant() { + return null; + } } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java Thu Aug 08 18:17:47 2013 +0200 @@ -113,6 +113,10 @@ return positiveInt; } + public static Stamp illegal() { + return IllegalStamp.ILLEGAL; + } + public static Stamp forInteger(Kind kind, long lowerBound, long upperBound, long mask) { return new IntegerStamp(kind, lowerBound, upperBound, mask); } @@ -199,4 +203,8 @@ public static Stamp exactNonNull(ResolvedJavaType type) { return new ObjectStamp(type, true, true, false); } + + public static Stamp exact(ResolvedJavaType type) { + return new ObjectStamp(type, true, false, false); + } } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java Thu Aug 08 18:17:47 2013 +0200 @@ -57,6 +57,13 @@ } } + public static Stamp add(Stamp stamp1, Stamp stamp2) { + if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) { + return add((IntegerStamp) stamp1, (IntegerStamp) stamp2); + } + return StampFactory.illegal(); + } + public static Stamp add(IntegerStamp stamp1, IntegerStamp stamp2) { Kind kind = stamp1.kind(); assert kind == stamp2.kind(); @@ -73,8 +80,15 @@ return StampFactory.forInteger(kind, lowerBound, upperBound, mask); } - public static Stamp sub(IntegerStamp stamp1, IntegerStamp stamp2) { - return add(stamp1, (IntegerStamp) StampTool.negate(stamp2)); + public static Stamp sub(Stamp stamp1, Stamp stamp2) { + return add(stamp1, StampTool.negate(stamp2)); + } + + public static Stamp div(Stamp stamp1, Stamp stamp2) { + if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) { + return div((IntegerStamp) stamp1, (IntegerStamp) stamp2); + } + return StampFactory.illegal(); } public static Stamp div(IntegerStamp stamp1, IntegerStamp stamp2) { @@ -122,12 +136,26 @@ return StampFactory.forInteger(kind, lowerBound, upperBound, mask); } + public static Stamp and(Stamp stamp1, Stamp stamp2) { + if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) { + return and((IntegerStamp) stamp1, (IntegerStamp) stamp2); + } + return StampFactory.illegal(); + } + public static Stamp and(IntegerStamp stamp1, IntegerStamp stamp2) { Kind kind = stamp1.kind(); long mask = stamp1.mask() & stamp2.mask(); return stampForMask(kind, mask); } + public static Stamp or(Stamp stamp1, Stamp stamp2) { + if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) { + return or((IntegerStamp) stamp1, (IntegerStamp) stamp2); + } + return StampFactory.illegal(); + } + public static Stamp or(IntegerStamp stamp1, IntegerStamp stamp2) { Kind kind = stamp1.kind(); long mask = stamp1.mask() | stamp2.mask(); @@ -138,12 +166,26 @@ } } + public static Stamp xor(Stamp stamp1, Stamp stamp2) { + if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) { + return xor((IntegerStamp) stamp1, (IntegerStamp) stamp2); + } + return StampFactory.illegal(); + } + public static Stamp xor(IntegerStamp stamp1, IntegerStamp stamp2) { Kind kind = stamp1.kind(); long mask = stamp1.mask() | stamp2.mask(); return stampForMask(kind, mask); } + public static Stamp unsignedRightShift(Stamp value, Stamp shift) { + if (value instanceof IntegerStamp && shift instanceof IntegerStamp) { + return unsignedRightShift((IntegerStamp) value, (IntegerStamp) shift); + } + return StampFactory.illegal(); + } + public static Stamp unsignedRightShift(IntegerStamp value, IntegerStamp shift) { Kind kind = value.kind(); if (shift.lowerBound() == shift.upperBound()) { @@ -167,6 +209,13 @@ return stampForMask(kind, mask); } + public static Stamp leftShift(Stamp value, Stamp shift) { + if (value instanceof IntegerStamp && shift instanceof IntegerStamp) { + return leftShift((IntegerStamp) value, (IntegerStamp) shift); + } + return StampFactory.illegal(); + } + public static Stamp leftShift(IntegerStamp value, IntegerStamp shift) { Kind kind = value.kind(); int shiftBits = kind == Kind.Int ? 5 : 6; diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Thu Aug 08 18:17:47 2013 +0200 @@ -34,7 +34,6 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.tiers.*; @@ -295,9 +294,7 @@ /** * Calls {@link ValueNode#inferStamp()} on the node and, if it returns true (which means - * that the stamp has changed), re-queues the node's usages . If the stamp has changed then - * this method also checks if the stamp now describes a constant integer value, in which - * case the node is replaced with a constant. + * that the stamp has changed), re-queues the node's usages. */ private boolean tryInferStamp(Node node, StructuredGraph graph) { if (node.isAlive() && node instanceof ValueNode) { @@ -305,16 +302,10 @@ METRIC_INFER_STAMP_CALLED.increment(); if (valueNode.inferStamp()) { METRIC_STAMP_CHANGED.increment(); - if (valueNode.stamp() instanceof IntegerStamp && valueNode.integerStamp().lowerBound() == valueNode.integerStamp().upperBound()) { - ValueNode replacement = ConstantNode.forIntegerKind(valueNode.kind(), valueNode.integerStamp().lowerBound(), graph); - Debug.log("Canonicalizer: replacing %s with %s (inferStamp)", valueNode, replacement); - valueNode.replaceAtUsages(replacement); - } else { - for (Node usage : valueNode.usages()) { - workList.addAgain(usage); - } - return true; + for (Node usage : valueNode.usages()) { + workList.addAgain(usage); } + return true; } } return false; diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Thu Aug 08 18:17:47 2013 +0200 @@ -114,7 +114,7 @@ break; } } - if (type != null && type != node.objectStamp().type()) { + if (type != null && type != ObjectStamp.typeOrNull(node)) { newKnownTypes.put(node, type); } } @@ -196,15 +196,15 @@ public ResolvedJavaType getNodeType(ValueNode node) { ResolvedJavaType result = knownTypes.get(GraphUtil.unproxify(node)); - return result == null ? node.objectStamp().type() : result; + return result == null ? ObjectStamp.typeOrNull(node) : result; } public boolean isNull(ValueNode value) { - return value.objectStamp().alwaysNull() || knownNull.contains(GraphUtil.unproxify(value)); + return ObjectStamp.isObjectAlwaysNull(value) || knownNull.contains(GraphUtil.unproxify(value)); } public boolean isNonNull(ValueNode value) { - return value.objectStamp().nonNull() || knownNonNull.contains(GraphUtil.unproxify(value)); + return ObjectStamp.isObjectNonNull(value) || knownNonNull.contains(GraphUtil.unproxify(value)); } @Override @@ -576,7 +576,7 @@ ValueNode receiver = callTarget.receiver(); if (receiver != null && (callTarget.invokeKind() == InvokeKind.Interface || callTarget.invokeKind() == InvokeKind.Virtual)) { ResolvedJavaType type = state.getNodeType(receiver); - if (type != receiver.objectStamp().type()) { + if (type != ObjectStamp.typeOrNull(receiver)) { ResolvedJavaMethod method = type.resolveMethod(callTarget.targetMethod()); if (method != null) { if ((method.getModifiers() & Modifier.FINAL) != 0 || (type.getModifiers() & Modifier.FINAL) != 0) { diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Thu Aug 08 18:17:47 2013 +0200 @@ -1036,7 +1036,10 @@ assert callTarget.invokeKind() == InvokeKind.Virtual || callTarget.invokeKind() == InvokeKind.Interface; ResolvedJavaType holder = targetMethod.getDeclaringClass(); - ObjectStamp receiverStamp = callTarget.receiver().objectStamp(); + if (!(callTarget.receiver().stamp() instanceof ObjectStamp)) { + return null; + } + ObjectStamp receiverStamp = (ObjectStamp) callTarget.receiver().stamp(); if (receiverStamp.alwaysNull()) { // Don't inline if receiver is known to be null return null; @@ -1442,8 +1445,8 @@ assert !callTarget.isStatic() : callTarget.targetMethod(); StructuredGraph graph = callTarget.graph(); ValueNode firstParam = callTarget.arguments().get(0); - if (firstParam.kind() == Kind.Object && !firstParam.objectStamp().nonNull()) { - assert !firstParam.objectStamp().alwaysNull(); + if (firstParam.kind() == Kind.Object && !ObjectStamp.isObjectNonNull(firstParam)) { + assert !ObjectStamp.isObjectAlwaysNull(firstParam); IsNullNode condition = graph.unique(new IsNullNode(firstParam)); Stamp stamp = firstParam.stamp().join(objectNonNull()); GuardingPiNode nonNullReceiver = graph.add(new GuardingPiNode(firstParam, condition, true, NullCheckException, InvalidateReprofile, stamp)); diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Thu Aug 08 18:17:47 2013 +0200 @@ -36,6 +36,7 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.spi.Lowerable.LoweringType; +import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.schedule.*; import com.oracle.graal.phases.tiers.*; @@ -77,7 +78,7 @@ @Override public GuardingNode createNullCheckGuard(GuardedNode guardedNode, ValueNode object) { - if (object.objectStamp().nonNull()) { + if (ObjectStamp.isObjectNonNull(object)) { // Short cut creation of null check guard if the object is known to be non-null. return null; } diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java Thu Aug 08 18:17:47 2013 +0200 @@ -45,7 +45,7 @@ private boolean isAssignableType(ValueNode node, MetaAccessProvider runtime) { if (node.stamp() instanceof ObjectStamp) { ResolvedJavaType valueType = runtime.lookupJavaType(klass); - ResolvedJavaType nodeType = node.objectStamp().type(); + ResolvedJavaType nodeType = ObjectStamp.typeOrNull(node); if (nodeType != null && valueType.isAssignableFrom(nodeType)) { return true; diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Thu Aug 08 18:17:47 2013 +0200 @@ -267,7 +267,7 @@ return inlineGraph; } }); - if (!methodCallTargetNode.isStatic() && methodCallTargetNode.receiver().objectStamp().alwaysNull()) { + if (!methodCallTargetNode.isStatic() && ObjectStamp.isObjectAlwaysNull(methodCallTargetNode.receiver())) { return invoke.next(); } FixedNode fixedNode = (FixedNode) invoke.predecessor(); diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerAddExactNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerAddExactNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerAddExactNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -43,7 +43,7 @@ @Override public boolean inferStamp() { // TODO Should probably use a specialised version which understands that it can't overflow - return updateStamp(StampTool.add(x().integerStamp(), y().integerStamp())); + return updateStamp(StampTool.add(x().stamp(), y().stamp())); } @Override diff -r 7894695caee6 -r ef6915cf1e59 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerSubExactNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerSubExactNode.java Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerSubExactNode.java Thu Aug 08 18:17:47 2013 +0200 @@ -43,7 +43,7 @@ @Override public boolean inferStamp() { // TODO Should probably use a specialised version which understands that it can't overflow - return updateStamp(StampTool.sub(x().integerStamp(), y().integerStamp())); + return updateStamp(StampTool.sub(x().stamp(), y().stamp())); } @Override diff -r 7894695caee6 -r ef6915cf1e59 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 Thu Aug 08 14:19:06 2013 +0200 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Thu Aug 08 18:17:47 2013 +0200 @@ -123,13 +123,14 @@ for (AccessIndexedNode node : graph.getNodes().filter(AccessIndexedNode.class).snapshot()) { ValueNode array = node.array(); - if (array.objectStamp().type() == null) { + ResolvedJavaType arrayType = ObjectStamp.typeOrNull(array); + if (arrayType == null) { // There are cases where the array does not have a known type yet. Assume it is not // a word type. continue; } - assert array.objectStamp().type().isArray(); - if (isWord(array.objectStamp().type().getComponentType())) { + assert arrayType.isArray(); + if (isWord(arrayType.getComponentType())) { /* * 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 @@ -374,8 +375,8 @@ if (node.stamp() == StampFactory.forWord()) { return true; } - if (node.kind() == Kind.Object) { - return isWord(node.objectStamp().type()); + if (node.stamp() instanceof ObjectStamp) { + return isWord(((ObjectStamp) node.stamp()).type()); } return false; } diff -r 7894695caee6 -r ef6915cf1e59 mx/projects --- a/mx/projects Thu Aug 08 14:19:06 2013 +0200 +++ b/mx/projects Thu Aug 08 18:17:47 2013 +0200 @@ -293,6 +293,14 @@ project@com.oracle.graal.nodes@javaCompliance=1.7 project@com.oracle.graal.nodes@workingSets=Graal,Graph +# graal.nodes.test +project@com.oracle.graal.nodes.test@subDir=graal +project@com.oracle.graal.nodes.test@sourceDirs=src +project@com.oracle.graal.nodes.test@dependencies=com.oracle.graal.compiler.test +project@com.oracle.graal.nodes.test@checkstyle=com.oracle.graal.graph +project@com.oracle.graal.nodes.test@javaCompliance=1.7 +project@com.oracle.graal.nodes.test@workingSets=Graal,Graph + # graal.phases project@com.oracle.graal.phases@subDir=graal project@com.oracle.graal.phases@sourceDirs=src