Mercurial > hg > graal-compiler
changeset 22910:6a508ee4c7ef
Merge
author | Tom Rodriguez <tom.rodriguez@oracle.com> |
---|---|
date | Fri, 30 Oct 2015 10:46:56 -0700 |
parents | 5ce3e8996c83 (current diff) 0bf0cdd17bd3 (diff) |
children | 3c00f45259b6 6b81cca49187 |
files | |
diffstat | 29 files changed, 2751 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Thu Oct 29 12:23:07 2015 -0700 +++ b/.hgignore Fri Oct 30 10:46:56 2015 -0700 @@ -30,6 +30,7 @@ \.dot$ \.pyc$ \.hprof$ +\.json$ \javafilelist.*\.txt$ \.hprof\.txt$ ^doc/.*/dot_temp_
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeMatchRules.java Thu Oct 29 12:23:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeMatchRules.java Fri Oct 30 10:46:56 2015 -0700 @@ -35,13 +35,6 @@ import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.QWORD; import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.SD; import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.SS; -import jdk.vm.ci.amd64.AMD64Kind; -import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.LIRKind; -import jdk.vm.ci.meta.PlatformKind; -import jdk.vm.ci.meta.Value; import com.oracle.graal.asm.NumUtil; import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MIOp; @@ -76,6 +69,14 @@ import com.oracle.graal.nodes.memory.Access; import com.oracle.graal.nodes.memory.WriteNode; +import jdk.vm.ci.amd64.AMD64Kind; +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.LIRKind; +import jdk.vm.ci.meta.PlatformKind; +import jdk.vm.ci.meta.Value; + public class AMD64NodeMatchRules extends NodeMatchRules { public AMD64NodeMatchRules(LIRGeneratorTool gen) { @@ -126,7 +127,7 @@ if (value.isConstant()) { JavaConstant constant = value.asJavaConstant(); - if (kind == AMD64Kind.QWORD && !NumUtil.isInt(constant.asLong())) { + if (constant != null && kind == AMD64Kind.QWORD && !NumUtil.isInt(constant.asLong())) { // Only imm32 as long return null; } @@ -134,7 +135,7 @@ Debug.log("Skipping constant compares for float kinds"); return null; } - if (constant.getJavaKind() == JavaKind.Object && !constant.isNull()) { + if (constant != null && constant.getJavaKind() == JavaKind.Object && !constant.isNull()) { Debug.log("Skipping constant compares for Object kinds"); return null; } @@ -151,8 +152,9 @@ boolean unorderedIsTrue = compare.unorderedIsTrue(); double trueLabelProbability = ifNode.probability(ifNode.trueSuccessor()); Value other; - if (value.isConstant()) { - other = gen.emitJavaConstant(value.asJavaConstant()); + JavaConstant constant = value.asJavaConstant(); + if (constant != null) { + other = gen.emitJavaConstant(constant); } else { other = operand(value); } @@ -172,7 +174,7 @@ OperandSize size = kind == AMD64Kind.QWORD ? QWORD : DWORD; if (value.isConstant()) { JavaConstant constant = value.asJavaConstant(); - if (kind == AMD64Kind.QWORD && !NumUtil.isInt(constant.asLong())) { + if (constant != null && kind == AMD64Kind.QWORD && !NumUtil.isInt(constant.asLong())) { // Only imm32 as long return null; }
--- a/graal/com.oracle.graal.compiler.match.processor/src/com/oracle/graal/compiler/match/processor/MatchProcessor.java Thu Oct 29 12:23:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.match.processor/src/com/oracle/graal/compiler/match/processor/MatchProcessor.java Fri Oct 30 10:46:56 2015 -0700 @@ -604,7 +604,7 @@ } private void createProviderFile(String pkg, String providerClassName, Element... originatingElements) throws IOException { - String filename = "META-INF/providers/" + pkg + "." + providerClassName; + String filename = "META-INF/jvmci.providers/" + pkg + "." + providerClassName; FileObject file = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", filename, originatingElements); PrintWriter writer = new PrintWriter(new OutputStreamWriter(file.openOutputStream(), "UTF-8")); writer.println(MatchStatementSet.class.getName());
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/JVMCIErrorTest.java Fri Oct 30 10:46:56 2015 -0700 @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.test; + +import java.util.function.Consumer; + +import jdk.vm.ci.code.CompilationResult; +import jdk.vm.ci.code.CompilationResult.ConstantReference; +import jdk.vm.ci.code.CompilationResult.DataPatch; +import jdk.vm.ci.code.CompilationResult.DataSectionReference; +import jdk.vm.ci.code.CompilationResult.Infopoint; +import jdk.vm.ci.code.CompilationResult.Reference; +import jdk.vm.ci.code.DataSection.Data; +import jdk.vm.ci.code.DataSection.DataBuilder; +import jdk.vm.ci.code.InfopointReason; +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.hotspot.HotSpotConstant; +import jdk.vm.ci.meta.Assumptions.Assumption; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.VMConstant; + +import org.junit.Test; + +import com.oracle.graal.compiler.test.GraalCompilerTest; + +public class JVMCIErrorTest extends GraalCompilerTest { + + public static void testMethod() { + } + + private void test(Consumer<CompilationResult> modify) { + ResolvedJavaMethod method = getResolvedJavaMethod("testMethod"); + CompilationResult compResult = compile(method, null); + + modify.accept(compResult); + + getCodeCache().addCode(method, compResult, null, null); + } + + @Test(expected = JVMCIError.class) + public void testInvalidAssumption() { + test(r -> r.setAssumptions(new Assumption[]{new InvalidAssumption()})); + } + + private static class InvalidAssumption extends Assumption { + } + + @Test(expected = JVMCIError.class) + public void testInvalidAlignment() { + test(r -> r.getDataSection().insertData(new Data(7, 1, DataBuilder.zero(1)))); + } + + @Test(expected = JVMCIError.class) + public void testInvalidDataSectionReference() { + test(r -> { + DataSectionReference ref = r.getDataSection().insertData(new Data(1, 1, DataBuilder.zero(1))); + Data data = new Data(1, 1, (buffer, patch) -> { + patch.accept(new DataPatch(buffer.position(), ref)); + buffer.put((byte) 0); + }); + r.getDataSection().insertData(data); + }); + } + + @Test(expected = JVMCIError.class) + public void testInvalidNarrowMethodInDataSection() { + test(r -> { + ResolvedJavaMethod method = getResolvedJavaMethod("testMethod"); + HotSpotConstant c = (HotSpotConstant) method.getEncoding(); + Data data = new Data(4, 4, (buffer, patch) -> { + patch.accept(new DataPatch(buffer.position(), new ConstantReference((VMConstant) c.compress()))); + buffer.putInt(0); + }); + r.getDataSection().insertData(data); + }); + } + + @Test(expected = JVMCIError.class) + public void testInvalidConstantInDataSection() { + test(r -> { + Data data = new Data(1, 1, (buffer, patch) -> { + patch.accept(new DataPatch(buffer.position(), new ConstantReference(new InvalidVMConstant()))); + }); + r.getDataSection().insertData(data); + }); + } + + @Test(expected = JVMCIError.class) + public void testInvalidConstantInCode() { + test(r -> r.recordDataPatch(0, new ConstantReference(new InvalidVMConstant()))); + } + + private static class InvalidVMConstant implements VMConstant { + + public boolean isDefaultForKind() { + return false; + } + + public String toValueString() { + return null; + } + } + + @Test(expected = JVMCIError.class) + public void testInvalidReference() { + test(r -> r.recordDataPatch(0, new InvalidReference())); + } + + private static class InvalidReference extends Reference { + + @Override + public int hashCode() { + return 0; + } + + @Override + public boolean equals(Object obj) { + return false; + } + } + + @Test(expected = JVMCIError.class) + public void testOutOfBoundsDataSectionReference() { + test(r -> { + DataSectionReference ref = new DataSectionReference(); + ref.setOffset(0x1000); + r.recordDataPatch(0, ref); + }); + } + + @Test(expected = JVMCIError.class) + public void testInvalidMark() { + test(r -> r.recordMark(0, new Object())); + } + + @Test(expected = JVMCIError.class) + public void testInvalidMarkInt() { + test(r -> r.recordMark(0, -1)); + } + + @Test(expected = JVMCIError.class) + public void testUnknownInfopointReason() { + test(r -> r.addInfopoint(new Infopoint(0, null, InfopointReason.UNKNOWN))); + } + + @Test(expected = JVMCIError.class) + public void testInfopointMissingDebugInfo() { + test(r -> r.addInfopoint(new Infopoint(0, null, InfopointReason.METHOD_START))); + } + + @Test(expected = JVMCIError.class) + public void testSafepointMissingDebugInfo() { + test(r -> r.addInfopoint(new Infopoint(0, null, InfopointReason.SAFEPOINT))); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/JVMCIInfopointErrorTest.java Fri Oct 30 10:46:56 2015 -0700 @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.test; + +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.REG; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.STACK; + +import java.util.function.Consumer; + +import jdk.vm.ci.code.BytecodeFrame; +import jdk.vm.ci.code.CompilationResult; +import jdk.vm.ci.code.InfopointReason; +import jdk.vm.ci.code.VirtualObject; +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.meta.AllocatableValue; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.JavaValue; +import jdk.vm.ci.meta.LIRKind; +import jdk.vm.ci.meta.PlatformKind; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.ResolvedJavaType; +import jdk.vm.ci.meta.Value; + +import org.junit.Test; + +import com.oracle.graal.compiler.common.type.StampFactory; +import com.oracle.graal.compiler.test.GraalCompilerTest; +import com.oracle.graal.debug.Debug; +import com.oracle.graal.debug.DebugConfigScope; +import com.oracle.graal.graph.NodeClass; +import com.oracle.graal.lir.FullInfopointOp; +import com.oracle.graal.lir.LIRFrameState; +import com.oracle.graal.lir.LIRInstruction; +import com.oracle.graal.lir.LIRInstructionClass; +import com.oracle.graal.lir.Variable; +import com.oracle.graal.lir.asm.CompilationResultBuilder; +import com.oracle.graal.lir.gen.LIRGeneratorTool; +import com.oracle.graal.nodeinfo.NodeInfo; +import com.oracle.graal.nodes.DeoptimizingFixedWithNextNode; +import com.oracle.graal.nodes.StructuredGraph; +import com.oracle.graal.nodes.spi.LIRLowerable; +import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; + +public class JVMCIInfopointErrorTest extends GraalCompilerTest { + + private static class ValueDef extends LIRInstruction { + private static final LIRInstructionClass<ValueDef> TYPE = LIRInstructionClass.create(ValueDef.class); + + @Def({REG, STACK}) AllocatableValue value; + + public ValueDef(AllocatableValue value) { + super(TYPE); + this.value = value; + } + + @Override + public void emitCode(CompilationResultBuilder crb) { + } + } + + private static class ValueUse extends LIRInstruction { + private static final LIRInstructionClass<ValueUse> TYPE = LIRInstructionClass.create(ValueUse.class); + + @Use({REG, STACK}) AllocatableValue value; + + public ValueUse(AllocatableValue value) { + super(TYPE); + this.value = value; + } + + @Override + public void emitCode(CompilationResultBuilder crb) { + } + } + + @NodeInfo + private static class TestNode extends DeoptimizingFixedWithNextNode implements LIRLowerable { + private static final NodeClass<TestNode> TYPE = NodeClass.create(TestNode.class); + + private final TestSpec spec; + + public TestNode(TestSpec spec) { + super(TYPE, StampFactory.forVoid()); + this.spec = spec; + } + + public boolean canDeoptimize() { + return true; + } + + public void generate(NodeLIRBuilderTool gen) { + LIRGeneratorTool tool = gen.getLIRGeneratorTool(); + LIRFrameState state = gen.state(this); + spec.spec(tool, state, st -> { + tool.append(new FullInfopointOp(st, InfopointReason.SAFEPOINT)); + }); + } + } + + @FunctionalInterface + private interface TestSpec { + void spec(LIRGeneratorTool tool, LIRFrameState state, Consumer<LIRFrameState> safepoint); + } + + public static void testMethod() { + } + + private void test(TestSpec spec) { + ResolvedJavaMethod method = getResolvedJavaMethod("testMethod"); + + StructuredGraph graph = parseForCompile(method); + TestNode test = graph.add(new TestNode(spec)); + graph.addAfterFixed(graph.start(), test); + + CompilationResult compResult = compile(method, graph); + getCodeCache().addCode(method, compResult, null, null); + } + + @Test(expected = JVMCIError.class) + public void testInvalidShortOop() { + test((tool, state, safepoint) -> { + PlatformKind kind = tool.target().arch.getPlatformKind(JavaKind.Short); + LIRKind lirKind = LIRKind.reference(kind); + + Variable var = tool.newVariable(lirKind); + tool.append(new ValueDef(var)); + safepoint.accept(state); + tool.append(new ValueUse(var)); + }); + } + + @Test(expected = JVMCIError.class) + public void testInvalidShortDerivedOop() { + test((tool, state, safepoint) -> { + Variable baseOop = tool.newVariable(tool.target().getLIRKind(JavaKind.Object)); + tool.append(new ValueDef(baseOop)); + + PlatformKind kind = tool.target().arch.getPlatformKind(JavaKind.Short); + LIRKind lirKind = LIRKind.derivedReference(kind, baseOop); + + Variable var = tool.newVariable(lirKind); + tool.append(new ValueDef(var)); + safepoint.accept(state); + tool.append(new ValueUse(var)); + }); + } + + private static LIRFrameState modifyTopFrame(LIRFrameState state, JavaValue[] values, JavaKind[] slotKinds, int locals, int stack, int locks) { + return modifyTopFrame(state, null, values, slotKinds, locals, stack, locks); + } + + private static LIRFrameState modifyTopFrame(LIRFrameState state, VirtualObject[] vobj, JavaValue[] values, JavaKind[] slotKinds, int locals, int stack, int locks) { + BytecodeFrame top = state.topFrame; + top = new BytecodeFrame(top.caller(), top.getMethod(), top.getBCI(), top.rethrowException, top.duringCall, values, slotKinds, locals, stack, locks); + return new LIRFrameState(top, vobj, state.exceptionEdge); + } + + @Test(expected = JVMCIError.class) + public void testUnexpectedScopeValuesLength() { + test((tool, state, safepoint) -> { + LIRFrameState newState = modifyTopFrame(state, new JavaValue[]{JavaConstant.FALSE}, new JavaKind[0], 0, 0, 0); + safepoint.accept(newState); + }); + } + + @Test(expected = JVMCIError.class) + public void testUnexpectedScopeSlotKindsLength() { + test((tool, state, safepoint) -> { + LIRFrameState newState = modifyTopFrame(state, new JavaValue[0], new JavaKind[]{JavaKind.Boolean}, 0, 0, 0); + safepoint.accept(newState); + }); + } + + @Test(expected = JVMCIError.class) + public void testWrongMonitorType() { + test((tool, state, safepoint) -> { + LIRFrameState newState = modifyTopFrame(state, new JavaValue[]{JavaConstant.INT_0}, new JavaKind[]{}, 0, 0, 1); + safepoint.accept(newState); + }); + } + + @Test(expected = JVMCIError.class) + public void testUnexpectedIllegalValue() { + test((tool, state, safepoint) -> { + LIRFrameState newState = modifyTopFrame(state, new JavaValue[]{Value.ILLEGAL}, new JavaKind[]{JavaKind.Int}, 1, 0, 0); + safepoint.accept(newState); + }); + } + + @Test(expected = JVMCIError.class) + public void testUnexpectedTypeInRegister() { + test((tool, state, safepoint) -> { + Variable var = tool.newVariable(tool.target().getLIRKind(JavaKind.Int)); + tool.append(new ValueDef(var)); + LIRFrameState newState = modifyTopFrame(state, new JavaValue[]{var}, new JavaKind[]{JavaKind.Illegal}, 1, 0, 0); + safepoint.accept(newState); + }); + } + + @Test(expected = JVMCIError.class) + public void testWrongConstantType() { + test((tool, state, safepoint) -> { + LIRFrameState newState = modifyTopFrame(state, new JavaValue[]{JavaConstant.INT_0}, new JavaKind[]{JavaKind.Object}, 1, 0, 0); + safepoint.accept(newState); + }); + } + + @Test(expected = JVMCIError.class) + public void testUnsupportedConstantType() { + test((tool, state, safepoint) -> { + LIRFrameState newState = modifyTopFrame(state, new JavaValue[]{JavaConstant.forShort((short) 0)}, new JavaKind[]{JavaKind.Short}, 1, 0, 0); + safepoint.accept(newState); + }); + } + + @Test(expected = JVMCIError.class) + public void testUnexpectedNull() { + test((tool, state, safepoint) -> { + LIRFrameState newState = modifyTopFrame(state, new JavaValue[]{JavaConstant.NULL_POINTER}, new JavaKind[]{JavaKind.Int}, 1, 0, 0); + safepoint.accept(newState); + }); + } + + @Test(expected = JVMCIError.class) + public void testUnexpectedObject() { + JavaValue wrapped = getSnippetReflection().forObject(this); + test((tool, state, safepoint) -> { + LIRFrameState newState = modifyTopFrame(state, new JavaValue[]{wrapped}, new JavaKind[]{JavaKind.Int}, 1, 0, 0); + safepoint.accept(newState); + }); + } + + private static class UnknownJavaValue implements JavaValue { + } + + @SuppressWarnings("try") + @Test(expected = Error.class) + public void testUnknownJavaValue() { + try (DebugConfigScope s = Debug.setConfig(Debug.silentConfig())) { + /* + * Expected: either AssertionError or JVMCIError, depending on whether the unit test run + * is with assertions enabled or disabled. + */ + test((tool, state, safepoint) -> { + LIRFrameState newState = modifyTopFrame(state, new JavaValue[]{new UnknownJavaValue()}, new JavaKind[]{JavaKind.Int}, 1, 0, 0); + safepoint.accept(newState); + }); + } + } + + @Test(expected = Error.class) + public void testMissingIllegalAfterDouble() { + /* + * Expected: either AssertionError or JVMCIError, depending on whether the unit test run is + * with assertions enabled or disabled. + */ + test((tool, state, safepoint) -> { + LIRFrameState newState = modifyTopFrame(state, new JavaValue[]{JavaConstant.DOUBLE_0, JavaConstant.INT_0}, new JavaKind[]{JavaKind.Double, JavaKind.Int}, 2, 0, 0); + safepoint.accept(newState); + }); + } + + @Test(expected = JVMCIError.class) + public void testInvalidVirtualObjectId() { + ResolvedJavaType obj = getMetaAccess().lookupJavaType(Object.class); + test((tool, state, safepoint) -> { + VirtualObject o = VirtualObject.get(obj, 5); + o.setValues(new JavaValue[0], new JavaKind[0]); + + safepoint.accept(new LIRFrameState(state.topFrame, new VirtualObject[]{o}, state.exceptionEdge)); + }); + } + + @Test(expected = JVMCIError.class) + public void testDuplicateVirtualObject() { + ResolvedJavaType obj = getMetaAccess().lookupJavaType(Object.class); + test((tool, state, safepoint) -> { + VirtualObject o1 = VirtualObject.get(obj, 0); + o1.setValues(new JavaValue[0], new JavaKind[0]); + + VirtualObject o2 = VirtualObject.get(obj, 0); + o2.setValues(new JavaValue[0], new JavaKind[0]); + + safepoint.accept(new LIRFrameState(state.topFrame, new VirtualObject[]{o1, o2}, state.exceptionEdge)); + }); + } + + @Test(expected = JVMCIError.class) + public void testUnexpectedVirtualObject() { + ResolvedJavaType obj = getMetaAccess().lookupJavaType(Object.class); + test((tool, state, safepoint) -> { + VirtualObject o = VirtualObject.get(obj, 0); + o.setValues(new JavaValue[0], new JavaKind[0]); + + LIRFrameState newState = modifyTopFrame(state, new VirtualObject[]{o}, new JavaValue[]{o}, new JavaKind[]{JavaKind.Int}, 1, 0, 0); + safepoint.accept(newState); + }); + } + + @Test(expected = JVMCIError.class) + public void testUndefinedVirtualObject() { + ResolvedJavaType obj = getMetaAccess().lookupJavaType(Object.class); + test((tool, state, safepoint) -> { + VirtualObject o0 = VirtualObject.get(obj, 0); + o0.setValues(new JavaValue[0], new JavaKind[0]); + + VirtualObject o1 = VirtualObject.get(obj, 1); + o1.setValues(new JavaValue[0], new JavaKind[0]); + + LIRFrameState newState = modifyTopFrame(state, new VirtualObject[]{o0}, new JavaValue[]{o1}, new JavaKind[]{JavaKind.Object}, 1, 0, 0); + safepoint.accept(newState); + }); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/Salver.java Fri Oct 30 10:46:56 2015 -0700 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2015, 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.salver; + +import static com.oracle.graal.salver.SalverOptions.SalverAddress; +import static com.oracle.graal.salver.SalverOptions.SalverPort; + +import java.net.InetSocketAddress; + +import com.oracle.graal.salver.util.ECIDUtil; + +public final class Salver { + + /** + * The Execution Context Identifier is a unique identifier that simplifies the grouping of + * events created in different DumpHandlers or Threads. It should be added as a special property + * to all :begin trace events. + */ + public static final String ECID = ECIDUtil.random(); + + private Salver() { + } + + public static InetSocketAddress getSocketAddress() { + return new InetSocketAddress(SalverAddress.getValue(), SalverPort.getValue()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/SalverDebugConfigCustomizer.java Fri Oct 30 10:46:56 2015 -0700 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2015, 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.salver; + +import static com.oracle.graal.salver.SalverOptions.Salver; + +import com.oracle.graal.debug.DebugConfig; +import com.oracle.graal.debug.DebugConfigCustomizer; +import com.oracle.graal.salver.handler.GraphDumpHandler; + +import jdk.vm.ci.service.ServiceProvider; + +@ServiceProvider(DebugConfigCustomizer.class) +public class SalverDebugConfigCustomizer implements DebugConfigCustomizer { + + public void customize(DebugConfig config) { + if (Salver.getValue()) { + config.dumpHandlers().add(new GraphDumpHandler()); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/SalverOptions.java Fri Oct 30 10:46:56 2015 -0700 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2015, 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.salver; + +import jdk.vm.ci.options.Option; +import jdk.vm.ci.options.OptionType; +import jdk.vm.ci.options.OptionValue; + +public final class SalverOptions { + + //@formatter:off + @Option(help = "Enable dumps via Salver trace events.", type = OptionType.Debug) + public static final OptionValue<Boolean> Salver = new OptionValue<>(false); + + @Option(help = "Network address (Salver).", type = OptionType.Debug) + public static final OptionValue<String> SalverAddress = new OptionValue<>("127.0.0.1"); + + @Option(help = "Network port (Salver).", type = OptionType.Debug) + public static final OptionValue<Integer> SalverPort = new OptionValue<>(2343); + + @Option(help = "Dump to files as opposed to sending them over the network (Salver).", type = OptionType.Debug) + public static final OptionValue<Boolean> SalverToFile = new OptionValue<>(false); + + //@Option(help = "Use binary format for dumps (Salver).", type = OptionType.Debug) + //public static final OptionValue<Boolean> SalverDumpBinary = new OptionValue<>(false); + //@formatter:on +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/data/DataDict.java Fri Oct 30 10:46:56 2015 -0700 @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2015, 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.salver.data; + +import java.util.LinkedHashMap; + +public class DataDict extends LinkedHashMap<Object, Object> { + + private static final long serialVersionUID = 1L; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/data/DataList.java Fri Oct 30 10:46:56 2015 -0700 @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2015, 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.salver.data; + +import java.util.ArrayList; + +public class DataList extends ArrayList<Object> { + + private static final long serialVersionUID = 1L; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/dumper/AbstractGraalDumper.java Fri Oct 30 10:46:56 2015 -0700 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2015, 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.salver.dumper; + +import java.io.IOException; + +import com.oracle.graal.salver.Salver; +import com.oracle.graal.salver.data.DataDict; + +public class AbstractGraalDumper extends AbstractSerializerDumper { + + public static final String EVENT_NAMESPACE = "graal"; + + private int eventCounter; + + public void beginDump() throws IOException { + beginDump(EVENT_NAMESPACE); + } + + protected void beginDump(String namespace) throws IOException { + beginDump(namespace, getBeginDumpDataDict()); + } + + protected void beginDump(String namespace, DataDict dataDict) throws IOException { + DataDict eventDict = createEventDict(":begin"); + eventDict.put("@time", System.currentTimeMillis()); + eventDict.put("@ecid", Salver.ECID); + if (namespace != null) { + eventDict.put("@namespace", namespace); + } + if (dataDict != null) { + eventDict.put("@data", dataDict); + } + serializeAndFlush(eventDict); + } + + protected DataDict getBeginDumpDataDict() { + DataDict dataDict = new DataDict(); + dataDict.put("dumper", getClass().getSimpleName()); + dataDict.put("thread", Thread.currentThread().getName()); + return dataDict; + } + + public void endDump() throws IOException { + DataDict eventDict = createEventDict(":end"); + eventDict.put("@time", System.currentTimeMillis()); + serializeAndFlush(eventDict); + } + + @Override + public void close() throws IOException { + endDump(); + } + + protected DataDict createEventDict(String name) { + DataDict eventDict = new DataDict(); + eventDict.put("@event", name); + eventDict.put("@n", eventCounter++); + return eventDict; + } + + protected DataDict createEventDict(String name, DataDict data) { + DataDict eventDict = createEventDict(name); + eventDict.put("@data", data); + return eventDict; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/dumper/AbstractMethodScopeDumper.java Fri Oct 30 10:46:56 2015 -0700 @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2015, 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.salver.dumper; + +import java.io.IOException; +import java.lang.reflect.Modifier; +import java.util.ArrayDeque; +import java.util.Collections; +import java.util.Deque; + +import com.oracle.graal.java.BytecodeDisassembler; +import com.oracle.graal.salver.data.DataDict; +import com.oracle.graal.salver.data.DataList; +import com.oracle.graal.salver.util.MethodContext; + +import jdk.vm.ci.meta.JavaMethod; +import jdk.vm.ci.meta.ResolvedJavaMethod; + +public abstract class AbstractMethodScopeDumper extends AbstractGraalDumper { + + protected MethodContext previousMethodContext; + + protected final Deque<Integer> pathStack = new ArrayDeque<>(); + protected int pathCounter; + protected final Deque<Integer> itemIdStack = new ArrayDeque<>(); + protected int itemIdCounter; + + protected void resolveMethodContext() throws IOException { + // Get all current JavaMethod instances in the context. + MethodContext methodContext = new MethodContext(); + // Reverse list such that inner method comes after outer method. + Collections.reverse(methodContext); + + int size = methodContext.size(); + int previousSize = previousMethodContext != null ? previousMethodContext.size() : 0; + // Check for method scopes that must be closed since the previous dump. + for (int i = 0; i < previousSize; ++i) { + if (i >= size || !methodContext.itemEquals(i, previousMethodContext)) { + for (int inlineDepth = previousSize - 1; inlineDepth >= i; --inlineDepth) { + closeScope(); + } + break; + } + } + // Check for method scopes that must be opened since the previous dump. + for (int i = 0; i < size; ++i) { + if (i >= previousSize || !methodContext.itemEquals(i, previousMethodContext)) { + for (int inlineDepth = i; inlineDepth < size; ++inlineDepth) { + openScope(methodContext.get(inlineDepth)); + } + break; + } + } + // Save inline context for next dump. + previousMethodContext = methodContext; + } + + protected void openScope(MethodContext.Item item) throws IOException { + int debugId = item.getDebugId(); + pathStack.push(debugId != -1 ? debugId : pathCounter); + itemIdStack.push(itemIdCounter); + pathCounter = 0; + itemIdCounter = 0; + + processMethod(item.getMethod(), item.getName()); + } + + @SuppressWarnings("unused") + protected void closeScope() throws IOException { + if (!pathStack.isEmpty()) { + pathCounter = pathStack.pop(); + pathCounter++; + } + if (!itemIdStack.isEmpty()) { + itemIdCounter = itemIdStack.pop(); + } + } + + protected void processMethod(JavaMethod method, String name) throws IOException { + DataDict dataDict = new DataDict(); + dataDict.put("name", name); + + if (method instanceof ResolvedJavaMethod) { + DataDict methodDict = new DataDict(); + dataDict.put("method", methodDict); + + ResolvedJavaMethod resolvedMethod = (ResolvedJavaMethod) method; + + methodDict.put("modifiers", Modifier.toString(resolvedMethod.getModifiers())); + methodDict.put("code", new BytecodeDisassembler(false).disassemble(resolvedMethod)); + } + serializeAndFlush(createEventDictWithId("method", dataDict, false)); + } + + protected int nextItemId() { + return itemIdCounter++; + } + + protected DataDict createEventDictWithId(String name, boolean isItem) { + DataDict eventDict = createEventDict(name); + + DataDict idDict = new DataDict(); + eventDict.put("@id", idDict); + + DataList pathList = new DataList(); + idDict.put("path", pathList); + + for (int i : pathStack) { + pathList.add(i); + } + if (isItem) { + pathList.add(pathCounter++); + } + return eventDict; + } + + protected DataDict createEventDictWithId(String name, DataDict dataDict, boolean isItem) { + DataDict eventDict = createEventDictWithId(name, isItem); + eventDict.put("@data", dataDict); + return eventDict; + } + + protected DataDict createEventDictWithId(String name) { + return createEventDictWithId(name, true); + } + + protected DataDict createEventDictWithId(String name, DataDict dataDict) { + return createEventDictWithId(name, dataDict, true); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/dumper/AbstractSerializerDumper.java Fri Oct 30 10:46:56 2015 -0700 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2015, 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.salver.dumper; + +import java.io.IOException; + +import com.oracle.graal.salver.serialize.Serializer; + +public abstract class AbstractSerializerDumper implements Dumper { + + protected Serializer serializer; + + public AbstractSerializerDumper() { + } + + public AbstractSerializerDumper(Serializer serializer) { + this.serializer = serializer; + } + + public Serializer getSerializer() { + return serializer; + } + + public void setSerializer(Serializer serializer) { + this.serializer = serializer; + } + + protected void serialize(Object obj) throws IOException { + if (serializer != null) { + serializer.serialize(obj); + } + } + + protected void serializeAndFlush(Object obj) throws IOException { + if (serializer != null) { + serializer.serialize(obj); + serializer.flush(); + } + } + + @Override + public void close() throws IOException { + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/dumper/Dumper.java Fri Oct 30 10:46:56 2015 -0700 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2015, 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.salver.dumper; + +import java.io.Closeable; + +public interface Dumper extends Closeable, AutoCloseable { + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/dumper/GraphDumper.java Fri Oct 30 10:46:56 2015 -0700 @@ -0,0 +1,353 @@ +/* + * Copyright (c) 2015, 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.salver.dumper; + +import static com.oracle.graal.compiler.common.GraalOptions.PrintGraphProbabilities; +import static com.oracle.graal.compiler.common.GraalOptions.PrintIdealGraphSchedule; + +import java.io.IOException; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import com.oracle.graal.compiler.common.Fields; +import com.oracle.graal.compiler.common.cfg.BlockMap; +import com.oracle.graal.debug.Debug; +import com.oracle.graal.debug.Debug.Scope; +import com.oracle.graal.graph.Edges; +import com.oracle.graal.graph.Edges.Type; +import com.oracle.graal.graph.Graph; +import com.oracle.graal.graph.InputEdges; +import com.oracle.graal.graph.Node; +import com.oracle.graal.graph.NodeClass; +import com.oracle.graal.graph.NodeList; +import com.oracle.graal.graph.NodeMap; +import com.oracle.graal.graph.iterators.NodeIterable; +import com.oracle.graal.nodes.AbstractBeginNode; +import com.oracle.graal.nodes.AbstractEndNode; +import com.oracle.graal.nodes.AbstractMergeNode; +import com.oracle.graal.nodes.ControlSinkNode; +import com.oracle.graal.nodes.ControlSplitNode; +import com.oracle.graal.nodes.FixedNode; +import com.oracle.graal.nodes.PhiNode; +import com.oracle.graal.nodes.ProxyNode; +import com.oracle.graal.nodes.StructuredGraph; +import com.oracle.graal.nodes.VirtualState; +import com.oracle.graal.nodes.cfg.Block; +import com.oracle.graal.nodes.cfg.ControlFlowGraph; +import com.oracle.graal.phases.schedule.SchedulePhase; +import com.oracle.graal.salver.data.DataDict; +import com.oracle.graal.salver.data.DataList; + +public class GraphDumper extends AbstractMethodScopeDumper { + + public static final String EVENT_NAMESPACE = "graal/graph"; + + private static final Map<Class<?>, String> nodeClassCategoryMap; + + static { + nodeClassCategoryMap = new LinkedHashMap<>(); + nodeClassCategoryMap.put(ControlSinkNode.class, "ControlSink"); + nodeClassCategoryMap.put(ControlSplitNode.class, "ControlSplit"); + nodeClassCategoryMap.put(AbstractMergeNode.class, "Merge"); + nodeClassCategoryMap.put(AbstractBeginNode.class, "Begin"); + nodeClassCategoryMap.put(AbstractEndNode.class, "End"); + nodeClassCategoryMap.put(FixedNode.class, "Fixed"); + nodeClassCategoryMap.put(VirtualState.class, "State"); + nodeClassCategoryMap.put(PhiNode.class, "Phi"); + nodeClassCategoryMap.put(ProxyNode.class, "Proxy"); + // nodeClassCategoryMap.put(Object.class, "Floating"); + } + + @Override + public void beginDump() throws IOException { + beginDump(EVENT_NAMESPACE); + } + + @SuppressWarnings("try") + public void dump(Graph graph, String msg) throws IOException { + resolveMethodContext(); + + try (Scope s = Debug.sandbox(getClass().getSimpleName(), null)) { + SchedulePhase predefinedSchedule = null; + for (Object obj : Debug.context()) { + if (obj instanceof SchedulePhase) { + predefinedSchedule = (SchedulePhase) obj; + } + } + processGraph(graph, msg, predefinedSchedule); + } catch (IOException e) { + throw e; + } catch (Throwable e) { + throw Debug.handle(e); + } + } + + private void processGraph(Graph graph, String name, SchedulePhase predefinedSchedule) throws IOException { + SchedulePhase schedule = predefinedSchedule; + if (schedule == null) { + // Also provide a schedule when an error occurs + if (PrintIdealGraphSchedule.getValue() || Debug.contextLookup(Throwable.class) != null) { + if (graph instanceof StructuredGraph) { + schedule = new SchedulePhase(); + schedule.apply((StructuredGraph) graph); + } + } + } + + ControlFlowGraph cfg = null; + List<Block> blocks = null; + NodeMap<Block> nodeToBlock = null; + BlockMap<List<Node>> blockToNodes = null; + + if (schedule != null) { + cfg = schedule.getCFG(); + if (cfg != null) { + blocks = cfg.getBlocks(); + nodeToBlock = schedule.getNodeToBlockMap(); + blockToNodes = schedule.getBlockToNodesMap(); + } + } + + DataDict dataDict = new DataDict(); + dataDict.put("id", nextItemId()); + dataDict.put("name", name); + + DataDict graphDict = new DataDict(); + dataDict.put("graph", graphDict); + + processNodes(graphDict, graph.getNodes(), nodeToBlock, cfg); + + if (blocks != null && blockToNodes != null) { + processBlocks(graphDict, blocks, blockToNodes); + } + serializeAndFlush(createEventDictWithId("graph", dataDict)); + } + + private static void processNodes(DataDict graphDict, NodeIterable<Node> nodes, NodeMap<Block> nodeToBlock, ControlFlowGraph cfg) { + Map<NodeClass<?>, Integer> classMap = new HashMap<>(); + + DataList classList = new DataList(); + graphDict.put("classes", classList); + + DataList nodeList = new DataList(); + graphDict.put("nodes", nodeList); + + DataList edgeList = new DataList(); + graphDict.put("edges", edgeList); + + for (Node node : nodes) { + NodeClass<?> nodeClass = node.getNodeClass(); + + DataDict nodeDict = new DataDict(); + nodeDict.put("id", getNodeId(node)); + nodeDict.put("class", getNodeClassId(classMap, classList, nodeClass)); + + if (nodeToBlock != null) { + if (nodeToBlock.isNew(node)) { + nodeDict.put("block", -1); + } else { + Block block = nodeToBlock.get(node); + if (block != null) { + nodeDict.put("block", block.getId()); + } + } + } + + if (cfg != null && PrintGraphProbabilities.getValue() && node instanceof FixedNode) { + try { + nodeDict.put("probability", cfg.blockFor(node).probability()); + } catch (Throwable t) { + nodeDict.put("probability", t); + } + } + + Map<Object, Object> debugProperties = node.getDebugProperties(); + if (!debugProperties.isEmpty()) { + DataDict propertyDict = new DataDict(); + nodeDict.put("properties", propertyDict); + for (Map.Entry<Object, Object> entry : debugProperties.entrySet()) { + propertyDict.put(entry.getKey().toString(), entry.getValue()); + } + } + + nodeList.add(nodeDict); + appendEdges(edgeList, node, Type.Inputs); + appendEdges(edgeList, node, Type.Successors); + } + } + + private static void processBlocks(DataDict graphDict, List<Block> blocks, BlockMap<List<Node>> blockToNodes) { + DataList blockList = new DataList(); + graphDict.put("blocks", blockList); + + for (Block block : blocks) { + List<Node> nodes = blockToNodes.get(block); + if (nodes != null) { + DataDict blockDict = new DataDict(); + blockDict.put("id", block.getId()); + + DataList nodeList = new DataList(); + blockDict.put("nodes", nodeList); + + for (Node node : nodes) { + nodeList.add(getNodeId(node)); + } + + DataList successorList = new DataList(); + blockDict.put("successors", successorList); + for (Block successor : block.getSuccessors()) { + successorList.add(successor.getId()); + } + + blockList.add(blockDict); + } + } + } + + private static void appendEdges(DataList edgeList, Node node, Edges.Type type) { + NodeClass<?> nodeClass = node.getNodeClass(); + + Edges edges = nodeClass.getEdges(type); + final long[] curOffsets = edges.getOffsets(); + + for (int i = 0; i < edges.getDirectCount(); i++) { + Node other = Edges.getNode(node, curOffsets, i); + if (other != null) { + DataDict edgeDict = new DataDict(); + + DataDict nodeDict = new DataDict(); + nodeDict.put("node", getNodeId(node)); + nodeDict.put("field", edges.getName(i)); + + edgeDict.put("from", type == Type.Inputs ? getNodeId(other) : nodeDict); + edgeDict.put("to", type == Type.Inputs ? nodeDict : getNodeId(other)); + edgeList.add(edgeDict); + } + } + for (int i = edges.getDirectCount(); i < edges.getCount(); i++) { + NodeList<Node> list = Edges.getNodeList(node, curOffsets, i); + if (list != null) { + for (int index = 0; index < list.size(); index++) { + Node other = list.get(index); + if (other != null) { + DataDict edgeDict = new DataDict(); + + DataDict nodeDict = new DataDict(); + nodeDict.put("node", getNodeId(node)); + nodeDict.put("field", edges.getName(i)); + nodeDict.put("index", index); + + edgeDict.put("from", type == Type.Inputs ? getNodeId(other) : nodeDict); + edgeDict.put("to", type == Type.Inputs ? nodeDict : getNodeId(other)); + edgeList.add(edgeDict); + } + } + } + } + } + + @SuppressWarnings("deprecation") + private static int getNodeId(Node node) { + return node != null ? node.getId() : -1; + } + + private static int getNodeClassId(Map<NodeClass<?>, Integer> classMap, DataList classList, NodeClass<?> nodeClass) { + if (classMap.containsKey(nodeClass)) { + return classMap.get(nodeClass); + } + int classId = classMap.size(); + classMap.put(nodeClass, classId); + + Class<?> javaClass = nodeClass.getJavaClass(); + + DataDict classDict = new DataDict(); + classList.add(classDict); + + classDict.put("id", classId); + classDict.put("name", nodeClass.getNameTemplate()); + classDict.put("jtype", javaClass.getName()); + + String category = getNodeClassCategory(javaClass); + if (category != null) { + classDict.put("category", category); + } + + Object propertyInfo = getPropertyInfo(nodeClass); + if (propertyInfo != null) { + classDict.put("properties", propertyInfo); + } + + Object inputInfo = getEdgeInfo(nodeClass, Type.Inputs); + if (inputInfo != null) { + classDict.put("inputs", inputInfo); + } + Object successorInfo = getEdgeInfo(nodeClass, Type.Successors); + if (successorInfo != null) { + classDict.put("successors", successorInfo); + } + return classId; + } + + private static DataDict getPropertyInfo(NodeClass<?> nodeClass) { + Fields properties = nodeClass.getData(); + if (properties.getCount() > 0) { + DataDict propertyInfoDict = new DataDict(); + for (int i = 0; i < properties.getCount(); i++) { + DataDict propertyDict = new DataDict(); + String name = properties.getName(i); + propertyDict.put("name", name); + propertyDict.put("jtype", properties.getType(i).getName()); + propertyInfoDict.put(name, propertyDict); + } + return propertyInfoDict; + } + return null; + } + + private static DataDict getEdgeInfo(NodeClass<?> nodeClass, Edges.Type type) { + DataDict edgeInfoDict = new DataDict(); + Edges edges = nodeClass.getEdges(type); + for (int i = 0; i < edges.getCount(); i++) { + DataDict edgeDict = new DataDict(); + String name = edges.getName(i); + edgeDict.put("name", name); + edgeDict.put("jtype", edges.getType(i).getName()); + if (type == Type.Inputs) { + edgeDict.put("type", ((InputEdges) edges).getInputType(i)); + } + edgeInfoDict.put(name, edgeDict); + } + return edgeInfoDict.isEmpty() ? null : edgeInfoDict; + } + + private static String getNodeClassCategory(Class<?> clazz) { + for (Map.Entry<Class<?>, String> entry : nodeClassCategoryMap.entrySet()) { + if (entry.getKey().isAssignableFrom(clazz)) { + return entry.getValue(); + } + } + return null; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/handler/AbstractDumpHandler.java Fri Oct 30 10:46:56 2015 -0700 @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2015, 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.salver.handler; + +import static java.nio.file.StandardOpenOption.CREATE; +import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING; +import static java.nio.file.StandardOpenOption.WRITE; + +import java.io.IOException; +import java.net.SocketAddress; +import java.nio.channels.FileChannel; +import java.nio.channels.SocketChannel; +import java.nio.channels.WritableByteChannel; +import java.nio.file.OpenOption; +import java.nio.file.Path; + +import com.oracle.graal.salver.dumper.Dumper; +import com.oracle.graal.salver.writer.ChannelDumpWriter; +import com.oracle.graal.salver.writer.DumpWriter; + +public abstract class AbstractDumpHandler<D extends Dumper> implements DumpHandler { + + protected String label; + + protected DumpWriter writer; + protected D dumper; + + public AbstractDumpHandler() { + setLabel(getClass().getSimpleName() + ":" + Thread.currentThread().getName()); + } + + public String getLabel() { + return label; + } + + protected void setLabel(String label) { + this.label = label; + } + + public DumpWriter getWriter() { + return writer; + } + + protected void setWriter(DumpWriter writer) { + this.writer = writer; + } + + protected void setWriter(WritableByteChannel channel) { + setWriter(new ChannelDumpWriter(channel)); + } + + protected void setWriter(SocketAddress remote) throws IOException { + setWriter(SocketChannel.open(remote)); + } + + protected void setWriter(Path path) throws IOException { + setWriter(path, WRITE, TRUNCATE_EXISTING, CREATE); + } + + protected void setWriter(Path path, OpenOption... options) throws IOException { + setWriter(FileChannel.open(path, options)); + } + + public D getDumper() { + return dumper; + } + + protected void setDumper(D dumper) { + this.dumper = dumper; + } + + public void close() throws IOException { + if (dumper != null) { + try { + dumper.close(); + } finally { + dumper = null; + } + } + if (writer != null) { + try { + writer.close(); + } finally { + writer = null; + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/handler/AbstractGraalDumpHandler.java Fri Oct 30 10:46:56 2015 -0700 @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2015, 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.salver.handler; + +import java.io.File; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.channels.ClosedByInterruptException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import com.oracle.graal.debug.DebugDumpHandler; +import com.oracle.graal.debug.TTY; +import com.oracle.graal.salver.Salver; +import com.oracle.graal.salver.SalverOptions; +import com.oracle.graal.salver.dumper.AbstractGraalDumper; +import com.oracle.graal.salver.serialize.JSONSerializer; +import com.oracle.graal.salver.serialize.Serializer; + +public abstract class AbstractGraalDumpHandler<D extends AbstractGraalDumper> extends AbstractDumpHandler<D> implements DebugDumpHandler { + + private Serializer serializer; + + private static final int MAX_FAILURES = 7; + private int failures; + + public static final class NotInitializedException extends IOException { + + private static final long serialVersionUID = 1L; + } + + protected void ensureInitialized() throws IOException { + if (writer == null) { + if (failures < MAX_FAILURES) { + if (SalverOptions.SalverToFile.getValue()) { + initializeFileChannelWriter(); + } else { + initializeSocketChannelWriter(); + } + } + if (writer == null) { + throw new NotInitializedException(); + } + } + if (dumper == null) { + dumper = createDumper(); + if (dumper == null) { + throw new NotInitializedException(); + } + if (serializer == null) { + serializer = createSerializer(); + } + if (serializer.getWriter() != writer) { + serializer.setWriter(writer); + } + dumper.setSerializer(serializer); + dumper.beginDump(); + } + } + + protected abstract D createDumper(); + + protected Serializer createSerializer() { + return new JSONSerializer(); + } + + protected abstract void handle(Object obj, String msg) throws IOException; + + protected void initializeSocketChannelWriter() { + InetSocketAddress socketAddress = Salver.getSocketAddress(); + try { + setWriter(socketAddress); + printlnTTY("Connected to %s:%d (ECID = %s)", socketAddress.getHostName(), socketAddress.getPort(), Salver.ECID); + } catch (ClosedByInterruptException e) { + // May be caused by a cancelled Graal compilation + } catch (IOException e) { + printlnTTY("Couldn't connect to %s:%d (%s)", socketAddress.getHostName(), socketAddress.getPort(), e); + failures++; + } + } + + private static final ThreadLocal<SimpleDateFormat> sdf = new ThreadLocal<SimpleDateFormat>() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("YYYY-MM-dd_HH-mm"); + } + }; + + protected void initializeFileChannelWriter() { + String filename = sdf.get().format(new Date()); + if (label != null) { + filename += "_" + Salver.ECID + "_" + label.replaceAll("(?i)[^a-z0-9-]", "-"); + } + String fileExt = JSONSerializer.getFileExtension(); + File file = new File(filename + "." + fileExt); + try { + for (int i = 1; file.exists(); i++) { + if (i < 1 << 7) { + file = new File(filename + "_" + i + "." + fileExt); + } else { + throw new IOException(); + } + } + setWriter(file.toPath()); + printlnTTY("Dumping to \"%s\"", file.getName()); + } catch (ClosedByInterruptException e) { + // May be caused by a cancelled Graal compilation + } catch (IOException e) { + printlnTTY("Failed to open %s for dumping (%s)", file.getName(), e); + failures++; + } + } + + public void dump(Object obj) { + dump(obj, null); + } + + @Override + public void dump(Object obj, String msg) { + try { + handle(obj, msg); + } catch (NotInitializedException e) { + // Ignore + } catch (IOException e) { + printlnTTY("%s", e); + if (failures < MAX_FAILURES) { + failures++; + } else { + close(); + } + } + } + + @Override + public void close() { + try { + super.close(); + } catch (IOException e) { + printlnTTY("%s", e); + } finally { + failures = 0; + } + } + + protected void printlnTTY(String format, Object... args) { + if (label != null) { + TTY.println("[" + label + "] " + format, args); + } else { + TTY.println(format, args); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/handler/DumpHandler.java Fri Oct 30 10:46:56 2015 -0700 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2015, 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.salver.handler; + +import java.io.Closeable; +import java.io.IOException; + +public interface DumpHandler extends Closeable, AutoCloseable { + + void dump(Object obj, String msg) throws IOException; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/handler/GraphDumpHandler.java Fri Oct 30 10:46:56 2015 -0700 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2015, 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.salver.handler; + +import java.io.IOException; + +import com.oracle.graal.graph.Graph; +import com.oracle.graal.salver.dumper.GraphDumper; + +public class GraphDumpHandler extends AbstractGraalDumpHandler<GraphDumper> { + + @Override + protected GraphDumper createDumper() { + return new GraphDumper(); + } + + @Override + public void handle(Object obj, String msg) throws IOException { + if (obj instanceof Graph) { + ensureInitialized(); + dumper.dump((Graph) obj, msg); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/package-info.java Fri Oct 30 10:46:56 2015 -0700 @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2015, 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. + */ +/** + * <p> + * This package provides the basic functionality to send debug dumps to a + * server that is able to process Salver trace events. + * </p> + * + * <p> + * Salver is a Web Application Framework for Trace Visualization which + * defines an interface for sending trace information via serializable events, + * e.g. as JSON text representation. Events are grouped into separate + * namespaces to simplify event processing. Listeners can register for a + * certain namespace and will receive all relevant events. + * </p> + * + * <p> + * In order to process trace events of this package the server needs to listen + * for the "graal/graph" namespace. + * </p> + * + * <p> + * See {@link com.oracle.graal.salver.SalverOptions SalverOptions} for all + * available options. + * <p> + * + * <p> + * Basic components of this package: + * <ul> + * <li>DumpHandler:<br/> + * Initialization of the corresponding Dumper in case a given object can + * be processed. + * </li> + * <li>Dumper:<br/> + * Processing the object about to be dumped and extract all necessary + * information in order to produce a serializable data object. + * </li> + * <li>Serializer:<br/> + * Serializing a given data object, e.g. to a JSON text representation. + * </li> + * <li>Writer:<br/> + * Writing the actual data, e.g. to a WritableByteChannel. + * </li> + * </ul> + * </p> + * + * <p> + * Currently available {@link com.oracle.graal.debug.DebugDumpHandler DebugDumpHandlers}: + * <ul> + * <li>{@link com.oracle.graal.salver.handler.GraphDumpHandler GraphDumpHandler}:<br> + * Dumps {@link com.oracle.graal.graph.Graph Graphs} (extracts almost the + * same information as IGV's dump handler). + * </li> + * </ul> + * </p> + */ +package com.oracle.graal.salver; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/serialize/AbstractSerializer.java Fri Oct 30 10:46:56 2015 -0700 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2015, 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.salver.serialize; + +import java.io.IOException; + +import com.oracle.graal.salver.writer.DumpWriter; + +public abstract class AbstractSerializer implements Serializer { + + protected DumpWriter writer; + + public AbstractSerializer() { + } + + public AbstractSerializer(DumpWriter writer) { + if (writer != null) { + setWriter(writer); + } + } + + public DumpWriter getWriter() { + return writer; + } + + public void setWriter(DumpWriter writer) { + this.writer = writer; + } + + public void reset() throws IOException { + } + + public void flush() throws IOException { + if (writer != null) { + writer.flush(); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/serialize/JSONSerializer.java Fri Oct 30 10:46:56 2015 -0700 @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2015, 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.salver.serialize; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import com.oracle.graal.salver.writer.DumpWriter; + +public class JSONSerializer extends AbstractSerializer { + + public static final String MEDIA_TYPE = "application/json"; + public static final String FILE_EXTENSION = "json"; + + public JSONSerializer() { + } + + public JSONSerializer(DumpWriter writer) { + super(writer); + } + + public JSONSerializer serialize(Object obj) throws IOException { + if (writer != null) { + writer.write(appendValue(new StringBuilder(), obj).append('\n')); + } + return this; + } + + public static StringBuilder stringify(StringBuilder sb, Object obj) { + return appendValue(sb, obj); + } + + public static String stringify(Object obj) { + return appendValue(new StringBuilder(), obj).toString(); + } + + public static String getMediaType() { + return MEDIA_TYPE; + } + + public static String getFileExtension() { + return FILE_EXTENSION; + } + + @SuppressWarnings("unchecked") + private static StringBuilder appendValue(StringBuilder sb, Object val) { + if (val instanceof Map<?, ?>) { + return appendDict(sb, (Map<Object, Object>) val); + } + if (val instanceof List<?>) { + return appendList(sb, (List<Object>) val); + } + if (val instanceof byte[]) { + return appendByteArray(sb, (byte[]) val); + } + if (val instanceof Number) { + return sb.append(val); + } + if (val instanceof Boolean) { + return sb.append(val); + } + if (val == null) { + return sb.append("null"); + } + return appendString(sb, String.valueOf(val)); + } + + private static StringBuilder appendDict(StringBuilder sb, Map<Object, Object> dict) { + sb.append('{'); + boolean comma = false; + for (Map.Entry<Object, Object> entry : dict.entrySet()) { + if (comma) { + sb.append(','); + } else { + comma = true; + } + appendString(sb, String.valueOf(entry.getKey())); + sb.append(':'); + appendValue(sb, entry.getValue()); + } + return sb.append('}'); + } + + private static StringBuilder appendList(StringBuilder sb, List<Object> list) { + sb.append('['); + boolean comma = false; + for (Object val : list) { + if (comma) { + sb.append(','); + } else { + comma = true; + } + appendValue(sb, val); + } + return sb.append(']'); + } + + private static StringBuilder appendString(StringBuilder sb, String str) { + sb.append('"'); + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + switch (c) { + case '"': + sb.append("\\\""); + break; + case '\\': + sb.append("\\\\"); + break; + case '\b': + sb.append("\\b"); + break; + case '\f': + sb.append("\\f"); + break; + case '\n': + sb.append("\\n"); + break; + case '\r': + sb.append("\\r"); + break; + case '\t': + sb.append("\\t"); + break; + default: { + if (Character.isISOControl(c)) { + sb.append("\\u00"); + sb.append(Character.forDigit((c >> 4) & 0xF, 16)); + sb.append(Character.forDigit(c & 0xF, 16)); + } else { + sb.append(c); + } + } + } + } + return sb.append('"'); + } + + private static StringBuilder appendByteArray(StringBuilder sb, byte[] arr) { + if (arr.length > 0) { + sb.append("0x"); + for (byte b : arr) { + sb.append(String.format("%02x", b)); + } + return sb; + } + return sb.append("null"); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/serialize/Serializer.java Fri Oct 30 10:46:56 2015 -0700 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2015, 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.salver.serialize; + +import java.io.Flushable; +import java.io.IOException; + +import com.oracle.graal.salver.writer.DumpWriter; + +public interface Serializer extends Flushable { + + DumpWriter getWriter(); + + void setWriter(DumpWriter writer); + + Serializer serialize(Object obj) throws IOException; + + void reset() throws IOException; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/util/ECIDUtil.java Fri Oct 30 10:46:56 2015 -0700 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2015, 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.salver.util; + +import java.security.SecureRandom; +import java.util.Random; + +public class ECIDUtil { + + private static final Random RANDOM = new SecureRandom(); + + private static final String BASE58_ALPHABET = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz123456789"; + + public static String random() { + return random(8); + } + + public static String random(int length) { + StringBuilder sb = new StringBuilder(); + byte[] bytes = new byte[length]; + RANDOM.nextBytes(bytes); + for (byte b : bytes) { + sb.append(BASE58_ALPHABET.charAt((b & 0xff) % 58)); + } + return sb.toString(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/util/MethodContext.java Fri Oct 30 10:46:56 2015 -0700 @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2015, 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.salver.util; + +import static com.oracle.graal.debug.GraalDebugConfig.asJavaMethod; + +import java.util.ArrayList; + +import com.oracle.graal.debug.Debug; +import com.oracle.graal.debug.DebugDumpScope; +import com.oracle.graal.graph.Graph; +import com.oracle.graal.salver.util.MethodContext.Item; + +import jdk.vm.ci.meta.JavaMethod; + +public class MethodContext extends ArrayList<Item> { + + private static final long serialVersionUID = 1L; + + public static final class Item { + + private String name; + private JavaMethod method; + private int debugId; + + private Item(String name, JavaMethod method, int debugId) { + this.name = name; + this.method = method; + this.debugId = debugId; + } + + private Item(JavaMethod method) { + this(method.format("%H::%n(%p)"), method, -1); + } + + private Item(String name) { + this(name, null, -1); + } + + public String getName() { + return name; + } + + public JavaMethod getMethod() { + return method; + } + + public int getDebugId() { + return debugId; + } + } + + public MethodContext() { + Object lastMethodOrGraph = null; + for (Object obj : Debug.context()) { + JavaMethod method = asJavaMethod(obj); + if (method != null) { + JavaMethod lastAsMethod = asJavaMethod(lastMethodOrGraph); + if (lastAsMethod == null || !lastAsMethod.equals(method)) { + add(new Item(method)); + } else { + /* + * This prevents multiple adjacent method context objects for the same method + * from resulting in multiple IGV tree levels. This works on the assumption that + * real inlining debug scopes will have a graph context object between the + * inliner and inlinee context objects. + */ + } + } else if (obj instanceof DebugDumpScope) { + DebugDumpScope debugDumpScope = (DebugDumpScope) obj; + if (debugDumpScope.decorator && !isEmpty()) { + try { + get(size() - 1).debugId = Integer.parseInt(debugDumpScope.name); + } catch (NumberFormatException e) { + // Ignore + } + } else { + add(new Item(debugDumpScope.name)); + } + } + if (obj instanceof JavaMethod || obj instanceof Graph) { + lastMethodOrGraph = obj; + } + } + if (isEmpty()) { + add(new Item("Top Scope")); + } + } + + public boolean itemEquals(int index, MethodContext context) { + Item i1 = get(index); + Item i2 = context != null ? context.get(index) : null; + if (i1 != null && i2 != null && i1.name != null && i2.name != null) { + return i1.name.equals(i2.name) && i1.debugId == i2.debugId; + } + return false; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/writer/ChannelDumpWriter.java Fri Oct 30 10:46:56 2015 -0700 @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2015, 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.salver.writer; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.ReadOnlyBufferException; +import java.nio.channels.WritableByteChannel; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CoderResult; +import java.nio.charset.StandardCharsets; + +public class ChannelDumpWriter implements DumpWriter { + + private static final int BUFFER_CAPACITY = 256 * 1024; + + protected final WritableByteChannel channel; + protected final ByteBuffer buffer; + + public ChannelDumpWriter(WritableByteChannel channel) { + this(channel, ByteBuffer.allocateDirect(BUFFER_CAPACITY)); + } + + public ChannelDumpWriter(WritableByteChannel channel, ByteBuffer buffer) { + this.channel = channel; + this.buffer = buffer; + } + + private void ensureAvailable(int len) throws IOException { + if (buffer.isReadOnly()) { + throw new ReadOnlyBufferException(); + } + if (buffer.capacity() < len) { + throw new IllegalArgumentException(); + } + while (buffer.remaining() < len) { + flush(); + } + } + + public ChannelDumpWriter write(byte b) throws IOException { + ensureAvailable(1); + buffer.put(b); + return this; + } + + public ChannelDumpWriter write(byte[] arr) throws IOException { + if (buffer.isReadOnly()) { + throw new ReadOnlyBufferException(); + } + int offset = 0; + while (offset < arr.length) { + int available = buffer.remaining(); + int length = Math.min(available, arr.length - offset); + buffer.put(arr, offset, length); + if (!buffer.hasRemaining()) { + flush(); + } + offset += length; + } + return this; + } + + public ChannelDumpWriter write(ByteBuffer buf) throws IOException { + if (buf == buffer) { + throw new IllegalArgumentException(); + } + if (buffer.isReadOnly()) { + throw new ReadOnlyBufferException(); + } + while (buf.hasRemaining()) { + int available = buffer.remaining(); + int remaining = buf.remaining(); + for (int i = 0, n = Math.min(available, remaining); i < n; i++) { + buffer.put(buf.get()); + } + if (!buffer.hasRemaining()) { + flush(); + } + } + return this; + } + + public ChannelDumpWriter write(CharSequence csq) throws IOException { + if (buffer.isReadOnly()) { + throw new ReadOnlyBufferException(); + } + CharsetEncoder encoder = StandardCharsets.UTF_8.newEncoder(); + CharBuffer buf = CharBuffer.wrap(csq); + while (true) { + CoderResult result = encoder.encode(buf, buffer, true); + if (result.isError()) { + throw new IOException(result.toString()); + } + if (!buffer.hasRemaining()) { + flush(); + } + if (result.isOverflow()) { + continue; + } + break; + } + return this; + } + + public ChannelDumpWriter writeChar(char v) throws IOException { + ensureAvailable(1 << 1); + buffer.putChar(v); + return this; + } + + public ChannelDumpWriter writeShort(short v) throws IOException { + ensureAvailable(1 << 1); + buffer.putShort(v); + return this; + } + + public ChannelDumpWriter writeInt(int v) throws IOException { + ensureAvailable(1 << 2); + buffer.putInt(v); + return this; + } + + public ChannelDumpWriter writeLong(long v) throws IOException { + ensureAvailable(1 << 3); + buffer.putLong(v); + return this; + } + + public ChannelDumpWriter writeFloat(float v) throws IOException { + ensureAvailable(1 << 2); + buffer.putFloat(v); + return this; + } + + public ChannelDumpWriter writeDouble(double v) throws IOException { + ensureAvailable(1 << 3); + buffer.putDouble(v); + return this; + } + + public void flush() throws IOException { + if (buffer != null && channel != null) { + buffer.flip(); + channel.write(buffer); + buffer.compact(); + } + } + + public void close() throws IOException { + if (channel != null) { + try { + flush(); + } finally { + channel.close(); + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/writer/DumpWriter.java Fri Oct 30 10:46:56 2015 -0700 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2015, 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.salver.writer; + +import java.io.Closeable; +import java.io.Flushable; +import java.io.IOException; +import java.nio.ByteBuffer; + +public interface DumpWriter extends Closeable, Flushable, AutoCloseable { + + DumpWriter write(byte b) throws IOException; + + DumpWriter write(byte[] arr) throws IOException; + + DumpWriter write(ByteBuffer buf) throws IOException; + + DumpWriter write(CharSequence csq) throws IOException; + + DumpWriter writeChar(char v) throws IOException; + + DumpWriter writeShort(short v) throws IOException; + + DumpWriter writeInt(int v) throws IOException; + + DumpWriter writeLong(long v) throws IOException; + + DumpWriter writeFloat(float v) throws IOException; + + DumpWriter writeDouble(double v) throws IOException; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/SafepointRethrowDeoptPETest.java Fri Oct 30 10:46:56 2015 -0700 @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2015, 2015, 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.truffle.test; + +import java.util.concurrent.CountDownLatch; + +import org.junit.Assert; +import org.junit.Assume; +import org.junit.Test; + +import com.oracle.graal.compiler.common.GraalOptions; +import com.oracle.graal.truffle.OptimizedCallTarget; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.RootNode; + +public class SafepointRethrowDeoptPETest extends PartialEvaluationTest { + + static final Object RETURN_VALUE = "1 2 3"; + static final RuntimeException BREAK_EX = new RuntimeException(); + static final RuntimeException CONTINUE_EX = new RuntimeException(); + static volatile int terminate; + static volatile int entered; + + public static class Test0RootNode extends RootNode { + public Test0RootNode() { + super(MockLanguage.class, null, null); + } + + @Override + public Object execute(VirtualFrame frame) { + entered = 1; + for (;;) { + try { + if (terminate != 0) { + throw BREAK_EX; + } else { + throw CONTINUE_EX; + } + } catch (RuntimeException e) { + if (e == BREAK_EX) { + break; + } else if (e == CONTINUE_EX) { + continue; + } + throw e; + } + } + return RETURN_VALUE; + } + } + + public abstract static class TestNode extends Node { + public abstract void executeVoid(); + } + + public static class ThrowNode extends TestNode { + private final RuntimeException exception; + + public ThrowNode(RuntimeException exception) { + this.exception = exception; + } + + @Override + public void executeVoid() { + throw exception; + } + } + + public static class Test1RootNode extends RootNode { + @Child private ThrowNode throwBreak = new ThrowNode(BREAK_EX); + @Child private ThrowNode throwContinue = new ThrowNode(CONTINUE_EX); + + public Test1RootNode() { + super(MockLanguage.class, null, null); + } + + @Override + public Object execute(VirtualFrame frame) { + entered = 1; + for (;;) { + try { + if (terminate != 0) { + throwBreak.executeVoid(); + } else { + throwContinue.executeVoid(); + } + } catch (RuntimeException e) { + if (e == BREAK_EX) { + break; + } else if (e == CONTINUE_EX) { + continue; + } + throw e; + } + } + return RETURN_VALUE; + } + } + + public static class BreakOrContinueNode extends TestNode { + @Child private ThrowNode throwBreak = new ThrowNode(BREAK_EX); + @Child private ThrowNode throwContinue = new ThrowNode(CONTINUE_EX); + + @Override + public void executeVoid() { + if (terminate != 0) { + throwBreak.executeVoid(); + } else { + throwContinue.executeVoid(); + } + } + } + + public static class ExceptionTargetNode extends TestNode { + @Child private TestNode body; + private final RuntimeException exception; + + public ExceptionTargetNode(RuntimeException exception, TestNode body) { + this.body = body; + this.exception = exception; + } + + @Override + public void executeVoid() { + try { + body.executeVoid(); + } catch (RuntimeException e) { + if (e != exception) { + throw e; + } + } + } + } + + public static class LoopNode extends TestNode { + @Child private TestNode body; + + public LoopNode(TestNode body) { + this.body = body; + } + + @Override + public void executeVoid() { + for (;;) { + body.executeVoid(); + } + } + } + + public static class Test2RootNode extends RootNode { + @Child private TestNode body; + + public Test2RootNode() { + super(MockLanguage.class, null, null); + this.body = new ExceptionTargetNode(BREAK_EX, new LoopNode(new ExceptionTargetNode(CONTINUE_EX, new BreakOrContinueNode()))); + } + + @Override + public Object execute(VirtualFrame frame) { + entered = 1; + body.executeVoid(); + return RETURN_VALUE; + } + } + + @Test + public void test() { + Assume.assumeTrue(GraalOptions.GenLoopSafepoints.getValue()); + synchronized (SafepointRethrowDeoptPETest.class) { // safeguard static fields + testInner(new Test0RootNode()); + testInner(new Test1RootNode()); + testInner(new Test2RootNode()); + } + } + + private void testInner(RootNode rootNode) { + terminate = 1; // executed 3 times + OptimizedCallTarget compiledMethod = compileHelper(rootNode.getClass().getSimpleName(), rootNode, new Object[0]); + + terminate = 0; + entered = 0; + CountDownLatch cdl = new CountDownLatch(1); + Thread t1 = new Thread(() -> { + try { + cdl.await(); + while (entered == 0) { + /* spin */ + } + /* Thread.sleep(100); */ + compiledMethod.invalidate(); + } catch (InterruptedException e) { + Assert.fail("interrupted"); + } + terminate = 1; + }); + Thread t2 = new Thread(() -> { + cdl.countDown(); + Object result = compiledMethod.call(); + Assert.assertEquals(RETURN_VALUE, result); + }); + + t1.start(); + t2.start(); + try { + t1.join(); + t2.join(); + } catch (InterruptedException e) { + Assert.fail("interrupted"); + } + } +}
--- a/mx.graal/suite.py Thu Oct 29 12:23:07 2015 -0700 +++ b/mx.graal/suite.py Fri Oct 30 10:46:56 2015 -0700 @@ -22,7 +22,7 @@ { "name" : "jvmci", "optional" : "true", - "version" : "6832e10a0b970b04d554ab561efb2bf9e867c2d6", + "version" : "3c1edc9c60d8f4ecea01794eb0acccea400a89b1", "urls" : [ {"url" : "http://lafo.ssw.uni-linz.ac.at/hg/graal-jvmci-8", "kind" : "hg"}, {"url" : "https://curio.ssw.jku.at/nexus/content/repositories/snapshots", "kind" : "binary"}, @@ -926,7 +926,24 @@ "javaCompliance" : _8_9, "annotationProcessors" : [ap("SERVICE")], "workingSets" : "Graal,Truffle,SPARC", - } + }, + + # ------------- Salver ------------- + + "com.oracle.graal.salver" : { + "subDir" : "graal", + "sourceDirs" : ["src"], + "dependencies" : [ + "com.oracle.graal.java", + ], + "annotationProcessors" : [ + ap("OPTIONS"), + ap("SERVICE"), + ], + "checkstyle" : "com.oracle.graal.graph", + "javaCompliance" : _8_9, + "workingSets" : "Graal", + }, }, "distributions" : { @@ -974,6 +991,7 @@ "com.oracle.graal.replacements.amd64", "com.oracle.graal.compiler.sparc", "com.oracle.graal.replacements.sparc", + "com.oracle.graal.salver", ], "distDependencies" : [ "GRAAL_API",