# HG changeset patch
# User Thomas Wuerthinger
# Date 1363219783 -3600
# Node ID ff91c7101ed0af8ee2b99a4982835d3f3ee556ae
# Parent 53683dc2815ec57d555285538df64800644918f0# Parent 1d40b7e8823b62c3cc33b8b62a24c47d92d43593
Merge.
diff -r 53683dc2815e -r ff91c7101ed0 GRAAL_AUTHORS
--- a/GRAAL_AUTHORS Thu Mar 14 01:09:32 2013 +0100
+++ b/GRAAL_AUTHORS Thu Mar 14 01:09:43 2013 +0100
@@ -1,9 +1,12 @@
Gilles Duboscq (gdub)
Peter Hofer
+Christian Haeubl (chaeubl)
+Christian Humer (chumer)
+Roland Schatz
+Doug Simon (dnsimon)
+Lukas Stadler (lstadler)
Alexander Stipsits
Katrin Strassl
-Christian Humer (chumer)
Christian Wimmer (cwimmer)
-Doug Simon (dnsimon)
-Lukas Stadler (lstadler)
+Andreas Woess (aw)
Thomas Wuerthinger (thomaswue)
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Thu Mar 14 01:09:32 2013 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Thu Mar 14 01:09:43 2013 +0100
@@ -221,7 +221,7 @@
return method.invoke(receiver, args);
}
- static class Result {
+ protected static class Result {
final Object returnValue;
final Throwable exception;
@@ -263,7 +263,10 @@
before();
Object[] executeArgs = argsWithReceiver(receiver, args);
- InstalledCode compiledMethod = getCode(runtime.lookupJavaMethod(method), parse(method));
+ ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(method);
+ checkArgs(javaMethod, executeArgs);
+
+ InstalledCode compiledMethod = getCode(javaMethod, parse(method));
try {
return new Result(compiledMethod.executeVarargs(executeArgs), null);
} catch (Throwable e) {
@@ -273,6 +276,25 @@
}
}
+ protected void checkArgs(ResolvedJavaMethod method, Object[] args) {
+ JavaType[] sig = MetaUtil.signatureToTypes(method);
+ Assert.assertEquals(sig.length, args.length);
+ for (int i = 0; i < args.length; i++) {
+ JavaType javaType = sig[i];
+ Kind kind = javaType.getKind();
+ Object arg = args[i];
+ if (kind == Kind.Object) {
+ if (arg != null && javaType instanceof ResolvedJavaType) {
+ ResolvedJavaType resolvedJavaType = (ResolvedJavaType) javaType;
+ Assert.assertTrue(resolvedJavaType + " from " + runtime.lookupJavaType(arg.getClass()), resolvedJavaType.isAssignableFrom(runtime.lookupJavaType(arg.getClass())));
+ }
+ } else {
+ Assert.assertNotNull(arg);
+ Assert.assertEquals(kind.toBoxedJavaClass(), arg.getClass());
+ }
+ }
+ }
+
/**
* Prepends a non-null receiver argument to a given list or args.
*
@@ -296,16 +318,28 @@
Method method = getMethod(name);
Object receiver = Modifier.isStatic(method.getModifiers()) ? null : this;
+ test(method, receiver, args);
+ }
+
+ protected void test(Method method, Object receiver, Object... args) {
Result expect = executeExpected(method, receiver, args);
if (runtime == null) {
return;
}
+ test(method, expect, receiver, args);
+ }
+
+ protected void test(Method method, Result expect, Object receiver, Object... args) {
Result actual = executeActual(method, receiver, args);
if (expect.exception != null) {
Assert.assertTrue("expected " + expect.exception, actual.exception != null);
Assert.assertEquals(expect.exception.getClass(), actual.exception.getClass());
} else {
+ if (actual.exception != null) {
+ actual.exception.printStackTrace();
+ Assert.fail("expected " + expect.returnValue + " but got an exception");
+ }
assertEquals(expect.returnValue, actual.returnValue);
}
}
@@ -360,8 +394,7 @@
GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
editPhasePlan(method, graph, phasePlan);
- CompilationResult compResult = GraalCompiler.compileMethod(runtime(), backend, runtime().getTarget(), method, graph, null, phasePlan, OptimisticOptimizations.ALL,
- new SpeculationLog());
+ CompilationResult compResult = GraalCompiler.compileMethod(runtime(), backend, runtime().getTarget(), method, graph, null, phasePlan, OptimisticOptimizations.ALL, new SpeculationLog());
if (printCompilation) {
TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s | %4dms %5dB", id, "", "", "", System.currentTimeMillis() - start, compResult.getTargetCodeSize()));
}
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Thu Mar 14 01:09:32 2013 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Thu Mar 14 01:09:43 2013 +0100
@@ -282,7 +282,6 @@
* @return the created interval
*/
Interval createInterval(Value operand) {
- assert isProcessed(operand);
assert isLegal(operand);
int operandNumber = operandNumber(operand);
Interval interval = new Interval(operand, operandNumber);
@@ -1951,12 +1950,6 @@
throw new GraalInternalError("");
}
- if (!isProcessed(i1.location())) {
- TTY.println("Can not have an Interval for an ignored register " + i1.location());
- TTY.println(i1.logString(this));
- throw new GraalInternalError("");
- }
-
if (i1.first() == Range.EndMarker) {
TTY.println("Interval %d has no Range", i1.operandNumber);
TTY.println(i1.logString(this));
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java Thu Mar 14 01:09:32 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java Thu Mar 14 01:09:43 2013 +0100
@@ -33,15 +33,12 @@
import com.oracle.graal.api.meta.*;
import com.oracle.graal.graph.*;
import com.oracle.graal.hotspot.*;
+import com.oracle.graal.phases.*;
// @formatter:off
public class AMD64HotSpotRegisterConfig implements RegisterConfig {
- private final Register[] allocatable = {
- rax, rbx, rcx, rdx, /*rsp,*/ rbp, rsi, rdi, r8, r9, /* r10, */r11, r12, r13, r14, /*r15, */
- xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
- xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
- };
+ private final Register[] allocatable = initAllocatable();
private final EnumMap categorized = Register.categorize(allocatable);
@@ -68,6 +65,34 @@
private final CalleeSaveLayout csl;
+ private static Register findRegister(String name, Register[] all) {
+ for (Register reg : all) {
+ if (reg.name.equals(name)) {
+ return reg;
+ }
+ }
+ throw new IllegalArgumentException("register " + name + " is not allocatable");
+ }
+
+ private static Register[] initAllocatable() {
+ Register[] allocatable = {
+ rax, rbx, rcx, rdx, /*rsp,*/ rbp, rsi, rdi, r8, r9, /* r10, */r11, r12, r13, r14, /*r15, */
+ xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
+ xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
+ };
+
+ if (GraalOptions.RegisterPressure != null) {
+ String[] names = GraalOptions.RegisterPressure.split(",");
+ Register[] regs = new Register[names.length];
+ for (int i = 0; i < names.length; i++) {
+ regs[i] = findRegister(names[i], allocatable);
+ }
+ return regs;
+ }
+
+ return allocatable;
+ }
+
public AMD64HotSpotRegisterConfig(HotSpotVMConfig config, boolean globalStubConfig) {
if (config.windowsOs) {
javaGeneralParameterRegisters = new Register[] {rdx, r8, r9, rdi, rsi, rcx};
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java Thu Mar 14 01:09:32 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java Thu Mar 14 01:09:43 2013 +0100
@@ -41,11 +41,6 @@
public static final Descriptor UNWIND_EXCEPTION = new Descriptor("unwindException", true, void.class, Object.class);
- /**
- * Vtable stubs expect the metaspace Method in RBX.
- */
- public static final Register METHOD = AMD64.rbx;
-
@Use({REG}) protected AllocatableValue exception;
@Temp private RegisterValue framePointer;
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Thu Mar 14 01:09:32 2013 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Thu Mar 14 01:09:43 2013 +0100
@@ -22,6 +22,8 @@
*/
package com.oracle.graal.java;
+import static com.oracle.graal.api.code.DeoptimizationAction.*;
+import static com.oracle.graal.api.meta.DeoptimizationReason.*;
import static com.oracle.graal.bytecode.Bytecodes.*;
import static java.lang.reflect.Modifier.*;
@@ -52,7 +54,7 @@
/**
* The {@code GraphBuilder} class parses the bytecode of a method and builds the IR graph.
*/
-public final class GraphBuilderPhase extends Phase {
+public class GraphBuilderPhase extends Phase {
public static final class RuntimeCalls {
@@ -72,7 +74,7 @@
*/
public static final int TRACELEVEL_STATE = 2;
- private StructuredGraph currentGraph;
+ protected StructuredGraph currentGraph;
private final MetaAccessProvider runtime;
private ConstantPool constantPool;
@@ -82,7 +84,7 @@
private BytecodeStream stream; // the bytecode stream
- private FrameStateBuilder frameState; // the current execution state
+ protected FrameStateBuilder frameState; // the current execution state
private Block currentBlock;
private ValueNode methodSynchronizedObject;
@@ -279,7 +281,7 @@
* @param type the unresolved type of the constant
*/
protected void handleUnresolvedLoadConstant(JavaType type) {
- append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved)));
+ append(currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved)));
frameState.push(Kind.Object, append(ConstantNode.forObject(null, runtime, currentGraph)));
}
@@ -288,7 +290,7 @@
* @param object the object value whose type is being checked against {@code type}
*/
protected void handleUnresolvedCheckCast(JavaType type, ValueNode object) {
- append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new IsNullNode(object)), DeoptimizationReason.Unresolved, DeoptimizationAction.InvalidateRecompile)));
+ append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new IsNullNode(object)), Unresolved, InvalidateRecompile)));
frameState.apush(appendConstant(Constant.NULL_OBJECT));
}
@@ -298,7 +300,7 @@
*/
protected void handleUnresolvedInstanceOf(JavaType type, ValueNode object) {
BlockPlaceholderNode successor = currentGraph.add(new BlockPlaceholderNode());
- DeoptimizeNode deopt = currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved));
+ DeoptimizeNode deopt = currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved));
IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new IsNullNode(object)), successor, deopt, 1));
append(ifNode);
lastInstr = successor;
@@ -309,7 +311,7 @@
* @param type the type being instantiated
*/
protected void handleUnresolvedNewInstance(JavaType type) {
- append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved)));
+ append(currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved)));
frameState.apush(appendConstant(Constant.NULL_OBJECT));
}
@@ -318,7 +320,7 @@
* @param length the length of the array
*/
protected void handleUnresolvedNewObjectArray(JavaType type, ValueNode length) {
- append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved)));
+ append(currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved)));
frameState.apush(appendConstant(Constant.NULL_OBJECT));
}
@@ -327,7 +329,7 @@
* @param dims the dimensions for the multi-array
*/
protected void handleUnresolvedNewMultiArray(JavaType type, ValueNode[] dims) {
- append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved)));
+ append(currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved)));
frameState.apush(appendConstant(Constant.NULL_OBJECT));
}
@@ -337,7 +339,7 @@
*/
protected void handleUnresolvedLoadField(JavaField field, ValueNode receiver) {
Kind kind = field.getKind();
- append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved)));
+ append(currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved)));
frameState.push(kind.getStackKind(), append(ConstantNode.defaultForKind(kind, currentGraph)));
}
@@ -347,7 +349,7 @@
* @param receiver the object containing the field or {@code null} if {@code field} is static
*/
protected void handleUnresolvedStoreField(JavaField field, ValueNode value, ValueNode receiver) {
- append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved)));
+ append(currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved)));
}
/**
@@ -355,12 +357,12 @@
* @param type
*/
protected void handleUnresolvedExceptionType(Representation representation, JavaType type) {
- append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved)));
+ append(currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved)));
}
protected void handleUnresolvedInvoke(JavaMethod javaMethod, InvokeKind invokeKind) {
boolean withReceiver = invokeKind != InvokeKind.Static;
- append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved)));
+ append(currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved)));
frameState.popArguments(javaMethod.getSignature().getParameterSlots(withReceiver), javaMethod.getSignature().getParameterCount(withReceiver));
Kind kind = javaMethod.getSignature().getReturnKind();
if (kind != Kind.Void) {
@@ -733,8 +735,7 @@
private void genThrow() {
ValueNode exception = frameState.apop();
- FixedGuardNode node = currentGraph.add(new FixedGuardNode(currentGraph.unique(new IsNullNode(exception)), DeoptimizationReason.NullCheckException, DeoptimizationAction.InvalidateReprofile,
- true));
+ FixedGuardNode node = currentGraph.add(new FixedGuardNode(currentGraph.unique(new IsNullNode(exception)), NullCheckException, InvalidateReprofile, true));
append(node);
append(handleException(exception, bci()));
}
@@ -826,7 +827,7 @@
/**
* Gets the kind of array elements for the array type code that appears in a
* {@link Bytecodes#NEWARRAY} bytecode.
- *
+ *
* @param code the array type code
* @return the kind from the array type code
*/
@@ -1109,7 +1110,7 @@
private void appendInvoke(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] args) {
Kind resultType = targetMethod.getSignature().getReturnKind();
if (GraalOptions.DeoptALot) {
- DeoptimizeNode deoptimize = currentGraph.add(new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint));
+ DeoptimizeNode deoptimize = currentGraph.add(new DeoptimizeNode(DeoptimizationAction.None, RuntimeConstraint));
append(deoptimize);
frameState.pushReturn(resultType, ConstantNode.defaultForKind(resultType, currentGraph));
return;
@@ -1190,8 +1191,7 @@
ValueNode local = frameState.loadLocal(localIndex);
JsrScope scope = currentBlock.jsrScope;
int retAddress = scope.nextReturnAddress();
- append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new IntegerEqualsNode(local, ConstantNode.forInt(retAddress, currentGraph))), DeoptimizationReason.JavaSubroutineMismatch,
- DeoptimizationAction.InvalidateReprofile)));
+ append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new IntegerEqualsNode(local, ConstantNode.forInt(retAddress, currentGraph))), JavaSubroutineMismatch, InvalidateReprofile)));
if (!successor.jsrScope.equals(scope.pop())) {
throw new JsrNotSupportedBailout("unstructured control flow (ret leaves more than one scope)");
}
@@ -1224,7 +1224,7 @@
/**
* Helper function that sums up the probabilities of all keys that lead to a specific successor.
- *
+ *
* @return an array of size successorCount with the accumulated probability for each successor.
*/
private static double[] successorProbabilites(int successorCount, int[] keySuccessors, double[] keyProbabilities) {
@@ -1391,7 +1391,7 @@
private FixedNode createTarget(double probability, Block block, FrameStateBuilder stateAfter) {
assert probability >= 0 && probability <= 1.01 : probability;
if (isNeverExecutedCode(probability)) {
- return currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.UnreachedCode));
+ return currentGraph.add(new DeoptimizeNode(InvalidateReprofile, UnreachedCode));
} else {
assert block != null;
return createTarget(block, stateAfter);
@@ -1553,7 +1553,10 @@
private void createUnwind() {
assert frameState.stackSize() == 1 : frameState;
synchronizedEpilogue(FrameState.AFTER_EXCEPTION_BCI);
- UnwindNode unwindNode = currentGraph.add(new UnwindNode(frameState.apop()));
+ ValueNode exception = frameState.apop();
+ FixedGuardNode guard = currentGraph.add(new FixedGuardNode(currentGraph.unique(new IsNullNode(exception)), NullCheckException, InvalidateReprofile, true));
+ append(guard);
+ UnwindNode unwindNode = currentGraph.add(new UnwindNode(exception));
append(unwindNode);
}
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/JTTTest.java
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/JTTTest.java Thu Mar 14 01:09:32 2013 +0100
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/JTTTest.java Thu Mar 14 01:09:43 2013 +0100
@@ -48,6 +48,10 @@
*/
Object[] argsToBind;
+ public JTTTest() {
+ Assert.assertNotNull(runtime);
+ }
+
@Override
protected StructuredGraph parse(Method m) {
StructuredGraph graph = super.parse(m);
@@ -89,10 +93,14 @@
}
protected void runTest(String name, Object... args) {
- // System.out.println(getClass().getSimpleName() + "." + name);
- super.test(name, args);
+ Method method = getMethod(name);
+ Object receiver = Modifier.isStatic(method.getModifiers()) ? null : this;
+
+ Result expect = executeExpected(method, receiver, args);
+
+ test(method, expect, receiver, args);
this.argsToBind = args;
- super.test(name, args);
+ test(method, expect, receiver, args);
this.argsToBind = null;
}
}
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/except/Except_Synchronized05.java
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/except/Except_Synchronized05.java Thu Mar 14 01:09:32 2013 +0100
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/except/Except_Synchronized05.java Thu Mar 14 01:09:43 2013 +0100
@@ -29,29 +29,11 @@
public class Except_Synchronized05 extends JTTTest {
- Object field;
-
- public static int test(int arg) {
- Except_Synchronized05 obj = new Except_Synchronized05();
- int a = obj.bar(arg) != null ? 1 : 0;
- int b = obj.baz(arg) != null ? 1 : 0;
- return a + b;
- }
+ static class Foo {
- public synchronized Object bar(int arg) {
- try {
- String f = foo1(arg);
- if (f == null) {
- field = new Object();
- }
- } catch (NullPointerException e) {
- // do nothing
- }
- return field;
- }
+ Object field;
- public Object baz(int arg) {
- synchronized (this) {
+ public synchronized Object bar(int arg) {
try {
String f = foo1(arg);
if (f == null) {
@@ -62,14 +44,36 @@
}
return field;
}
+
+ public Object baz(int arg) {
+ synchronized (this) {
+ try {
+ String f = foo1(arg);
+ if (f == null) {
+ field = new Object();
+ }
+ } catch (NullPointerException e) {
+ // do nothing
+ }
+ return field;
+ }
+ }
+
+ @SuppressWarnings("static-method")
+ private String foo1(int arg) {
+ if (arg == 0) {
+ throw null;
+ }
+ return null;
+ }
+
}
- @SuppressWarnings("static-method")
- private String foo1(int arg) {
- if (arg == 0) {
- throw null;
- }
- return null;
+ public static int test(int arg) {
+ Foo obj = new Foo();
+ int a = obj.bar(arg) != null ? 1 : 0;
+ int b = obj.baz(arg) != null ? 1 : 0;
+ return a + b;
}
@Test
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java Thu Mar 14 01:09:32 2013 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java Thu Mar 14 01:09:43 2013 +0100
@@ -59,12 +59,19 @@
BeginNode trueSuccessor;
BeginNode falseSuccessor;
DeoptimizeNode deopt = graph.add(new DeoptimizeNode(guard.action(), guard.reason()));
+ BeginNode deoptBranch = BeginNode.begin(deopt);
+ Loop loop = block.getLoop();
+ while (loop != null) {
+ LoopExitNode exit = graph.add(new LoopExitNode(loop.loopBegin()));
+ graph.addBeforeFixed(deopt, exit);
+ loop = loop.parent;
+ }
if (guard.negated()) {
- trueSuccessor = BeginNode.begin(deopt);
+ trueSuccessor = deoptBranch;
falseSuccessor = fastPath;
} else {
trueSuccessor = fastPath;
- falseSuccessor = BeginNode.begin(deopt);
+ falseSuccessor = deoptBranch;
}
IfNode ifNode = graph.add(new IfNode(guard.condition(), trueSuccessor, falseSuccessor, trueSuccessor == fastPath ? 1 : 0));
guard.replaceAndDelete(fastPath);
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Thu Mar 14 01:09:32 2013 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Thu Mar 14 01:09:43 2013 +0100
@@ -1000,6 +1000,17 @@
return count;
}
+ static MonitorExitNode findPrecedingMonitorExit(UnwindNode unwind) {
+ Node pred = unwind.predecessor();
+ while (pred != null) {
+ if (pred instanceof MonitorExitNode) {
+ return (MonitorExitNode) pred;
+ }
+ pred = pred.predecessor();
+ }
+ return null;
+ }
+
/**
* Performs an actual inlining, thereby replacing the given invoke with the given inlineGraph.
*
@@ -1070,13 +1081,13 @@
} else {
if (unwindNode != null) {
UnwindNode unwindDuplicate = (UnwindNode) duplicates.get(unwindNode);
+ MonitorExitNode monitorExit = findPrecedingMonitorExit(unwindDuplicate);
DeoptimizeNode deoptimizeNode = new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.NotCompiledExceptionHandler);
unwindDuplicate.replaceAndDelete(graph.add(deoptimizeNode));
// move the deopt upwards if there is a monitor exit that tries to use the
// "after exception" frame state
// (because there is no "after exception" frame state!)
- if (deoptimizeNode.predecessor() instanceof MonitorExitNode) {
- MonitorExitNode monitorExit = (MonitorExitNode) deoptimizeNode.predecessor();
+ if (monitorExit != null) {
if (monitorExit.stateAfter() != null && monitorExit.stateAfter().bci == FrameState.AFTER_EXCEPTION_BCI) {
FrameState monitorFrameState = monitorExit.stateAfter();
graph.removeFixed(monitorExit);
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Thu Mar 14 01:09:32 2013 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Thu Mar 14 01:09:43 2013 +0100
@@ -148,6 +148,9 @@
public static boolean ExitVMOnBailout = ____;
public static boolean ExitVMOnException = true;
+ // Register allocator debugging
+ public static String RegisterPressure = null;
+
// Code generator settings
public static boolean ConditionalElimination = true;
public static boolean CullFrameStates = ____;
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java Thu Mar 14 01:09:32 2013 +0100
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java Thu Mar 14 01:09:43 2013 +0100
@@ -82,16 +82,22 @@
if (sdf == null) {
sdf = new SimpleDateFormat("YYYY-MM-dd-HHmm");
}
- String fileName = "Graphs-" + Thread.currentThread().getName() + "-" + sdf.format(new Date()) + ext;
+ String prefix = "Graphs-" + Thread.currentThread().getName() + "-" + sdf.format(new Date());
+ String num = "";
+ File file;
+ int i = 0;
+ while ((file = new File(prefix + num + ext)).exists()) {
+ num = "-" + Integer.toString(++i);
+ }
try {
if (GraalOptions.PrintBinaryGraphs) {
- printer = new BinaryGraphPrinter(FileChannel.open(new File(fileName).toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW));
+ printer = new BinaryGraphPrinter(FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW));
} else {
- printer = new IdealGraphPrinter(new FileOutputStream(fileName));
+ printer = new IdealGraphPrinter(new FileOutputStream(file));
}
- TTY.println("Dumping IGV graphs to %s", fileName);
+ TTY.println("Dumping IGV graphs to %s", file.getName());
} catch (IOException e) {
- TTY.println("Failed to open %s to dump IGV graphs : %s", fileName, e);
+ TTY.println("Failed to open %s to dump IGV graphs : %s", file.getName(), e);
failuresCount++;
printer = null;
}
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/BinaryOperationTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/BinaryOperationTest.java Thu Mar 14 01:09:43 2013 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.codegen.test;
+
+import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.api.codegen.test.TypeSystemTest.ValueNode;
+
+public class BinaryOperationTest {
+
+ static int convertInt(Object value) {
+ if (value instanceof Number) {
+ return ((Number) value).intValue();
+ } else if (value instanceof String) {
+ return Integer.parseInt((String) value);
+ }
+ throw new RuntimeException("Invalid datatype");
+ }
+
+ @NodeClass(BinaryNode.class)
+ abstract static class BinaryNode extends ValueNode {
+
+ @Child protected ValueNode leftNode;
+ @Child protected ValueNode rightNode;
+
+ public BinaryNode(ValueNode left, ValueNode right) {
+ this.leftNode = left;
+ this.rightNode = right;
+ }
+
+ public BinaryNode(BinaryNode prev) {
+ this(prev.leftNode, prev.rightNode);
+ }
+
+ @Specialization
+ int add(int left, int right) {
+ return left + right;
+ }
+
+ @Generic
+ int add(Object left, Object right) {
+ return convertInt(left) + convertInt(right);
+ }
+
+ @Specialization
+ int sub(int left, int right) {
+ return left + right;
+ }
+
+ @Generic
+ int sub(Object left, Object right) {
+ return convertInt(left) + convertInt(right);
+ }
+
+ }
+
+}
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/RuntimeStringTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/RuntimeStringTest.java Thu Mar 14 01:09:43 2013 +0100
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.codegen.test;
+
+import org.junit.*;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.api.codegen.test.TypeSystemTest.TestRootNode;
+import com.oracle.truffle.api.codegen.test.TypeSystemTest.ValueNode;
+
+public class RuntimeStringTest {
+
+ @Test
+ public void testSubstr() {
+ assertExecute(new RuntimeString("es"), "substr", new RuntimeString("test"), 1, 3);
+ }
+
+ @Test
+ public void testConcat() {
+ assertExecute(new RuntimeString("concatconcat"), "concat", new RuntimeString("concat"), new RuntimeString("concat"));
+ }
+
+ @Test(expected = ArrayIndexOutOfBoundsException.class)
+ public void testConcatFail() {
+ assertExecute(new RuntimeString("concatconcat"), "concat", new RuntimeString("concat"));
+ }
+
+ @Test
+ public void testFindMethodByMethodName() {
+ // TODO
+ }
+
+ private static void assertExecute(Object expectedResult, String name, Object... argumentsArray) {
+ ArgNode[] args = new ArgNode[argumentsArray.length];
+ for (int i = 0; i < args.length; i++) {
+ args[i] = new ArgNode(argumentsArray, i);
+ }
+
+ BuiltinNode node = null;
+ for (NodeFactory nodeFactory : RuntimeStringTestFactory.getFactories()) {
+ GeneratedBy generated = nodeFactory.getClass().getAnnotation(GeneratedBy.class);
+ Assert.assertNotNull(generated);
+ Assert.assertNotSame("", generated.methodName());
+ if (generated.methodName().equals(name)) {
+ node = nodeFactory.createNode((Object) args);
+ break;
+ }
+ }
+ Assert.assertNotNull("Node not found", node);
+ CallTarget target = Truffle.getRuntime().createCallTarget(new TestRootNode(node));
+ Assert.assertEquals(expectedResult, target.call());
+ }
+
+ static class ArgNode extends ValueNode {
+
+ final Object[] arguments;
+ final int index;
+
+ ArgNode(Object[] args, int index) {
+ this.arguments = args;
+ this.index = index;
+ }
+
+ @Override
+ Object execute() {
+ return arguments[index];
+ }
+
+ }
+
+ abstract static class BuiltinNode extends ValueNode {
+
+ @Children ArgNode[] parameters;
+
+ BuiltinNode(ArgNode[] parameters) {
+ this.parameters = adoptChildren(parameters);
+ }
+
+ BuiltinNode(BuiltinNode prev) {
+ this(prev.parameters);
+ }
+
+ }
+
+ @NodeClass(BuiltinNode.class)
+ static class RuntimeString {
+
+ private final String internal;
+
+ public RuntimeString(String internal) {
+ this.internal = internal;
+ }
+
+ @Specialization
+ static RuntimeString concat(RuntimeString s1, RuntimeString s2) {
+ return new RuntimeString(s1.internal + s2.internal);
+ }
+
+ @Specialization
+ RuntimeString substr(int beginIndex, int endIndex) {
+ return new RuntimeString(internal.substring(beginIndex, endIndex));
+ }
+
+ @Generic
+ RuntimeString substr(Object beginIndex, Object endIndex) {
+ return substr(convertInt(beginIndex), convertInt(endIndex));
+ }
+
+ static int convertInt(Object value) {
+ if (value instanceof Number) {
+ return ((Number) value).intValue();
+ } else if (value instanceof String) {
+ return Integer.parseInt((String) value);
+ }
+ throw new RuntimeException("Invalid datatype");
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof RuntimeString) {
+ return internal.equals(((RuntimeString) obj).internal);
+ }
+ return super.equals(obj);
+ }
+
+ @Override
+ public int hashCode() {
+ return internal.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return internal;
+ }
+
+ }
+
+}
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/TypeSystemTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/TypeSystemTest.java Thu Mar 14 01:09:43 2013 +0100
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.codegen.test;
+
+import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.api.codegen.test.RuntimeStringTest.RuntimeString;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+
+public class TypeSystemTest {
+
+ @TypeSystem({int.class, RuntimeString.class})
+ static class SimpleTypes {
+ }
+
+ @TypeSystemReference(SimpleTypes.class)
+ abstract static class ValueNode extends Node {
+
+ int executeInt() throws UnexpectedResultException {
+ return SimpleTypesGen.SIMPLETYPES.expectInteger(execute());
+ }
+
+ RuntimeString executeString() {
+ return new RuntimeString(execute().toString());
+ }
+
+ @SuppressWarnings("static-method")
+ final long executeSpecial() {
+ return 42L;
+ }
+
+ abstract Object execute();
+
+ }
+
+ @TypeSystemReference(SimpleTypes.class)
+ static class TestRootNode extends RootNode {
+
+ @Child private ValueNode node;
+
+ public TestRootNode(ValueNode node) {
+ this.node = adoptChild(node);
+ }
+
+ @Override
+ public Object execute(VirtualFrame frame) {
+ return node.execute();
+ }
+ }
+
+}
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/package-info.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/package-info.java Thu Mar 14 01:09:43 2013 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/**
+ *
This package contains basic tests of the Truffle-Source-Code-Generation (short Codegen) API and serves at the same
+ * time as an introduction to the Codegen API for language implementors. Every test gives an example on how to use the construct explained in the class description.
+ *
+ *
+ * This API relies heavily on the concepts described in com.oracle.truffle.api.test. We assume that the
+ * reader is already familiarized with those concepts.
+ *
+ *
+ *
+ * TODO general description
+ *
+ *
+ *
+ * This introduction to Codegen contains items in the following recommended order:
+ *
+ * Prerequisites:
+ *
+ *
+ *
+ *
What do I need to get started? {@link com.oracle.truffle.api.codegen.test.TypeSystemTest}
+ *
How would you generate function nodes for runtime objects? {@link com.oracle.truffle.api.codegen.test.RuntimeStringTest}
+ *
+ *
+ *
+ */
+package com.oracle.truffle.api.codegen.test;
+
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/GeneratedBy.java
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/GeneratedBy.java Thu Mar 14 01:09:32 2013 +0100
+++ b/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/GeneratedBy.java Thu Mar 14 01:09:43 2013 +0100
@@ -25,12 +25,14 @@
import java.lang.annotation.*;
/**
- * Marks a type to be generated by another class.
+ * Marks a type to be generated by another class or a method.
*/
-@Retention(RetentionPolicy.CLASS)
+@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface GeneratedBy {
Class> value();
+ String methodName() default "";
+
}
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/GuardCheck.java
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/GuardCheck.java Thu Mar 14 01:09:32 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen;
-
-import java.lang.annotation.*;
-
-/**
- *
- *
- * @see SpecializationGuard
- */
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.METHOD})
-public @interface GuardCheck {
-
-}
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeClass.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeClass.java Thu Mar 14 01:09:43 2013 +0100
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.codegen;
+
+import java.lang.annotation.*;
+
+import com.oracle.truffle.api.nodes.*;
+
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.TYPE})
+public @interface NodeClass {
+
+ Class extends Node> value();
+
+}
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeFactory.java
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeFactory.java Thu Mar 14 01:09:32 2013 +0100
+++ b/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeFactory.java Thu Mar 14 01:09:43 2013 +0100
@@ -24,6 +24,8 @@
import java.util.*;
+import com.oracle.truffle.api.nodes.*;
+
/**
* Enables the dynamic creation of generated nodes. It provides an convenient way to instantiate
* generated node classes without using reflection.
@@ -63,4 +65,10 @@
*/
List>> getNodeSignatures();
+ /**
+ * Returns a list of children that will be executed by the created node. This is useful for base
+ * nodes that can execute a variable amount of nodes.
+ */
+ List> getExecutionSignature();
+
}
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeId.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeId.java Thu Mar 14 01:09:43 2013 +0100
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.codegen;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface NodeId {
+
+ String value();
+
+}
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/Specialization.java
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/Specialization.java Thu Mar 14 01:09:32 2013 +0100
+++ b/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/Specialization.java Thu Mar 14 01:09:43 2013 +0100
@@ -32,8 +32,8 @@
int order() default DEFAULT_ORDER;
- SpecializationThrows[] exceptions() default {};
+ Class extends Throwable>[] rewriteOn() default {};
- SpecializationGuard[] guards() default {};
+ String[] guards() default {};
}
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/SpecializationGuard.java
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/SpecializationGuard.java Thu Mar 14 01:09:32 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen;
-
-import java.lang.annotation.*;
-
-/**
- * Specifies the use of a guard for a specialization.
- */
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.METHOD})
-public @interface SpecializationGuard {
-
- /**
- * Specifies the name of the guard method annotated by {@link GuardCheck} specified as method in
- * the {@link TypeSystem} class.
- */
- String methodName();
-
- /**
- * Determines if a guard check is invoked on specialization. Defaults to true.
- */
- boolean onSpecialization() default true;
-
- /**
- * Determines if a guard check is invoked on execution. Defaults to true.
- */
- boolean onExecution() default true;
-
-}
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/SpecializationThrows.java
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/SpecializationThrows.java Thu Mar 14 01:09:32 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen;
-
-import java.lang.annotation.*;
-
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.METHOD})
-public @interface SpecializationThrows {
-
- Class extends Throwable> javaClass();
-
- String transitionTo();
-}
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/TypeSystem.java
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/TypeSystem.java Thu Mar 14 01:09:32 2013 +0100
+++ b/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/TypeSystem.java Thu Mar 14 01:09:43 2013 +0100
@@ -28,8 +28,8 @@
*
* Annotates a type system class that represents type information for a node. Generates code for
* converting and managing types. Methods contained in the type system may be annotated with
- * {@link TypeCast}, {@link TypeCheck} or {@link GuardCheck}. These methods alter the default
- * behavior of the type system.
+ * {@link TypeCast} or {@link TypeCheck}. These methods alter the default behavior of the type
+ * system.
*
*
*
@@ -62,7 +62,6 @@
*
* @see TypeCast
* @see TypeCheck
- * @see GuardCheck
*/
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.TYPE})
diff -r 53683dc2815e -r ff91c7101ed0 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 Thu Mar 14 01:09:32 2013 +0100
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReturnTypeSpecializationTest.java Thu Mar 14 01:09:43 2013 +0100
@@ -38,7 +38,7 @@
* should be speculated on. When the speculation fails and the child node cannot return the
* appropriate type of value, it can use an {@link UnexpectedResultException} to still pass the
* result to the caller. In such a case, the caller must rewrite itself to a more general version in
- * oder to avoid future failures of this kind.
+ * order to avoid future failures of this kind.
*
*/
public class ReturnTypeSpecializationTest {
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/AbstractParser.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/AbstractParser.java Thu Mar 14 01:09:32 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/AbstractParser.java Thu Mar 14 01:09:43 2013 +0100
@@ -58,12 +58,22 @@
if (!context.getTruffleTypes().verify(context, element, mirror)) {
return null;
}
- return parse(element, mirror);
+ M model = parse(element, mirror);
+ if (model == null) {
+ return null;
+ }
+
+ model.emitMessages((TypeElement) element, log);
+ return filterErrorElements(model);
} finally {
this.roundEnv = null;
}
}
+ protected M filterErrorElements(M model) {
+ return model.hasErrors() ? null : model;
+ }
+
protected abstract M parse(Element element, AnnotationMirror mirror);
public abstract Class extends Annotation> getAnnotationType();
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Log.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Log.java Thu Mar 14 01:09:32 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Log.java Thu Mar 14 01:09:43 2013 +0100
@@ -41,30 +41,6 @@
this.processingEnv = env;
}
- public void warning(Element element, String format, Object... args) {
- message(Kind.WARNING, element, null, null, format, args);
- }
-
- public void warning(Element element, AnnotationMirror mirror, String format, Object... args) {
- message(Kind.WARNING, element, mirror, null, format, args);
- }
-
- public void error(Element element, String format, Object... args) {
- message(Kind.ERROR, element, null, null, format, args);
- }
-
- public void error(String format, Object... args) {
- message(Kind.ERROR, null, null, null, format, args);
- }
-
- public void error(Element element, AnnotationMirror mirror, String format, Object... args) {
- message(Kind.ERROR, element, mirror, null, format, args);
- }
-
- public void error(Element element, AnnotationMirror mirror, AnnotationValue value, String format, Object... args) {
- message(Kind.ERROR, element, mirror, value, format, args);
- }
-
public void message(Kind kind, Element element, AnnotationMirror mirror, AnnotationValue value, String format, Object... args) {
AnnotationMirror usedMirror = mirror;
Element usedElement = element;
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/TruffleProcessor.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/TruffleProcessor.java Thu Mar 14 01:09:32 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/TruffleProcessor.java Thu Mar 14 01:09:43 2013 +0100
@@ -28,6 +28,7 @@
import javax.annotation.processing.*;
import javax.lang.model.*;
import javax.lang.model.element.*;
+import javax.tools.Diagnostic.*;
import com.oracle.truffle.codegen.processor.ProcessorContext.ProcessCallback;
import com.oracle.truffle.codegen.processor.node.*;
@@ -95,7 +96,7 @@
private static void handleThrowable(AnnotationProcessor generator, Throwable t, Element e) {
String message = "Uncaught error in " + generator.getClass().getSimpleName() + " while processing " + e;
- generator.getContext().getLog().error(e, message + ": " + Utils.printException(t));
+ generator.getContext().getLog().message(Kind.ERROR, e, null, null, message + ": " + Utils.printException(t));
}
@SuppressWarnings("unchecked")
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/TruffleTypes.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/TruffleTypes.java Thu Mar 14 01:09:32 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/TruffleTypes.java Thu Mar 14 01:09:43 2013 +0100
@@ -26,6 +26,7 @@
import javax.lang.model.element.*;
import javax.lang.model.type.*;
+import javax.tools.Diagnostic.*;
import com.oracle.truffle.api.frame.*;
import com.oracle.truffle.api.intrinsics.*;
@@ -66,7 +67,7 @@
}
for (String error : errors) {
- context.getLog().error(element, mirror, error);
+ context.getLog().message(Kind.ERROR, element, mirror, null, error);
}
return false;
diff -r 53683dc2815e -r ff91c7101ed0 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Utils.java
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Utils.java Thu Mar 14 01:09:32 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Utils.java Thu Mar 14 01:09:43 2013 +0100
@@ -55,9 +55,17 @@
return boxedType;
}
+ public static List asTypeMirrors(List extends Element> elements) {
+ List types = new ArrayList<>(elements.size());
+ for (Element element : elements) {
+ types.add(element.asType());
+ }
+ return types;
+ }
+
public static List collectAnnotations(ProcessorContext context, AnnotationMirror markerAnnotation, String elementName, Element element,
Class extends Annotation> annotationClass) {
- List result = Utils.getAnnotationValueList(markerAnnotation, elementName);
+ List result = Utils.getAnnotationValueList(AnnotationMirror.class, markerAnnotation, elementName);
AnnotationMirror explicit = Utils.findAnnotationMirror(context.getEnvironment(), element, annotationClass);
if (explicit != null) {
result.add(explicit);
@@ -167,6 +175,46 @@
return new LinkedHashSet<>(Arrays.asList(modifier));
}
+ public static String getTypeId(TypeMirror mirror) {
+ switch (mirror.getKind()) {
+ case BOOLEAN:
+ return "Boolean";
+ case BYTE:
+ return "Byte";
+ case CHAR:
+ return "Char";
+ case DOUBLE:
+ return "Double";
+ case FLOAT:
+ return "Float";
+ case SHORT:
+ return "Short";
+ case INT:
+ return "Int";
+ case LONG:
+ return "Long";
+ case DECLARED:
+ return ((DeclaredType) mirror).asElement().getSimpleName().toString();
+ case ARRAY:
+ return getTypeId(((ArrayType) mirror).getComponentType()) + "Array";
+ case VOID:
+ return "Void";
+ case WILDCARD:
+ StringBuilder b = new StringBuilder();
+ WildcardType type = (WildcardType) mirror;
+ if (type.getExtendsBound() != null) {
+ b.append("Extends").append(getTypeId(type.getExtendsBound()));
+ } else if (type.getSuperBound() != null) {
+ b.append("Super").append(getTypeId(type.getExtendsBound()));
+ }
+ return b.toString();
+ case TYPEVAR:
+ return "Any";
+ default:
+ throw new RuntimeException("Unknown type specified " + mirror.getKind() + " mirror: " + mirror);
+ }
+ }
+
public static String getSimpleName(TypeElement element) {
return getSimpleName(element.asType());
}
@@ -428,29 +476,32 @@
}
@SuppressWarnings("unchecked")
- public static List getAnnotationValueList(AnnotationMirror mirror, String name) {
+ public static List getAnnotationValueList(Class expectedListType, AnnotationMirror mirror, String name) {
+ List extends AnnotationValue> values = getAnnotationValue(List.class, mirror, name);
List result = new ArrayList<>();
- List extends AnnotationValue> values = (List extends AnnotationValue>) getAnnotationValue(mirror, name).getValue();
+
for (AnnotationValue value : values) {
- result.add((T) value.getValue());
+ result.add(resolveAnnotationValue(expectedListType, value));
}
return result;
}
- public static TypeMirror getAnnotationValueType(AnnotationMirror mirror, String name) {
- return (TypeMirror) getAnnotationValue(mirror, name).getValue();
+ public static T getAnnotationValue(Class expectedType, AnnotationMirror mirror, String name) {
+ return resolveAnnotationValue(expectedType, getAnnotationValue(mirror, name));
}
- public static TypeMirror getAnnotationValueTypeMirror(AnnotationMirror mirror, String name) {
- return (TypeMirror) getAnnotationValue(mirror, name).getValue();
- }
-
- public static String getAnnotationValueString(AnnotationMirror mirror, String name) {
- return (String) getAnnotationValue(mirror, name).getValue();
- }
-
- public static int getAnnotationValueInt(AnnotationMirror mirror, String name) {
- return (int) getAnnotationValue(mirror, name).getValue();
+ @SuppressWarnings({"unchecked"})
+ private static T resolveAnnotationValue(Class expectedType, AnnotationValue value) {
+ Object unboxedValue = value.accept(new AnnotationValueVisitorImpl(), null);
+ if (unboxedValue != null) {
+ if (expectedType == TypeMirror.class && unboxedValue instanceof String) {
+ return null;
+ }
+ if (!expectedType.isAssignableFrom(unboxedValue.getClass())) {
+ throw new ClassCastException(unboxedValue.getClass().getName() + " not assignable from " + expectedType.getName());
+ }
+ }
+ return (T) unboxedValue;
}
public static AnnotationValue getAnnotationValue(AnnotationMirror mirror, String name) {
@@ -470,9 +521,79 @@
if (value == null) {
value = valueMethod.getDefaultValue();
}
+
return value;
}
+ private static class AnnotationValueVisitorImpl extends AbstractAnnotationValueVisitor7