# HG changeset patch # User Roland Schatz # Date 1360601241 -3600 # Node ID f1f4fc5a609fa4b406e447148296ce82379bcc6f # Parent 62bcf515831d3f23a7eef5c7c31954cf8d6d9e3c# Parent f0aa36715f356bf8323d7d9f3447fb673dccd8b0 Merge. diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Mon Feb 11 17:47:21 2013 +0100 @@ -186,7 +186,9 @@ ReturnNode returnNode = testEscapeAnalysis("testInstanceOfSnippet", null, false); ValueNode result = returnNode.result(); Assert.assertTrue(result instanceof ConditionalNode); - Assert.assertEquals(Constant.TRUE, ((ConditionalNode) result).condition().asConstant()); + ConditionalNode conditional = (ConditionalNode) result; + Assert.assertTrue(conditional.condition() instanceof LogicConstantNode); + Assert.assertEquals(true, ((LogicConstantNode) conditional.condition()).getValue()); } public boolean testInstanceOfSnippet() { diff -r 62bcf515831d -r f1f4fc5a609f 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 Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Mon Feb 11 17:47:21 2013 +0100 @@ -585,10 +585,10 @@ } @Override - public void emitGuardCheck(BooleanNode comp, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) { + public void emitGuardCheck(LogicNode comp, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) { if (comp instanceof IsNullNode && negated) { emitNullCheckGuard(((IsNullNode) comp).object()); - } else if (comp instanceof ConstantNode && (comp.asConstant().asBoolean() != negated)) { + } else if (comp instanceof LogicConstantNode && ((LogicConstantNode) comp).getValue() != negated) { // True constant, nothing to emit. // False constants are handled within emitBranch. } else { @@ -605,13 +605,13 @@ protected abstract void emitNullCheckGuard(ValueNode object); - public void emitBranch(BooleanNode node, LabelRef trueSuccessor, LabelRef falseSuccessor, LIRFrameState info) { + public void emitBranch(LogicNode node, LabelRef trueSuccessor, LabelRef falseSuccessor, LIRFrameState info) { if (node instanceof IsNullNode) { emitNullCheckBranch((IsNullNode) node, trueSuccessor, falseSuccessor, info); } else if (node instanceof CompareNode) { emitCompareBranch((CompareNode) node, trueSuccessor, falseSuccessor, info); - } else if (node instanceof ConstantNode) { - emitConstantBranch(((ConstantNode) node).asConstant().asBoolean(), trueSuccessor, falseSuccessor, info); + } else if (node instanceof LogicConstantNode) { + emitConstantBranch(((LogicConstantNode) node).getValue(), trueSuccessor, falseSuccessor, info); } else if (node instanceof IntegerTestNode) { emitIntegerTestBranch((IntegerTestNode) node, trueSuccessor, falseSuccessor, info); } else { @@ -666,16 +666,15 @@ setResult(conditional, emitConditional(conditional.condition(), tVal, fVal)); } - public Variable emitConditional(BooleanNode node, Value trueValue, Value falseValue) { + public Variable emitConditional(LogicNode node, Value trueValue, Value falseValue) { if (node instanceof IsNullNode) { IsNullNode isNullNode = (IsNullNode) node; return emitConditionalMove(operand(isNullNode.object()), Constant.NULL_OBJECT, Condition.EQ, false, trueValue, falseValue); } else if (node instanceof CompareNode) { CompareNode compare = (CompareNode) node; return emitConditionalMove(operand(compare.x()), operand(compare.y()), compare.condition(), compare.unorderedIsTrue(), trueValue, falseValue); - } else if (node instanceof ConstantNode) { - ConstantNode constantNode = (ConstantNode) node; - return emitMove(constantNode.asConstant().asBoolean() ? trueValue : falseValue); + } else if (node instanceof LogicConstantNode) { + return emitMove(((LogicConstantNode) node).getValue() ? trueValue : falseValue); } else if (node instanceof IntegerTestNode) { IntegerTestNode test = (IntegerTestNode) node; return emitIntegerTestMove(operand(test.x()), operand(test.y()), trueValue, falseValue); diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Mon Feb 11 17:47:21 2013 +0100 @@ -74,7 +74,7 @@ /** * Denotes that a parameter of an {@linkplain NodeIntrinsic intrinsic} method must be a compile - * time constant at all call sites to the intrinic method. + * time constant at all call sites to the intrinsic method. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Mon Feb 11 17:47:21 2013 +0100 @@ -287,6 +287,7 @@ public int layoutHelperLog2ElementSizeMask; public int layoutHelperElementTypeShift; public int layoutHelperElementTypeMask; + public int layoutHelperElementTypePrimitiveInPlace; public int layoutHelperHeaderSizeShift; public int layoutHelperHeaderSizeMask; public int layoutHelperOffset; diff -r 62bcf515831d -r f1f4fc5a609f 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 Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Mon Feb 11 17:47:21 2013 +0100 @@ -350,6 +350,9 @@ if (GraalOptions.IntrinsifyArrayCopy) { installer.installSnippets(ArrayCopySnippets.class); } + if (GraalOptions.IntrinsifyObjectClone) { + installer.installSnippets(ObjectCloneSnippets.class); + } installer.installSnippets(CheckCastSnippets.class); installer.installSnippets(InstanceOfSnippets.class); @@ -705,7 +708,7 @@ assert loadHub.kind() == wordKind; LocationNode location = LocationNode.create(LocationNode.FINAL_LOCATION, wordKind, config.hubOffset, graph); ValueNode object = loadHub.object(); - assert !object.isConstant(); + assert !object.isConstant() || object.asConstant().isNull(); ValueNode guard = tool.createNullCheckGuard(object); ReadNode hub = graph.add(new ReadNode(object, location, StampFactory.forKind(wordKind()))); hub.dependencies().add(guard); diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java Mon Feb 11 17:47:21 2013 +0100 @@ -256,7 +256,7 @@ long end = (dstAddr + header + ((long) destPos + length - 1) * scale) >>> cardShift; long count = end - start + 1; while (count-- > 0) { - DirectStoreNode.store((start + cardStart) + count, false); + DirectStoreNode.store((start + cardStart) + count, false, Kind.Boolean); } } } diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java Mon Feb 11 17:47:21 2013 +0100 @@ -442,6 +442,12 @@ return config().layoutHelperElementTypeMask; } + @Fold + public static int layoutHelperElementTypePrimitiveInPlace() { + System.out.println(String.format("%x", config().layoutHelperElementTypePrimitiveInPlace)); + return config().layoutHelperElementTypePrimitiveInPlace; + } + static { assert arrayIndexScale(Kind.Byte) == 1; assert arrayIndexScale(Kind.Boolean) == 1; diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectCloneNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectCloneNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -0,0 +1,156 @@ +/* + * 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.hotspot.snippets; + +import java.lang.reflect.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.virtual.*; +import com.oracle.graal.phases.*; +import com.oracle.graal.phases.common.*; +import com.oracle.graal.snippets.nodes.*; + +public class ObjectCloneNode extends MacroNode implements VirtualizableAllocation, ArrayLengthProvider { + + public ObjectCloneNode(Invoke invoke) { + super(invoke); + } + + @Override + public boolean inferStamp() { + return updateStamp(getObject().stamp()); + } + + private ValueNode getObject() { + return arguments.get(0); + } + + private Method selectSnippetMethod(LoweringTool tool) { + ResolvedJavaType type = getObject().objectStamp().type(); + if (type.isArray()) { + return ObjectCloneSnippets.arrayCloneMethod; + } else if (type.isAssignableFrom(tool.getRuntime().lookupJavaType(Object[].class))) { + // arrays are assignable to Object, Cloneable and Serializable + return ObjectCloneSnippets.genericCloneMethod; + } else { + return ObjectCloneSnippets.instanceCloneMethod; + } + } + + @Override + public void lower(LoweringTool tool) { + if (!GraalOptions.IntrinsifyObjectClone) { + super.lower(tool); + return; + } + ResolvedJavaMethod snippetMethod = tool.getRuntime().lookupJavaMethod(selectSnippetMethod(tool)); + if (Debug.isLogEnabled()) { + Debug.log("%s > Intrinsify (%s)", Debug.currentScope(), snippetMethod.getSignature().getParameterType(0, snippetMethod.getDeclaringClass()).getComponentType()); + } + + StructuredGraph snippetGraph = (StructuredGraph) snippetMethod.getCompilerStorage().get(Graph.class); + assert snippetGraph != null : "ObjectCloneSnippets should be installed"; + InvokeNode invoke = replaceWithInvoke(); + InliningUtil.inline(invoke, snippetGraph, false); + } + + private static boolean isCloneableType(ResolvedJavaType type, MetaAccessProvider metaAccess) { + return metaAccess.lookupJavaType(Cloneable.class).isAssignableFrom(type); + } + + private static ResolvedJavaType getConcreteType(ObjectStamp stamp, Assumptions assumptions) { + if (stamp.isExactType()) { + return stamp.type(); + } else { + ResolvedJavaType type = stamp.type().findUniqueConcreteSubtype(); + if (type != null) { + assumptions.recordConcreteSubtype(stamp.type(), type); + } + return type; + } + } + + @Override + public void virtualize(VirtualizerTool tool) { + State originalState = tool.getObjectState(getObject()); + if (originalState != null && originalState.getState() == EscapeState.Virtual) { + VirtualObjectNode originalVirtual = originalState.getVirtualObject(); + if (isCloneableType(originalVirtual.type(), tool.getMetaAccessProvider())) { + ValueNode[] newEntryState = new ValueNode[originalVirtual.entryCount()]; + for (int i = 0; i < newEntryState.length; i++) { + newEntryState[i] = originalState.getEntry(i); + } + VirtualObjectNode newVirtual = originalVirtual.duplicate(); + tool.createVirtualObject(newVirtual, newEntryState, 0); + tool.replaceWithVirtual(newVirtual); + } + } else { + ValueNode obj; + if (originalState != null) { + obj = originalState.getMaterializedValue(); + } else { + obj = tool.getReplacedValue(getObject()); + } + ResolvedJavaType type = getConcreteType(obj.objectStamp(), tool.getAssumptions()); + if (isCloneableType(type, tool.getMetaAccessProvider())) { + if (!type.isArray()) { + ResolvedJavaField[] fields = type.getInstanceFields(true); + ValueNode[] state = new ValueNode[fields.length]; + final LoadFieldNode[] loads = new LoadFieldNode[fields.length]; + for (int i = 0; i < fields.length; i++) { + state[i] = loads[i] = graph().add(new LoadFieldNode(obj, fields[i])); + } + + VirtualObjectNode newVirtual = new VirtualInstanceNode(type, fields); + final StructuredGraph structuredGraph = (StructuredGraph) graph(); + tool.customAction(new Runnable() { + + public void run() { + for (LoadFieldNode load : loads) { + structuredGraph.addBeforeFixed(ObjectCloneNode.this, load); + } + } + }); + tool.createVirtualObject(newVirtual, state, 0); + tool.replaceWithVirtual(newVirtual); + } + } + } + } + + @Override + public ValueNode length() { + if (getObject() instanceof ArrayLengthProvider) { + return ((ArrayLengthProvider) getObject()).length(); + } else { + return null; + } + } +} diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectCloneSnippets.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectCloneSnippets.java Mon Feb 11 17:47:21 2013 +0100 @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.snippets; + +import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*; +import static com.oracle.graal.snippets.nodes.BranchProbabilityNode.*; + +import java.lang.reflect.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.phases.*; +import com.oracle.graal.snippets.*; +import com.oracle.graal.word.*; + +public class ObjectCloneSnippets implements SnippetsInterface { + + public static final Method instanceCloneMethod = getCloneMethod("instanceClone"); + public static final Method arrayCloneMethod = getCloneMethod("arrayClone"); + public static final Method genericCloneMethod = getCloneMethod("genericClone"); + + private static Method getCloneMethod(String name) { + try { + return ObjectCloneSnippets.class.getDeclaredMethod(name, Object.class); + } catch (SecurityException | NoSuchMethodException e) { + throw new GraalInternalError(e); + } + } + + private static Object instanceClone(Object src, Word hub, int layoutHelper) { + int instanceSize = layoutHelper; + Pointer memory = NewObjectSnippets.allocate(instanceSize); + Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset()); + Object result = NewObjectSnippets.initializeObject((Word) memory, hub, prototypeMarkWord, instanceSize, false, false); + + memory = Word.fromObject(result); + for (int offset = 2 * wordSize(); offset < instanceSize; offset += wordSize()) { + memory.writeWord(offset, Word.fromObject(src).readWord(offset)); + } + + return result; + } + + private static Object arrayClone(Object src, Word hub, int layoutHelper) { + int arrayLength = ArrayLengthNode.arrayLength(src); + int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask(); + int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift()) & layoutHelperHeaderSizeMask(); + int sizeInBytes = NewObjectSnippets.computeArrayAllocationSize(arrayLength, wordSize(), headerSize, log2ElementSize); + + Pointer memory = NewObjectSnippets.allocate(sizeInBytes); + Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset()); + Object result = NewObjectSnippets.initializeArray((Word) memory, hub, arrayLength, sizeInBytes, prototypeMarkWord, headerSize, false, false); + + memory = Word.fromObject(result); + for (int offset = headerSize; offset < sizeInBytes; offset += wordSize()) { + memory.writeWord(offset, Word.fromObject(src).readWord(offset)); + } + return result; + } + + private static Word getAndCheckHub(Object src) { + Word hub = loadHub(src); + if (!(src instanceof Cloneable)) { + probability(DEOPT_PATH_PROBABILITY); + DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); + } + return hub; + } + + @Snippet + public static Object instanceClone(Object src) { + instanceCloneCounter.inc(); + Word hub = getAndCheckHub(src); + return instanceClone(src, hub, hub.readInt(layoutHelperOffset())); + } + + @Snippet + public static Object arrayClone(Object src) { + arrayCloneCounter.inc(); + Word hub = getAndCheckHub(src); + int layoutHelper = hub.readInt(layoutHelperOffset()); + return arrayClone(src, hub, layoutHelper); + } + + @Snippet + public static Object genericClone(Object src) { + genericCloneCounter.inc(); + Word hub = getAndCheckHub(src); + int layoutHelper = hub.readInt(layoutHelperOffset()); + if (layoutHelper < 0) { + probability(LIKELY_PROBABILITY); + genericArrayCloneCounter.inc(); + return arrayClone(src, hub, layoutHelper); + } else { + genericInstanceCloneCounter.inc(); + return instanceClone(src, hub, layoutHelper); + } + } + + private static final SnippetCounter.Group cloneCounters = GraalOptions.SnippetCounters ? new SnippetCounter.Group("Object.clone") : null; + private static final SnippetCounter instanceCloneCounter = new SnippetCounter(cloneCounters, "instanceClone", "clone snippet for instances"); + private static final SnippetCounter arrayCloneCounter = new SnippetCounter(cloneCounters, "arrayClone", "clone snippet for arrays"); + private static final SnippetCounter genericCloneCounter = new SnippetCounter(cloneCounters, "genericClone", "clone snippet for arrays and instances"); + + private static final SnippetCounter.Group genericCloneCounters = GraalOptions.SnippetCounters ? new SnippetCounter.Group("Object.clone generic snippet") : null; + private static final SnippetCounter genericInstanceCloneCounter = new SnippetCounter(genericCloneCounters, "genericInstanceClone", "generic clone implementation took instance path"); + private static final SnippetCounter genericArrayCloneCounter = new SnippetCounter(genericCloneCounters, "genericArrayClone", "generic clone implementation took array path"); + +} diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectSubstitutions.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectSubstitutions.java Mon Feb 11 17:47:21 2013 +0100 @@ -26,7 +26,7 @@ import static com.oracle.graal.nodes.extended.UnsafeCastNode.*; import com.oracle.graal.snippets.*; -import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution; +import com.oracle.graal.snippets.ClassSubstitution.*; import com.oracle.graal.word.*; /** @@ -45,4 +45,7 @@ public static int hashCode(final Object thisObj) { return computeHashCode(thisObj); } + + @MacroSubstitution(macro = ObjectCloneNode.class, isStatic = false) + public static native Object clone(Object obj); } diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/SystemSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/SystemSubstitutions.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/SystemSubstitutions.java Mon Feb 11 17:47:21 2013 +0100 @@ -42,7 +42,7 @@ public static final Descriptor JAVA_TIME_MILLIS = new Descriptor("javaTimeMillis", false, long.class); public static final Descriptor JAVA_TIME_NANOS = new Descriptor("javaTimeNanos", false, long.class); - @MacroSubstitution(macro = ArrayCopyNode.class, isStatic = true) + @MacroSubstitution(macro = ArrayCopyNode.class) public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length); @MethodSubstitution diff -r 62bcf515831d -r f1f4fc5a609f 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 Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Mon Feb 11 17:47:21 2013 +0100 @@ -512,7 +512,7 @@ private void genLogicOp(Kind kind, int opcode) { ValueNode y = frameState.pop(kind); ValueNode x = frameState.pop(kind); - LogicNode v; + BitLogicNode v; switch (opcode) { case IAND: case LAND: @@ -642,14 +642,14 @@ private JavaMethod lookupMethod(int cpi, int opcode) { eagerResolvingForSnippets(cpi, opcode); JavaMethod result = constantPool.lookupMethod(cpi, opcode); - assert !graphBuilderConfig.eagerResolvingForSnippets() || ((result instanceof ResolvedJavaMethod) && ((ResolvedJavaMethod) result).getDeclaringClass().isInitialized()); + assert !graphBuilderConfig.eagerResolvingForSnippets() || ((result instanceof ResolvedJavaMethod) && ((ResolvedJavaMethod) result).getDeclaringClass().isInitialized()) : result; return result; } private JavaField lookupField(int cpi, int opcode) { eagerResolvingForSnippets(cpi, opcode); JavaField result = constantPool.lookupField(cpi, opcode); - assert !graphBuilderConfig.eagerResolvingForSnippets() || (result instanceof ResolvedJavaField && ((ResolvedJavaField) result).getDeclaringClass().isInitialized()); + assert !graphBuilderConfig.eagerResolvingForSnippets() || (result instanceof ResolvedJavaField && ((ResolvedJavaField) result).getDeclaringClass().isInitialized()) : result; return result; } diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64TestOp.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64TestOp.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64TestOp.java Mon Feb 11 17:47:21 2013 +0100 @@ -30,7 +30,6 @@ import com.oracle.graal.graph.*; import com.oracle.graal.lir.asm.*; -//@formatter:off public class AMD64TestOp extends AMD64LIRInstruction { @Use({REG}) protected Value x; @@ -55,21 +54,36 @@ public static void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value x, Value y) { if (isRegister(y)) { switch (x.getKind()) { - case Int: masm.testl(asIntReg(x), asIntReg(y)); break; - case Long: masm.testq(asLongReg(x), asLongReg(y)); break; - default: throw GraalInternalError.shouldNotReachHere(); + case Int: + masm.testl(asIntReg(x), asIntReg(y)); + break; + case Long: + masm.testq(asLongReg(x), asLongReg(y)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); } } else if (isConstant(y)) { switch (x.getKind()) { - case Int: masm.testl(asIntReg(x), tasm.asIntConst(y)); break; - case Long: masm.testq(asLongReg(x), tasm.asIntConst(y)); break; - default: throw GraalInternalError.shouldNotReachHere(); + case Int: + masm.testl(asIntReg(x), tasm.asIntConst(y)); + break; + case Long: + masm.testq(asLongReg(x), tasm.asIntConst(y)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); } } else { switch (x.getKind()) { - case Int: masm.testl(asIntReg(x), tasm.asIntAddr(y)); break; - case Long: masm.testq(asLongReg(x), tasm.asLongAddr(y)); break; - default: throw GraalInternalError.shouldNotReachHere(); + case Int: + masm.testl(asIntReg(x), tasm.asIntAddr(y)); + break; + case Long: + masm.testq(asLongReg(x), tasm.asLongAddr(y)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); } } } diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java Mon Feb 11 17:47:21 2013 +0100 @@ -102,7 +102,7 @@ } negated = true; } - BooleanNode ifTest = ifNode.condition(); + LogicNode ifTest = ifNode.condition(); if (!(ifTest instanceof IntegerLessThanNode)) { if (ifTest instanceof IntegerBelowThanNode) { Debug.log("Ignored potential Counted loop at %s with |<|", loopBegin); diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BooleanNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BooleanNode.java Mon Feb 11 17:41:33 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.nodes; - -import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; - -public abstract class BooleanNode extends FloatingNode { - - public BooleanNode(Stamp stamp) { - super(stamp); - } - - public BooleanNode(Stamp stamp, ValueNode... dependencies) { - super(stamp, dependencies); - } - - /** - * Tells all usages of this node to negate their effect. For example, IfNodes should switch - * their true and false successors. - */ - public void negateUsages() { - for (Node n : usages().snapshot()) { - assert n instanceof Negatable; - ((Negatable) n).negate(); - } - } -} diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -27,6 +27,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -35,7 +36,7 @@ * reference, address, etc. */ @NodeInfo(shortName = "Const", nameTemplate = "Const({p#rawvalue})") -public class ConstantNode extends BooleanNode implements LIRLowerable { +public class ConstantNode extends FloatingNode implements LIRLowerable { public final Constant value; diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -31,25 +31,25 @@ @NodeInfo(nameTemplate = "FixedGuard(!={p#negated}) {p#reason/s}") public final class FixedGuardNode extends FixedWithNextNode implements Simplifiable, Lowerable, LIRLowerable, Node.IterableNodeType, Negatable { - @Input private BooleanNode condition; + @Input private LogicNode condition; private final DeoptimizationReason reason; private final DeoptimizationAction action; private boolean negated; - public BooleanNode condition() { + public LogicNode condition() { return condition; } - public void setCondition(BooleanNode x) { + public void setCondition(LogicNode x) { updateUsages(condition, x); condition = x; } - public FixedGuardNode(BooleanNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action) { + public FixedGuardNode(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action) { this(condition, deoptReason, action, false); } - public FixedGuardNode(BooleanNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) { + public FixedGuardNode(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) { super(StampFactory.forVoid()); this.action = action; this.negated = negated; @@ -85,9 +85,9 @@ @Override public void simplify(SimplifierTool tool) { - if (condition instanceof ConstantNode) { - ConstantNode c = (ConstantNode) condition; - if (c.asConstant().asBoolean() != negated) { + if (condition instanceof LogicConstantNode) { + LogicConstantNode c = (LogicConstantNode) condition; + if (c.getValue() != negated) { ((StructuredGraph) graph()).removeFixed(this); } else { FixedNode next = this.next(); diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -44,12 +44,12 @@ @NodeInfo(nameTemplate = "Guard(!={p#negated}) {p#reason/s}") public final class GuardNode extends FloatingNode implements Canonicalizable, LIRLowerable, Node.IterableNodeType, Negatable { - @Input private BooleanNode condition; + @Input private LogicNode condition; private final DeoptimizationReason reason; private final DeoptimizationAction action; private boolean negated; - public GuardNode(BooleanNode condition, FixedNode anchor, DeoptimizationReason reason, DeoptimizationAction action, boolean negated) { + public GuardNode(LogicNode condition, FixedNode anchor, DeoptimizationReason reason, DeoptimizationAction action, boolean negated) { super(StampFactory.dependency(), anchor); this.condition = condition; this.reason = reason; @@ -60,11 +60,11 @@ /** * The instruction that produces the tested boolean value. */ - public BooleanNode condition() { + public LogicNode condition() { return condition; } - public void setCondition(BooleanNode x) { + public void setCondition(LogicNode x) { updateUsages(condition, x); condition = x; } @@ -97,9 +97,9 @@ @Override public ValueNode canonical(CanonicalizerTool tool) { - if (condition() instanceof ConstantNode) { - ConstantNode c = (ConstantNode) condition(); - if (c.asConstant().asBoolean() != negated) { + if (condition() instanceof LogicConstantNode) { + LogicConstantNode c = (LogicConstantNode) condition(); + if (c.getValue() != negated) { if (!dependencies().isEmpty()) { for (Node usage : usages()) { if (usage instanceof ValueNode) { diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -41,23 +41,23 @@ @Successor private BeginNode trueSuccessor; @Successor private BeginNode falseSuccessor; - @Input private BooleanNode condition; + @Input private LogicNode condition; private double trueSuccessorProbability; - public BooleanNode condition() { + public LogicNode condition() { return condition; } - public void setCondition(BooleanNode x) { + public void setCondition(LogicNode x) { updateUsages(condition, x); condition = x; } - public IfNode(BooleanNode condition, FixedNode trueSuccessor, FixedNode falseSuccessor, double trueSuccessorProbability) { + public IfNode(LogicNode condition, FixedNode trueSuccessor, FixedNode falseSuccessor, double trueSuccessorProbability) { this(condition, BeginNode.begin(trueSuccessor), BeginNode.begin(falseSuccessor), trueSuccessorProbability); } - public IfNode(BooleanNode condition, BeginNode trueSuccessor, BeginNode falseSuccessor, double trueSuccessorProbability) { + public IfNode(LogicNode condition, BeginNode trueSuccessor, BeginNode falseSuccessor, double trueSuccessorProbability) { super(StampFactory.forVoid()); this.condition = condition; this.falseSuccessor = falseSuccessor; @@ -140,9 +140,9 @@ @Override public void simplify(SimplifierTool tool) { - if (condition() instanceof ConstantNode) { - ConstantNode c = (ConstantNode) condition(); - if (c.asConstant().asBoolean()) { + if (condition() instanceof LogicConstantNode) { + LogicConstantNode c = (LogicConstantNode) condition(); + if (c.getValue()) { tool.deleteBranch(falseSuccessor()); tool.addToWorkList(trueSuccessor()); ((StructuredGraph) graph()).removeSplit(this, trueSuccessor()); diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicConstantNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicConstantNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes; + +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.spi.*; + +/** + * The {@code ConstantNode} represents a constant such as an integer value, long, float, object + * reference, address, etc. + */ +@NodeInfo(nameTemplate = "{p#value}") +public class LogicConstantNode extends LogicNode implements LIRLowerable { + + public final boolean value; + + protected LogicConstantNode(boolean value) { + super(); + this.value = value; + } + + /** + * Returns a node for a boolean constant. + * + * @param v the boolean value for which to create the instruction + * @param graph + * @return a node representing the boolean + */ + public static LogicConstantNode forBoolean(boolean v, Graph graph) { + return graph.unique(new LogicConstantNode(v)); + } + + public static LogicConstantNode tautology(Graph graph) { + return forBoolean(true, graph); + } + + public static LogicConstantNode contradiction(Graph graph) { + return forBoolean(false, graph); + } + + public boolean getValue() { + return value; + } + + @Override + public LogicNode canonical(CanonicalizerTool tool) { + throw new GraalInternalError("shouldn't call canonical on LogicConstantNode"); + } + + @Override + public void generate(LIRGeneratorTool generator) { + // nothing to do + } +} diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes; + +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +public abstract class LogicNode extends FloatingNode { + + public LogicNode(ValueNode... dependencies) { + super(StampFactory.condition(), dependencies); + } + + /** + * Tells all usages of this node to negate their effect. For example, IfNodes should switch + * their true and false successors. + */ + public void negateUsages() { + for (Node n : usages().snapshot()) { + assert n instanceof Negatable; + ((Negatable) n).negate(); + } + } + + // forces all subclasses to canonicalize to BooleanNode instances + public abstract LogicNode canonical(CanonicalizerTool tool); +} diff -r 62bcf515831d -r f1f4fc5a609f 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 Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -29,7 +29,7 @@ import com.oracle.graal.nodes.type.*; @NodeInfo(shortName = "&") -public final class AndNode extends LogicNode implements Canonicalizable, LIRLowerable { +public final class AndNode extends BitLogicNode implements Canonicalizable, LIRLowerable { public AndNode(Kind kind, ValueNode x, ValueNode y) { super(kind, x, y); diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -175,11 +175,11 @@ } else if (node instanceof IntegerMulNode) { return IntegerArithmeticNode.mul(a, IntegerAddNode.mul(m1, m2)); } else if (node instanceof AndNode) { - return LogicNode.and(a, LogicNode.and(m1, m2)); + return BitLogicNode.and(a, BitLogicNode.and(m1, m2)); } else if (node instanceof OrNode) { - return LogicNode.or(a, LogicNode.or(m1, m2)); + return BitLogicNode.or(a, BitLogicNode.or(m1, m2)); } else if (node instanceof XorNode) { - return LogicNode.xor(a, LogicNode.xor(m1, m2)); + return BitLogicNode.xor(a, BitLogicNode.xor(m1, m2)); } else { throw GraalInternalError.shouldNotReachHere(); } diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BitLogicNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BitLogicNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes.calc; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; + +/** + * The {@code LogicNode} class definition. + */ +public abstract class BitLogicNode extends BinaryNode { + + /** + * Constructs a new logic operation node. + * + * @param x the first input into this node + * @param y the second input into this node + */ + public BitLogicNode(Kind kind, ValueNode x, ValueNode y) { + super(kind, x, y); + assert kind == Kind.Int || kind == Kind.Long; + } + + public static BitLogicNode and(ValueNode v1, ValueNode v2) { + assert v1.kind() == v2.kind() && v1.graph() == v2.graph(); + Graph graph = v1.graph(); + switch (v1.kind()) { + case Int: + return graph.unique(new AndNode(Kind.Int, v1, v2)); + case Long: + return graph.unique(new AndNode(Kind.Long, v1, v2)); + default: + throw ValueNodeUtil.shouldNotReachHere(); + } + } + + public static BitLogicNode or(ValueNode v1, ValueNode v2) { + assert v1.kind() == v2.kind() && v1.graph() == v2.graph(); + Graph graph = v1.graph(); + switch (v1.kind()) { + case Int: + return graph.unique(new OrNode(Kind.Int, v1, v2)); + case Long: + return graph.unique(new OrNode(Kind.Long, v1, v2)); + default: + throw ValueNodeUtil.shouldNotReachHere(); + } + } + + public static BitLogicNode xor(ValueNode v1, ValueNode v2) { + assert v1.kind() == v2.kind() && v1.graph() == v2.graph(); + Graph graph = v1.graph(); + switch (v1.kind()) { + case Int: + return graph.unique(new XorNode(Kind.Int, v1, v2)); + case Long: + return graph.unique(new XorNode(Kind.Long, v1, v2)); + default: + throw ValueNodeUtil.shouldNotReachHere(); + } + } +} diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -26,7 +26,6 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; /* TODO (thomaswue/gdub) For high-level optimization purpose the compare node should be a boolean *value* (it is currently only a helper node) * But in the back-end the comparison should not always be materialized (for example in x86 the comparison result will not be in a register but in a flag) @@ -34,7 +33,7 @@ * Compare should probably be made a value (so that it can be canonicalized for example) and in later stages some Compare usage should be transformed * into variants that do not materialize the value (CompareIf, CompareGuard...) */ -public abstract class CompareNode extends BooleanNode implements Canonicalizable, LIRLowerable { +public abstract class CompareNode extends LogicNode implements Canonicalizable, LIRLowerable { @Input private ValueNode x; @Input private ValueNode y; @@ -54,7 +53,6 @@ * @param y the instruction that produces the second input to this instruction */ public CompareNode(ValueNode x, ValueNode y) { - super(StampFactory.condition()); assert (x == null && y == null) || x.kind() == y.kind(); this.x = x; this.y = y; @@ -78,7 +76,7 @@ public void generate(LIRGeneratorTool gen) { } - private ValueNode optimizeConditional(Constant constant, ConditionalNode conditionalNode, MetaAccessProvider runtime, Condition cond) { + private LogicNode optimizeConditional(Constant constant, ConditionalNode conditionalNode, MetaAccessProvider runtime, Condition cond) { Constant trueConstant = conditionalNode.trueValue().asConstant(); Constant falseConstant = conditionalNode.falseValue().asConstant(); @@ -87,7 +85,7 @@ boolean falseResult = cond.foldCondition(falseConstant, constant, runtime, unorderedIsTrue()); if (trueResult == falseResult) { - return ConstantNode.forBoolean(trueResult, graph()); + return LogicConstantNode.forBoolean(trueResult, graph()); } else { if (trueResult) { assert falseResult == false; @@ -103,13 +101,14 @@ return this; } - protected ValueNode optimizeNormalizeCmp(Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) { + protected LogicNode optimizeNormalizeCmp(Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) { throw new GraalInternalError("NormalizeCompareNode connected to %s (%s %s %s)", this, constant, normalizeNode, mirrored); } - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public LogicNode canonical(CanonicalizerTool tool) { if (x().isConstant() && y().isConstant() && tool.runtime() != null) { - return ConstantNode.forBoolean(condition().foldCondition(x().asConstant(), y().asConstant(), tool.runtime(), unorderedIsTrue()), graph()); + return LogicConstantNode.forBoolean(condition().foldCondition(x().asConstant(), y().asConstant(), tool.runtime(), unorderedIsTrue()), graph()); } if (x().isConstant()) { if (y() instanceof ConditionalNode) { diff -r 62bcf515831d -r f1f4fc5a609f 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 Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -35,13 +35,13 @@ */ public final class ConditionalNode extends BinaryNode implements Canonicalizable, LIRLowerable, Negatable { - @Input private BooleanNode condition; + @Input private LogicNode condition; - public BooleanNode condition() { + public LogicNode condition() { return condition; } - public ConditionalNode(BooleanNode condition, ValueNode trueValue, ValueNode falseValue) { + public ConditionalNode(LogicNode condition, ValueNode trueValue, ValueNode falseValue) { super(trueValue.kind(), trueValue, falseValue); assert trueValue.kind() == falseValue.kind(); this.condition = condition; @@ -73,9 +73,9 @@ } } } - if (condition instanceof ConstantNode) { - ConstantNode c = (ConstantNode) condition; - if (c.asConstant().asBoolean()) { + if (condition instanceof LogicConstantNode) { + LogicConstantNode c = (LogicConstantNode) condition; + if (c.getValue()) { return trueValue(); } else { return falseValue(); diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -58,9 +58,9 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public LogicNode canonical(CanonicalizerTool tool) { if (x() == y() && !unorderedIsTrue()) { - return ConstantNode.forBoolean(false, graph()); + return LogicConstantNode.contradiction(graph()); } return super.canonical(tool); } diff -r 62bcf515831d -r f1f4fc5a609f 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 Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -54,17 +54,17 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public LogicNode canonical(CanonicalizerTool tool) { if (x() == y()) { - return ConstantNode.forBoolean(false, graph()); + return LogicConstantNode.contradiction(graph()); } else { IntegerStamp xStamp = x().integerStamp(); IntegerStamp yStamp = y().integerStamp(); if (yStamp.isPositive()) { if (xStamp.isPositive() && xStamp.upperBound() < yStamp.lowerBound()) { - return ConstantNode.forBoolean(true, graph()); + return LogicConstantNode.tautology(graph()); } else if (xStamp.isStrictlyNegative() || xStamp.lowerBound() >= yStamp.upperBound()) { - return ConstantNode.forBoolean(false, graph()); + return LogicConstantNode.contradiction(graph()); } } } diff -r 62bcf515831d -r f1f4fc5a609f 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 Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -53,7 +53,7 @@ } @Override - protected ValueNode optimizeNormalizeCmp(Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) { + protected LogicNode optimizeNormalizeCmp(Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) { if (constant.getKind() == Kind.Int && constant.asInt() == 0) { ValueNode a = mirrored ? normalizeNode.y() : normalizeNode.x(); ValueNode b = mirrored ? normalizeNode.x() : normalizeNode.y(); @@ -68,11 +68,11 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public LogicNode canonical(CanonicalizerTool tool) { if (x() == y()) { - return ConstantNode.forBoolean(true, graph()); + return LogicConstantNode.tautology(graph()); } else if (x().integerStamp().alwaysDistinct(y().integerStamp())) { - return ConstantNode.forBoolean(false, graph()); + return LogicConstantNode.contradiction(graph()); } if (x() instanceof AndNode && y().isConstant() && y().asConstant().asLong() == 0) { diff -r 62bcf515831d -r f1f4fc5a609f 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 Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -54,7 +54,7 @@ } @Override - protected ValueNode optimizeNormalizeCmp(Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) { + protected LogicNode optimizeNormalizeCmp(Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) { assert condition() == Condition.LT; if (constant.getKind() == Kind.Int && constant.asInt() == 0) { ValueNode a = mirrored ? normalizeNode.y() : normalizeNode.x(); @@ -70,13 +70,13 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public LogicNode canonical(CanonicalizerTool tool) { if (x() == y()) { - return ConstantNode.forBoolean(false, graph()); + return LogicConstantNode.contradiction(graph()); } else if (x().integerStamp().upperBound() < y().integerStamp().lowerBound()) { - return ConstantNode.forBoolean(true, graph()); + return LogicConstantNode.tautology(graph()); } else if (x().integerStamp().lowerBound() >= y().integerStamp().upperBound()) { - return ConstantNode.forBoolean(false, graph()); + return LogicConstantNode.contradiction(graph()); } if (IntegerStamp.sameSign(x().integerStamp(), y().integerStamp())) { return graph().unique(new IntegerBelowThanNode(x(), y())); diff -r 62bcf515831d -r f1f4fc5a609f 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 Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -24,9 +24,13 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; -public class IntegerTestNode extends BooleanNode implements Canonicalizable, LIRLowerable { +/** + * This node will perform a "test" operation on its arguments. Its result is equivalent to the + * expression "(x & y) == 0", meaning that it will return true if (and only if) no bit is set in + * both x and y. + */ +public class IntegerTestNode extends LogicNode implements Canonicalizable, LIRLowerable { @Input private ValueNode x; @Input private ValueNode y; @@ -46,7 +50,6 @@ * @param y the instruction that produces the second input to this instruction */ public IntegerTestNode(ValueNode x, ValueNode y) { - super(StampFactory.condition()); assert (x == null && y == null) || x.kind() == y.kind(); this.x = x; this.y = y; @@ -56,12 +59,13 @@ public void generate(LIRGeneratorTool gen) { } - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public LogicNode canonical(CanonicalizerTool tool) { if (x().isConstant() && y().isConstant()) { - return ConstantNode.forBoolean((x().asConstant().asLong() & y().asConstant().asLong()) == 0, graph()); + return LogicConstantNode.forBoolean((x().asConstant().asLong() & y().asConstant().asLong()) == 0, graph()); } if ((x().integerStamp().mask() & y().integerStamp().mask()) == 0) { - return ConstantNode.forBoolean(true, graph()); + return LogicConstantNode.tautology(graph()); } return this; } diff -r 62bcf515831d -r f1f4fc5a609f 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 Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -25,12 +25,11 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; /** * An IsNullNode will be true if the supplied value is null, and false if it is non-null. */ -public final class IsNullNode extends BooleanNode implements Canonicalizable, LIRLowerable, Virtualizable { +public final class IsNullNode extends LogicNode implements Canonicalizable, LIRLowerable, Virtualizable { @Input private ValueNode object; @@ -44,7 +43,6 @@ * @param object the instruction producing the object to check against null */ public IsNullNode(ValueNode object) { - super(StampFactory.condition()); assert object.kind() == Kind.Object : object; this.object = object; } @@ -62,14 +60,14 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public LogicNode canonical(CanonicalizerTool tool) { Constant constant = object().asConstant(); if (constant != null) { assert constant.getKind() == Kind.Object; - return ConstantNode.forBoolean(constant.isNull(), graph()); + return LogicConstantNode.forBoolean(constant.isNull(), graph()); } if (object.objectStamp().nonNull()) { - return ConstantNode.forBoolean(false, graph()); + return LogicConstantNode.contradiction(graph()); } return this; } @@ -77,7 +75,7 @@ @Override public void virtualize(VirtualizerTool tool) { if (tool.getObjectState(object) != null) { - tool.replaceWithValue(ConstantNode.forBoolean(false, graph())); + tool.replaceWithValue(LogicConstantNode.contradiction(graph())); } } } diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LogicNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LogicNode.java Mon Feb 11 17:41:33 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.nodes.calc; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.*; - -/** - * The {@code LogicNode} class definition. - */ -public abstract class LogicNode extends BinaryNode { - - /** - * Constructs a new logic operation node. - * - * @param x the first input into this node - * @param y the second input into this node - */ - public LogicNode(Kind kind, ValueNode x, ValueNode y) { - super(kind, x, y); - assert kind == Kind.Int || kind == Kind.Long; - } - - public static LogicNode and(ValueNode v1, ValueNode v2) { - assert v1.kind() == v2.kind() && v1.graph() == v2.graph(); - Graph graph = v1.graph(); - switch (v1.kind()) { - case Int: - return graph.unique(new AndNode(Kind.Int, v1, v2)); - case Long: - return graph.unique(new AndNode(Kind.Long, v1, v2)); - default: - throw ValueNodeUtil.shouldNotReachHere(); - } - } - - public static LogicNode or(ValueNode v1, ValueNode v2) { - assert v1.kind() == v2.kind() && v1.graph() == v2.graph(); - Graph graph = v1.graph(); - switch (v1.kind()) { - case Int: - return graph.unique(new OrNode(Kind.Int, v1, v2)); - case Long: - return graph.unique(new OrNode(Kind.Long, v1, v2)); - default: - throw ValueNodeUtil.shouldNotReachHere(); - } - } - - public static LogicNode xor(ValueNode v1, ValueNode v2) { - assert v1.kind() == v2.kind() && v1.graph() == v2.graph(); - Graph graph = v1.graph(); - switch (v1.kind()) { - case Int: - return graph.unique(new XorNode(Kind.Int, v1, v2)); - case Long: - return graph.unique(new XorNode(Kind.Long, v1, v2)); - default: - throw ValueNodeUtil.shouldNotReachHere(); - } - } -} diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -51,8 +51,8 @@ public void lower(LoweringTool tool) { StructuredGraph graph = (StructuredGraph) graph(); - BooleanNode equalComp; - BooleanNode lessComp; + LogicNode equalComp; + LogicNode lessComp; if (x().kind() == Kind.Double || x().kind() == Kind.Float) { equalComp = graph.unique(new FloatEqualsNode(x(), y())); lessComp = graph.unique(new FloatLessThanNode(x(), y(), isUnorderedLess)); diff -r 62bcf515831d -r f1f4fc5a609f 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 Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -53,9 +53,9 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public LogicNode canonical(CanonicalizerTool tool) { if (x() == y()) { - return ConstantNode.forBoolean(true, graph()); + return LogicConstantNode.tautology(graph()); } if (x().objectStamp().alwaysNull()) { @@ -64,7 +64,7 @@ return graph().unique(new IsNullNode(x())); } if (x().stamp().alwaysDistinct(y().stamp())) { - return ConstantNode.forBoolean(false, graph()); + return LogicConstantNode.contradiction(graph()); } return super.canonical(tool); @@ -79,10 +79,10 @@ if (xVirtual ^ yVirtual) { // one of them is virtual: they can never be the same objects - tool.replaceWithValue(ConstantNode.forBoolean(false, graph())); + tool.replaceWithValue(LogicConstantNode.contradiction(graph())); } else if (xVirtual && yVirtual) { // both are virtual: check if they refer to the same object - tool.replaceWithValue(ConstantNode.forBoolean(stateX == stateY, graph())); + tool.replaceWithValue(LogicConstantNode.forBoolean(stateX == stateY, graph())); } } } diff -r 62bcf515831d -r f1f4fc5a609f 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 Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -29,7 +29,7 @@ import com.oracle.graal.nodes.type.*; @NodeInfo(shortName = "|") -public final class OrNode extends LogicNode implements Canonicalizable, LIRLowerable { +public final class OrNode extends BitLogicNode implements Canonicalizable, LIRLowerable { public OrNode(Kind kind, ValueNode x, ValueNode y) { super(kind, x, y); diff -r 62bcf515831d -r f1f4fc5a609f 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 Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -29,7 +29,7 @@ import com.oracle.graal.nodes.type.*; @NodeInfo(shortName = "^") -public final class XorNode extends LogicNode implements Canonicalizable, LIRLowerable { +public final class XorNode extends BitLogicNode implements Canonicalizable, LIRLowerable { public XorNode(Kind kind, ValueNode x, ValueNode y) { super(kind, x, y); diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -47,8 +47,9 @@ public ValueNode canonical(CanonicalizerTool tool) { if (array() instanceof ArrayLengthProvider) { ValueNode length = ((ArrayLengthProvider) array()).length(); - assert length != null; - return length; + if (length != null) { + return length; + } } MetaAccessProvider runtime = tool.runtime(); if (runtime != null && array().isConstant() && !array().isNullConstant()) { diff -r 62bcf515831d -r f1f4fc5a609f 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 Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -27,14 +27,13 @@ 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 * known at compile time. This is used, for instance, to intrinsify {@link Class#isInstance(Object)} * . */ -public final class InstanceOfDynamicNode extends BooleanNode implements Canonicalizable, Lowerable { +public final class InstanceOfDynamicNode extends LogicNode implements Canonicalizable, Lowerable { @Input private ValueNode object; @Input private ValueNode mirror; @@ -47,7 +46,6 @@ * @param object the object being tested by the instanceof */ public InstanceOfDynamicNode(ValueNode mirror, ValueNode object) { - super(StampFactory.condition()); this.mirror = mirror; this.object = object; assert mirror.kind() == Kind.Object; @@ -61,7 +59,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public LogicNode canonical(CanonicalizerTool tool) { assert object() != null : this; if (mirror().isConstant()) { Class clazz = (Class) mirror().asConstant().asObject(); diff -r 62bcf515831d -r f1f4fc5a609f 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 Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -32,7 +32,7 @@ /** * The {@code InstanceOfNode} represents an instanceof test. */ -public final class InstanceOfNode extends BooleanNode implements Canonicalizable, Lowerable, Virtualizable { +public final class InstanceOfNode extends LogicNode implements Canonicalizable, Lowerable, Virtualizable { @Input private ValueNode object; private final ResolvedJavaType type; @@ -45,7 +45,6 @@ * @param object the object being tested by the instanceof */ public InstanceOfNode(ResolvedJavaType type, ValueNode object, JavaTypeProfile profile) { - super(StampFactory.condition()); this.type = type; this.object = object; this.profile = profile; @@ -58,7 +57,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public LogicNode canonical(CanonicalizerTool tool) { assert object() != null : this; ObjectStamp stamp = object().objectStamp(); @@ -70,7 +69,7 @@ if (subType) { if (stamp.nonNull()) { // the instanceOf matches, so return true - return ConstantNode.forBoolean(true, graph()); + return LogicConstantNode.tautology(graph()); } else { // the instanceof matches if the object is non-null, so return true depending on // the null-ness. @@ -81,7 +80,7 @@ // 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. - return ConstantNode.forBoolean(false, graph()); + return LogicConstantNode.contradiction(graph()); } } else if (stampType != null) { boolean subType = type().isAssignableFrom(stampType); @@ -89,7 +88,7 @@ if (subType) { if (stamp.nonNull()) { // the instanceOf matches, so return true - return ConstantNode.forBoolean(true, graph()); + return LogicConstantNode.tautology(graph()); } else { // the instanceof matches if the object is non-null, so return true depending on // the null-ness. @@ -102,7 +101,7 @@ } } if (object().objectStamp().alwaysNull()) { - return ConstantNode.forBoolean(false, graph()); + return LogicConstantNode.contradiction(graph()); } return this; } @@ -134,7 +133,7 @@ public void virtualize(VirtualizerTool tool) { State state = tool.getObjectState(object); if (state != null) { - tool.replaceWithValue(ConstantNode.forBoolean(type().isAssignableFrom(state.getVirtualObject().type()), graph())); + tool.replaceWithValue(LogicConstantNode.forBoolean(type().isAssignableFrom(state.getVirtualObject().type()), graph())); } } } diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ArrayLengthProvider.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ArrayLengthProvider.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ArrayLengthProvider.java Mon Feb 11 17:47:21 2013 +0100 @@ -26,5 +26,8 @@ public interface ArrayLengthProvider { + /** + * @return the length of the array described by this node, or null if it is not available + */ ValueNode length(); } diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Mon Feb 11 17:47:21 2013 +0100 @@ -117,7 +117,7 @@ public abstract void emitConditional(ConditionalNode i); - public abstract void emitGuardCheck(BooleanNode comp, DeoptimizationReason deoptReason, DeoptimizationAction deoptAction, boolean negated); + public abstract void emitGuardCheck(LogicNode comp, DeoptimizationReason deoptReason, DeoptimizationAction deoptAction, boolean negated); public abstract void emitSwitch(SwitchNode i); diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java Mon Feb 11 17:47:21 2013 +0100 @@ -36,9 +36,9 @@ ValueNode createNullCheckGuard(ValueNode object); - ValueNode createGuard(BooleanNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action); + ValueNode createGuard(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action); - ValueNode createGuard(BooleanNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated); + ValueNode createGuard(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated); Assumptions assumptions(); diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java Mon Feb 11 17:47:21 2013 +0100 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.spi; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -43,6 +44,12 @@ MetaAccessProvider getMetaAccessProvider(); /** + * @return the {@link Assumptions} associated with the current compilation, which can be used to + * make type assumptions during virtualization. + */ + Assumptions getAssumptions(); + + /** * This method should be used to query the maximum size of virtualized objects before attempting * virtualization. * diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/BoxedVirtualObjectNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/BoxedVirtualObjectNode.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/BoxedVirtualObjectNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -70,4 +70,9 @@ public Kind entryKind(int index) { return kind; } + + @Override + public BoxedVirtualObjectNode duplicate() { + return new BoxedVirtualObjectNode(type, kind, unboxedValue); + } } diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -132,4 +132,9 @@ assert index >= 0 && index < length; return componentType.getKind(); } + + @Override + public VirtualArrayNode duplicate() { + return new VirtualArrayNode(componentType, length); + } } diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -32,16 +32,23 @@ private final ResolvedJavaType type; private final ResolvedJavaField[] fields; - private final HashMap fieldMap = new HashMap<>(); + private final HashMap fieldMap; public VirtualInstanceNode(ResolvedJavaType type, ResolvedJavaField[] fields) { this.type = type; this.fields = fields; + fieldMap = new HashMap<>(); for (int i = 0; i < fields.length; i++) { fieldMap.put(fields[i], i); } } + private VirtualInstanceNode(ResolvedJavaType type, ResolvedJavaField[] fields, HashMap fieldMap) { + this.type = type; + this.fields = fields; + this.fieldMap = fieldMap; + } + @Override public ResolvedJavaType type() { return type; @@ -85,4 +92,9 @@ assert index >= 0 && index < fields.length; return fields[index].getKind(); } + + @Override + public VirtualInstanceNode duplicate() { + return new VirtualInstanceNode(type, fields, fieldMap); + } } diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -53,4 +53,6 @@ public abstract int entryIndexForOffset(long constantOffset); public abstract Kind entryKind(int index); + + public abstract VirtualObjectNode duplicate(); } diff -r 62bcf515831d -r f1f4fc5a609f 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 Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Mon Feb 11 17:47:21 2013 +0100 @@ -68,8 +68,8 @@ private IdentityHashMap knownTypes; private HashSet knownNonNull; private HashSet knownNull; - private IdentityHashMap trueConditions; - private IdentityHashMap falseConditions; + private IdentityHashMap trueConditions; + private IdentityHashMap falseConditions; public State() { this.knownTypes = new IdentityHashMap<>(); @@ -90,8 +90,8 @@ @Override public boolean merge(MergeNode merge, List withStates) { IdentityHashMap newKnownTypes = new IdentityHashMap<>(); - IdentityHashMap newTrueConditions = new IdentityHashMap<>(); - IdentityHashMap newFalseConditions = new IdentityHashMap<>(); + IdentityHashMap newTrueConditions = new IdentityHashMap<>(); + IdentityHashMap newFalseConditions = new IdentityHashMap<>(); HashSet newKnownNull = new HashSet<>(knownNull); HashSet newKnownNonNull = new HashSet<>(knownNonNull); @@ -116,8 +116,8 @@ } } - for (Map.Entry entry : trueConditions.entrySet()) { - BooleanNode check = entry.getKey(); + for (Map.Entry entry : trueConditions.entrySet()) { + LogicNode check = entry.getKey(); ValueNode guard = entry.getValue(); for (State other : withStates) { @@ -134,8 +134,8 @@ newTrueConditions.put(check, guard); } } - for (Map.Entry entry : falseConditions.entrySet()) { - BooleanNode check = entry.getKey(); + for (Map.Entry entry : falseConditions.entrySet()) { + LogicNode check = entry.getKey(); ValueNode guard = entry.getValue(); for (State other : withStates) { @@ -225,7 +225,7 @@ * Adds information about a condition. If isTrue is true then the condition is known to * hold, otherwise the condition is known not to hold. */ - public void addCondition(boolean isTrue, BooleanNode condition, ValueNode anchor) { + public void addCondition(boolean isTrue, LogicNode condition, ValueNode anchor) { if (isTrue) { if (!trueConditions.containsKey(condition)) { trueConditions.put(condition, anchor); @@ -294,16 +294,16 @@ public class ConditionalElimination extends PostOrderNodeIterator { - private final BooleanNode trueConstant; - private final BooleanNode falseConstant; + private final LogicNode trueConstant; + private final LogicNode falseConstant; public ConditionalElimination(FixedNode start, State initialState) { super(start, initialState); - this.trueConstant = ConstantNode.forBoolean(true, graph); - this.falseConstant = ConstantNode.forBoolean(false, graph); + this.trueConstant = LogicConstantNode.tautology(graph); + this.falseConstant = LogicConstantNode.contradiction(graph); } - private void registerCondition(boolean isTrue, BooleanNode condition, ValueNode anchor) { + private void registerCondition(boolean isTrue, LogicNode condition, ValueNode anchor) { state.addCondition(isTrue, condition, anchor); if (isTrue && condition instanceof InstanceOfNode) { @@ -351,7 +351,7 @@ if (pred instanceof IfNode) { IfNode ifNode = (IfNode) pred; - if (!(ifNode.condition() instanceof ConstantNode)) { + if (!(ifNode.condition() instanceof LogicConstantNode)) { registerCondition(begin == ifNode.trueSuccessor(), ifNode.condition(), begin); } } else if (pred instanceof TypeSwitchNode) { @@ -378,7 +378,7 @@ } private void registerGuard(GuardNode guard) { - BooleanNode condition = guard.condition(); + LogicNode condition = guard.condition(); ValueNode existingGuards = guard.negated() ? state.falseConditions.get(condition) : state.trueConditions.get(condition); if (existingGuards != null) { @@ -386,7 +386,7 @@ GraphUtil.killWithUnusedFloatingInputs(guard); metricGuardsRemoved.increment(); } else { - BooleanNode replacement = evaluateCondition(condition, trueConstant, falseConstant); + LogicNode replacement = evaluateCondition(condition, trueConstant, falseConstant); if (replacement != null) { guard.setCondition(replacement); if (condition.usages().isEmpty()) { @@ -404,7 +404,7 @@ * true, false or unknown. In case of true or false the corresponding value is returned, * otherwise null. */ - private T evaluateCondition(BooleanNode condition, T trueValue, T falseValue) { + private T evaluateCondition(LogicNode condition, T trueValue, T falseValue) { if (state.trueConditions.containsKey(condition)) { return trueValue; } else if (state.falseConditions.containsKey(condition)) { @@ -482,8 +482,8 @@ } } else if (node instanceof IfNode) { IfNode ifNode = (IfNode) node; - BooleanNode compare = ifNode.condition(); - BooleanNode replacement = evaluateCondition(compare, trueConstant, falseConstant); + LogicNode compare = ifNode.condition(); + LogicNode replacement = evaluateCondition(compare, trueConstant, falseConstant); if (replacement != null) { ifNode.setCondition(replacement); @@ -498,7 +498,7 @@ ValueNode value = phi.valueAt(index); if (value instanceof ConditionalNode) { ConditionalNode materialize = (ConditionalNode) value; - BooleanNode compare = materialize.condition(); + LogicNode compare = materialize.condition(); ValueNode replacement = evaluateCondition(compare, materialize.trueValue(), materialize.falseValue()); if (replacement != null) { diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java Mon Feb 11 17:47:21 2013 +0100 @@ -79,7 +79,7 @@ } else if (deoptBegin.predecessor() instanceof IfNode) { IfNode ifNode = (IfNode) deoptBegin.predecessor(); BeginNode otherBegin = ifNode.trueSuccessor(); - BooleanNode conditionNode = ifNode.condition(); + LogicNode conditionNode = ifNode.condition(); if (conditionNode instanceof InstanceOfNode) { // TODO The lowering currently does not support a FixedGuard as the usage of an // InstanceOfNode. Relax this restriction. diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/EliminatePartiallyRedundantGuardsPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/EliminatePartiallyRedundantGuardsPhase.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/EliminatePartiallyRedundantGuardsPhase.java Mon Feb 11 17:47:21 2013 +0100 @@ -49,10 +49,10 @@ private static class Condition { - final BooleanNode conditionNode; + final LogicNode conditionNode; final boolean negated; - public Condition(BooleanNode conditionNode, boolean negated) { + public Condition(LogicNode conditionNode, boolean negated) { this.conditionNode = conditionNode; this.negated = negated; } diff -r 62bcf515831d -r f1f4fc5a609f 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 Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Mon Feb 11 17:47:21 2013 +0100 @@ -70,7 +70,7 @@ } @Override - public ValueNode createGuard(BooleanNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action) { + public ValueNode createGuard(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action) { return createGuard(condition, deoptReason, action, false); } @@ -80,7 +80,7 @@ } @Override - public ValueNode createGuard(BooleanNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) { + public ValueNode createGuard(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) { if (GraalOptions.OptEliminateGuards) { for (Node usage : condition.usages()) { if (!activeGuards.isNew(usage) && activeGuards.isMarked(usage)) { diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Mon Feb 11 17:47:21 2013 +0100 @@ -197,6 +197,7 @@ public static boolean OptDevirtualizeInvokesOptimistically = true; // Intrinsification settings + public static boolean IntrinsifyObjectClone = ____; public static boolean IntrinsifyArrayCopy = true; public static boolean IntrinsifyObjectMethods = true; public static boolean IntrinsifySystemMethods = true; diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/UnsafeSubstitutions.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/UnsafeSubstitutions.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/UnsafeSubstitutions.java Mon Feb 11 17:47:21 2013 +0100 @@ -313,37 +313,37 @@ @MethodSubstitution(isStatic = false) public static void putByte(@SuppressWarnings("unused") final Object thisObj, long address, byte value) { - DirectStoreNode.store(address, value); + DirectStoreNode.store(address, value, Kind.Byte); } @MethodSubstitution(isStatic = false) public static void putShort(@SuppressWarnings("unused") final Object thisObj, long address, short value) { - DirectStoreNode.store(address, value); + DirectStoreNode.store(address, value, Kind.Short); } @MethodSubstitution(isStatic = false) public static void putChar(@SuppressWarnings("unused") final Object thisObj, long address, char value) { - DirectStoreNode.store(address, value); + DirectStoreNode.store(address, value, Kind.Char); } @MethodSubstitution(isStatic = false) public static void putInt(@SuppressWarnings("unused") final Object thisObj, long address, int value) { - DirectStoreNode.store(address, value); + DirectStoreNode.store(address, value, Kind.Int); } @MethodSubstitution(isStatic = false) public static void putLong(@SuppressWarnings("unused") final Object thisObj, long address, long value) { - DirectStoreNode.store(address, value); + DirectStoreNode.store(address, value, Kind.Long); } @MethodSubstitution(isStatic = false) public static void putFloat(@SuppressWarnings("unused") final Object thisObj, long address, float value) { - DirectStoreNode.store(address, value); + DirectStoreNode.store(address, value, Kind.Float); } @MethodSubstitution(isStatic = false) public static void putDouble(@SuppressWarnings("unused") final Object thisObj, long address, double value) { - DirectStoreNode.store(address, value); + DirectStoreNode.store(address, value, Kind.Double); } @MethodSubstitution(isStatic = false) diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/DirectStoreNode.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/DirectStoreNode.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/DirectStoreNode.java Mon Feb 11 17:47:21 2013 +0100 @@ -37,40 +37,48 @@ @Input private ValueNode address; @Input private ValueNode value; + private final Kind kind; - public DirectStoreNode(ValueNode address, ValueNode value) { + public DirectStoreNode(ValueNode address, ValueNode value, Kind kind) { super(StampFactory.forVoid()); this.address = address; this.value = value; + this.kind = kind; } - @NodeIntrinsic - public static native void store(long address, boolean value); - - @NodeIntrinsic - public static native void store(long address, byte value); - - @NodeIntrinsic - public static native void store(long address, short value); - - @NodeIntrinsic - public static native void store(long address, char value); - - @NodeIntrinsic - public static native void store(long address, int value); - - @NodeIntrinsic - public static native void store(long address, long value); - - @NodeIntrinsic - public static native void store(long address, float value); - - @NodeIntrinsic - public static native void store(long address, double value); - @Override public void generate(LIRGeneratorTool gen) { Value v = gen.operand(value); - gen.emitStore(new Address(v.getKind(), gen.operand(address)), v, false); + gen.emitStore(new Address(kind, gen.operand(address)), v, false); } + + /* + * The kind of the store is provided explicitly in these intrinsics because it is not always + * possible to determine the kind from the given value during compilation (because stack kinds + * are used). + */ + + @NodeIntrinsic + public static native void store(long address, boolean value, @ConstantNodeParameter Kind kind); + + @NodeIntrinsic + public static native void store(long address, byte value, @ConstantNodeParameter Kind kind); + + @NodeIntrinsic + public static native void store(long address, short value, @ConstantNodeParameter Kind kind); + + @NodeIntrinsic + public static native void store(long address, char value, @ConstantNodeParameter Kind kind); + + @NodeIntrinsic + public static native void store(long address, int value, @ConstantNodeParameter Kind kind); + + @NodeIntrinsic + public static native void store(long address, long value, @ConstantNodeParameter Kind kind); + + @NodeIntrinsic + public static native void store(long address, float value, @ConstantNodeParameter Kind kind); + + @NodeIntrinsic + public static native void store(long address, double value, @ConstantNodeParameter Kind kind); } diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java Mon Feb 11 17:47:21 2013 +0100 @@ -92,7 +92,7 @@ public Boolean call() { SchedulePhase schedule = new SchedulePhase(); schedule.apply(graph, false); - PartialEscapeClosure closure = new PartialEscapeClosure(graph.createNodeBitMap(), schedule, runtime); + PartialEscapeClosure closure = new PartialEscapeClosure(graph.createNodeBitMap(), schedule, runtime, assumptions); ReentrantBlockIterator.apply(closure, schedule.getCFG().getStartBlock(), new BlockState(), null); if (closure.getNewVirtualObjectCount() == 0) { diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Mon Feb 11 17:47:21 2013 +0100 @@ -26,6 +26,7 @@ import java.util.*; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; @@ -59,10 +60,10 @@ private final VirtualizerToolImpl tool; - public PartialEscapeClosure(NodeBitMap usages, SchedulePhase schedule, MetaAccessProvider metaAccess) { + public PartialEscapeClosure(NodeBitMap usages, SchedulePhase schedule, MetaAccessProvider metaAccess, Assumptions assumptions) { this.usages = usages; this.schedule = schedule; - tool = new VirtualizerToolImpl(effects, usages, metaAccess); + tool = new VirtualizerToolImpl(effects, usages, metaAccess, assumptions); } public GraphEffectList getEffects() { diff -r 62bcf515831d -r f1f4fc5a609f graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java Mon Feb 11 17:41:33 2013 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java Mon Feb 11 17:47:21 2013 +0100 @@ -24,6 +24,7 @@ import static com.oracle.graal.virtual.phases.ea.PartialEscapeAnalysisPhase.*; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -38,11 +39,13 @@ private final GraphEffectList effects; private final NodeBitMap usages; private final MetaAccessProvider metaAccess; + private final Assumptions assumptions; - VirtualizerToolImpl(GraphEffectList effects, NodeBitMap usages, MetaAccessProvider metaAccess) { + VirtualizerToolImpl(GraphEffectList effects, NodeBitMap usages, MetaAccessProvider metaAccess, Assumptions assumptions) { this.effects = effects; this.usages = usages; this.metaAccess = metaAccess; + this.assumptions = assumptions; } private boolean deleted; @@ -56,6 +59,11 @@ return metaAccess; } + @Override + public Assumptions getAssumptions() { + return assumptions; + } + public void reset(BlockState newState, ValueNode newCurrent) { deleted = false; customAction = false; diff -r 62bcf515831d -r f1f4fc5a609f src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Mon Feb 11 17:41:33 2013 +0100 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Mon Feb 11 17:47:21 2013 +0100 @@ -701,6 +701,8 @@ set_int("layoutHelperLog2ElementSizeMask", Klass::_lh_log2_element_size_mask); set_int("layoutHelperElementTypeShift", Klass::_lh_element_type_shift); set_int("layoutHelperElementTypeMask", Klass::_lh_element_type_mask); + // this filters out the bit that differentiates a type array from an object array + set_int("layoutHelperElementTypePrimitiveInPlace", (Klass::_lh_array_tag_type_value & ~Klass::_lh_array_tag_obj_value) << Klass::_lh_array_tag_shift); set_int("layoutHelperHeaderSizeShift", Klass::_lh_header_size_shift); set_int("layoutHelperHeaderSizeMask", Klass::_lh_header_size_mask); set_int("layoutHelperOffset", in_bytes(Klass::layout_helper_offset()));