Mercurial > hg > graal-jvmci-8
changeset 17146:2e4bd9de8682
Merge
author | Stefan Anzinger <stefan.anzinger@oracle.com> |
---|---|
date | Wed, 17 Sep 2014 17:06:37 -0700 |
parents | d75276c49399 (current diff) 62d7d16b170b (diff) |
children | 7a3f6543d383 5ecd1f298c64 |
files | |
diffstat | 44 files changed, 493 insertions(+), 268 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/InstalledCode.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/InstalledCode.java Wed Sep 17 17:06:37 2014 -0700 @@ -44,6 +44,11 @@ this.name = name; } + public final void setAddress(long address) { + this.address = address; + version++; + } + /** * @return the address of this code blob */ @@ -67,6 +72,13 @@ } /** + * Returns the number of instruction bytes for this code. + */ + public long getCodeSize() { + return 0; + } + + /** * Returns a copy of this installed code if it is {@linkplain #isValid() valid}, null otherwise. */ public byte[] getCode() {
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java Wed Sep 17 17:06:37 2014 -0700 @@ -214,6 +214,15 @@ assertEquals(1000L, annotation.timeout()); } + @Test(timeout = 1000L) + public void getAnnotationsTest() throws NoSuchMethodException { + ResolvedJavaMethod method = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("getAnnotationsTest")); + Annotation[] annotations = method.getAnnotations(); + assertNotNull(annotations); + assertEquals(1, annotations.length); + assertEquals(1000L, ((Test) annotations[0]).timeout()); + } + @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) @interface NonNull {
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/PrimitiveConstant.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/PrimitiveConstant.java Wed Sep 17 17:06:37 2014 -0700 @@ -123,7 +123,7 @@ if (getKind() == Kind.Illegal) { return "illegal"; } else { - return getKind().getJavaName() + "[" + getKind().format(asBoxedPrimitive()) + "|0x" + Long.toHexString(primitive) + "]"; + return getKind().getJavaName() + "[" + asBoxedPrimitive() + "|0x" + Long.toHexString(primitive) + "]"; } } }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java Wed Sep 17 17:06:37 2014 -0700 @@ -141,6 +141,12 @@ ConstantPool getConstantPool(); /** + * Returns all annotations of this method. If no annotations are present, an array of length 0 + * is returned. + */ + Annotation[] getAnnotations(); + + /** * Returns the annotation for the specified type of this method, if such an annotation is * present. *
--- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java Wed Sep 17 17:06:37 2014 -0700 @@ -95,7 +95,7 @@ BciBlockMapping blockMap; try (Scope ds = Debug.scope("BciBlockMapping")) { // compute the block map, setup exception handlers and get the entrypoint(s) - blockMap = BciBlockMapping.create(method); + blockMap = BciBlockMapping.create(method, graphBuilderConfig.doLivenessAnalysis()); } catch (Throwable e) { throw Debug.handle(e); } @@ -158,7 +158,7 @@ try (Scope s = Debug.scope("Allocator")) { if (backend.shouldAllocateRegisters()) { - new LinearScan(target, lir, frameMap).allocate(); + LinearScan.allocate(target, lir, frameMap); } } catch (Throwable e) { throw Debug.handle(e);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Wed Sep 17 17:06:37 2014 -0700 @@ -269,7 +269,7 @@ try (Scope s = Debug.scope("Allocator", nodeLirGen)) { if (backend.shouldAllocateRegisters()) { - new LinearScan(target, lir, frameMap).allocate(); + LinearScan.allocate(target, lir, frameMap); } } catch (Throwable e) { throw Debug.handle(e);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Wed Sep 17 17:06:37 2014 -0700 @@ -1856,7 +1856,11 @@ } } - public void allocate() { + public static void allocate(TargetDescription target, LIR lir, FrameMap frameMap) { + new LinearScan(target, lir, frameMap).allocate(); + } + + private void allocate() { /* * This is the point to enable debug logging for the whole register allocation.
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Wed Sep 17 17:06:37 2014 -0700 @@ -30,12 +30,18 @@ import com.oracle.graal.debug.*; import com.oracle.graal.graph.Node.ValueNumberable; import com.oracle.graal.graph.iterators.*; +import com.oracle.graal.options.*; /** * This class is a graph container, it contains the set of nodes that belong to this graph. */ public class Graph { + static class Options { + @Option(help = "Verify graphs often during compilation when assertions are turned on")// + public static final OptionValue<Boolean> VerifyGraalGraphs = new OptionValue<>(true); + } + public final String name; /** @@ -566,7 +572,7 @@ * mark}. */ public NodeIterable<Node> getNewNodes(Mark mark) { - final int index = mark.getValue(); + final int index = mark == null ? 0 : mark.getValue(); return new NodeIterable<Node>() { @Override @@ -752,17 +758,19 @@ } public boolean verify() { - for (Node node : getNodes()) { - try { + if (Options.VerifyGraalGraphs.getValue()) { + for (Node node : getNodes()) { try { - assert node.verify(); - } catch (AssertionError t) { - throw new GraalInternalError(t); - } catch (RuntimeException t) { - throw new GraalInternalError(t); + try { + assert node.verify(); + } catch (AssertionError t) { + throw new GraalInternalError(t); + } catch (RuntimeException t) { + throw new GraalInternalError(t); + } + } catch (GraalInternalError e) { + throw GraalGraphInternalError.transformAndAddContext(e, node).addContext(this); } - } catch (GraalInternalError e) { - throw GraalGraphInternalError.transformAndAddContext(e, node).addContext(this); } } return true;
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Wed Sep 17 17:06:37 2014 -0700 @@ -254,7 +254,7 @@ } if (nodeClass.getClazz().isAssignableFrom(clazz) && IterableNodeType.class.isAssignableFrom(nodeClass.getClazz())) { NodeClass superNodeClass = (NodeClass) nodeClass; - if (!USE_GENERATED_NODES || !containsId(this.iterableId, superNodeClass.iterableIds)) { + if (!containsId(this.iterableId, superNodeClass.iterableIds)) { superNodeClass.iterableIds = Arrays.copyOf(superNodeClass.iterableIds, superNodeClass.iterableIds.length + 1); superNodeClass.iterableIds[superNodeClass.iterableIds.length - 1] = this.iterableId; } @@ -346,7 +346,7 @@ * * <pre> * if (node.getNodeClass().is(BeginNode.class)) { ... } - * + * * // Due to generated Node classes, the test below * // is *not* the same as the test above: * if (node.getClass() == BeginNode.class) { ... }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java Wed Sep 17 17:06:37 2014 -0700 @@ -166,7 +166,7 @@ } else if (n instanceof IntegerDivNode || n instanceof IntegerRemNode || n instanceof UnsignedDivNode || n instanceof UnsignedRemNode) { // Nothing to do for division nodes. The HotSpot signal handler catches divisions by // zero and the MIN_VALUE / -1 cases. - } else if (n instanceof DeoptimizeNode || n instanceof UnwindNode || n instanceof FloatRemNode) { + } else if (n instanceof AbstractDeoptimizeNode || n instanceof UnwindNode || n instanceof FloatRemNode) { /* No lowering, we generate LIR directly for these nodes. */ } else { super.lower(n, tool);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java Wed Sep 17 17:06:37 2014 -0700 @@ -80,6 +80,7 @@ return codeStart; } + @Override public long getCodeSize() { return codeSize; }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Wed Sep 17 17:06:37 2014 -0700 @@ -461,6 +461,16 @@ } @Override + public Annotation[] getAnnotations() { + if (isConstructor()) { + Constructor<?> javaConstructor = toJavaConstructor(); + return javaConstructor == null ? new Annotation[0] : javaConstructor.getAnnotations(); + } + Method javaMethod = toJava(); + return javaMethod == null ? new Annotation[0] : javaMethod.getAnnotations(); + } + + @Override public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { if (isConstructor()) { Constructor<?> javaConstructor = toJavaConstructor();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyCallNode.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyCallNode.java Wed Sep 17 17:06:37 2014 -0700 @@ -185,6 +185,10 @@ return uninitialized; } + static boolean isHeapWordAligned(Constant value, Kind kind) { + return (arrayBaseOffset(kind) + (long) value.asInt() * arrayIndexScale(kind)) % heapWordSize() == 0; + } + public void updateAlignedDisjoint() { Kind componentKind = elementKind; if (srcPos == destPos) { @@ -195,7 +199,7 @@ Constant constantDst = destPos.stamp().asConstant(); if (constantSrc != null && constantDst != null) { if (!aligned) { - aligned = ArrayCopyNode.isHeapWordAligned(constantSrc, componentKind) && ArrayCopyNode.isHeapWordAligned(constantDst, componentKind); + aligned = isHeapWordAligned(constantSrc, componentKind) && isHeapWordAligned(constantDst, componentKind); } if (constantSrc.asInt() >= constantDst.asInt()) { // low to high copy so treat as disjoint
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java Wed Sep 17 17:06:37 2014 -0700 @@ -23,7 +23,6 @@ package com.oracle.graal.hotspot.replacements; import static com.oracle.graal.compiler.GraalCompiler.*; -import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; @@ -34,13 +33,12 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.replacements.nodes.*; @NodeInfo -public class ArrayCopyNode extends MacroStateSplitNode implements Virtualizable, Lowerable { +public class ArrayCopyNode extends BasicArrayCopyNode implements Virtualizable, Lowerable { public static ArrayCopyNode create(Invoke invoke) { return USE_GENERATED_NODES ? new ArrayCopyNodeGen(invoke) : new ArrayCopyNode(invoke); @@ -50,30 +48,6 @@ super(invoke); } - private ValueNode getSource() { - return arguments.get(0); - } - - private ValueNode getSourcePosition() { - return arguments.get(1); - } - - private ValueNode getDestination() { - return arguments.get(2); - } - - private ValueNode getDestinationPosition() { - return arguments.get(3); - } - - private ValueNode getLength() { - return arguments.get(4); - } - - static boolean isHeapWordAligned(Constant value, Kind kind) { - return (arrayBaseOffset(kind) + (long) value.asInt() * arrayIndexScale(kind)) % heapWordSize() == 0; - } - private StructuredGraph selectSnippet(LoweringTool tool, final Replacements replacements) { ResolvedJavaType srcType = StampTool.typeOrNull(getSource().stamp()); ResolvedJavaType destType = StampTool.typeOrNull(getDestination().stamp()); @@ -162,67 +136,4 @@ } return false; } - - private static boolean checkBounds(int position, int length, VirtualObjectNode virtualObject) { - return position >= 0 && position + length <= virtualObject.entryCount(); - } - - private static boolean checkEntryTypes(int srcPos, int length, State srcState, ResolvedJavaType destComponentType, VirtualizerTool tool) { - if (destComponentType.getKind() == Kind.Object) { - for (int i = 0; i < length; i++) { - ValueNode entry = srcState.getEntry(srcPos + i); - State state = tool.getObjectState(entry); - ResolvedJavaType type; - if (state != null) { - if (state.getState() == EscapeState.Virtual) { - type = state.getVirtualObject().type(); - } else { - type = StampTool.typeOrNull(state.getMaterializedValue()); - } - } else { - type = StampTool.typeOrNull(entry); - } - if (type == null || !destComponentType.isAssignableFrom(type)) { - return false; - } - } - } - return true; - } - - @Override - public void virtualize(VirtualizerTool tool) { - if (getSourcePosition().isConstant() && getDestinationPosition().isConstant() && getLength().isConstant()) { - int srcPos = getSourcePosition().asConstant().asInt(); - int destPos = getDestinationPosition().asConstant().asInt(); - int length = getLength().asConstant().asInt(); - State srcState = tool.getObjectState(getSource()); - State destState = tool.getObjectState(getDestination()); - - if (srcState != null && srcState.getState() == EscapeState.Virtual && destState != null && destState.getState() == EscapeState.Virtual) { - VirtualObjectNode srcVirtual = srcState.getVirtualObject(); - VirtualObjectNode destVirtual = destState.getVirtualObject(); - if (!(srcVirtual instanceof VirtualArrayNode) || !(destVirtual instanceof VirtualArrayNode)) { - return; - } - if (((VirtualArrayNode) srcVirtual).componentType().getKind() != Kind.Object || ((VirtualArrayNode) destVirtual).componentType().getKind() != Kind.Object) { - return; - } - if (length < 0 || !checkBounds(srcPos, length, srcVirtual) || !checkBounds(destPos, length, destVirtual)) { - return; - } - if (!checkEntryTypes(srcPos, length, srcState, destVirtual.type().getComponentType(), tool)) { - return; - } - for (int i = 0; i < length; i++) { - tool.setVirtualEntry(destState, destPos + i, srcState.getEntry(srcPos + i), false); - } - tool.delete(); - if (Debug.isLogEnabled()) { - Debug.log("virtualized arraycopyf(%s, %d, %s, %d, %d)", getSource(), srcPos, getDestination(), destPos, length); - } - } - } - } - }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Wed Sep 17 17:06:37 2014 -0700 @@ -25,11 +25,8 @@ import static com.oracle.graal.compiler.GraalCompiler.*; import java.lang.reflect.*; -import java.util.*; -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.nodeinfo.*; @@ -37,11 +34,10 @@ 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.replacements.nodes.*; @NodeInfo -public class ObjectCloneNode extends MacroStateSplitNode implements VirtualizableAllocation, ArrayLengthProvider { +public class ObjectCloneNode extends BasicObjectCloneNode implements VirtualizableAllocation, ArrayLengthProvider { public static ObjectCloneNode create(Invoke invoke) { return USE_GENERATED_NODES ? new ObjectCloneNodeGen(invoke) : new ObjectCloneNode(invoke); @@ -52,15 +48,6 @@ } @Override - public boolean inferStamp() { - return updateStamp(getObject().stamp()); - } - - private ValueNode getObject() { - return arguments.get(0); - } - - @Override protected StructuredGraph getLoweredSnippetGraph(LoweringTool tool) { if (!shouldIntrinsify(getTargetMethod())) { return null; @@ -105,81 +92,4 @@ } return null; } - - private static boolean isCloneableType(ResolvedJavaType type, MetaAccessProvider metaAccess) { - return metaAccess.lookupJavaType(Cloneable.class).isAssignableFrom(type); - } - - /* - * Looks at the given stamp and determines if it is an exact type (or can be assumed to be an - * exact type) and if it is a cloneable type. - * - * If yes, then the exact type is returned, otherwise it returns null. - */ - private static ResolvedJavaType getConcreteType(Stamp stamp, Assumptions assumptions, MetaAccessProvider metaAccess) { - if (!(stamp instanceof ObjectStamp)) { - return null; - } - ObjectStamp objectStamp = (ObjectStamp) stamp; - if (objectStamp.type() == null) { - return null; - } else if (objectStamp.isExactType()) { - return isCloneableType(objectStamp.type(), metaAccess) ? objectStamp.type() : null; - } else { - ResolvedJavaType type = objectStamp.type().findUniqueConcreteSubtype(); - if (type != null && isCloneableType(type, metaAccess)) { - assumptions.recordConcreteSubtype(objectStamp.type(), type); - return type; - } else { - return null; - } - } - } - - @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, Collections.<MonitorIdNode> emptyList()); - tool.replaceWithVirtual(newVirtual); - } - } else { - ValueNode obj; - if (originalState != null) { - obj = originalState.getMaterializedValue(); - } else { - obj = tool.getReplacedValue(getObject()); - } - ResolvedJavaType type = getConcreteType(obj.stamp(), tool.getAssumptions(), tool.getMetaAccessProvider()); - if (type != null && !type.isArray()) { - VirtualInstanceNode newVirtual = VirtualInstanceNode.create(type, true); - ResolvedJavaField[] fields = newVirtual.getFields(); - - 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] = LoadFieldNode.create(obj, fields[i]); - tool.addNode(loads[i]); - } - tool.createVirtualObject(newVirtual, state, Collections.<MonitorIdNode> emptyList()); - tool.replaceWithVirtual(newVirtual); - } - } - } - - @Override - public ValueNode length() { - if (getObject() instanceof ArrayLengthProvider) { - return ((ArrayLengthProvider) getObject()).length(); - } else { - return null; - } - } }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Wed Sep 17 17:06:37 2014 -0700 @@ -64,7 +64,7 @@ protected F frameState; protected BytecodeStream stream; - private GraphBuilderConfiguration graphBuilderConfig; + protected GraphBuilderConfiguration graphBuilderConfig; protected ResolvedJavaMethod method; protected BciBlock currentBlock; protected ProfilingInfo profilingInfo;
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java Wed Sep 17 17:06:37 2014 -0700 @@ -273,6 +273,7 @@ private BciBlock[] blockMap; public BciBlock[] loopHeaders; + private final boolean doLivenessAnalysis; public LocalLiveness liveness; /** @@ -280,7 +281,8 @@ * * @param method the compiler interface method containing the code */ - private BciBlockMapping(ResolvedJavaMethod method) { + private BciBlockMapping(ResolvedJavaMethod method, boolean doLivenessAnalysis) { + this.doLivenessAnalysis = doLivenessAnalysis; this.method = method; exceptionHandlers = method.getExceptionHandlers(); stream = new BytecodeStream(method.getCode()); @@ -319,7 +321,7 @@ if (Debug.isLogEnabled()) { this.log("Before LivenessAnalysis"); } - if (OptLivenessAnalysis.getValue()) { + if (doLivenessAnalysis) { try (Scope s = Debug.scope("LivenessAnalysis")) { liveness = method.getMaxLocals() <= 64 ? new SmallLocalLiveness() : new LargeLocalLiveness(); liveness.computeLiveness(); @@ -1058,8 +1060,8 @@ } } - public static BciBlockMapping create(ResolvedJavaMethod method) { - BciBlockMapping map = new BciBlockMapping(method); + public static BciBlockMapping create(ResolvedJavaMethod method, boolean doLivenessAnalysis) { + BciBlockMapping map = new BciBlockMapping(method, doLivenessAnalysis); map.build(); if (Debug.isDumpEnabled()) { Debug.dump(map, method.format("After block building %f %R %H.%n(%P)"));
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java Wed Sep 17 17:06:37 2014 -0700 @@ -25,6 +25,7 @@ import java.util.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.nodes.*; public class GraphBuilderConfiguration { @@ -34,6 +35,7 @@ private final boolean omitAllExceptionEdges; private final ResolvedJavaType[] skippedExceptionTypes; private final DebugInfoMode debugInfoMode; + private final boolean doLivenessAnalysis; public static enum DebugInfoMode { SafePointsOnly, @@ -59,20 +61,25 @@ Full, } - protected GraphBuilderConfiguration(boolean eagerResolving, boolean omitAllExceptionEdges, DebugInfoMode debugInfoMode, ResolvedJavaType[] skippedExceptionTypes) { + protected GraphBuilderConfiguration(boolean eagerResolving, boolean omitAllExceptionEdges, DebugInfoMode debugInfoMode, ResolvedJavaType[] skippedExceptionTypes, boolean doLivenessAnalysis) { this.eagerResolving = eagerResolving; this.omitAllExceptionEdges = omitAllExceptionEdges; this.debugInfoMode = debugInfoMode; this.skippedExceptionTypes = skippedExceptionTypes; + this.doLivenessAnalysis = doLivenessAnalysis; } public GraphBuilderConfiguration withSkippedExceptionTypes(ResolvedJavaType[] newSkippedExceptionTypes) { - return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, newSkippedExceptionTypes); + return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, newSkippedExceptionTypes, doLivenessAnalysis); } public GraphBuilderConfiguration withDebugInfoMode(DebugInfoMode newDebugInfoMode) { ResolvedJavaType[] newSkippedExceptionTypes = skippedExceptionTypes == EMPTY ? EMPTY : Arrays.copyOf(skippedExceptionTypes, skippedExceptionTypes.length); - return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, newDebugInfoMode, newSkippedExceptionTypes); + return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, newDebugInfoMode, newSkippedExceptionTypes, doLivenessAnalysis); + } + + public GraphBuilderConfiguration withDoLivenessAnalysis(boolean newLivenessAnalysis) { + return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, newLivenessAnalysis); } public ResolvedJavaType[] getSkippedExceptionTypes() { @@ -95,20 +102,24 @@ return debugInfoMode.ordinal() >= DebugInfoMode.Full.ordinal(); } + public boolean doLivenessAnalysis() { + return doLivenessAnalysis; + } + public static GraphBuilderConfiguration getDefault() { - return new GraphBuilderConfiguration(false, false, DebugInfoMode.SafePointsOnly, EMPTY); + return new GraphBuilderConfiguration(false, false, DebugInfoMode.SafePointsOnly, EMPTY, GraalOptions.OptLivenessAnalysis.getValue()); } public static GraphBuilderConfiguration getEagerDefault() { - return new GraphBuilderConfiguration(true, false, DebugInfoMode.SafePointsOnly, EMPTY); + return new GraphBuilderConfiguration(true, false, DebugInfoMode.SafePointsOnly, EMPTY, GraalOptions.OptLivenessAnalysis.getValue()); } public static GraphBuilderConfiguration getSnippetDefault() { - return new GraphBuilderConfiguration(true, true, DebugInfoMode.SafePointsOnly, EMPTY); + return new GraphBuilderConfiguration(true, true, DebugInfoMode.SafePointsOnly, EMPTY, GraalOptions.OptLivenessAnalysis.getValue()); } public static GraphBuilderConfiguration getFullDebugDefault() { - return new GraphBuilderConfiguration(true, false, DebugInfoMode.Full, EMPTY); + return new GraphBuilderConfiguration(true, false, DebugInfoMode.Full, EMPTY, GraalOptions.OptLivenessAnalysis.getValue()); } /**
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Sep 17 17:06:37 2014 -0700 @@ -230,7 +230,7 @@ try (Indent indent = Debug.logAndIndent("build graph for %s", method)) { // compute the block map, setup exception handlers and get the entrypoint(s) - BciBlockMapping blockMap = BciBlockMapping.create(method); + BciBlockMapping blockMap = BciBlockMapping.create(method, graphBuilderConfig.doLivenessAnalysis()); loopHeaders = blockMap.loopHeaders; liveness = blockMap.liveness;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java Wed Sep 17 17:06:37 2014 -0700 @@ -33,7 +33,7 @@ public class LIRInstructionClass extends LIRIntrospection { - static final LIRInstructionClass get(Class<? extends LIRInstruction> c) { + public static final LIRInstructionClass get(Class<? extends LIRInstruction> c) { LIRInstructionClass clazz = (LIRInstructionClass) allClasses.get(c); if (clazz != null) { return clazz; @@ -76,7 +76,7 @@ } @SuppressWarnings("unchecked") - private LIRInstructionClass(Class<? extends LIRInstruction> clazz, CalcOffset calcOffset) { + public LIRInstructionClass(Class<? extends LIRInstruction> clazz, CalcOffset calcOffset) { super(clazz); assert INSTRUCTION_CLASS.isAssignableFrom(clazz);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java Wed Sep 17 17:06:37 2014 -0700 @@ -29,7 +29,7 @@ import com.oracle.graal.nodes.spi.*; @NodeInfo -public class DynamicDeoptimizeNode extends AbstractDeoptimizeNode implements LIRLowerable, Canonicalizable { +public class DynamicDeoptimizeNode extends AbstractDeoptimizeNode implements LIRLowerable, Lowerable, Canonicalizable { @Input ValueNode actionAndReason; @Input ValueNode speculation; @@ -60,6 +60,11 @@ return getSpeculation(); } + @Override + public void lower(LoweringTool tool) { + tool.getLowerer().lower(this, tool); + } + public void generate(NodeLIRBuilderTool generator) { generator.getLIRGeneratorTool().emitDeoptimize(generator.operand(actionAndReason), generator.operand(speculation), generator.state(this)); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FixedBinaryNode.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FixedBinaryNode.java Wed Sep 17 17:06:37 2014 -0700 @@ -30,8 +30,8 @@ @NodeInfo public abstract class FixedBinaryNode extends DeoptimizingFixedWithNextNode implements Canonicalizable.Binary<ValueNode> { - @Input ValueNode x; - @Input ValueNode y; + @Input protected ValueNode x; + @Input protected ValueNode y; public FixedBinaryNode(Stamp stamp, ValueNode x, ValueNode y) { super(stamp);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java Wed Sep 17 17:06:37 2014 -0700 @@ -48,7 +48,7 @@ return USE_GENERATED_NODES ? new ForeignCallNodeGen(foreignCalls, descriptor, arguments) : new ForeignCallNode(foreignCalls, descriptor, arguments); } - ForeignCallNode(ForeignCallsProvider foreignCalls, ForeignCallDescriptor descriptor, ValueNode... arguments) { + protected ForeignCallNode(ForeignCallsProvider foreignCalls, ForeignCallDescriptor descriptor, ValueNode... arguments) { super(StampFactory.forKind(Kind.fromJavaClass(descriptor.getResultType()))); this.arguments = new NodeInputList<>(this, arguments); this.descriptor = descriptor;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Wed Sep 17 17:06:37 2014 -0700 @@ -43,7 +43,7 @@ @NodeInfo public class CheckCastNode extends FixedWithNextNode implements Canonicalizable, Simplifiable, Lowerable, Virtualizable, ValueProxy { - @Input ValueNode object; + @Input protected ValueNode object; private final ResolvedJavaType type; private final JavaTypeProfile profile; @@ -63,7 +63,7 @@ return USE_GENERATED_NODES ? new CheckCastNodeGen(type, object, profile, forStoreCheck) : new CheckCastNode(type, object, profile, forStoreCheck); } - CheckCastNode(ResolvedJavaType type, ValueNode object, JavaTypeProfile profile, boolean forStoreCheck) { + protected CheckCastNode(ResolvedJavaType type, ValueNode object, JavaTypeProfile profile, boolean forStoreCheck) { super(StampFactory.declared(type)); assert type != null; this.type = type;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Wed Sep 17 17:06:37 2014 -0700 @@ -49,7 +49,7 @@ return USE_GENERATED_NODES ? new InstanceOfNodeGen(type, object, profile) : new InstanceOfNode(type, object, profile); } - InstanceOfNode(ResolvedJavaType type, ValueNode object, JavaTypeProfile profile) { + protected InstanceOfNode(ResolvedJavaType type, ValueNode object, JavaTypeProfile profile) { super(object); this.type = type; this.profile = profile;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Wed Sep 17 17:06:37 2014 -0700 @@ -41,7 +41,7 @@ return USE_GENERATED_NODES ? new MethodCallTargetNodeGen(invokeKind, targetMethod, arguments, returnType) : new MethodCallTargetNode(invokeKind, targetMethod, arguments, returnType); } - MethodCallTargetNode(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, JavaType returnType) { + protected MethodCallTargetNode(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, JavaType returnType) { super(arguments, targetMethod, invokeKind); this.returnType = returnType; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java Wed Sep 17 17:06:37 2014 -0700 @@ -81,13 +81,17 @@ for (int i = 0; i < constantLength; i++) { state[i] = defaultForKind; } - VirtualObjectNode virtualObject = VirtualArrayNode.create(elementType(), constantLength); + VirtualObjectNode virtualObject = createVirtualArrayNode(constantLength); tool.createVirtualObject(virtualObject, state, Collections.<MonitorIdNode> emptyList()); tool.replaceWithVirtual(virtualObject); } } } + protected VirtualArrayNode createVirtualArrayNode(int constantLength) { + return VirtualArrayNode.create(elementType(), constantLength); + } + /* Factored out in a separate method so that subclasses can override it. */ protected ConstantNode defaultElementValue() { return ConstantNode.defaultForKind(elementType().getKind(), graph());
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Wed Sep 17 17:06:37 2014 -0700 @@ -51,7 +51,7 @@ return USE_GENERATED_NODES ? new NewInstanceNodeGen(type, fillContents) : new NewInstanceNode(type, fillContents); } - NewInstanceNode(ResolvedJavaType type, boolean fillContents) { + protected NewInstanceNode(ResolvedJavaType type, boolean fillContents) { super(StampFactory.exactNonNull(type), fillContents); assert !type.isArray() && !type.isInterface() && !type.isPrimitive(); this.instanceClass = type; @@ -73,7 +73,7 @@ * they're excluded from escape analysis. */ if (!tool.getMetaAccessProvider().lookupJavaType(Reference.class).isAssignableFrom(instanceClass)) { - VirtualInstanceNode virtualObject = VirtualInstanceNode.create(instanceClass(), true); + VirtualInstanceNode virtualObject = createVirtualInstanceNode(true); ResolvedJavaField[] fields = virtualObject.getFields(); ValueNode[] state = new ValueNode[fields.length]; for (int i = 0; i < state.length; i++) { @@ -84,6 +84,10 @@ } } + protected VirtualInstanceNode createVirtualInstanceNode(boolean hasIdentity) { + return VirtualInstanceNode.create(instanceClass(), hasIdentity); + } + /* Factored out in a separate method so that subclasses can override it. */ protected ConstantNode defaultFieldValue(ResolvedJavaField field) { return ConstantNode.defaultForKind(field.getType().getKind(), graph());
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java Wed Sep 17 17:06:37 2014 -0700 @@ -35,7 +35,7 @@ @NodeInfo public class NewMultiArrayNode extends DeoptimizingFixedWithNextNode implements Lowerable, ArrayLengthProvider { - @Input NodeInputList<ValueNode> dimensions; + @Input protected NodeInputList<ValueNode> dimensions; private final ResolvedJavaType type; public ValueNode dimension(int index) { @@ -60,7 +60,7 @@ return USE_GENERATED_NODES ? new NewMultiArrayNodeGen(type, dimensions) : new NewMultiArrayNode(type, dimensions); } - NewMultiArrayNode(ResolvedJavaType type, ValueNode[] dimensions) { + protected NewMultiArrayNode(ResolvedJavaType type, ValueNode[] dimensions) { super(StampFactory.exactNonNull(type)); this.type = type; this.dimensions = new NodeInputList<>(this, dimensions);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java Wed Sep 17 17:06:37 2014 -0700 @@ -32,14 +32,14 @@ @NodeInfo(nameTemplate = "VirtualArray {p#componentType/s}[{p#length}]") public class VirtualArrayNode extends VirtualObjectNode implements ArrayLengthProvider { - private final ResolvedJavaType componentType; - private final int length; + protected final ResolvedJavaType componentType; + protected final int length; public static VirtualArrayNode create(ResolvedJavaType componentType, int length) { return USE_GENERATED_NODES ? new VirtualArrayNodeGen(componentType, length) : new VirtualArrayNode(componentType, length); } - VirtualArrayNode(ResolvedJavaType componentType, int length) { + protected VirtualArrayNode(ResolvedJavaType componentType, int length) { super(componentType.getArrayClass(), true); this.componentType = componentType; this.length = length;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualBoxingNode.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualBoxingNode.java Wed Sep 17 17:06:37 2014 -0700 @@ -41,6 +41,10 @@ this.boxingKind = boxingKind; } + public Kind getBoxingKind() { + return boxingKind; + } + @Override public VirtualBoxingNode duplicate() { return VirtualBoxingNode.create(type(), boxingKind);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java Wed Sep 17 17:06:37 2014 -0700 @@ -29,14 +29,14 @@ @NodeInfo(nameTemplate = "VirtualInstance {p#type/s}") public class VirtualInstanceNode extends VirtualObjectNode { - private final ResolvedJavaType type; - private final ResolvedJavaField[] fields; + protected final ResolvedJavaType type; + protected final ResolvedJavaField[] fields; public static VirtualInstanceNode create(ResolvedJavaType type, boolean hasIdentity) { return USE_GENERATED_NODES ? new VirtualInstanceNodeGen(type, hasIdentity) : new VirtualInstanceNode(type, hasIdentity); } - VirtualInstanceNode(ResolvedJavaType type, boolean hasIdentity) { + protected VirtualInstanceNode(ResolvedJavaType type, boolean hasIdentity) { this(type, type.getInstanceFields(true), hasIdentity); }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java Wed Sep 17 17:06:37 2014 -0700 @@ -24,7 +24,6 @@ import java.util.*; -import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.nodes.*; @@ -57,11 +56,13 @@ if (target instanceof AbstractDeoptimizeNode) { merge = graph.add(MergeNode.create()); EndNode firstEnd = graph.add(EndNode.create()); - reasonActionPhi = graph.addWithoutUnique(ValuePhiNode.create(StampFactory.forKind(Kind.Int), merge)); - speculationPhi = graph.addWithoutUnique(ValuePhiNode.create(StampFactory.forKind(Kind.Object), merge)); + ValueNode actionAndReason = ((AbstractDeoptimizeNode) target).getActionAndReason(context.getMetaAccess()); + ValueNode speculation = ((AbstractDeoptimizeNode) target).getSpeculation(context.getMetaAccess()); + reasonActionPhi = graph.addWithoutUnique(ValuePhiNode.create(StampFactory.forKind(actionAndReason.getKind()), merge)); + speculationPhi = graph.addWithoutUnique(ValuePhiNode.create(StampFactory.forKind(speculation.getKind()), merge)); merge.addForwardEnd(firstEnd); - reasonActionPhi.addInput(((AbstractDeoptimizeNode) target).getActionAndReason(context.getMetaAccess())); - speculationPhi.addInput(((AbstractDeoptimizeNode) target).getSpeculation(context.getMetaAccess())); + reasonActionPhi.addInput(actionAndReason); + speculationPhi.addInput(speculation); target.replaceAtPredecessor(firstEnd); exitLoops((AbstractDeoptimizeNode) target, firstEnd, cfg);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Wed Sep 17 17:06:37 2014 -0700 @@ -146,7 +146,9 @@ graph.addBeforeFixed(before, fixedGuard); DummyGuardHandle handle = graph.add(DummyGuardHandle.create(fixedGuard)); fixedGuard.lower(this); - return handle.getGuard(); + GuardingNode result = handle.getGuard(); + handle.safeDelete(); + return result; } else { GuardNode newGuard = graph.unique(GuardNode.create(condition, guardAnchor, deoptReason, action, negated, Constant.NULL_OBJECT)); if (OptEliminateGuards.getValue()) {
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java Wed Sep 17 17:06:37 2014 -0700 @@ -50,7 +50,7 @@ * Gets a global output stream on a file in the current working directory. This stream is first * opened if necessary. The name of the file is * {@code "compilations-" + System.currentTimeMillis() + ".cfg"}. - * + * * @return the global output stream or {@code null} if there was an error opening the file for * writing */ @@ -70,7 +70,7 @@ /** * Creates a control flow graph printer. - * + * * @param os where the output generated via this printer will be sent */ public CompilationPrinter(OutputStream os) { @@ -101,7 +101,7 @@ /** * Prints a compilation timestamp for a given method. - * + * * @param method the method for which a timestamp will be printed */ public void printCompilation(JavaMethod method) { @@ -227,7 +227,7 @@ } public void printBytecodes(String code) { - if (code.length() == 0) { + if (code == null || code.length() == 0) { return; } begin("bytecodes");
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java Wed Sep 17 17:06:37 2014 -0700 @@ -346,9 +346,9 @@ int entryCount = virtual.entryCount(); AbstractNewObjectNode newObject; if (virtual instanceof VirtualInstanceNode) { - newObject = graph.add(NewInstanceNode.create(virtual.type(), true)); + newObject = graph.add(createNewInstanceFromVirtual(virtual)); } else { - newObject = graph.add(NewArrayNode.create(((VirtualArrayNode) virtual).componentType(), ConstantNode.forInt(entryCount, graph), true)); + newObject = graph.add(createNewArrayFromVirtual(virtual, ConstantNode.forInt(entryCount, graph))); } recursiveLowerings.add(newObject); graph.addBeforeFixed(commit, newObject); @@ -433,6 +433,14 @@ } } + public NewInstanceNode createNewInstanceFromVirtual(VirtualObjectNode virtual) { + return NewInstanceNode.create(virtual.type(), true); + } + + protected NewArrayNode createNewArrayFromVirtual(VirtualObjectNode virtual, ValueNode length) { + return NewArrayNode.create(((VirtualArrayNode) virtual).componentType(), length, true); + } + public static void finishAllocatedObjects(LoweringTool tool, CommitAllocationNode commit, ValueNode[] allocations) { StructuredGraph graph = commit.graph(); for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraphKit.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraphKit.java Wed Sep 17 17:06:37 2014 -0700 @@ -137,7 +137,7 @@ if (invoke.getKind() != Kind.Void) { frameStateBuilder.push(invoke.getKind(), invoke); } - invoke.setStateAfter(frameStateBuilder.create(0)); + invoke.setStateAfter(frameStateBuilder.create(bci)); if (invoke.getKind() != Kind.Void) { frameStateBuilder.pop(invoke.getKind()); }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Wed Sep 17 17:06:37 2014 -0700 @@ -208,7 +208,7 @@ return result; } - private Node createNodeInstance(StructuredGraph graph, ResolvedJavaType nodeClass, ResolvedJavaType[] parameterTypes, Stamp invokeStamp, boolean setStampFromReturnType, + protected Node createNodeInstance(StructuredGraph graph, ResolvedJavaType nodeClass, ResolvedJavaType[] parameterTypes, Stamp invokeStamp, boolean setStampFromReturnType, Constant[] nodeFactoryArguments) { ResolvedJavaMethod factory = null; Constant[] arguments = null; @@ -233,7 +233,7 @@ } try { - ValueNode intrinsicNode = (ValueNode) snippetReflection.asObject(factory.invoke(null, arguments)); + ValueNode intrinsicNode = (ValueNode) snippetReflection.asObject(invokeFactory(factory, arguments)); if (setStampFromReturnType) { intrinsicNode.setStamp(invokeStamp); @@ -244,6 +244,10 @@ } } + protected Constant invokeFactory(ResolvedJavaMethod factory, Constant[] arguments) { + return factory.invoke(null, arguments); + } + private static String sigString(ResolvedJavaType[] types) { StringBuilder sb = new StringBuilder("("); for (int i = 0; i < types.length; i++) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Wed Sep 17 17:06:37 2014 -0700 @@ -75,9 +75,9 @@ * Encapsulates method and macro substitutions for a single class. */ protected class ClassReplacements { - protected final Map<ResolvedJavaMethod, ResolvedJavaMethod> methodSubstitutions = new HashMap<>(); - private final Map<ResolvedJavaMethod, Class<? extends FixedWithNextNode>> macroSubstitutions = new HashMap<>(); - private final Set<ResolvedJavaMethod> forcedSubstitutions = new HashSet<>(); + public final Map<ResolvedJavaMethod, ResolvedJavaMethod> methodSubstitutions = new HashMap<>(); + public final Map<ResolvedJavaMethod, Class<? extends FixedWithNextNode>> macroSubstitutions = new HashMap<>(); + public final Set<ResolvedJavaMethod> forcedSubstitutions = new HashSet<>(); public ClassReplacements(Class<?>[] substitutionClasses, AtomicReference<ClassReplacements> ref) { for (Class<?> substitutionClass : substitutionClasses) { @@ -266,11 +266,15 @@ // Do deferred intrinsification of node intrinsics - new NodeIntrinsificationPhase(providers, snippetReflection).apply(specializedSnippet); + createNodeIntrinsificationPhase().apply(specializedSnippet); new CanonicalizerPhase(true).apply(specializedSnippet, new PhaseContext(providers, assumptions)); NodeIntrinsificationVerificationPhase.verify(specializedSnippet); } + protected NodeIntrinsificationPhase createNodeIntrinsificationPhase() { + return new NodeIntrinsificationPhase(providers, snippetReflection); + } + @Override public StructuredGraph getMethodSubstitution(ResolvedJavaMethod original) { ClassReplacements cr = getClassReplacements(original.getDeclaringClass().getName()); @@ -491,7 +495,7 @@ * Does final processing of a snippet graph. */ protected void finalizeGraph(StructuredGraph graph) { - new NodeIntrinsificationPhase(providers, snippetReflection).apply(graph); + createNodeIntrinsificationPhase().apply(graph); if (!SnippetTemplate.hasConstantParameter(method)) { NodeIntrinsificationVerificationPhase.verify(graph); } @@ -576,6 +580,7 @@ } else { createGraphBuilder(metaAccess, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(graph); } + afterParsing(graph); new WordTypeVerificationPhase(metaAccess, snippetReflection, target.wordKind).apply(graph); new WordTypeRewriterPhase(metaAccess, snippetReflection, target.wordKind).apply(graph); @@ -592,6 +597,9 @@ return new GraphBuilderPhase.Instance(metaAccess, graphBuilderConfig, optimisticOpts); } + protected void afterParsing(@SuppressWarnings("unused") StructuredGraph graph) { + } + protected Object beforeInline(@SuppressWarnings("unused") MethodCallTargetNode callTarget, @SuppressWarnings("unused") StructuredGraph callee) { return null; } @@ -613,7 +621,7 @@ * Called after all inlining for a given graph is complete. */ protected void afterInlining(StructuredGraph graph) { - new NodeIntrinsificationPhase(providers, snippetReflection).apply(graph); + createNodeIntrinsificationPhase().apply(graph); new DeadCodeEliminationPhase(Optional).apply(graph); if (OptCanonicalizer.getValue()) { new CanonicalizerPhase(true).apply(graph, new PhaseContext(providers, assumptions));
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Wed Sep 17 17:06:37 2014 -0700 @@ -74,12 +74,14 @@ */ public class SnippetTemplate { + public static boolean LAZY_SNIPPETS = true; + /** * Holds the {@link ResolvedJavaMethod} of the snippet, together with some information about the * method that needs to be computed only once. The {@link SnippetInfo} should be created once * per snippet and then cached. */ - public static class SnippetInfo { + public abstract static class SnippetInfo { protected final ResolvedJavaMethod method; @@ -126,8 +128,6 @@ } - protected final AtomicReference<Lazy> lazy = new AtomicReference<>(null); - /** * Times instantiations of all templates derived form this snippet. * @@ -142,12 +142,7 @@ */ private final DebugMetric instantiationCounter; - private Lazy lazy() { - if (lazy.get() == null) { - lazy.compareAndSet(null, new Lazy(method)); - } - return lazy.get(); - } + protected abstract Lazy lazy(); protected SnippetInfo(ResolvedJavaMethod method) { this.method = method; @@ -192,6 +187,36 @@ } } + protected static class LazySnippetInfo extends SnippetInfo { + protected final AtomicReference<Lazy> lazy = new AtomicReference<>(null); + + protected LazySnippetInfo(ResolvedJavaMethod method) { + super(method); + } + + @Override + protected Lazy lazy() { + if (lazy.get() == null) { + lazy.compareAndSet(null, new Lazy(method)); + } + return lazy.get(); + } + } + + protected static class EagerSnippetInfo extends SnippetInfo { + protected final Lazy lazy; + + protected EagerSnippetInfo(ResolvedJavaMethod method) { + super(method); + lazy = new Lazy(method); + } + + @Override + protected Lazy lazy() { + return lazy; + } + } + /** * Values that are bound to the snippet method parameters. The methods {@link #add}, * {@link #addConst}, and {@link #addVarargs} must be called in the same order as in the @@ -473,7 +498,11 @@ assert findMethod(declaringClass, methodName, method) == null : "found more than one method named " + methodName + " in " + declaringClass; ResolvedJavaMethod javaMethod = providers.getMetaAccess().lookupJavaMethod(method); providers.getReplacements().registerSnippet(javaMethod); - return new SnippetInfo(javaMethod); + if (LAZY_SNIPPETS) { + return new LazySnippetInfo(javaMethod); + } else { + return new EagerSnippetInfo(javaMethod); + } } /** @@ -957,6 +986,10 @@ // no floating reads yet, ignore locations created while lowering return true; } + if (returnNode == null) { + // The snippet terminates control flow + return true; + } MemoryMapNode memoryMap = returnNode.getMemoryMap(); if (memoryMap == null || memoryMap.isEmpty()) { // there are no kills in the snippet graph
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BasicArrayCopyNode.java Wed Sep 17 17:06:37 2014 -0700 @@ -0,0 +1,126 @@ +/* + * 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.replacements.nodes; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.nodeinfo.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.virtual.*; + +@NodeInfo +public class BasicArrayCopyNode extends MacroStateSplitNode implements Virtualizable { + + public static BasicArrayCopyNode create(Invoke invoke) { + return USE_GENERATED_NODES ? new BasicArrayCopyNodeGen(invoke) : new BasicArrayCopyNode(invoke); + } + + protected BasicArrayCopyNode(Invoke invoke) { + super(invoke); + } + + protected ValueNode getSource() { + return arguments.get(0); + } + + protected ValueNode getSourcePosition() { + return arguments.get(1); + } + + protected ValueNode getDestination() { + return arguments.get(2); + } + + protected ValueNode getDestinationPosition() { + return arguments.get(3); + } + + protected ValueNode getLength() { + return arguments.get(4); + } + + private static boolean checkBounds(int position, int length, VirtualObjectNode virtualObject) { + return position >= 0 && position + length <= virtualObject.entryCount(); + } + + private static boolean checkEntryTypes(int srcPos, int length, State srcState, ResolvedJavaType destComponentType, VirtualizerTool tool) { + if (destComponentType.getKind() == Kind.Object) { + for (int i = 0; i < length; i++) { + ValueNode entry = srcState.getEntry(srcPos + i); + State state = tool.getObjectState(entry); + ResolvedJavaType type; + if (state != null) { + if (state.getState() == EscapeState.Virtual) { + type = state.getVirtualObject().type(); + } else { + type = StampTool.typeOrNull(state.getMaterializedValue()); + } + } else { + type = StampTool.typeOrNull(entry); + } + if (type == null || !destComponentType.isAssignableFrom(type)) { + return false; + } + } + } + return true; + } + + @Override + public void virtualize(VirtualizerTool tool) { + if (getSourcePosition().isConstant() && getDestinationPosition().isConstant() && getLength().isConstant()) { + int srcPos = getSourcePosition().asConstant().asInt(); + int destPos = getDestinationPosition().asConstant().asInt(); + int length = getLength().asConstant().asInt(); + State srcState = tool.getObjectState(getSource()); + State destState = tool.getObjectState(getDestination()); + + if (srcState != null && srcState.getState() == EscapeState.Virtual && destState != null && destState.getState() == EscapeState.Virtual) { + VirtualObjectNode srcVirtual = srcState.getVirtualObject(); + VirtualObjectNode destVirtual = destState.getVirtualObject(); + if (!(srcVirtual instanceof VirtualArrayNode) || !(destVirtual instanceof VirtualArrayNode)) { + return; + } + if (((VirtualArrayNode) srcVirtual).componentType().getKind() != Kind.Object || ((VirtualArrayNode) destVirtual).componentType().getKind() != Kind.Object) { + return; + } + if (length < 0 || !checkBounds(srcPos, length, srcVirtual) || !checkBounds(destPos, length, destVirtual)) { + return; + } + if (!checkEntryTypes(srcPos, length, srcState, destVirtual.type().getComponentType(), tool)) { + return; + } + for (int i = 0; i < length; i++) { + tool.setVirtualEntry(destState, destPos + i, srcState.getEntry(srcPos + i), false); + } + tool.delete(); + if (Debug.isLogEnabled()) { + Debug.log("virtualized arraycopyf(%s, %d, %s, %d, %d)", getSource(), srcPos, getDestination(), destPos, length); + } + } + } + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BasicObjectCloneNode.java Wed Sep 17 17:06:37 2014 -0700 @@ -0,0 +1,136 @@ +/* + * 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.replacements.nodes; + +import java.util.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.nodeinfo.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.virtual.*; + +@NodeInfo +public class BasicObjectCloneNode extends MacroStateSplitNode implements VirtualizableAllocation, ArrayLengthProvider { + + public static BasicObjectCloneNode create(Invoke invoke) { + return USE_GENERATED_NODES ? new BasicObjectCloneNodeGen(invoke) : new BasicObjectCloneNode(invoke); + } + + protected BasicObjectCloneNode(Invoke invoke) { + super(invoke); + } + + @Override + public boolean inferStamp() { + return updateStamp(getObject().stamp()); + } + + public ValueNode getObject() { + return arguments.get(0); + } + + protected static boolean isCloneableType(ResolvedJavaType type, MetaAccessProvider metaAccess) { + return metaAccess.lookupJavaType(Cloneable.class).isAssignableFrom(type); + } + + /* + * Looks at the given stamp and determines if it is an exact type (or can be assumed to be an + * exact type) and if it is a cloneable type. + * + * If yes, then the exact type is returned, otherwise it returns null. + */ + protected static ResolvedJavaType getConcreteType(Stamp stamp, Assumptions assumptions, MetaAccessProvider metaAccess) { + if (!(stamp instanceof ObjectStamp)) { + return null; + } + ObjectStamp objectStamp = (ObjectStamp) stamp; + if (objectStamp.type() == null) { + return null; + } else if (objectStamp.isExactType()) { + return isCloneableType(objectStamp.type(), metaAccess) ? objectStamp.type() : null; + } else { + ResolvedJavaType type = objectStamp.type().findUniqueConcreteSubtype(); + if (type != null && isCloneableType(type, metaAccess)) { + assumptions.recordConcreteSubtype(objectStamp.type(), type); + return type; + } else { + return null; + } + } + } + + @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, Collections.<MonitorIdNode> emptyList()); + tool.replaceWithVirtual(newVirtual); + } + } else { + ValueNode obj; + if (originalState != null) { + obj = originalState.getMaterializedValue(); + } else { + obj = tool.getReplacedValue(getObject()); + } + ResolvedJavaType type = getConcreteType(obj.stamp(), tool.getAssumptions(), tool.getMetaAccessProvider()); + if (type != null && !type.isArray()) { + VirtualInstanceNode newVirtual = createVirtualInstanceNode(type, true); + ResolvedJavaField[] fields = newVirtual.getFields(); + + 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] = LoadFieldNode.create(obj, fields[i]); + tool.addNode(loads[i]); + } + tool.createVirtualObject(newVirtual, state, Collections.<MonitorIdNode> emptyList()); + tool.replaceWithVirtual(newVirtual); + } + } + } + + protected VirtualInstanceNode createVirtualInstanceNode(ResolvedJavaType type, boolean hasIdentity) { + return VirtualInstanceNode.create(type, hasIdentity); + } + + @Override + public ValueNode length() { + if (getObject() instanceof ArrayLengthProvider) { + return ((ArrayLengthProvider) getObject()).length(); + } else { + return null; + } + } +}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLHelloEqualsWorldBuiltin.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLHelloEqualsWorldBuiltin.java Wed Sep 17 17:06:37 2014 -0700 @@ -23,6 +23,7 @@ package com.oracle.truffle.sl.builtins; import com.oracle.truffle.api.*; +import com.oracle.truffle.api.CompilerDirectives.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.frame.FrameInstance.FrameAccess; @@ -40,6 +41,7 @@ } @Specialization + @SlowPath public String change() { FrameInstance frameInstance = Truffle.getRuntime().getCallerFrame(); Frame frame = frameInstance.getFrame(FrameAccess.READ_WRITE, false);
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLStackTraceBuiltin.java Wed Sep 17 17:06:06 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLStackTraceBuiltin.java Wed Sep 17 17:06:37 2014 -0700 @@ -52,17 +52,17 @@ StringBuilder str = new StringBuilder(); Truffle.getRuntime().iterateFrames(frameInstance -> { - dumpFrame(str, frameInstance.getCallTarget(), frameInstance.getFrame(FrameAccess.READ_ONLY, true), frameInstance.isVirtualFrame()); + dumpFrame(str, frameInstance.getCallTarget(), frameInstance.getFrame(FrameAccess.READ_ONLY, true)); return null; }); return str.toString(); } - private static void dumpFrame(StringBuilder str, CallTarget callTarget, Frame frame, boolean isVirtual) { + private static void dumpFrame(StringBuilder str, CallTarget callTarget, Frame frame) { if (str.length() > 0) { str.append("\n"); } - str.append("Frame: ").append(callTarget).append(isVirtual ? " (virtual)" : ""); + str.append("Frame: ").append(((RootCallTarget) callTarget).getRootNode().toString()); FrameDescriptor frameDescriptor = frame.getFrameDescriptor(); for (FrameSlot s : frameDescriptor.getSlots()) { str.append(", ").append(s.getIdentifier()).append("=").append(frame.getValue(s));