# HG changeset patch # User Christian Wimmer # Date 1385156477 28800 # Node ID 3adfe375b01b46090d3b95d28e0598a328e6731f # Parent c7ce697ddb9a91e8060dcacb9bc51cde55d0ae1f# Parent 124860fac4701f983e1d55c455145ad9ee493332 Merge diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Address.java --- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Address.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Address.java Fri Nov 22 13:41:17 2013 -0800 @@ -70,6 +70,8 @@ this.index = index; this.scale = scale; this.displacement = displacement; + + assert scale != null; } /** @@ -104,7 +106,7 @@ case 8: return Times8; default: - throw new IllegalArgumentException(String.valueOf(scale)); + return null; } } } diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Fri Nov 22 13:41:17 2013 -0800 @@ -164,6 +164,17 @@ if (isConstant(index)) { finalDisp += asConstant(index).asLong() * scale; indexRegister = Value.ILLEGAL; + + } else if (scaleEnum == null) { + /* Scale value that architecture cannot handle, so scale manually. */ + Value longIndex = index.getKind().getStackKind() == Kind.Int ? emitConvert(Kind.Int, Kind.Long, index) : index; + if (CodeUtil.isPowerOf2(scale)) { + indexRegister = emitShl(longIndex, Constant.forLong(CodeUtil.log2(scale))); + } else { + indexRegister = emitMul(longIndex, Constant.forLong(scale)); + } + scaleEnum = Scale.Times1; + } else { indexRegister = asAllocatable(index); } @@ -812,7 +823,10 @@ Kind from = inputVal.getKind(); AllocatableValue input = asAllocatable(inputVal); - // These cases require a move between CPU and FPU registers: + /* + * Conversions between integer to floating point types require moves between CPU and FPU + * registers. + */ switch (to) { case Int: switch (from) { @@ -826,6 +840,19 @@ case Float: case Double: return emitConvert2Op(to, MOV_D2L, input); + case Int: + /* + * Unsigned int-to-long conversion: In theory, instructions that move or + * generate 32-bit register values also set the upper 32 bits of the + * register to zero. However, we cannot rely that the value was really + * generated by an instruction, it could come from an untrusted source such + * as native code. Therefore, make sure the high bits are really cleared. + */ + Variable temp = newVariable(Kind.Int); + Variable result = newVariable(Kind.Long); + append(new BinaryRegConst(AMD64Arithmetic.IAND, temp, input, Constant.forInt(0xFFFFFFFF))); + emitMove(result, temp); + return result; } break; case Float: @@ -843,12 +870,7 @@ } break; } - - // Otherwise, just emit an ordinary move instruction. - // Instructions that move or generate 32-bit register values also set the upper 32 - // bits of the register to zero. - // Consequently, there is no need for a special zero-extension move. - return emitConvertMove(to, input); + throw GraalInternalError.shouldNotReachHere(); } @Override diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Fri Nov 22 13:41:17 2013 -0800 @@ -212,6 +212,10 @@ return providers; } + protected TargetDescription getTarget() { + return getProviders().getCodeCache().getTarget(); + } + protected CodeCacheProvider getCodeCache() { return getProviders().getCodeCache(); } diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Fri Nov 22 13:41:17 2013 -0800 @@ -37,7 +37,7 @@ public class HighTier extends PhaseSuite { - static class Options { + public static class Options { // @formatter:off @Option(help = "") diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java Fri Nov 22 13:41:17 2013 -0800 @@ -89,7 +89,9 @@ appendPhase(new FrameStateAssignmentPhase()); - appendPhase(new DeoptimizationGroupingPhase()); + if (OptDeoptimizationGrouping.getValue()) { + appendPhase(new DeoptimizationGroupingPhase()); + } if (OptCanonicalizer.getValue()) { appendPhase(canonicalizer); diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Fri Nov 22 13:41:17 2013 -0800 @@ -158,13 +158,17 @@ */ private final boolean isSimplifiable; - private NodeClass(Class clazz) { + public NodeClass(Class clazz) { + this(clazz, new DefaultCalcOffset(), null, 0); + } + + public NodeClass(Class clazz, CalcOffset calcOffset, int[] presetIterableIds, int presetIterableId) { super(clazz); assert NODE_CLASS.isAssignableFrom(clazz); this.isCanonicalizable = Canonicalizable.class.isAssignableFrom(clazz); this.isSimplifiable = Simplifiable.class.isAssignableFrom(clazz); - FieldScanner scanner = new FieldScanner(new DefaultCalcOffset()); + FieldScanner scanner = new FieldScanner(calcOffset); scanner.scan(clazz); directInputCount = scanner.inputOffsets.size(); @@ -200,7 +204,10 @@ } this.nameTemplate = newNameTemplate == null ? newShortName : newNameTemplate; this.shortName = newShortName; - if (IterableNodeType.class.isAssignableFrom(clazz)) { + if (presetIterableIds != null) { + this.iterableIds = presetIterableIds; + this.iterableId = presetIterableId; + } else if (IterableNodeType.class.isAssignableFrom(clazz)) { ITERABLE_NODE_TYPES.increment(); this.iterableId = nextIterableId++; List existingClasses = new LinkedList<>(); diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Fri Nov 22 13:41:17 2013 -0800 @@ -84,7 +84,7 @@ } protected Replacements createReplacements(HotSpotGraalRuntime runtime, Assumptions assumptions, Providers p) { - return new HotSpotReplacementsImpl(p, runtime.getConfig(), assumptions); + return new HotSpotReplacementsImpl(p, runtime.getConfig(), assumptions, p.getCodeCache().getTarget()); } protected AMD64HotSpotForeignCallsProvider createForeignCalls(HotSpotGraalRuntime runtime, HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java Fri Nov 22 13:41:17 2013 -0800 @@ -48,7 +48,7 @@ // to be valid for the entire run of the VM. Assumptions assumptions = new Assumptions(false); Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null); - Replacements replacements = new HSAILHotSpotReplacementsImpl(p, assumptions, host.getReplacements()); + Replacements replacements = new HSAILHotSpotReplacementsImpl(p, assumptions, codeCache.getTarget(), host.getReplacements()); HotSpotDisassemblerProvider disassembler = host.getDisassembler(); HotSpotSuitesProvider suites = host.getSuites(); HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers); diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java Fri Nov 22 13:41:17 2013 -0800 @@ -38,8 +38,8 @@ private final Replacements host; - public HSAILHotSpotReplacementsImpl(Providers providers, Assumptions assumptions, Replacements host) { - super(providers, assumptions); + public HSAILHotSpotReplacementsImpl(Providers providers, Assumptions assumptions, TargetDescription target, Replacements host) { + super(providers, assumptions, target); this.host = host; } diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Fri Nov 22 13:41:17 2013 -0800 @@ -61,7 +61,7 @@ // to be valid for the entire run of the VM. Assumptions assumptions = new Assumptions(false); Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null); - HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, runtime.getConfig(), assumptions); + HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, runtime.getConfig(), assumptions, target); HotSpotDisassemblerProvider disassembler = new HotSpotDisassemblerProvider(runtime); HotSpotSuitesProvider suites = new HotSpotSuitesProvider(runtime); HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers); diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java Fri Nov 22 13:41:17 2013 -0800 @@ -40,8 +40,8 @@ private final HotSpotVMConfig config; - public HotSpotReplacementsImpl(Providers providers, HotSpotVMConfig config, Assumptions assumptions) { - super(providers, assumptions); + public HotSpotReplacementsImpl(Providers providers, HotSpotVMConfig config, Assumptions assumptions, TargetDescription target) { + super(providers, assumptions, target); this.config = config; } diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Fri Nov 22 13:41:17 2013 -0800 @@ -520,6 +520,8 @@ boxingSnippets.lower((BoxNode) n, tool); } else if (n instanceof UnboxNode) { boxingSnippets.lower((UnboxNode) n, tool); + } else if (n instanceof DeoptimizeNode || n instanceof UnwindNode) { + /* No lowering, we generate LIR directly for these nodes. */ } else { assert false : "Node implementing Lowerable not handled: " + n; throw GraalInternalError.shouldNotReachHere(); diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java Fri Nov 22 13:41:17 2013 -0800 @@ -317,7 +317,7 @@ private void inline(InvokeNode invoke) { ResolvedJavaMethod method = ((MethodCallTargetNode) invoke.callTarget()).targetMethod(); - ReplacementsImpl repl = new ReplacementsImpl(providers, new Assumptions(false)); + ReplacementsImpl repl = new ReplacementsImpl(providers, new Assumptions(false), providers.getCodeCache().getTarget()); StructuredGraph calleeGraph = repl.makeGraph(method, null, null, false); InliningUtil.inline(invoke, calleeGraph, false); } diff -r 124860fac470 -r 3adfe375b01b 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 Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Fri Nov 22 13:41:17 2013 -0800 @@ -159,6 +159,10 @@ return currentGraph; } + protected ResolvedJavaMethod getMethod() { + return method; + } + public GraphBuilderPhase(MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) { this.graphBuilderConfig = graphBuilderConfig; this.optimisticOpts = optimisticOpts; @@ -864,12 +868,16 @@ void genNewInstance(int cpi) { JavaType type = lookupType(cpi, NEW); if (type instanceof ResolvedJavaType && ((ResolvedJavaType) type).isInitialized()) { - frameState.apush(append(new NewInstanceNode((ResolvedJavaType) type, true))); + frameState.apush(append(createNewInstance((ResolvedJavaType) type, true))); } else { handleUnresolvedNewInstance(type); } } + protected NewInstanceNode createNewInstance(ResolvedJavaType type, boolean fillContents) { + return new NewInstanceNode(type, fillContents); + } + /** * Gets the kind of array elements for the array type code that appears in a * {@link Bytecodes#NEWARRAY} bytecode. @@ -905,20 +913,24 @@ private void genNewPrimitiveArray(int typeCode) { Class clazz = arrayTypeCodeToClass(typeCode); ResolvedJavaType elementType = metaAccess.lookupJavaType(clazz); - frameState.apush(append(new NewArrayNode(elementType, frameState.ipop(), true))); + frameState.apush(append(createNewArray(elementType, frameState.ipop(), true))); } private void genNewObjectArray(int cpi) { JavaType type = lookupType(cpi, ANEWARRAY); ValueNode length = frameState.ipop(); if (type instanceof ResolvedJavaType) { - frameState.apush(append(new NewArrayNode((ResolvedJavaType) type, length, true))); + frameState.apush(append(createNewArray((ResolvedJavaType) type, length, true))); } else { handleUnresolvedNewObjectArray(type, length); } } + protected NewArrayNode createNewArray(ResolvedJavaType elementType, ValueNode length, boolean fillContents) { + return new NewArrayNode(elementType, length, fillContents); + } + private void genNewMultiArray(int cpi) { JavaType type = lookupType(cpi, MULTIANEWARRAY); int rank = stream().readUByte(bci() + 3); @@ -1187,16 +1199,21 @@ args[0] = TypeProfileProxyNode.create(args[0], profile); } } - MethodCallTargetNode callTarget = currentGraph.add(new MethodCallTargetNode(invokeKind, targetMethod, args, returnType)); + MethodCallTargetNode callTarget = currentGraph.add(createMethodCallTarget(invokeKind, targetMethod, args, returnType)); createInvokeNode(callTarget, resultType); } + protected MethodCallTargetNode createMethodCallTarget(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] args, JavaType returnType) { + return new MethodCallTargetNode(invokeKind, targetMethod, args, returnType); + } + protected Invoke createInvokeNode(CallTargetNode callTarget, Kind resultType) { // be conservative if information was not recorded (could result in endless recompiles // otherwise) if (graphBuilderConfig.omitAllExceptionEdges() || (optimisticOpts.useExceptionProbability() && profilingInfo.getExceptionSeen(bci()) == TriState.FALSE)) { - frameState.pushReturn(resultType, append(new InvokeNode(callTarget, bci()))); - return new InvokeNode(callTarget, bci()); + InvokeNode invoke = new InvokeNode(callTarget, bci()); + frameState.pushReturn(resultType, append(invoke)); + return invoke; } else { DispatchBeginNode exceptionEdge = handleException(null, bci()); InvokeWithExceptionNode invoke = append(new InvokeWithExceptionNode(callTarget, exceptionEdge, bci())); @@ -1636,15 +1653,15 @@ ValueNode x = returnKind == Kind.Void ? null : frameState.pop(returnKind); assert frameState.stackSize() == 0; + if (graphBuilderConfig.eagerInfopointMode()) { + append(new InfopointNode(InfopointReason.METHOD_END, frameState.create(bci()))); + } + synchronizedEpilogue(FrameState.AFTER_BCI, x); if (frameState.lockDepth() != 0) { throw new BailoutException("unbalanced monitors"); } - if (graphBuilderConfig.eagerInfopointMode()) { - append(new InfopointNode(InfopointReason.METHOD_END, frameState.create(FrameState.AFTER_BCI))); - } - append(new ReturnNode(x)); } diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64AddressValue.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64AddressValue.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64AddressValue.java Fri Nov 22 13:41:17 2013 -0800 @@ -51,6 +51,8 @@ this.index = index; this.scale = scale; this.displacement = displacement; + + assert scale != null; } private static Register toRegister(AllocatableValue value) { diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java Fri Nov 22 13:41:17 2013 -0800 @@ -61,11 +61,15 @@ private final long[] componentOffsets; private final EnumSet[] componentFlags; + public CompositeValueClass(Class clazz) { + this(clazz, new DefaultCalcOffset()); + } + @SuppressWarnings("unchecked") - public CompositeValueClass(Class clazz) { + public CompositeValueClass(Class clazz, CalcOffset calcOffset) { super(clazz); - ValueFieldScanner scanner = new ValueFieldScanner(new DefaultCalcOffset()); + ValueFieldScanner scanner = new ValueFieldScanner(calcOffset); scanner.scan(clazz); OperandModeAnnotation mode = scanner.valueAnnotations.get(CompositeValue.Component.class); diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java Fri Nov 22 13:41:17 2013 -0800 @@ -73,12 +73,16 @@ private String opcodeConstant; private long opcodeOffset; + public LIRInstructionClass(Class clazz) { + this(clazz, new DefaultCalcOffset()); + } + @SuppressWarnings("unchecked") - public LIRInstructionClass(Class clazz) { + public LIRInstructionClass(Class clazz, CalcOffset calcOffset) { super(clazz); assert INSTRUCTION_CLASS.isAssignableFrom(clazz); - InstructionFieldScanner scanner = new InstructionFieldScanner(new DefaultCalcOffset()); + InstructionFieldScanner scanner = new InstructionFieldScanner(calcOffset); scanner.scan(clazz); OperandModeAnnotation mode = scanner.valueAnnotations.get(LIRInstruction.Use.class); diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Fri Nov 22 13:41:17 2013 -0800 @@ -27,7 +27,7 @@ import com.oracle.graal.nodes.spi.*; @NodeInfo(shortName = "Deopt", nameTemplate = "Deopt {p#reason/s}") -public class DeoptimizeNode extends AbstractDeoptimizeNode implements LIRLowerable { +public class DeoptimizeNode extends AbstractDeoptimizeNode implements Lowerable, LIRLowerable { private final DeoptimizationAction action; private final DeoptimizationReason reason; @@ -54,6 +54,11 @@ } @Override + public void lower(LoweringTool tool) { + tool.getLowerer().lower(this, tool); + } + + @Override public void generate(LIRGeneratorTool gen) { gen.emitDeoptimize(gen.getMetaAccess().encodeDeoptActionAndReason(action, reason, speculationId), this); } diff -r 124860fac470 -r 3adfe375b01b 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 Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Fri Nov 22 13:41:17 2013 -0800 @@ -57,6 +57,8 @@ this.negated = negated; this.condition = condition; this.reason = deoptReason; + + assert action != null && reason != null; } public DeoptimizationReason getReason() { diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java Fri Nov 22 13:41:17 2013 -0800 @@ -108,10 +108,12 @@ if (c.getValue() == negated) { // The guard always fails return graph().add(new DeoptimizeNode(action, reason)); - } - - if (c.getValue() != negated && stamp().equals(object().stamp())) { + } else if (stamp().equals(object().stamp())) { + // The guard always succeeds, and does not provide new type information return object; + } else { + // The guard always succeeds, and provides new type information + return graph().unique(new PiNode(object, stamp())); } } return this; diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnwindNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnwindNode.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnwindNode.java Fri Nov 22 13:41:17 2013 -0800 @@ -29,7 +29,7 @@ /** * Unwinds the current frame to an exception handler in the caller frame. */ -public final class UnwindNode extends ControlSinkNode implements LIRLowerable { +public final class UnwindNode extends ControlSinkNode implements Lowerable, LIRLowerable { @Input private ValueNode exception; @@ -44,6 +44,11 @@ } @Override + public void lower(LoweringTool tool) { + tool.getLowerer().lower(this, tool); + } + + @Override public void generate(LIRGeneratorTool gen) { gen.emitUnwind(gen.operand(exception())); } diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java Fri Nov 22 13:41:17 2013 -0800 @@ -61,7 +61,7 @@ @Override public void lower(LoweringTool tool) { - if (graph().getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { + if (graph().getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS || graph().getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { tool.getLowerer().lower(this, tool); } } diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Fri Nov 22 13:41:17 2013 -0800 @@ -43,6 +43,15 @@ super(object, location, stamp, guard, barrierType, compressible); } + private ReadNode(ValueNode object, ValueNode location, ValueNode guard, BarrierType barrierType, boolean compressible) { + /* + * Used by node intrinsics. Really, you can trust me on that! Since the initial value for + * location is a parameter, i.e., a LocalNode, the constructor cannot use the declared type + * LocationNode. + */ + super(object, location, StampFactory.forNodeIntrinsic(), (GuardingNode) guard, barrierType, compressible); + } + @Override public void generate(LIRGeneratorTool gen) { Value address = location().generateAddress(gen, gen.operand(object())); diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Fri Nov 22 13:41:17 2013 -0800 @@ -45,6 +45,16 @@ return stateAfter; } + @Override + public FrameState getState() { + if (stateAfter != null) { + assert super.getState() == null; + return stateAfter; + } else { + return super.getState(); + } + } + public void setStateAfter(FrameState x) { assert x == null || x.isAlive() : "frame state must be in a graph"; updateUsages(stateAfter, x); diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java Fri Nov 22 13:41:17 2013 -0800 @@ -34,8 +34,6 @@ */ public class NewArrayNode extends AbstractNewArrayNode implements VirtualizableAllocation { - private final ResolvedJavaType elementType; - /** * Constructs a new NewArrayNode. * @@ -46,7 +44,6 @@ */ public NewArrayNode(ResolvedJavaType elementType, ValueNode length, boolean fillContents) { super(StampFactory.exactNonNull(elementType.getArrayClass()), length, fillContents); - this.elementType = elementType; } /** @@ -55,7 +52,7 @@ * @return the element type of the array */ public ResolvedJavaType elementType() { - return elementType; + return ObjectStamp.typeOrNull(this).getComponentType(); } @Override @@ -64,14 +61,19 @@ final int constantLength = length().asConstant().asInt(); if (constantLength >= 0 && constantLength < tool.getMaximumEntryCount()) { ValueNode[] state = new ValueNode[constantLength]; - ConstantNode defaultForKind = constantLength == 0 ? null : ConstantNode.defaultForKind(elementType().getKind(), graph()); + ConstantNode defaultForKind = constantLength == 0 ? null : defaultElementValue(); for (int i = 0; i < constantLength; i++) { state[i] = defaultForKind; } - VirtualObjectNode virtualObject = new VirtualArrayNode(elementType, constantLength); + VirtualObjectNode virtualObject = new VirtualArrayNode(elementType(), constantLength); tool.createVirtualObject(virtualObject, state, null); tool.replaceWithVirtual(virtualObject); } } } + + /* Factored out in a separate method so that subclasses can override it. */ + protected ConstantNode defaultElementValue() { + return ConstantNode.defaultForKind(elementType().getKind(), graph()); + } } diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Fri Nov 22 13:41:17 2013 -0800 @@ -36,7 +36,7 @@ * The {@code NewInstanceNode} represents the allocation of an instance class object. */ @NodeInfo(nameTemplate = "New {p#instanceClass/s}") -public final class NewInstanceNode extends DeoptimizingFixedWithNextNode implements Canonicalizable, Lowerable, VirtualizableAllocation { +public class NewInstanceNode extends DeoptimizingFixedWithNextNode implements Canonicalizable, Lowerable, VirtualizableAllocation { private final ResolvedJavaType instanceClass; private final boolean fillContents; @@ -96,13 +96,18 @@ ResolvedJavaField[] fields = virtualObject.getFields(); ValueNode[] state = new ValueNode[fields.length]; for (int i = 0; i < state.length; i++) { - state[i] = ConstantNode.defaultForKind(fields[i].getType().getKind(), graph()); + state[i] = defaultFieldValue(fields[i]); } tool.createVirtualObject(virtualObject, state, null); tool.replaceWithVirtual(virtualObject); } } + /* Factored out in a separate method so that subclasses can override it. */ + protected ConstantNode defaultFieldValue(ResolvedJavaField field) { + return ConstantNode.defaultForKind(field.getType().getKind(), graph()); + } + @Override public boolean canDeoptimize() { return true; diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Fri Nov 22 13:41:17 2013 -0800 @@ -1511,12 +1511,7 @@ InliningUtil.replaceInvokeCallTarget(invoke, graph, InvokeKind.Special, concrete); } - FixedWithNextNode macroNode; - try { - macroNode = macroNodeClass.getConstructor(Invoke.class).newInstance(invoke); - } catch (ReflectiveOperationException | IllegalArgumentException | SecurityException e) { - throw new GraalInternalError(e).addContext(invoke.asNode()).addContext("macroSubstitution", macroNodeClass); - } + FixedWithNextNode macroNode = createMacroNodeInstance(macroNodeClass, invoke); CallTargetNode callTarget = invoke.callTarget(); if (invoke instanceof InvokeNode) { @@ -1529,4 +1524,12 @@ GraphUtil.killWithUnusedFloatingInputs(callTarget); return macroNode; } + + private static FixedWithNextNode createMacroNodeInstance(Class macroNodeClass, Invoke invoke) throws GraalInternalError { + try { + return macroNodeClass.getConstructor(Invoke.class).newInstance(invoke); + } catch (ReflectiveOperationException | IllegalArgumentException | SecurityException e) { + throw new GraalInternalError(e).addContext(invoke.asNode()).addContext("macroSubstitution", macroNodeClass); + } + } } diff -r 124860fac470 -r 3adfe375b01b 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 Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Fri Nov 22 13:41:17 2013 -0800 @@ -178,7 +178,7 @@ Mark expectedMark = graph.getMark(); lower(graph, context, 1); Mark mark = graph.getMark(); - assert mark.equals(expectedMark) : graph + ": a second round in the current lowering phase introduced these new nodes: " + graph.getNewNodes(mark).snapshot(); + assert mark.equals(expectedMark) : graph + ": a second round in the current lowering phase introduced these new nodes: " + graph.getNewNodes(expectedMark).snapshot(); return true; } diff -r 124860fac470 -r 3adfe375b01b 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 Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Fri Nov 22 13:41:17 2013 -0800 @@ -258,7 +258,9 @@ @Option(help = "") public static final OptionValue OptCanonicalizer = new OptionValue<>(true); @Option(help = "") - public static final OptionValue OptScheduleOutOfLoops = new OptionValue<>(true); + public static final OptionValue OptDeoptimizationGrouping = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptScheduleOutOfLoops = new OptionValue<>(true); @Option(help = "") public static final OptionValue OptEliminateGuards = new OptionValue<>(true); @Option(help = "") diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java Fri Nov 22 13:41:17 2013 -0800 @@ -46,7 +46,7 @@ private final ReplacementsImpl installer; public ObjectAccessTest() { - installer = new ReplacementsImpl(getProviders(), new Assumptions(false)); + installer = new ReplacementsImpl(getProviders(), new Assumptions(false), getTarget()); } private static final ThreadLocal inliningPolicy = new ThreadLocal<>(); @@ -60,7 +60,7 @@ @Test public void testRead1() { for (Kind kind : KINDS) { - assertRead(parse("read" + kind.name() + "1"), kind, false, ID); + assertRead(parse("read" + kind.name() + "1"), kind, true, ID); } } @@ -74,14 +74,14 @@ @Test public void testRead3() { for (Kind kind : KINDS) { - assertRead(parse("read" + kind.name() + "3"), kind, false, LocationIdentity.ANY_LOCATION); + assertRead(parse("read" + kind.name() + "3"), kind, true, LocationIdentity.ANY_LOCATION); } } @Test public void testWrite1() { for (Kind kind : KINDS) { - assertWrite(parse("write" + kind.name() + "1"), kind, false, ID); + assertWrite(parse("write" + kind.name() + "1"), kind, true, ID); } } @@ -95,7 +95,7 @@ @Test public void testWrite3() { for (Kind kind : KINDS) { - assertWrite(parse("write" + kind.name() + "3"), kind, false, LocationIdentity.ANY_LOCATION); + assertWrite(parse("write" + kind.name() + "3"), kind, true, LocationIdentity.ANY_LOCATION); } } diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java Fri Nov 22 13:41:17 2013 -0800 @@ -52,7 +52,7 @@ public PointerTest() { target = getCodeCache().getTarget(); - installer = new ReplacementsImpl(getProviders(), new Assumptions(false)); + installer = new ReplacementsImpl(getProviders(), new Assumptions(false), getTarget()); } private static final ThreadLocal inliningPolicy = new ThreadLocal<>(); @@ -66,7 +66,7 @@ @Test public void testRead1() { for (Kind kind : KINDS) { - assertRead(parse("read" + kind.name() + "1"), kind, false, ID); + assertRead(parse("read" + kind.name() + "1"), kind, true, ID); } } @@ -80,14 +80,14 @@ @Test public void testRead3() { for (Kind kind : KINDS) { - assertRead(parse("read" + kind.name() + "3"), kind, false, LocationIdentity.ANY_LOCATION); + assertRead(parse("read" + kind.name() + "3"), kind, true, LocationIdentity.ANY_LOCATION); } } @Test public void testWrite1() { for (Kind kind : KINDS) { - assertWrite(parse("write" + kind.name() + "1"), kind, false, ID); + assertWrite(parse("write" + kind.name() + "1"), kind, true, ID); } } @@ -101,7 +101,7 @@ @Test public void testWrite3() { for (Kind kind : KINDS) { - assertWrite(parse("write" + kind.name() + "3"), kind, false, LocationIdentity.ANY_LOCATION); + assertWrite(parse("write" + kind.name() + "3"), kind, true, LocationIdentity.ANY_LOCATION); } } diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java Fri Nov 22 13:41:17 2013 -0800 @@ -41,7 +41,7 @@ private final ReplacementsImpl installer; public WordTest() { - installer = new ReplacementsImpl(getProviders(), new Assumptions(false)); + installer = new ReplacementsImpl(getProviders(), new Assumptions(false), getTarget()); } private static final ThreadLocal inliningPolicy = new ThreadLocal<>(); diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Fri Nov 22 13:41:17 2013 -0800 @@ -69,9 +69,9 @@ private final Set forcedSubstitutions; private final Map, SnippetTemplateCache> snippetTemplateCache; - public ReplacementsImpl(Providers providers, Assumptions assumptions) { + public ReplacementsImpl(Providers providers, Assumptions assumptions, TargetDescription target) { this.providers = providers.copyWith(this); - this.target = providers.getCodeCache().getTarget(); + this.target = target; this.assumptions = assumptions; this.graphs = new ConcurrentHashMap<>(); this.registeredMethodSubstitutions = new HashMap<>(); @@ -212,7 +212,15 @@ return originalJavaMethod; } - private SnippetInliningPolicy inliningPolicy(ResolvedJavaMethod method) { + private static SnippetInliningPolicy createPolicyClassInstance(Class policyClass) { + try { + return policyClass.getConstructor().newInstance(); + } catch (Exception e) { + throw new GraalInternalError(e); + } + } + + protected SnippetInliningPolicy inliningPolicy(ResolvedJavaMethod method) { Class policyClass = SnippetInliningPolicy.class; Snippet snippet = method.getAnnotation(Snippet.class); if (snippet != null) { @@ -221,11 +229,7 @@ if (policyClass == SnippetInliningPolicy.class) { return new DefaultSnippetInliningPolicy(providers.getMetaAccess()); } - try { - return policyClass.getConstructor().newInstance(); - } catch (Exception e) { - throw new GraalInternalError(e); - } + return createPolicyClassInstance(policyClass); } /** diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Fri Nov 22 13:41:17 2013 -0800 @@ -926,8 +926,8 @@ private class DuplicateMapper extends MemoryMapNode { - Map duplicates; - StartNode replaceeStart; + private final Map duplicates; + @Input private StartNode replaceeStart; public DuplicateMapper(Map duplicates, StartNode replaceeStart) { this.duplicates = duplicates; @@ -1005,7 +1005,7 @@ // Replace all usages of the replacee with the value returned by the snippet ValueNode returnValue = null; - if (returnNode != null) { + if (returnNode != null && !(replacee instanceof ControlSinkNode)) { if (returnNode.result() instanceof LocalNode) { returnValue = (ValueNode) replacements.get(returnNode.result()); } else if (returnNode.result() != null) { diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java Fri Nov 22 13:41:17 2013 -0800 @@ -43,7 +43,7 @@ private final Replacements graalReplacements; private TruffleReplacements(Providers providers) { - super(providers, providers.getReplacements().getAssumptions()); + super(providers, providers.getReplacements().getAssumptions(), providers.getCodeCache().getTarget()); this.graalReplacements = providers.getReplacements(); } diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.word/src/com/oracle/graal/word/ComparableWord.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/ComparableWord.java Fri Nov 22 13:41:17 2013 -0800 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.word; + +public interface ComparableWord extends WordBase { + + /** + * Compares this word with the specified value. + * + * @param val value to which this word is to be compared. + * @return {@code this == val} + */ + boolean equal(ComparableWord val); + + /** + * Compares this word with the specified value. + * + * @param val value to which this word is to be compared. + * @return {@code this != val} + */ + boolean notEqual(ComparableWord val); +} diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.word/src/com/oracle/graal/word/Pointer.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/Pointer.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Pointer.java Fri Nov 22 13:41:17 2013 -0800 @@ -26,7 +26,7 @@ import com.oracle.graal.nodes.HeapAccess.BarrierType; import com.oracle.graal.nodes.extended.*; -public interface Pointer extends Unsigned { +public interface Pointer extends Unsigned, PointerBase { /** * Unsafe conversion of this Pointer to a Java language object. No correctness checks or type diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.word/src/com/oracle/graal/word/PointerBase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/PointerBase.java Fri Nov 22 13:41:17 2013 -0800 @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2013, 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.word; + +/** + * Marker interface for all {@link WordBase word types} that have the semantic of a pointer (but not + * necessarily all the memory access methods defined in {@link Pointer}). + */ +public interface PointerBase extends ComparableWord { +} diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.word/src/com/oracle/graal/word/Signed.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/Signed.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Signed.java Fri Nov 22 13:41:17 2013 -0800 @@ -22,7 +22,7 @@ */ package com.oracle.graal.word; -public interface Signed extends WordBase { +public interface Signed extends ComparableWord { /** * Returns a Signed whose value is {@code (this + val)}. diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.word/src/com/oracle/graal/word/Unsigned.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/Unsigned.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Unsigned.java Fri Nov 22 13:41:17 2013 -0800 @@ -22,7 +22,7 @@ */ package com.oracle.graal.word; -public interface Unsigned extends WordBase { +public interface Unsigned extends ComparableWord { /** * Returns a Unsigned whose value is {@code (this + val)}. diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java Fri Nov 22 13:41:17 2013 -0800 @@ -427,6 +427,12 @@ @Override @Operation(opcode = Opcode.COMPARISON, condition = Condition.EQ) + public boolean equal(ComparableWord val) { + return equal((Word) val); + } + + @Override + @Operation(opcode = Opcode.COMPARISON, condition = Condition.EQ) public boolean equal(Signed val) { return equal((Word) val); } @@ -450,6 +456,12 @@ @Override @Operation(opcode = Opcode.COMPARISON, condition = Condition.NE) + public boolean notEqual(ComparableWord val) { + return notEqual((Word) val); + } + + @Override + @Operation(opcode = Opcode.COMPARISON, condition = Condition.NE) public boolean notEqual(Signed val) { return notEqual((Word) val); } diff -r 124860fac470 -r 3adfe375b01b graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Fri Nov 22 21:09:36 2013 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Fri Nov 22 13:41:17 2013 -0800 @@ -86,6 +86,21 @@ * prepared to see the word type during canonicalization. */ protected void inferStamps(StructuredGraph graph) { + /* + * We want to make the stamps more precise. For cyclic phi functions, this means we have to + * ignore the initial stamp because the imprecise stamp would always propagate around the + * cycle. We therefore set the stamp to an illegal stamp, which is automatically ignored + * when the phi function performs the "meet" operator on its input stamps. + */ + for (Node n : graph.getNodes()) { + if (n instanceof PhiNode || n instanceof ProxyNode) { + ValueNode node = (ValueNode) n; + if (node.kind() == Kind.Object) { + node.setStamp(StampFactory.illegal(node.kind())); + } + } + } + boolean stampChanged; do { stampChanged = false; @@ -104,6 +119,22 @@ } } } while (stampChanged); + + /* + * Check that all the illegal stamps we introduced above are correctly replaced with real + * stamps again. + */ + assert checkNoIllegalStamp(graph); + } + + private static boolean checkNoIllegalStamp(StructuredGraph graph) { + for (Node n : graph.getNodes()) { + if (n instanceof ValueNode) { + ValueNode node = (ValueNode) n; + assert !(node.stamp() instanceof IllegalStamp); + } + } + return true; } /** @@ -243,7 +274,7 @@ } else { location = makeLocation(graph, arguments.get(1), readKind, arguments.get(2)); } - replace(invoke, readOp(graph, arguments.get(0), invoke, location, BarrierType.NONE, false)); + replace(invoke, readOp(graph, arguments.get(0), invoke, location, readKind, BarrierType.NONE, false)); break; } case READ_HEAP: { @@ -251,7 +282,7 @@ Kind readKind = asKind(callTargetNode.returnType()); LocationNode location = makeLocation(graph, arguments.get(1), readKind, ANY_LOCATION); BarrierType barrierType = (BarrierType) arguments.get(2).asConstant().asObject(); - replace(invoke, readOp(graph, arguments.get(0), invoke, location, barrierType, arguments.get(3).asConstant().asInt() == 0 ? false : true)); + replace(invoke, readOp(graph, arguments.get(0), invoke, location, readKind, barrierType, arguments.get(3).asConstant().asInt() == 0 ? false : true)); break; } case WRITE: @@ -390,15 +421,16 @@ if (locationIdentity.isConstant()) { return makeLocation(graph, offset, readKind, (LocationIdentity) locationIdentity.asConstant().asObject()); } - return SnippetLocationNode.create(locationIdentity, ConstantNode.forObject(readKind, metaAccess, graph), ConstantNode.forLong(0, graph), offset, ConstantNode.forInt(1, graph), graph); + return SnippetLocationNode.create(locationIdentity, ConstantNode.forObject(readKind, metaAccess, graph), ConstantNode.forLong(0, graph), fromSigned(graph, offset), + ConstantNode.forInt(1, graph), graph); } protected LocationNode makeLocation(StructuredGraph graph, ValueNode offset, Kind readKind, LocationIdentity locationIdentity) { - return IndexedLocationNode.create(locationIdentity, readKind, 0, offset, graph, 1); + return IndexedLocationNode.create(locationIdentity, readKind, 0, fromSigned(graph, offset), graph, 1); } - protected ValueNode readOp(StructuredGraph graph, ValueNode base, Invoke invoke, LocationNode location, BarrierType barrierType, boolean compressible) { - ReadNode read = graph.add(new ReadNode(base, location, invoke.asNode().stamp(), barrierType, compressible)); + protected ValueNode readOp(StructuredGraph graph, ValueNode base, Invoke invoke, LocationNode location, Kind readKind, BarrierType barrierType, boolean compressible) { + ReadNode read = graph.add(new ReadNode(base, location, StampFactory.forKind(readKind), barrierType, compressible)); graph.addBeforeFixed(invoke.asNode(), read); /* * The read must not float outside its block otherwise it may float above an explicit zero