# HG changeset patch
# User Christian Humer
# Date 1367009045 -7200
# Node ID f43d043888154c76ee6487c566cb88be463aa651
# Parent 52fde777a605e0784c128d5d0697c6212b704e67# Parent 52e6d0e8d6f7da8610607032c7677c1bd94a1b48
Merge.
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java Fri Apr 26 22:44:05 2013 +0200
@@ -22,15 +22,11 @@
*/
package com.oracle.graal.compiler.test;
-import java.util.*;
-
import org.junit.*;
import com.oracle.graal.api.code.*;
import com.oracle.graal.debug.*;
-import com.oracle.graal.graph.*;
import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
import com.oracle.graal.nodes.extended.*;
import com.oracle.graal.nodes.spi.Lowerable.*;
import com.oracle.graal.phases.common.*;
@@ -96,36 +92,10 @@
Debug.dump(graph, "After lowering");
- ArrayList merges = new ArrayList<>();
- ArrayList reads = new ArrayList<>();
- for (Node n : graph.getNodes()) {
- if (n instanceof MergeNode) {
- // check shape
- MergeNode merge = (MergeNode) n;
-
- if (merge.inputs().count() == 2) {
- for (EndNode m : merge.forwardEnds()) {
- if (m.predecessor() != null && m.predecessor() instanceof BeginNode && m.predecessor().predecessor() instanceof IfNode) {
- IfNode o = (IfNode) m.predecessor().predecessor();
- if (o.falseSuccessor().next() instanceof DeoptimizeNode) {
- merges.add(merge);
- }
- }
- }
- }
- }
- if (n instanceof IntegerAddNode) {
- IntegerAddNode ian = (IntegerAddNode) n;
-
- Assert.assertTrue(ian.y() instanceof ConstantNode);
- Assert.assertTrue(ian.x() instanceof FloatingReadNode);
- reads.add((FloatingReadNode) ian.x());
- }
- }
-
- Assert.assertTrue(merges.size() >= reads.size());
- for (int i = 0; i < reads.size(); i++) {
- assertOrderedAfterSchedule(graph, merges.get(i), reads.get(i));
+ for (FloatingReadNode node : graph.getNodes(LocalNode.class).first().usages().filter(FloatingReadNode.class)) {
+ // Checking that the parameter a is not directly used for the access to field
+ // x10 (because x10 must be guarded by the checkcast).
+ Assert.assertTrue(node.location().locationIdentity() == LocationNode.FINAL_LOCATION);
}
}
});
diff -r 52fde777a605 -r f43d04388815 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 Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Fri Apr 26 22:44:05 2013 +0200
@@ -34,16 +34,10 @@
public HighTier() {
if (GraalOptions.FullUnroll) {
addPhase(new LoopFullUnrollPhase());
- if (GraalOptions.OptCanonicalizer) {
- addPhase(new CanonicalizerPhase());
- }
}
if (GraalOptions.OptTailDuplication) {
addPhase(new TailDuplicationPhase());
- if (GraalOptions.OptCanonicalizer) {
- addPhase(new CanonicalizerPhase());
- }
}
if (GraalOptions.PartialEscapeAnalysis) {
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Fri Apr 26 22:44:05 2013 +0200
@@ -47,7 +47,8 @@
private int deletedNodeCount;
private GraphEventLog eventLog;
- InputChangedListener inputChanged;
+ NodeChangedListener inputChanged;
+ NodeChangedListener usagesDroppedZero;
private final HashMap cachedNodes = new HashMap<>();
private static final class CacheEntry {
@@ -152,12 +153,12 @@
return node;
}
- public interface InputChangedListener {
+ public interface NodeChangedListener {
- void inputChanged(Node node);
+ void nodeChanged(Node node);
}
- public void trackInputChange(InputChangedListener inputChangedListener) {
+ public void trackInputChange(NodeChangedListener inputChangedListener) {
this.inputChanged = inputChangedListener;
}
@@ -165,6 +166,14 @@
inputChanged = null;
}
+ public void trackUsagesDroppedZero(NodeChangedListener usagesDroppedZeroListener) {
+ this.usagesDroppedZero = usagesDroppedZeroListener;
+ }
+
+ public void stopTrackingUsagesDroppedZero() {
+ usagesDroppedZero = null;
+ }
+
/**
* Adds a new node to the graph, if a similar node already exists in the graph, the
* provided node will not be added to the graph but the similar node will be returned
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Fri Apr 26 22:44:05 2013 +0200
@@ -25,7 +25,7 @@
import java.lang.annotation.*;
import java.util.*;
-import com.oracle.graal.graph.Graph.InputChangedListener;
+import com.oracle.graal.graph.Graph.NodeChangedListener;
import com.oracle.graal.graph.NodeClass.*;
import com.oracle.graal.graph.iterators.*;
@@ -193,12 +193,17 @@
assert assertTrue(result, "not found in usages, old input: %s", oldInput);
}
if (newInput != null) {
- InputChangedListener inputChanged = graph.inputChanged;
+ NodeChangedListener inputChanged = graph.inputChanged;
if (inputChanged != null) {
- inputChanged.inputChanged(this);
+ inputChanged.nodeChanged(this);
}
assert newInput.usages != null : "not yet added? " + newInput;
newInput.usages.add(this);
+ } else if (oldInput != null && oldInput.usages().isEmpty()) {
+ NodeChangedListener nodeChangedListener = graph.usagesDroppedZero;
+ if (nodeChangedListener != null) {
+ nodeChangedListener.nodeChanged(oldInput);
+ }
}
}
}
@@ -253,9 +258,9 @@
boolean result = usage.getNodeClass().replaceFirstInput(usage, this, other);
assert assertTrue(result, "not found in inputs, usage: %s", usage);
if (other != null) {
- InputChangedListener inputChanged = graph.inputChanged;
+ NodeChangedListener inputChanged = graph.inputChanged;
if (inputChanged != null) {
- inputChanged.inputChanged(usage);
+ inputChanged.nodeChanged(usage);
}
other.usages.add(usage);
}
@@ -299,6 +304,12 @@
for (Node input : inputs()) {
removeThisFromUsages(input);
+ if (input.usages().isEmpty()) {
+ NodeChangedListener nodeChangedListener = graph.usagesDroppedZero;
+ if (nodeChangedListener != null) {
+ nodeChangedListener.nodeChanged(input);
+ }
+ }
}
getNodeClass().clearInputs(this);
}
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Fri Apr 26 22:44:05 2013 +0200
@@ -27,6 +27,7 @@
import static com.oracle.graal.api.code.ValueUtil.*;
import static com.oracle.graal.hotspot.amd64.AMD64HotSpotUnwindOp.*;
+import java.lang.reflect.*;
import java.util.*;
import com.oracle.graal.amd64.*;
@@ -234,6 +235,7 @@
} else {
assert invokeKind == InvokeKind.Static || invokeKind == InvokeKind.Special;
HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) callTarget.target();
+ assert !Modifier.isAbstract(resolvedMethod.getModifiers()) : "Cannot make direct call to abstract method.";
Constant metaspaceMethod = resolvedMethod.getMetaspaceMethodConstant();
append(new AMD64HotspotDirectStaticCallOp(callTarget.target(), result, parameters, temps, callState, invokeKind, metaspaceMethod));
}
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java Fri Apr 26 22:44:05 2013 +0200
@@ -84,8 +84,8 @@
long nonVectorBytes = byteLength % VECTOR_SIZE;
long srcOffset = (long) srcPos * elementSize;
long destOffset = (long) destPos * elementSize;
- if (src == dest && srcPos < destPos) { // bad aliased case
- probability(NOT_FREQUENT_PROBABILITY);
+ if (probability(NOT_FREQUENT_PROBABILITY, src == dest) && probability(NOT_FREQUENT_PROBABILITY, srcPos < destPos)) {
+ // bad aliased case
for (long i = byteLength - elementSize; i >= byteLength - nonVectorBytes; i -= elementSize) {
UnsafeStoreNode.store(dest, header, i + destOffset, UnsafeLoadNode.load(src, header, i + srcOffset, baseKind), baseKind);
}
@@ -107,7 +107,6 @@
public static void checkNonNull(Object obj) {
if (obj == null) {
- probability(DEOPT_PATH_PROBABILITY);
checkNPECounter.inc();
DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
}
@@ -116,7 +115,6 @@
public static int checkArrayType(Word hub) {
int layoutHelper = readLayoutHelper(hub);
if (layoutHelper >= 0) {
- probability(DEOPT_PATH_PROBABILITY);
DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
}
return layoutHelper;
@@ -124,27 +122,22 @@
public static void checkLimits(Object src, int srcPos, Object dest, int destPos, int length) {
if (srcPos < 0) {
- probability(DEOPT_PATH_PROBABILITY);
checkAIOOBECounter.inc();
DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
}
if (destPos < 0) {
- probability(DEOPT_PATH_PROBABILITY);
checkAIOOBECounter.inc();
DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
}
if (length < 0) {
- probability(DEOPT_PATH_PROBABILITY);
checkAIOOBECounter.inc();
DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
}
if (srcPos + length > ArrayLengthNode.arrayLength(src)) {
- probability(DEOPT_PATH_PROBABILITY);
checkAIOOBECounter.inc();
DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
}
if (destPos + length > ArrayLengthNode.arrayLength(dest)) {
- probability(DEOPT_PATH_PROBABILITY);
checkAIOOBECounter.inc();
DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
}
@@ -278,13 +271,10 @@
int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask();
final boolean isObjectArray = ((layoutHelper & layoutHelperElementTypePrimitiveInPlace()) == 0);
- if (srcHub.equal(destHub) && src != dest) {
- probability(FAST_PATH_PROBABILITY);
-
+ if (probability(FAST_PATH_PROBABILITY, srcHub.equal(destHub)) && probability(FAST_PATH_PROBABILITY, src != dest)) {
checkLimits(src, srcPos, dest, destPos, length);
- if (isObjectArray) {
+ if (probability(FAST_PATH_PROBABILITY, isObjectArray)) {
genericObjectExactCallCounter.inc();
- probability(FAST_PATH_PROBABILITY);
arrayObjectCopy(src, srcPos, dest, destPos, length);
} else {
genericPrimitiveCallCounter.inc();
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java Fri Apr 26 22:44:05 2013 +0200
@@ -65,13 +65,11 @@
*/
@Snippet
public static Object checkcastExact(Object object, Word exactHub, @ConstantParameter boolean checkNull) {
- if (checkNull && object == null) {
- probability(NOT_FREQUENT_PROBABILITY);
+ if (checkNull && probability(NOT_FREQUENT_PROBABILITY, object == null)) {
isNull.inc();
} else {
Word objectHub = loadHub(object);
if (objectHub.notEqual(exactHub)) {
- probability(DEOPT_PATH_PROBABILITY);
exactMiss.inc();
DeoptimizeNode.deopt(InvalidateReprofile, ClassCastException);
}
@@ -92,13 +90,11 @@
*/
@Snippet
public static Object checkcastPrimary(Word hub, Object object, @ConstantParameter int superCheckOffset, @ConstantParameter boolean checkNull) {
- if (checkNull && object == null) {
- probability(NOT_FREQUENT_PROBABILITY);
+ if (checkNull && probability(NOT_FREQUENT_PROBABILITY, object == null)) {
isNull.inc();
} else {
Word objectHub = loadHub(object);
if (objectHub.readWord(superCheckOffset, FINAL_LOCATION).notEqual(hub)) {
- probability(DEOPT_PATH_PROBABILITY);
displayMiss.inc();
DeoptimizeNode.deopt(InvalidateReprofile, ClassCastException);
}
@@ -113,8 +109,7 @@
*/
@Snippet
public static Object checkcastSecondary(Word hub, Object object, @VarargsParameter Word[] hints, @ConstantParameter boolean checkNull) {
- if (checkNull && object == null) {
- probability(NOT_FREQUENT_PROBABILITY);
+ if (checkNull && probability(NOT_FREQUENT_PROBABILITY, object == null)) {
isNull.inc();
} else {
Word objectHub = loadHub(object);
@@ -142,8 +137,7 @@
*/
@Snippet
public static Object checkcastDynamic(Word hub, Object object, @ConstantParameter boolean checkNull) {
- if (checkNull && object == null) {
- probability(NOT_FREQUENT_PROBABILITY);
+ if (checkNull && probability(NOT_FREQUENT_PROBABILITY, object == null)) {
isNull.inc();
} else {
Word objectHub = loadHub(object);
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSnippetUtils.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSnippetUtils.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSnippetUtils.java Fri Apr 26 22:44:05 2013 +0200
@@ -608,11 +608,9 @@
// this code is independent from biased locking (although it does not look that way)
final Word biasedLock = mark.and(biasedLockMaskInPlace());
- if (biasedLock.equal(Word.unsigned(unlockedMask()))) {
- probability(FAST_PATH_PROBABILITY);
+ if (probability(FAST_PATH_PROBABILITY, biasedLock.equal(Word.unsigned(unlockedMask())))) {
int hash = (int) mark.unsignedShiftRight(identityHashCodeShift()).rawValue();
- if (hash != uninitializedIdentityHashCodeValue()) {
- probability(FAST_PATH_PROBABILITY);
+ if (probability(FAST_PATH_PROBABILITY, hash != uninitializedIdentityHashCodeValue())) {
return hash;
}
}
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Fri Apr 26 22:44:05 2013 +0200
@@ -58,14 +58,12 @@
*/
@Snippet
public static Object instanceofExact(Object object, Word exactHub, Object trueValue, Object falseValue, @ConstantParameter boolean checkNull) {
- if (checkNull && object == null) {
- probability(NOT_FREQUENT_PROBABILITY);
+ if (checkNull && probability(NOT_FREQUENT_PROBABILITY, object == null)) {
isNull.inc();
return falseValue;
}
Word objectHub = loadHub(object);
- if (objectHub.notEqual(exactHub)) {
- probability(LIKELY_PROBABILITY);
+ if (probability(LIKELY_PROBABILITY, objectHub.notEqual(exactHub))) {
exactMiss.inc();
return falseValue;
}
@@ -78,14 +76,12 @@
*/
@Snippet
public static Object instanceofPrimary(Word hub, Object object, @ConstantParameter int superCheckOffset, Object trueValue, Object falseValue, @ConstantParameter boolean checkNull) {
- if (checkNull && object == null) {
- probability(NOT_FREQUENT_PROBABILITY);
+ if (checkNull && probability(NOT_FREQUENT_PROBABILITY, object == null)) {
isNull.inc();
return falseValue;
}
Word objectHub = loadHub(object);
- if (objectHub.readWord(superCheckOffset, FINAL_LOCATION).notEqual(hub)) {
- probability(NOT_LIKELY_PROBABILITY);
+ if (probability(NOT_LIKELY_PROBABILITY, objectHub.readWord(superCheckOffset, FINAL_LOCATION).notEqual(hub))) {
displayMiss.inc();
return falseValue;
}
@@ -99,8 +95,7 @@
@Snippet
public static Object instanceofSecondary(Word hub, Object object, @VarargsParameter Word[] hints, @VarargsParameter boolean[] hintIsPositive, Object trueValue, Object falseValue,
@ConstantParameter boolean checkNull) {
- if (checkNull && object == null) {
- probability(NOT_FREQUENT_PROBABILITY);
+ if (checkNull && probability(NOT_FREQUENT_PROBABILITY, object == null)) {
isNull.inc();
return falseValue;
}
@@ -110,8 +105,7 @@
for (int i = 0; i < hints.length; i++) {
Word hintHub = hints[i];
boolean positive = hintIsPositive[i];
- if (hintHub.equal(objectHub)) {
- probability(NOT_FREQUENT_PROBABILITY);
+ if (probability(NOT_FREQUENT_PROBABILITY, hintHub.equal(objectHub))) {
hintsHit.inc();
return positive ? trueValue : falseValue;
}
@@ -127,8 +121,7 @@
*/
@Snippet
public static Object instanceofDynamic(Class mirror, Object object, Object trueValue, Object falseValue, @ConstantParameter boolean checkNull) {
- if (checkNull && object == null) {
- probability(NOT_FREQUENT_PROBABILITY);
+ if (checkNull && probability(NOT_FREQUENT_PROBABILITY, object == null)) {
isNull.inc();
return falseValue;
}
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Fri Apr 26 22:44:05 2013 +0200
@@ -102,10 +102,9 @@
final Word biasableLockBits = mark.and(biasedLockMaskInPlace());
// First check to see whether biasing is enabled for this object
- if (biasableLockBits.notEqual(Word.unsigned(biasedLockPattern()))) {
+ if (probability(NOT_FREQUENT_PROBABILITY, biasableLockBits.notEqual(Word.unsigned(biasedLockPattern())))) {
// Biasing not enabled -> fall through to lightweight locking
} else {
- probability(FREQUENT_PROBABILITY);
// The bias pattern is present in the object's mark word. Need to check
// whether the bias owner and the epoch are both still current.
Word hub = loadHub(object);
@@ -115,9 +114,8 @@
trace(trace, "prototypeMarkWord: 0x%016lx\n", prototypeMarkWord);
trace(trace, " thread: 0x%016lx\n", thread);
trace(trace, " tmp: 0x%016lx\n", tmp);
- if (tmp.equal(0)) {
+ if (probability(FREQUENT_PROBABILITY, tmp.equal(0))) {
// Object is already biased to current thread -> done
- probability(FREQUENT_PROBABILITY);
traceObject(trace, "+lock{bias:existing}", object);
return;
}
@@ -131,8 +129,7 @@
// If the low three bits in the xor result aren't clear, that means
// the prototype header is no longer biasable and we have to revoke
// the bias on this object.
- if (tmp.and(biasedLockMaskInPlace()).equal(0)) {
- probability(FREQUENT_PROBABILITY);
+ if (probability(FREQUENT_PROBABILITY, tmp.and(biasedLockMaskInPlace()).equal(0))) {
// Biasing is still enabled for object's type. See whether the
// epoch of the current bias is still valid, meaning that the epoch
// bits of the mark word are equal to the epoch bits of the
@@ -142,8 +139,7 @@
// that the current epoch is invalid in order to do this because
// otherwise the manipulations it performs on the mark word are
// illegal.
- if (tmp.and(epochMaskInPlace()).equal(0)) {
- probability(FREQUENT_PROBABILITY);
+ if (probability(FREQUENT_PROBABILITY, tmp.and(epochMaskInPlace()).equal(0))) {
// The epoch of the current bias is still valid but we know nothing
// about the owner; it might be set or it might be clear. Try to
// acquire the bias of the object using an atomic operation. If this
@@ -154,7 +150,7 @@
Word biasedMark = unbiasedMark.or(thread);
trace(trace, " unbiasedMark: 0x%016lx\n", unbiasedMark);
trace(trace, " biasedMark: 0x%016lx\n", biasedMark);
- if (compareAndSwap(object, markOffset(), unbiasedMark, biasedMark, MARK_WORD_LOCATION).equal(unbiasedMark)) {
+ if (probability(VERY_FAST_DEOPT_PATH_PROBABILITY, compareAndSwap(object, markOffset(), unbiasedMark, biasedMark, MARK_WORD_LOCATION).equal(unbiasedMark))) {
// Object is now biased to current thread -> done
traceObject(trace, "+lock{bias:acquired}", object);
return;
@@ -162,7 +158,6 @@
// If the biasing toward our thread failed, this means that another thread
// owns the bias and we need to revoke that bias. The revocation will occur
// in the interpreter runtime.
- probability(DEOPT_PATH_PROBABILITY);
traceObject(trace, "+lock{stub:revoke}", object);
MonitorEnterStubCall.call(object, lock);
return;
@@ -175,7 +170,7 @@
// the bias from one thread to another directly in this situation.
Word biasedMark = prototypeMarkWord.or(thread);
trace(trace, " biasedMark: 0x%016lx\n", biasedMark);
- if (compareAndSwap(object, markOffset(), mark, biasedMark, MARK_WORD_LOCATION).equal(mark)) {
+ if (probability(VERY_FAST_DEOPT_PATH_PROBABILITY, compareAndSwap(object, markOffset(), mark, biasedMark, MARK_WORD_LOCATION).equal(mark))) {
// Object is now biased to current thread -> done
traceObject(trace, "+lock{bias:transfer}", object);
return;
@@ -183,7 +178,6 @@
// If the biasing toward our thread failed, then another thread
// succeeded in biasing it toward itself and we need to revoke that
// bias. The revocation will occur in the runtime in the slow case.
- probability(DEOPT_PATH_PROBABILITY);
traceObject(trace, "+lock{stub:epoch-expired}", object);
MonitorEnterStubCall.call(object, lock);
return;
@@ -239,9 +233,8 @@
// significant 2 bits cleared and page_size is a power of 2
final Word alignedMask = Word.unsigned(wordSize() - 1);
final Word stackPointer = stackPointer();
- if (currentMark.subtract(stackPointer).and(alignedMask.subtract(pageSize())).notEqual(0)) {
+ if (probability(VERY_SLOW_PATH_PROBABILITY, currentMark.subtract(stackPointer).and(alignedMask.subtract(pageSize())).notEqual(0))) {
// Most likely not a recursive lock, go into a slow runtime call
- probability(DEOPT_PATH_PROBABILITY);
traceObject(trace, "+lock{stub:failed-cas}", object);
MonitorEnterStubCall.call(object, lock);
return;
@@ -290,8 +283,7 @@
// the bias bit would be clear.
final Word mark = loadWordFromObject(object, markOffset());
trace(trace, " mark: 0x%016lx\n", mark);
- if (mark.and(biasedLockMaskInPlace()).equal(Word.unsigned(biasedLockPattern()))) {
- probability(FREQUENT_PROBABILITY);
+ if (probability(FREQUENT_PROBABILITY, mark.and(biasedLockMaskInPlace()).equal(Word.unsigned(biasedLockPattern())))) {
endLockScope();
decCounter();
traceObject(trace, "-lock{bias}", object);
@@ -313,10 +305,9 @@
// Test if object's mark word is pointing to the displaced mark word, and if so, restore
// the displaced mark in the object - if the object's mark word is not pointing to
// the displaced mark word, do unlocking via runtime call.
- if (DirectCompareAndSwapNode.compareAndSwap(object, markOffset(), lock, displacedMark, MARK_WORD_LOCATION).notEqual(lock)) {
+ if (probability(VERY_SLOW_PATH_PROBABILITY, DirectCompareAndSwapNode.compareAndSwap(object, markOffset(), lock, displacedMark, MARK_WORD_LOCATION).notEqual(lock))) {
// The object's mark word was not pointing to the displaced header,
// we do unlocking via runtime call.
- probability(DEOPT_PATH_PROBABILITY);
traceObject(trace, "-lock{stub}", object);
MonitorExitStubCall.call(object);
} else {
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Fri Apr 26 22:44:05 2013 +0200
@@ -64,8 +64,7 @@
* this check might lead to problems if the TLAB is within 16GB of the address space end
* (checked in c++ code)
*/
- if (newTop.belowOrEqual(end)) {
- probability(FAST_PATH_PROBABILITY);
+ if (probability(FAST_PATH_PROBABILITY, newTop.belowOrEqual(end))) {
writeTlabTop(thread, newTop);
return top;
}
@@ -76,11 +75,10 @@
public static Object initializeObject(Word memory, Word hub, Word prototypeMarkWord, @ConstantParameter int size, @ConstantParameter boolean fillContents, @ConstantParameter boolean locked) {
Object result;
- if (memory.equal(0)) {
+ if (probability(SLOW_PATH_PROBABILITY, memory.equal(0))) {
new_stub.inc();
result = NewInstanceStubCall.call(hub);
} else {
- probability(FAST_PATH_PROBABILITY);
if (locked) {
formatObject(hub, size, memory, thread().or(biasedLockPattern()), fillContents);
} else {
@@ -108,11 +106,10 @@
private static Object initializeArray(Word memory, Word hub, int length, int allocationSize, Word prototypeMarkWord, int headerSize, boolean fillContents) {
Object result;
- if (memory.equal(0)) {
+ if (probability(SLOW_PATH_PROBABILITY, memory.equal(0))) {
newarray_stub.inc();
result = NewArrayStubCall.call(hub, length);
} else {
- probability(FAST_PATH_PROBABILITY);
newarray_loopInit.inc();
formatArray(hub, allocationSize, length, headerSize, memory, prototypeMarkWord, fillContents);
result = memory.toObject();
@@ -130,7 +127,6 @@
public static Object allocateArrayAndInitialize(int length, @ConstantParameter int alignment, @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize,
@ConstantParameter boolean fillContents, @ConstantParameter ResolvedJavaType type) {
if (!belowThan(length, MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH)) {
- probability(DEOPT_PATH_PROBABILITY);
// This handles both negative array sizes and very large array sizes
DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
}
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java Fri Apr 26 22:44:05 2013 +0200
@@ -84,7 +84,6 @@
private static Word getAndCheckHub(Object src) {
Word hub = loadHub(src);
if (!(src instanceof Cloneable)) {
- probability(DEOPT_PATH_PROBABILITY);
DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
}
return hub;
@@ -110,8 +109,7 @@
genericCloneCounter.inc();
Word hub = getAndCheckHub(src);
int layoutHelper = hub.readInt(layoutHelperOffset(), FINAL_LOCATION);
- if (layoutHelper < 0) {
- probability(LIKELY_PROBABILITY);
+ if (probability(LIKELY_PROBABILITY, layoutHelper < 0)) {
genericArrayCloneCounter.inc();
return arrayClone(src, hub, layoutHelper);
} else {
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemSubstitutions.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemSubstitutions.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemSubstitutions.java Fri Apr 26 22:44:05 2013 +0200
@@ -56,8 +56,7 @@
@MethodSubstitution
public static int identityHashCode(Object x) {
- if (x == null) {
- probability(NOT_FREQUENT_PROBABILITY);
+ if (probability(NOT_FREQUENT_PROBABILITY, x == null)) {
return 0;
}
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java Fri Apr 26 22:44:05 2013 +0200
@@ -89,8 +89,7 @@
Word secondarySupers = s.readWord(secondarySupersOffset(), SECONDARY_SUPERS_LOCATION);
int length = secondarySupers.readInt(metaspaceArrayLengthOffset(), FINAL_LOCATION);
for (int i = 0; i < length; i++) {
- if (t.equal(loadSecondarySupersElement(secondarySupers, i))) {
- probability(NOT_LIKELY_PROBABILITY);
+ if (probability(NOT_LIKELY_PROBABILITY, t.equal(loadSecondarySupersElement(secondarySupers, i)))) {
s.writeWord(secondarySuperCacheOffset(), t, SECONDARY_SUPER_CACHE_LOCATION);
secondariesHit.inc();
return true;
diff -r 52fde777a605 -r f43d04388815 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 Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Fri Apr 26 22:44:05 2013 +0200
@@ -34,7 +34,6 @@
import com.oracle.graal.api.code.*;
import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType;
import com.oracle.graal.api.meta.ProfilingInfo.TriState;
import com.oracle.graal.api.meta.ResolvedJavaType.Representation;
import com.oracle.graal.bytecode.*;
@@ -798,12 +797,7 @@
if (!optimisticOpts.useTypeCheckHints() || !canHaveSubtype(type)) {
return null;
} else {
- ResolvedJavaType uniqueSubtype = type.findUniqueConcreteSubtype();
- if (uniqueSubtype != null) {
- return new JavaTypeProfile(profilingInfo.getNullSeen(bci()), 0.0D, new ProfiledType(uniqueSubtype, 1.0D));
- } else {
- return profilingInfo.getTypeProfile(bci());
- }
+ return profilingInfo.getTypeProfile(bci());
}
}
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/reflect/Reflection_getCallerClass01.java
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/reflect/Reflection_getCallerClass01.java Fri Apr 26 22:43:37 2013 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2007, 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.jtt.reflect;
-
-import com.oracle.graal.jtt.*;
-import org.junit.*;
-
-import sun.reflect.*;
-
-/*
- */
-public final class Reflection_getCallerClass01 extends JTTTest {
-
- public static final class Caller1 {
-
- private Caller1() {
- }
-
- static String caller1(int depth) {
- return Reflection.getCallerClass(depth).getName();
- }
- }
-
- public static final class Caller2 {
-
- private Caller2() {
- }
-
- static String caller2(int depth) {
- return Caller1.caller1(depth);
- }
- }
-
- public static String test(int depth) {
- return Caller2.caller2(depth);
- }
-
- @Test
- public void run0() throws Throwable {
- runTest("test", 0);
- }
-
- @Test
- public void run1() throws Throwable {
- runTest("test", 1);
- }
-
- @Test
- public void run2() throws Throwable {
- runTest("test", 2);
- }
-
-}
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Fri Apr 26 22:44:05 2013 +0200
@@ -22,6 +22,8 @@
*/
package com.oracle.graal.nodes.java;
+import java.lang.reflect.*;
+
import com.oracle.graal.api.meta.*;
import com.oracle.graal.graph.*;
import com.oracle.graal.nodes.*;
@@ -102,6 +104,14 @@
for (Node n : usages()) {
assertTrue(n instanceof Invoke, "call target can only be used from an invoke (%s)", n);
}
+ if (invokeKind == InvokeKind.Special || invokeKind == InvokeKind.Static) {
+ assertFalse(Modifier.isAbstract(targetMethod.getModifiers()), "special calls or static calls are only allowed for concrete methods (%s)", targetMethod);
+ }
+ if (invokeKind == InvokeKind.Static) {
+ assertTrue(Modifier.isStatic(targetMethod.getModifiers()), "static calls are only allowed for static methods (%s)", targetMethod);
+ } else {
+ assertFalse(Modifier.isStatic(targetMethod.getModifiers()), "static calls are only allowed for non-static methods (%s)", targetMethod);
+ }
return super.verify();
}
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Fri Apr 26 22:44:05 2013 +0200
@@ -22,14 +22,13 @@
*/
package com.oracle.graal.phases.common;
-import java.util.*;
import java.util.concurrent.*;
import com.oracle.graal.api.code.*;
import com.oracle.graal.api.meta.*;
import com.oracle.graal.debug.*;
import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.Graph.InputChangedListener;
+import com.oracle.graal.graph.Graph.NodeChangedListener;
import com.oracle.graal.nodes.*;
import com.oracle.graal.nodes.calc.*;
import com.oracle.graal.nodes.spi.*;
@@ -49,6 +48,7 @@
public static final DebugMetric METRIC_GLOBAL_VALUE_NUMBERING_HITS = Debug.metric("GlobalValueNumberingHits");
private final CustomCanonicalizer customCanonicalizer;
+ private final Iterable workingSet;
public interface CustomCanonicalizer {
@@ -60,12 +60,17 @@
}
public CanonicalizerPhase(CustomCanonicalizer customCanonicalizer) {
+ this(customCanonicalizer, null);
+ }
+
+ public CanonicalizerPhase(CustomCanonicalizer customCanonicalizer, Iterable workingSet) {
this.customCanonicalizer = customCanonicalizer;
+ this.workingSet = workingSet;
}
@Override
protected void run(StructuredGraph graph, PhaseContext context) {
- new Instance(context.getRuntime(), context.getAssumptions(), null, customCanonicalizer).run(graph);
+ new Instance(context.getRuntime(), context.getAssumptions(), workingSet, customCanonicalizer).run(graph);
}
public static class Instance extends Phase {
@@ -78,7 +83,6 @@
private NodeWorkList workList;
private Tool tool;
- private List snapshotTemp;
public Instance(MetaAccessProvider runtime, Assumptions assumptions) {
this(runtime, assumptions, null, 0, null);
@@ -110,7 +114,6 @@
this.runtime = runtime;
this.customCanonicalizer = customCanonicalizer;
this.initWorkingSet = workingSet;
- this.snapshotTemp = new ArrayList<>();
}
@Override
@@ -129,19 +132,22 @@
}
private void processWorkSet(StructuredGraph graph) {
- graph.trackInputChange(new InputChangedListener() {
+ NodeChangedListener nodeChangedListener = new NodeChangedListener() {
@Override
- public void inputChanged(Node node) {
+ public void nodeChanged(Node node) {
workList.addAgain(node);
}
- });
+ };
+ graph.trackInputChange(nodeChangedListener);
+ graph.trackUsagesDroppedZero(nodeChangedListener);
for (Node n : workList) {
processNode(n, graph);
}
graph.stopTrackingInputChange();
+ graph.stopTrackingUsagesDroppedZero();
}
private void processNode(Node node, StructuredGraph graph) {
@@ -153,17 +159,9 @@
}
int mark = graph.getMark();
if (!tryKillUnused(node)) {
- node.inputs().filter(GraphUtil.isFloatingNode()).snapshotTo(snapshotTemp);
if (!tryCanonicalize(node, graph)) {
tryInferStamp(node, graph);
- } else {
- for (Node in : snapshotTemp) {
- if (in.isAlive() && in.usages().isEmpty()) {
- GraphUtil.killWithUnusedFloatingInputs(in);
- }
- }
}
- snapshotTemp.clear();
}
for (Node newNode : graph.getNewNodes(mark)) {
diff -r 52fde777a605 -r f43d04388815 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 Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Fri Apr 26 22:44:05 2013 +0200
@@ -42,6 +42,7 @@
import com.oracle.graal.nodes.type.*;
import com.oracle.graal.nodes.util.*;
import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.tiers.*;
public class InliningUtil {
@@ -254,6 +255,10 @@
Class extends FixedWithNextNode> macroNodeClass = getMacroNodeClass(replacements, concrete);
StructuredGraph graph = (StructuredGraph) invoke.asNode().graph();
if (macroNodeClass != null) {
+ if (((MethodCallTargetNode) invoke.callTarget()).targetMethod() != concrete) {
+ assert ((MethodCallTargetNode) invoke.callTarget()).invokeKind() != InvokeKind.Static;
+ InliningUtil.replaceInvokeCallTarget(invoke, graph, InvokeKind.Special, concrete);
+ }
FixedWithNextNode macroNode;
try {
macroNode = macroNodeClass.getConstructor(Invoke.class).newInstance(invoke);
@@ -294,12 +299,12 @@
}
});
}
+ }
- protected void replaceInvokeCallTarget(StructuredGraph graph, InvokeKind invokeKind, ResolvedJavaMethod targetMethod) {
- MethodCallTargetNode oldCallTarget = (MethodCallTargetNode) invoke.callTarget();
- MethodCallTargetNode newCallTarget = graph.add(new MethodCallTargetNode(invokeKind, targetMethod, oldCallTarget.arguments().toArray(new ValueNode[0]), oldCallTarget.returnType()));
- invoke.asNode().replaceFirstInput(oldCallTarget, newCallTarget);
- }
+ public static void replaceInvokeCallTarget(Invoke invoke, StructuredGraph graph, InvokeKind invokeKind, ResolvedJavaMethod targetMethod) {
+ MethodCallTargetNode oldCallTarget = (MethodCallTargetNode) invoke.callTarget();
+ MethodCallTargetNode newCallTarget = graph.add(new MethodCallTargetNode(invokeKind, targetMethod, oldCallTarget.arguments().toArray(new ValueNode[0]), oldCallTarget.returnType()));
+ invoke.asNode().replaceFirstInput(oldCallTarget, newCallTarget);
}
/**
@@ -378,7 +383,7 @@
@Override
public void tryToDevirtualizeInvoke(StructuredGraph graph, MetaAccessProvider runtime, Assumptions assumptions) {
createGuard(graph, runtime);
- replaceInvokeCallTarget(graph, InvokeKind.Special, concrete);
+ replaceInvokeCallTarget(invoke, graph, InvokeKind.Special, concrete);
}
private void createGuard(StructuredGraph graph, MetaAccessProvider runtime) {
@@ -446,7 +451,7 @@
if (hasSingleMethod()) {
inlineSingleMethod(graph, callback, replacements, assumptions);
} else {
- inlineMultipleMethods(graph, callback, replacements, assumptions);
+ inlineMultipleMethods(graph, callback, replacements, assumptions, runtime);
}
}
@@ -458,7 +463,7 @@
return notRecordedTypeProbability > 0;
}
- private void inlineMultipleMethods(StructuredGraph graph, InliningCallback callback, Replacements replacements, Assumptions assumptions) {
+ private void inlineMultipleMethods(StructuredGraph graph, InliningCallback callback, Replacements replacements, Assumptions assumptions, MetaAccessProvider runtime) {
int numberOfMethods = concretes.size();
FixedNode continuation = invoke.next();
@@ -560,7 +565,7 @@
if (opportunities > 0) {
metricInliningTailDuplication.increment();
Debug.log("MultiTypeGuardInlineInfo starting tail duplication (%d opportunities)", opportunities);
- TailDuplicationPhase.tailDuplicate(returnMerge, TailDuplicationPhase.TRUE_DECISION, replacementNodes);
+ TailDuplicationPhase.tailDuplicate(returnMerge, TailDuplicationPhase.TRUE_DECISION, replacementNodes, new HighTierContext(runtime, assumptions, replacements));
}
}
}
@@ -730,7 +735,7 @@
ValueNode receiver = ((MethodCallTargetNode) invoke.callTarget()).receiver();
PiNode anchoredReceiver = createAnchoredReceiver(graph, invocationEntry, target.getDeclaringClass(), receiver, false);
invoke.callTarget().replaceFirstInput(receiver, anchoredReceiver);
- replaceInvokeCallTarget(graph, kind, target);
+ replaceInvokeCallTarget(invoke, graph, kind, target);
}
private static BeginNode createUnknownTypeSuccessor(StructuredGraph graph) {
@@ -775,15 +780,13 @@
@Override
public void inline(StructuredGraph graph, MetaAccessProvider runtime, Replacements replacements, InliningCallback callback, Assumptions assumptions) {
assumptions.record(takenAssumption);
- Debug.log("recording assumption: %s", takenAssumption);
-
super.inline(graph, runtime, replacements, callback, assumptions);
}
@Override
public void tryToDevirtualizeInvoke(StructuredGraph graph, MetaAccessProvider runtime, Assumptions assumptions) {
assumptions.record(takenAssumption);
- replaceInvokeCallTarget(graph, InvokeKind.Special, concrete);
+ replaceInvokeCallTarget(invoke, graph, InvokeKind.Special, concrete);
}
@Override
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java Fri Apr 26 22:44:05 2013 +0200
@@ -24,7 +24,7 @@
import java.util.*;
-import com.oracle.graal.graph.Graph.InputChangedListener;
+import com.oracle.graal.graph.Graph.NodeChangedListener;
import com.oracle.graal.graph.*;
import com.oracle.graal.nodes.*;
import com.oracle.graal.phases.*;
@@ -49,7 +49,7 @@
}
}
- private static class Listener implements InputChangedListener {
+ private static class Listener implements NodeChangedListener {
private final Set canonicalizationRoots;
@@ -58,7 +58,7 @@
}
@Override
- public void inputChanged(Node node) {
+ public void nodeChanged(Node node) {
canonicalizationRoots.add(node);
}
}
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java Fri Apr 26 22:44:05 2013 +0200
@@ -36,13 +36,14 @@
import com.oracle.graal.nodes.util.*;
import com.oracle.graal.phases.*;
import com.oracle.graal.phases.graph.*;
+import com.oracle.graal.phases.tiers.*;
/**
* This class is a phase that looks for opportunities for tail duplication. The static method
- * {@link #tailDuplicate(MergeNode, TailDuplicationDecision, List)} can also be used to drive tail
- * duplication from other places, e.g., inlining.
+ * {@link #tailDuplicate(MergeNode, TailDuplicationDecision, List, PhaseContext)} can also be used
+ * to drive tail duplication from other places, e.g., inlining.
*/
-public class TailDuplicationPhase extends Phase {
+public class TailDuplicationPhase extends BasePhase {
/*
* Various metrics on the circumstances in which tail duplication was/wasn't performed.
@@ -129,14 +130,14 @@
};
@Override
- protected void run(StructuredGraph graph) {
+ protected void run(StructuredGraph graph, PhaseContext phaseContext) {
NodesToDoubles nodeProbabilities = new ComputeProbabilityClosure(graph).apply();
// A snapshot is taken here, so that new MergeNode instances aren't considered for tail
// duplication.
for (MergeNode merge : graph.getNodes(MergeNode.class).snapshot()) {
if (!(merge instanceof LoopBeginNode) && nodeProbabilities.get(merge) >= GraalOptions.TailDuplicationProbability) {
- tailDuplicate(merge, DEFAULT_DECISION, null);
+ tailDuplicate(merge, DEFAULT_DECISION, null, phaseContext);
}
}
}
@@ -156,8 +157,9 @@
* size needs to match the merge's end count. Each entry can either be null or a
* {@link PiNode}, and is used to replace {@link PiNode#object()} with the
* {@link PiNode} in the duplicated branch that corresponds to the entry.
+ * @param phaseContext
*/
- public static boolean tailDuplicate(MergeNode merge, TailDuplicationDecision decision, List replacements) {
+ public static boolean tailDuplicate(MergeNode merge, TailDuplicationDecision decision, List replacements, PhaseContext phaseContext) {
assert !(merge instanceof LoopBeginNode);
assert replacements == null || replacements.size() == merge.forwardEndCount();
FixedNode fixed = merge;
@@ -171,14 +173,14 @@
metricDuplicationEnd.increment();
if (decision.doTransform(merge, fixedCount)) {
metricDuplicationEndPerformed.increment();
- new DuplicationOperation(merge, replacements).duplicate();
+ new DuplicationOperation(merge, replacements).duplicate(phaseContext);
return true;
}
} else if (merge.stateAfter() != null) {
metricDuplicationOther.increment();
if (decision.doTransform(merge, fixedCount)) {
metricDuplicationOtherPerformed.increment();
- new DuplicationOperation(merge, replacements).duplicate();
+ new DuplicationOperation(merge, replacements).duplicate(phaseContext);
return true;
}
}
@@ -220,10 +222,14 @@
* Determines the complete set of duplicated nodes.
* Performs the actual duplication.
*
+ *
+ * @param phaseContext
*/
- private void duplicate() {
+ private void duplicate(PhaseContext phaseContext) {
Debug.log("tail duplication at merge %s in %s", merge, graph.method());
+ int startMark = graph.getMark();
+
ValueAnchorNode anchor = addValueAnchor();
// determine the fixed nodes that should be duplicated (currently: all nodes up until
@@ -297,6 +303,7 @@
phi.setMerge(mergeAfter);
}
}
+ new CanonicalizerPhase(null, graph.getNewNodes(startMark)).apply(graph, phaseContext);
Debug.dump(graph, "After tail duplication at %s", merge);
}
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java
--- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java Fri Apr 26 22:44:05 2013 +0200
@@ -57,8 +57,7 @@
*/
@Snippet
public static int f2i(float input, int result) {
- if (result == Integer.MIN_VALUE) {
- probability(NOT_FREQUENT_PROBABILITY);
+ if (probability(SLOW_PATH_PROBABILITY, result == Integer.MIN_VALUE)) {
if (Float.isNaN(input)) {
// input is NaN -> return 0
return 0;
@@ -83,8 +82,7 @@
*/
@Snippet
public static long f2l(float input, long result) {
- if (result == Long.MIN_VALUE) {
- probability(NOT_FREQUENT_PROBABILITY);
+ if (probability(SLOW_PATH_PROBABILITY, result == Long.MIN_VALUE)) {
if (Float.isNaN(input)) {
// input is NaN -> return 0
return 0;
@@ -109,8 +107,7 @@
*/
@Snippet
public static int d2i(double input, int result) {
- if (result == Integer.MIN_VALUE) {
- probability(NOT_FREQUENT_PROBABILITY);
+ if (probability(SLOW_PATH_PROBABILITY, result == Integer.MIN_VALUE)) {
if (Double.isNaN(input)) {
// input is NaN -> return 0
return 0;
@@ -135,8 +132,7 @@
*/
@Snippet
public static long d2l(double input, long result) {
- if (result == Long.MIN_VALUE) {
- probability(NOT_FREQUENT_PROBABILITY);
+ if (probability(SLOW_PATH_PROBABILITY, result == Long.MIN_VALUE)) {
if (Double.isNaN(input)) {
// input is NaN -> return 0
return 0;
diff -r 52fde777a605 -r f43d04388815 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 Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Fri Apr 26 22:44:05 2013 +0200
@@ -282,6 +282,7 @@
if (!SnippetTemplate.hasConstantParameter(method)) {
NodeIntrinsificationVerificationPhase.verify(graph);
}
+ new ConvertDeoptimizeToGuardPhase().apply(graph);
if (original == null) {
new SnippetFrameStateCleanupPhase().apply(graph);
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BranchProbabilityNode.java
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BranchProbabilityNode.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BranchProbabilityNode.java Fri Apr 26 22:44:05 2013 +0200
@@ -22,17 +22,17 @@
*/
package com.oracle.graal.replacements.nodes;
+import com.oracle.graal.graph.*;
import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.nodes.util.*;
/**
* Instances of this node class will look for a preceding if node and put the given probability into
* the if node's taken probability. Then the branch probability node will be removed. This node is
* intended primarily for snippets, so that they can define their fast and slow paths.
*/
-public class BranchProbabilityNode extends FixedWithNextNode implements Simplifiable {
+public class BranchProbabilityNode extends FloatingNode implements Canonicalizable, Lowerable {
public static final double LIKELY_PROBABILITY = 0.6;
public static final double NOT_LIKELY_PROBABILITY = 1 - LIKELY_PROBABILITY;
@@ -43,41 +43,80 @@
public static final double FAST_PATH_PROBABILITY = 0.99;
public static final double SLOW_PATH_PROBABILITY = 1 - FAST_PATH_PROBABILITY;
- public static final double NOT_DEOPT_PATH_PROBABILITY = 0.999;
- public static final double DEOPT_PATH_PROBABILITY = 1 - NOT_DEOPT_PATH_PROBABILITY;
+ public static final double VERY_FAST_DEOPT_PATH_PROBABILITY = 0.999;
+ public static final double VERY_SLOW_PATH_PROBABILITY = 1 - VERY_FAST_DEOPT_PATH_PROBABILITY;
- private final double probability;
+ @Input private ValueNode probability;
+ @Input private ValueNode condition;
- public BranchProbabilityNode(double probability) {
- super(StampFactory.forVoid());
- assert probability >= 0 && probability <= 1;
+ public BranchProbabilityNode(ValueNode probability, ValueNode condition) {
+ super(condition.stamp());
this.probability = probability;
+ this.condition = condition;
+ }
+
+ public ValueNode getProbability() {
+ return probability;
+ }
+
+ public ValueNode getCondition() {
+ return condition;
}
@Override
- public void simplify(SimplifierTool tool) {
- FixedNode current = this;
- while (!(current instanceof BeginNode)) {
- current = (FixedNode) current.predecessor();
+ public ValueNode canonical(CanonicalizerTool tool) {
+ if (probability.isConstant()) {
+ double probabilityValue = probability.asConstant().asDouble();
+ if (probabilityValue < 0.0) {
+ throw new GraalInternalError("A negative probability of " + probabilityValue + " is not allowed!");
+ } else if (probabilityValue > 1.0) {
+ throw new GraalInternalError("A probability of more than 1.0 (" + probabilityValue + ") is not allowed!");
+ }
+ boolean couldSet = false;
+ for (IntegerEqualsNode node : this.usages().filter(IntegerEqualsNode.class)) {
+ if (node.condition() == Condition.EQ) {
+ ValueNode other = node.x();
+ if (node.x() == this) {
+ other = node.y();
+ }
+ if (other.isConstant()) {
+ double probabilityToSet = probabilityValue;
+ if (other.asConstant().asInt() == 0) {
+ probabilityToSet = 1.0 - probabilityToSet;
+ }
+ for (IfNode ifNodeUsages : node.usages().filter(IfNode.class)) {
+ couldSet = true;
+ ifNodeUsages.setTrueSuccessorProbability(probabilityToSet);
+ }
+ }
+ }
+ }
+ if (!couldSet) {
+ throw new GraalInternalError("Wrong usage of branch probability injection!");
+ }
+ return condition;
}
- BeginNode begin = (BeginNode) current;
- assert begin.predecessor() instanceof IfNode : "explicit branch probability cannot follow a merge, only if nodes";
- IfNode ifNode = (IfNode) begin.predecessor();
- if (ifNode.trueSuccessor() == begin) {
- ifNode.setTrueSuccessorProbability(probability);
- } else {
- ifNode.setTrueSuccessorProbability(1 - probability);
- }
-
- FixedNode next = next();
- setNext(null);
- ((FixedWithNextNode) predecessor()).setNext(next);
- GraphUtil.killCFG(this);
+ return this;
}
- @SuppressWarnings("unused")
+ /**
+ * This intrinsic should only be used for the condition of an if statement. The parameter
+ * condition should also only denote a simple condition and not a combined condition involving
+ * && or || operators. It injects the probability of the condition into the if statement.
+ *
+ * @param probability the probability that the given condition is true as a double value between
+ * 0.0 and 1.0.
+ * @param condition the simple condition without any && or || operators
+ * @return the condition
+ */
@NodeIntrinsic
- public static void probability(@ConstantNodeParameter double probability) {
+ public static boolean probability(double probability, boolean condition) {
+ assert probability >= 0.0 && probability <= 1.0;
+ return condition;
}
+ @Override
+ public void lower(LoweringTool tool, LoweringType loweringType) {
+ throw new GraalInternalError("Branch probability could not be injected, because the probability value did not reduce to a constant value.");
+ }
}
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Fri Apr 26 22:44:05 2013 +0200
@@ -71,6 +71,7 @@
StructuredGraph snippetGraph = getSnippetGraph(tool);
InvokeNode invoke = replaceWithInvoke();
+ assert invoke.verify();
if (snippetGraph != null) {
InliningUtil.inline(invoke, snippetGraph, false);
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/TypeSystemTest.java
--- a/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/TypeSystemTest.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/TypeSystemTest.java Fri Apr 26 22:44:05 2013 +0200
@@ -115,7 +115,7 @@
@Override
public Object execute(VirtualFrame frame) {
invocationCount++;
- return ((TestArguments) frame.getArguments()).get(index);
+ return frame.getArguments(TestArguments.class).get(index);
}
}
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ArgumentsTest.java
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ArgumentsTest.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ArgumentsTest.java Fri Apr 26 22:44:05 2013 +0200
@@ -35,7 +35,7 @@
* A guest language can pass its own custom arguments when invoking a Truffle method by creating a
* subclass of {@link Arguments}. When invoking a call target with
* {@link CallTarget#call(Arguments)}, the arguments can be passed. A Truffle node can access the
- * arguments passed into the Truffle method by using {@link VirtualFrame#getArguments()}.
+ * arguments passed into the Truffle method by using {@link VirtualFrame#getArguments}.
*
*
*
@@ -97,7 +97,7 @@
}
int execute(VirtualFrame frame) {
- return ((TestArguments) frame.getArguments()).values[index];
+ return frame.getArguments(TestArguments.class).values[index];
}
}
}
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameSlotTypeSpecializationTest.java
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameSlotTypeSpecializationTest.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameSlotTypeSpecializationTest.java Fri Apr 26 22:44:05 2013 +0200
@@ -34,7 +34,7 @@
*
* Dynamically typed languages can speculate on the type of a frame slot and only fall back at run
* time to a more generic type if necessary. The new type of a frame slot can be set using the
- * {@link FrameSlot#setType(Class)} method.
+ * {@link FrameSlot#setKind(FrameSlotKind)} method.
*
*
*
@@ -48,13 +48,13 @@
public void test() {
TruffleRuntime runtime = Truffle.getRuntime();
FrameDescriptor frameDescriptor = new FrameDescriptor();
- FrameSlot slot = frameDescriptor.addFrameSlot("localVar", int.class);
+ FrameSlot slot = frameDescriptor.addFrameSlot("localVar", FrameSlotKind.Int);
TestRootNode rootNode = new TestRootNode(new IntAssignLocal(slot, new StringTestChildNode()), new IntReadLocal(slot));
CallTarget target = runtime.createCallTarget(rootNode, frameDescriptor);
- Assert.assertEquals(int.class, slot.getType());
+ Assert.assertEquals(FrameSlotKind.Int, slot.getKind());
Object result = target.call();
Assert.assertEquals("42", result);
- Assert.assertEquals(Object.class, slot.getType());
+ Assert.assertEquals(FrameSlotKind.Object, slot.getKind());
}
class TestRootNode extends RootNode {
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java Fri Apr 26 22:44:05 2013 +0200
@@ -35,9 +35,9 @@
* The frame is the preferred data structure for passing values between nodes. It can in particular
* be used for storing the values of local variables of the guest language. The
* {@link FrameDescriptor} represents the current structure of the frame. The method
- * {@link FrameDescriptor#addFrameSlot(Object, Class)} can be used to create predefined frame slots.
- * The setter and getter methods in the {@link Frame} class can be used to access the current value
- * of a particular frame slot.
+ * {@link FrameDescriptor#addFrameSlot(Object, FrameSlotKind)} can be used to create predefined
+ * frame slots. The setter and getter methods in the {@link Frame} class can be used to access the
+ * current value of a particular frame slot.
*
*
*
@@ -64,7 +64,7 @@
public void test() {
TruffleRuntime runtime = Truffle.getRuntime();
FrameDescriptor frameDescriptor = new FrameDescriptor();
- FrameSlot slot = frameDescriptor.addFrameSlot("localVar", int.class);
+ FrameSlot slot = frameDescriptor.addFrameSlot("localVar", FrameSlotKind.Int);
TestRootNode rootNode = new TestRootNode(new AssignLocal(slot), new ReadLocal(slot));
CallTarget target = runtime.createCallTarget(rootNode, frameDescriptor);
Object result = target.call();
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReturnTypeSpecializationTest.java
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReturnTypeSpecializationTest.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReturnTypeSpecializationTest.java Fri Apr 26 22:44:05 2013 +0200
@@ -47,13 +47,13 @@
public void test() {
TruffleRuntime runtime = Truffle.getRuntime();
FrameDescriptor frameDescriptor = new FrameDescriptor();
- FrameSlot slot = frameDescriptor.addFrameSlot("localVar", int.class);
+ FrameSlot slot = frameDescriptor.addFrameSlot("localVar", FrameSlotKind.Int);
TestRootNode rootNode = new TestRootNode(new IntAssignLocal(slot, new StringTestChildNode()), new IntReadLocal(slot));
CallTarget target = runtime.createCallTarget(rootNode, frameDescriptor);
- Assert.assertEquals(int.class, slot.getType());
+ Assert.assertEquals(FrameSlotKind.Int, slot.getKind());
Object result = target.call();
Assert.assertEquals("42", result);
- Assert.assertEquals(Object.class, slot.getType());
+ Assert.assertEquals(FrameSlotKind.Object, slot.getKind());
}
class TestRootNode extends RootNode {
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java Fri Apr 26 22:44:05 2013 +0200
@@ -22,6 +22,7 @@
*/
package com.oracle.truffle.api;
+import java.lang.annotation.*;
import java.util.concurrent.*;
/**
@@ -30,7 +31,11 @@
*/
public class CompilerDirectives {
- private static final double SLOWPATH_PROBABILITY = 0.0001;
+ public static final double LIKELY_PROBABILITY = 0.75;
+ public static final double UNLIKELY_PROBABILITY = 1.0 - LIKELY_PROBABILITY;
+
+ public static final double SLOWPATH_PROBABILITY = 0.0001;
+ public static final double FASTPATH_PROBABILITY = 1.0 - SLOWPATH_PROBABILITY;
/**
* Directive for the compiler to discontinue compilation at this code position and instead
@@ -62,20 +67,38 @@
}
/**
- * Directive for the compiler that the current path has a very low probability to be executed.
- */
- public static void slowpath() {
- injectBranchProbability(SLOWPATH_PROBABILITY);
- }
-
- /**
- * Injects a probability for the current path into the probability information of the
- * immediately preceeding branch instruction.
+ * Injects a probability for the given condition into the probability information of the
+ * immediately succeeding branch instruction for the condition. The probability must be a value
+ * between 0.0 and 1.0 (inclusive). The condition should not be a combined condition.
+ *
+ * Example usage immediately before an if statement (it specifies that the likelihood for a to
+ * be greater than b is 90%):
+ *
+ *
+ * if (injectBranchProbability(0.9, a > b)) {
+ * // ...
+ * }
+ *
+ *
+ * Example usage for a combined condition (it specifies that the likelihood for a to be greater
+ * than b is 90% and under the assumption that this is true, the likelihood for a being 0 is
+ * 10%):
+ *
+ *
+ * if (injectBranchProbability(0.9, a > b) && injectBranchProbability(0.1, a == 0)) {
+ * // ...
+ * }
+ *
+ *
+ * There are predefined constants for commonly used probabilities (see
+ * {@link #LIKELY_PROBABILITY} , {@link #UNLIKELY_PROBABILITY}, {@link #SLOWPATH_PROBABILITY},
+ * {@link #FASTPATH_PROBABILITY} ).
*
* @param probability the probability value between 0.0 and 1.0 that should be injected
*/
- public static void injectBranchProbability(double probability) {
+ public static boolean injectBranchProbability(double probability, boolean condition) {
assert probability >= 0.0 && probability <= 1.0;
+ return condition;
}
/**
@@ -85,4 +108,13 @@
*/
public static void bailout(String reason) {
}
+
+ /**
+ * Marks fields that should be considered final for a Truffle compilation although they are not
+ * final while executing in the interpreter.
+ */
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target({ElementType.FIELD})
+ public @interface CompilationFinal {
+ }
}
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/SourceSection.java
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/SourceSection.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/SourceSection.java Fri Apr 26 22:44:05 2013 +0200
@@ -117,4 +117,10 @@
public final String getCode() {
return getSource().getCode().substring(charIndex, charLength);
}
+
+ @Override
+ public String toString() {
+ return String.format("%s:%d", source.getName(), startLine);
+ }
+
}
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/Frame.java
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/Frame.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/Frame.java Fri Apr 26 22:44:05 2013 +0200
@@ -36,9 +36,16 @@
FrameDescriptor getFrameDescriptor();
/**
+ * Retrieves the arguments object from this frame. The runtime assumes that the arguments object
+ * is never null. Additionally, the runtime may assume that the given parameter indicating the
+ * class of the arguments object is correct. The runtime is not required to actually check the
+ * type of the arguments object. The parameter must be a value that can be reduced to a compile
+ * time constant.
+ *
+ * @param clazz the known type of the arguments object as a compile time constant
* @return the arguments used when calling this method
*/
- Arguments getArguments();
+ T getArguments(Class clazz);
/**
* Read access to a local variable of type {@link Object}.
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java Fri Apr 26 22:44:05 2013 +0200
@@ -53,9 +53,9 @@
return addFrameSlot(identifier, null);
}
- public FrameSlot addFrameSlot(Object identifier, Class> type) {
+ public FrameSlot addFrameSlot(Object identifier, FrameSlotKind kind) {
assert !identifierToSlotMap.containsKey(identifier);
- FrameSlotImpl slot = new FrameSlotImpl(this, identifier, slots.size(), type);
+ FrameSlotImpl slot = new FrameSlotImpl(this, identifier, slots.size(), kind);
slots.add(slot);
identifierToSlotMap.put(identifier, slot);
updateVersion();
@@ -74,12 +74,12 @@
return addFrameSlot(identifier);
}
- public FrameSlot findOrAddFrameSlot(Object identifier, Class> type) {
+ public FrameSlot findOrAddFrameSlot(Object identifier, FrameSlotKind kind) {
FrameSlot result = findFrameSlot(identifier);
if (result != null) {
return result;
}
- return addFrameSlot(identifier, type);
+ return addFrameSlot(identifier, kind);
}
public int getSize() {
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlot.java
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlot.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlot.java Fri Apr 26 22:44:05 2013 +0200
@@ -31,9 +31,9 @@
int getIndex();
- Class> getType();
+ FrameSlotKind getKind();
- void setType(Class> type);
+ void setKind(FrameSlotKind kind);
FrameDescriptor getFrameDescriptor();
}
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotImpl.java
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotImpl.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotImpl.java Fri Apr 26 22:44:05 2013 +0200
@@ -27,13 +27,13 @@
private final FrameDescriptor descriptor;
private final Object identifier;
private final int index;
- private Class> type;
+ private FrameSlotKind kind;
- protected FrameSlotImpl(FrameDescriptor descriptor, Object identifier, int index, Class> type) {
+ protected FrameSlotImpl(FrameDescriptor descriptor, Object identifier, int index, FrameSlotKind kind) {
this.descriptor = descriptor;
this.identifier = identifier;
this.index = index;
- this.type = type;
+ this.kind = kind;
}
public Object getIdentifier() {
@@ -44,19 +44,19 @@
return index;
}
- public Class> getType() {
- return type;
+ public FrameSlotKind getKind() {
+ return kind;
}
- public void setType(final Class> type) {
- assert this.type != type;
- this.type = type;
+ public void setKind(final FrameSlotKind kind) {
+ assert this.kind != kind;
+ this.kind = kind;
this.descriptor.updateVersion();
}
@Override
public String toString() {
- return "[" + index + "," + identifier + "," + type + "]";
+ return "[" + index + "," + identifier + "," + kind + "]";
}
@Override
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotKind.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotKind.java Fri Apr 26 22:44:05 2013 +0200
@@ -0,0 +1,27 @@
+/*
+ * 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.truffle.api.frame;
+
+public enum FrameSlotKind {
+ Illegal, Object, Long, Int, Double, Float, Boolean;
+}
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameUtil.java
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameUtil.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameUtil.java Fri Apr 26 22:44:05 2013 +0200
@@ -33,8 +33,8 @@
* @param value the new value of the local variable
*/
public static void setObjectSafe(Frame frame, FrameSlot slot, Object value) {
- if (slot.getType() != Object.class) {
- slot.setType(Object.class);
+ if (slot.getKind() != FrameSlotKind.Object) {
+ slot.setKind(FrameSlotKind.Object);
}
try {
frame.setObject(slot, value);
@@ -52,8 +52,8 @@
* @param value the new value of the local variable
*/
public static void setBooleanSafe(Frame frame, FrameSlot slot, boolean value) {
- if (slot.getType() != boolean.class) {
- slot.setType(boolean.class);
+ if (slot.getKind() != FrameSlotKind.Boolean) {
+ slot.setKind(FrameSlotKind.Boolean);
}
try {
frame.setBoolean(slot, value);
@@ -71,8 +71,8 @@
* @param value the new value of the local variable
*/
public static void setIntSafe(Frame frame, FrameSlot slot, int value) {
- if (slot.getType() != int.class) {
- slot.setType(int.class);
+ if (slot.getKind() != FrameSlotKind.Int) {
+ slot.setKind(FrameSlotKind.Int);
}
try {
frame.setInt(slot, value);
@@ -90,8 +90,8 @@
* @param value the new value of the local variable
*/
public static void setLongSafe(Frame frame, FrameSlot slot, long value) {
- if (slot.getType() != long.class) {
- slot.setType(long.class);
+ if (slot.getKind() != FrameSlotKind.Long) {
+ slot.setKind(FrameSlotKind.Long);
}
try {
frame.setLong(slot, value);
@@ -109,8 +109,8 @@
* @param value the new value of the local variable
*/
public static void setFloatSafe(Frame frame, FrameSlot slot, float value) {
- if (slot.getType() != float.class) {
- slot.setType(float.class);
+ if (slot.getKind() != FrameSlotKind.Float) {
+ slot.setKind(FrameSlotKind.Float);
}
try {
frame.setFloat(slot, value);
@@ -128,8 +128,8 @@
* @param value the new value of the local variable
*/
public static void setDoubleSafe(Frame frame, FrameSlot slot, double value) {
- if (slot.getType() != double.class) {
- slot.setType(double.class);
+ if (slot.getKind() != FrameSlotKind.Double) {
+ slot.setKind(FrameSlotKind.Double);
}
try {
frame.setDouble(slot, value);
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/NativeFrame.java
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/NativeFrame.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/NativeFrame.java Fri Apr 26 22:44:05 2013 +0200
@@ -38,9 +38,10 @@
this.arguments = arguments;
}
+ @SuppressWarnings("unchecked")
@Override
- public Arguments getArguments() {
- return arguments;
+ public T getArguments(Class clazz) {
+ return (T) arguments;
}
@Override
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultMaterializedFrame.java
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultMaterializedFrame.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultMaterializedFrame.java Fri Apr 26 22:44:05 2013 +0200
@@ -34,8 +34,8 @@
}
@Override
- public Arguments getArguments() {
- return wrapped.getArguments();
+ public T getArguments(Class clazz) {
+ return wrapped.getArguments(clazz);
}
@Override
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java Fri Apr 26 22:44:05 2013 +0200
@@ -33,19 +33,20 @@
private final PackedFrame caller;
private final Arguments arguments;
private Object[] locals;
- private Class[] tags;
+ private byte[] tags;
public DefaultVirtualFrame(FrameDescriptor descriptor, PackedFrame caller, Arguments arguments) {
this.descriptor = descriptor;
this.caller = caller;
this.arguments = arguments;
this.locals = new Object[descriptor.getSize()];
- this.tags = new Class[descriptor.getSize()];
+ this.tags = new byte[descriptor.getSize()];
}
+ @SuppressWarnings("unchecked")
@Override
- public Arguments getArguments() {
- return arguments;
+ public T getArguments(Class clazz) {
+ return (T) arguments;
}
@Override
@@ -65,73 +66,73 @@
@Override
public Object getObject(FrameSlot slot) throws FrameSlotTypeException {
- verifyGet(slot, Object.class);
+ verifyGet(slot, FrameSlotKind.Object);
return locals[slot.getIndex()];
}
@Override
public void setObject(FrameSlot slot, Object value) throws FrameSlotTypeException {
- verifySet(slot, Object.class);
+ verifySet(slot, FrameSlotKind.Object);
locals[slot.getIndex()] = value;
}
@Override
public boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException {
- verifyGet(slot, boolean.class);
+ verifyGet(slot, FrameSlotKind.Boolean);
return (boolean) locals[slot.getIndex()];
}
@Override
public void setBoolean(FrameSlot slot, boolean value) throws FrameSlotTypeException {
- verifySet(slot, boolean.class);
+ verifySet(slot, FrameSlotKind.Boolean);
locals[slot.getIndex()] = value;
}
@Override
public int getInt(FrameSlot slot) throws FrameSlotTypeException {
- verifyGet(slot, int.class);
+ verifyGet(slot, FrameSlotKind.Int);
return (int) locals[slot.getIndex()];
}
@Override
public void setInt(FrameSlot slot, int value) throws FrameSlotTypeException {
- verifySet(slot, int.class);
+ verifySet(slot, FrameSlotKind.Int);
locals[slot.getIndex()] = value;
}
@Override
public long getLong(FrameSlot slot) throws FrameSlotTypeException {
- verifyGet(slot, long.class);
+ verifyGet(slot, FrameSlotKind.Long);
return (long) locals[slot.getIndex()];
}
@Override
public void setLong(FrameSlot slot, long value) throws FrameSlotTypeException {
- verifySet(slot, long.class);
+ verifySet(slot, FrameSlotKind.Long);
locals[slot.getIndex()] = value;
}
@Override
public float getFloat(FrameSlot slot) throws FrameSlotTypeException {
- verifyGet(slot, float.class);
+ verifyGet(slot, FrameSlotKind.Float);
return (float) locals[slot.getIndex()];
}
@Override
public void setFloat(FrameSlot slot, float value) throws FrameSlotTypeException {
- verifySet(slot, float.class);
+ verifySet(slot, FrameSlotKind.Float);
locals[slot.getIndex()] = value;
}
@Override
public double getDouble(FrameSlot slot) throws FrameSlotTypeException {
- verifyGet(slot, double.class);
+ verifyGet(slot, FrameSlotKind.Double);
return (double) locals[slot.getIndex()];
}
@Override
public void setDouble(FrameSlot slot, double value) throws FrameSlotTypeException {
- verifySet(slot, double.class);
+ verifySet(slot, FrameSlotKind.Double);
locals[slot.getIndex()] = value;
}
@@ -147,19 +148,19 @@
assert index >= 0 && index < descriptor.getSize();
return descriptor.getTypeConversion().getDefaultValue();
}
- Class tag = tags[index];
- if (tag == null) {
+ byte tag = tags[index];
+ if (tag == FrameSlotKind.Illegal.ordinal()) {
return descriptor.getTypeConversion().getDefaultValue();
} else {
return locals[index];
}
}
- private void verifySet(FrameSlot slot, Class accessType) throws FrameSlotTypeException {
- Class> slotType = slot.getType();
- if (slotType != accessType) {
- if (slotType == null) {
- slot.setType(accessType);
+ private void verifySet(FrameSlot slot, FrameSlotKind accessKind) throws FrameSlotTypeException {
+ FrameSlotKind slotKind = slot.getKind();
+ if (slotKind != accessKind) {
+ if (slotKind == FrameSlotKind.Illegal) {
+ slot.setKind(accessKind);
} else {
throw new FrameSlotTypeException();
}
@@ -168,14 +169,14 @@
if (slotIndex >= tags.length) {
resize();
}
- tags[slotIndex] = accessType;
+ tags[slotIndex] = (byte) accessKind.ordinal();
}
- private void verifyGet(FrameSlot slot, Class accessType) throws FrameSlotTypeException {
- Class> slotType = slot.getType();
- if (slotType != accessType) {
- if (slotType == null && accessType == Object.class) {
- slot.setType(Object.class);
+ private void verifyGet(FrameSlot slot, FrameSlotKind accessKind) throws FrameSlotTypeException {
+ FrameSlotKind slotKind = slot.getKind();
+ if (slotKind != accessKind) {
+ if (slotKind == FrameSlotKind.Illegal && accessKind == FrameSlotKind.Object) {
+ slot.setKind(FrameSlotKind.Object);
this.setObject(slot, descriptor.getTypeConversion().getDefaultValue());
} else {
throw new FrameSlotTypeException();
@@ -185,9 +186,9 @@
if (slotIndex >= tags.length) {
resize();
}
- if (tags[slotIndex] != accessType) {
+ if (tags[slotIndex] != accessKind.ordinal()) {
descriptor.getTypeConversion().updateFrameSlot(this, slot, getValue(slot));
- if (tags[slotIndex] != accessType) {
+ if (tags[slotIndex] != accessKind.ordinal()) {
throw new FrameSlotTypeException();
}
}
diff -r 52fde777a605 -r f43d04388815 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/NodeFactory.java
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/NodeFactory.java Fri Apr 26 22:43:37 2013 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/NodeFactory.java Fri Apr 26 22:44:05 2013 +0200
@@ -59,7 +59,7 @@
}
public TypedNode createLocal(String name) {
- return ReadLocalNodeFactory.create(frameDescriptor.findOrAddFrameSlot(name, int.class));
+ return ReadLocalNodeFactory.create(frameDescriptor.findOrAddFrameSlot(name, FrameSlotKind.Int));
}
public TypedNode createStringLiteral(String value) {
@@ -67,7 +67,7 @@
}
public StatementNode createAssignment(String name, TypedNode right) {
- return WriteLocalNodeFactory.create(frameDescriptor.findOrAddFrameSlot(name, int.class), right);
+ return WriteLocalNodeFactory.create(frameDescriptor.findOrAddFrameSlot(name, FrameSlotKind.Int), right);
}
public StatementNode createPrint(List expressions) {
@@ -123,7 +123,7 @@
}
public StatementNode createReturn(TypedNode value) {
- FrameSlot slot = frameDescriptor.findOrAddFrameSlot("", int.class);
+ FrameSlot slot = frameDescriptor.findOrAddFrameSlot("", FrameSlotKind.Int);
if (returnValue == null) {
returnValue = ReadLocalNodeFactory.create(slot);
}
diff -r 52fde777a605 -r f43d04388815 mx/sanitycheck.py
--- a/mx/sanitycheck.py Fri Apr 26 22:43:37 2013 +0200
+++ b/mx/sanitycheck.py Fri Apr 26 22:44:05 2013 +0200
@@ -47,7 +47,8 @@
}
dacapoScalaSanityWarmup = {
- 'actors': [0, 0, 2, 8, 10],
+# (tw) actors sometimes fails verification; hardly reproducible
+ 'actors': [0, 0, 0, 0, 0],
# (lstadler) apparat was disabled due to a deadlock which I think is the benchmarks fault.
'apparat': [0, 0, 0, 0, 0],
'factorie': [0, 0, 2, 5, 5],