Mercurial > hg > truffle
changeset 13736:64fa70319890
Merge with 9161ed8ce7964ca3df5e91894522b207a2bc4a3e
author | Michael Van De Vanter <michael.van.de.vanter@oracle.com> |
---|---|
date | Wed, 22 Jan 2014 21:34:00 -0800 |
parents | 2c1c805153e6 (current diff) 9161ed8ce796 (diff) |
children | b9c5875e3a36 7b80276a4e65 174aebb02383 3f27e57439ed |
files | graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/CoreMethodNodeManager.java graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/JRubyParser.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/RubyContext.java |
diffstat | 116 files changed, 1271 insertions(+), 742 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java Wed Jan 22 21:34:00 2014 -0800 @@ -146,6 +146,7 @@ case Short: case Int: case Long: + case NarrowOop: case Object: return true; }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Architecture.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Architecture.java Wed Jan 22 21:34:00 2014 -0800 @@ -223,6 +223,8 @@ return 8; case Object: return wordSize; + case NarrowOop: + return wordSize / 2; default: return 0; }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java Wed Jan 22 21:34:00 2014 -0800 @@ -227,10 +227,17 @@ return sb; } + public interface RefMapFormatter { + + String formatStackSlot(int frameRefMapIndex); + + String formatRegister(int regRefMapIndex); + } + /** * Formats a location present in a register or frame reference map. */ - public static class RefMapFormatter { + public static class DefaultRefMapFormatter implements RefMapFormatter { /** * The size of a stack slot. @@ -252,7 +259,7 @@ */ public final int refMapToFPOffset; - public RefMapFormatter(Architecture arch, int slotSize, Register fp, int refMapToFPOffset) { + public DefaultRefMapFormatter(Architecture arch, int slotSize, Register fp, int refMapToFPOffset) { this.arch = arch; this.slotSize = slotSize; this.fp = fp; @@ -283,25 +290,16 @@ */ public static StringBuilder append(StringBuilder sb, DebugInfo info, RefMapFormatter formatter) { String nl = NEW_LINE; - if (info.hasRegisterRefMap()) { + ReferenceMap refMap = info.getReferenceMap(); + if (refMap != null && refMap.hasRegisterRefMap()) { sb.append(" reg-ref-map:"); - BitSet bm = info.getRegisterRefMap(); - if (formatter != null) { - for (int reg = bm.nextSetBit(0); reg >= 0; reg = bm.nextSetBit(reg + 1)) { - sb.append(" " + formatter.formatRegister(reg)); - } - } - sb.append(' ').append(bm).append(nl); + refMap.appendRegisterMap(sb, formatter); + sb.append(nl); } - if (info.hasStackRefMap()) { + if (refMap != null && refMap.hasFrameRefMap()) { sb.append("frame-ref-map:"); - BitSet bm = info.getFrameRefMap(); - if (formatter != null) { - for (int i = bm.nextSetBit(0); i >= 0; i = bm.nextSetBit(i + 1)) { - sb.append(" " + formatter.formatStackSlot(i)); - } - } - sb.append(' ').append(bm).append(nl); + refMap.appendFrameMap(sb, formatter); + sb.append(nl); } RegisterSaveLayout calleeSaveInfo = info.getCalleeSaveInfo(); if (calleeSaveInfo != null) {
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java Wed Jan 22 21:34:00 2014 -0800 @@ -696,8 +696,19 @@ private static void appendDebugInfo(StringBuilder sb, DebugInfo info) { if (info != null) { - appendRefMap(sb, "stackMap", info.getFrameRefMap()); - appendRefMap(sb, "registerMap", info.getRegisterRefMap()); + ReferenceMap refMap = info.getReferenceMap(); + if (refMap != null) { + if (refMap.hasFrameRefMap()) { + sb.append(" stackMap["); + refMap.appendFrameMap(sb, null); + sb.append(']'); + } + if (refMap.hasRegisterRefMap()) { + sb.append(" registerMap["); + refMap.appendRegisterMap(sb, null); + sb.append(']'); + } + } RegisterSaveLayout calleeSaveInfo = info.getCalleeSaveInfo(); if (calleeSaveInfo != null) { sb.append(" callee-save-info["); @@ -721,12 +732,6 @@ } } - private static void appendRefMap(StringBuilder sb, String name, BitSet map) { - if (map != null) { - sb.append(' ').append(name).append('[').append(map.toString()).append(']'); - } - } - /** * @return the list of infopoints, sorted by {@link Site#pcOffset} */
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DebugInfo.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DebugInfo.java Wed Jan 22 21:34:00 2014 -0800 @@ -23,15 +23,13 @@ package com.oracle.graal.api.code; import java.io.*; -import java.util.*; /** * Represents the debugging information for a particular point of execution. This information * includes: * <ul> * <li>a {@linkplain #getBytecodePosition() bytecode position}</li> - * <li>a reference map for {@linkplain #getRegisterRefMap() registers}</li> - * <li>a reference map for {@linkplain #getFrameRefMap() stack slots} in the current frame</li> + * <li>a reference map for registers and stack slots in the current frame</li> * <li>a map from bytecode locals and operand stack slots to their values or locations from which * their values can be read</li> * <li>a map from the registers (in the caller's frame) to the slots where they are saved in the @@ -42,8 +40,7 @@ private static final long serialVersionUID = -6047206624915812516L; private final BytecodePosition bytecodePosition; - private final BitSet registerRefMap; - private final BitSet frameRefMap; + private final ReferenceMap referenceMap; private RegisterSaveLayout calleeSaveInfo; /** @@ -51,13 +48,11 @@ * * @param codePos the {@linkplain BytecodePosition code position} or {@linkplain BytecodeFrame * frame} info - * @param registerRefMap the register map - * @param frameRefMap the reference map for {@code frame}, which may be {@code null} + * @param referenceMap the reference map */ - public DebugInfo(BytecodePosition codePos, BitSet registerRefMap, BitSet frameRefMap) { + public DebugInfo(BytecodePosition codePos, ReferenceMap referenceMap) { this.bytecodePosition = codePos; - this.registerRefMap = registerRefMap; - this.frameRefMap = frameRefMap; + this.referenceMap = referenceMap; } /** @@ -68,20 +63,6 @@ } /** - * @return {@code true} if this debug info has a reference map for the registers - */ - public boolean hasRegisterRefMap() { - return getRegisterRefMap() != null && getRegisterRefMap().size() > 0; - } - - /** - * @return {@code true} if this debug info has a reference map for the stack - */ - public boolean hasStackRefMap() { - return getFrameRefMap() != null && getFrameRefMap().size() > 0; - } - - /** * Gets the deoptimization information for each inlined frame (if available). * * @return {@code null} if no frame de-opt info is {@linkplain #hasFrame() available} @@ -107,21 +88,8 @@ return bytecodePosition; } - /** - * @return The reference map for the registers at this point. The reference map is <i>packed</i> - * in that for bit {@code k} in byte {@code n}, it refers to the register whose - * {@linkplain Register#number number} is {@code (k + n * 8)}. - */ - public BitSet getRegisterRefMap() { - return registerRefMap; - } - - /** - * @return The reference map for the stack frame at this point. A set bit at {@code k} in the - * map represents stack slot number {@code k}. - */ - public BitSet getFrameRefMap() { - return frameRefMap; + public ReferenceMap getReferenceMap() { + return referenceMap; } /**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java Wed Jan 22 21:34:00 2014 -0800 @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2009, 2011, 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.api.code; + +import java.io.*; +import java.util.*; + +import com.oracle.graal.api.code.CodeUtil.RefMapFormatter; + +public class ReferenceMap implements Serializable { + + private static final long serialVersionUID = -1052183095979496819L; + + /** + * Contains 2 bits per register. + * <ul> + * <li>bit0 = 0: contains no references</li> + * <li>bit0 = 1, bit1 = 0: contains a wide oop</li> + * <li>bit0 = 1, bit1 = 1: contains a narrow oop</li> + * </ul> + */ + private final BitSet registerRefMap; + + /** + * Contains 3 bits per stack slot. + * <ul> + * <li>bit0 = 0: contains no references</li> + * <li>bit0 = 1, bit1+2 = 0: contains a wide oop</li> + * <li>bit0 = 1, bit1 = 1: contains a narrow oop in the lower half</li> + * <li>bit0 = 1, bit2 = 1: contains a narrow oop in the upper half</li> + * </ul> + */ + private final BitSet frameRefMap; + + public ReferenceMap(int registerCount, int frameSlotCount) { + if (registerCount > 0) { + this.registerRefMap = new BitSet(registerCount * 2); + } else { + this.registerRefMap = null; + } + this.frameRefMap = new BitSet(frameSlotCount * 3); + } + + public void setRegister(int idx, boolean narrow) { + registerRefMap.set(2 * idx); + if (narrow) { + registerRefMap.set(2 * idx + 1); + } + } + + public void setStackSlot(int idx, boolean narrow1, boolean narrow2) { + frameRefMap.set(3 * idx); + if (narrow1) { + frameRefMap.set(3 * idx + 1); + } + if (narrow2) { + frameRefMap.set(3 * idx + 2); + } + } + + public boolean hasRegisterRefMap() { + return registerRefMap != null && registerRefMap.size() > 0; + } + + public boolean hasFrameRefMap() { + return frameRefMap != null && frameRefMap.size() > 0; + } + + private static class NumberedRefMapFormatter implements RefMapFormatter { + + public String formatStackSlot(int frameRefMapIndex) { + return "s" + frameRefMapIndex; + } + + public String formatRegister(int regRefMapIndex) { + return "r" + regRefMapIndex; + } + } + + public void appendRegisterMap(StringBuilder sb, RefMapFormatter formatterArg) { + RefMapFormatter formatter = formatterArg; + if (formatter == null) { + formatter = new NumberedRefMapFormatter(); + } + + for (int reg = registerRefMap.nextSetBit(0); reg >= 0; reg = registerRefMap.nextSetBit(reg + 2)) { + sb.append(' ').append(formatter.formatRegister(reg / 2)); + } + } + + public void appendFrameMap(StringBuilder sb, RefMapFormatter formatterArg) { + RefMapFormatter formatter = formatterArg; + if (formatter == null) { + formatter = new NumberedRefMapFormatter(); + } + + for (int slot = frameRefMap.nextSetBit(0); slot >= 0; slot = frameRefMap.nextSetBit(slot + 3)) { + sb.append(' ').append(formatter.formatStackSlot(slot / 3)); + } + } +}
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java Wed Jan 22 21:34:00 2014 -0800 @@ -159,6 +159,7 @@ case Double: return asDouble(); case Object: + case NarrowOop: return object; case Illegal: return this; @@ -171,7 +172,7 @@ if (!ignoreKind && getKind() != other.getKind()) { return false; } - if (getKind() == Kind.Object) { + if (getKind() == Kind.Object || getKind() == Kind.NarrowOop) { return object == other.object; } return primitive == other.primitive && getPrimitiveAnnotation() == other.getPrimitiveAnnotation(); @@ -234,12 +235,12 @@ /** * Returns the object reference this constant represents. The constant must have kind - * {@link Kind#Object}. + * {@link Kind#Object} or {@link Kind#NarrowOop}. * * @return the constant value */ public Object asObject() { - assert getKind() == Kind.Object; + assert getKind() == Kind.Object || getKind() == Kind.NarrowOop; return object; } @@ -249,7 +250,7 @@ * @return null if this constant is not primitive or has no annotation */ public Object getPrimitiveAnnotation() { - return getKind() == Kind.Object ? null : object; + return getKind() == Kind.Object || getKind() == Kind.NarrowOop ? null : object; } /** @@ -259,7 +260,7 @@ */ @Override public int hashCode() { - if (getKind() == Kind.Object) { + if (getKind() == Kind.Object || getKind() == Kind.NarrowOop) { return System.identityHashCode(object); } return (int) primitive * getKind().ordinal(); @@ -393,6 +394,16 @@ } /** + * Creates a boxed narrow oop constant. + * + * @param o the object value to box + * @return a boxed copy of {@code value} + */ + public static Constant forNarrowOop(Object o) { + return new Constant(Kind.NarrowOop, o, 0L); + } + + /** * Creates an annotated int or long constant. An annotation enables a client to associate some * extra semantic or debugging information with a primitive. An annotated primitive constant is * never {@linkplain #equals(Object) equal} to a non-annotated constant. @@ -440,6 +451,8 @@ return forDouble((Double) value); case Object: return forObject(value); + case NarrowOop: + return forNarrowOop(value); default: throw new RuntimeException("cannot create Constant for boxed " + kind + " value"); } @@ -472,6 +485,8 @@ return LONG_0; case Object: return NULL_OBJECT; + case NarrowOop: + return forNarrowOop(null); default: throw new IllegalArgumentException(kind.toString()); }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java Wed Jan 22 21:34:00 2014 -0800 @@ -57,6 +57,9 @@ /** The Object kind, also used for arrays. */ Object('a', "Object", false, null, null), + /** The narrow oop kind. */ + NarrowOop('n', "NarrowOop", false, null, null), + /** The void float kind. */ Void('v', "void", false, java.lang.Void.TYPE, java.lang.Void.class),
--- a/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java Wed Jan 22 21:34:00 2014 -0800 @@ -700,6 +700,9 @@ bra(str); } + /** + * @param r + */ public void nullCheck(Register r) { // setp(....); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXMethodInvalidation1Test.java Wed Jan 22 21:34:00 2014 -0800 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.ptx.test; + +import org.junit.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.ptx.*; + +/** + * Tests that a {@linkplain PTXWrapperBuilder PTX kernel wrapper} deoptimizes if the kernel is + * invalid. + */ +public class PTXMethodInvalidation1Test extends PTXTest { + + @Test + public void test() { + test("testSnippet", 100); + } + + @Override + protected HotSpotNmethod installKernel(ResolvedJavaMethod method, ExternalCompilationResult ptxCode) { + HotSpotNmethod ptxKernel = super.installKernel(method, ptxCode); + ptxKernel.invalidate(); + return ptxKernel; + } + + int f = 42; + + public int testSnippet(int delta) { + return f + delta; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXMethodInvalidation2Test.java Wed Jan 22 21:34:00 2014 -0800 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.ptx.test; + +import java.lang.ref.*; + +import org.junit.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.ptx.*; +import com.oracle.graal.nodes.*; + +/** + * A full GC on HotSpot will unload an nmethod that contains an embedded oop which is the only + * reference to its referent. The nmethod created for a {@linkplain PTXWrapperBuilder PTX kernel + * wrapper} has an embedded oop referring to a {@link HotSpotNmethod} object associated with the + * nmethod for the installed PTX kernel. This embedded oop is a weak reference as described above so + * there must be another strong reference from the wrapper to the {@link HotSpotNmethod} object. + */ +public class PTXMethodInvalidation2Test extends PTXTest { + + @Test + public void test() { + test("testSnippet", 100); + } + + @Override + protected InstalledCode getCode(ResolvedJavaMethod method, StructuredGraph graph) { + InstalledCode code = super.getCode(method, graph); + + // Try hard to force a full GC + int attempts = 0; + WeakReference<Object> ref = new WeakReference<>(new Object()); + while (ref.get() != null) { + System.gc(); + // Give up after 1000 attempts + Assume.assumeTrue(++attempts < 1000); + } + + Assert.assertFalse(code.getStart() == 0L); + return code; + } + + int f = 42; + + public int testSnippet(int delta) { + return f + delta; + } +}
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTest.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTest.java Wed Jan 22 21:34:00 2014 -0800 @@ -57,13 +57,18 @@ return compileKernel(getMetaAccess().lookupJavaMethod(getMethod(test))); } + protected HotSpotNmethod installKernel(ResolvedJavaMethod method, ExternalCompilationResult ptxCode) { + PTXHotSpotBackend ptxBackend = getPTXBackend(); + return ptxBackend.installKernel(method, ptxCode); + } + @Override protected InstalledCode getCode(ResolvedJavaMethod method, StructuredGraph graph) { PTXHotSpotBackend ptxBackend = getPTXBackend(); ExternalCompilationResult ptxCode = compileKernel(method); Assume.assumeTrue(ptxBackend.isDeviceInitialized()); - InstalledCode installedPTXCode = ptxBackend.installKernel(method, ptxCode); - StructuredGraph wrapper = new PTXWrapperBuilder(method, installedPTXCode.getStart(), (HotSpotProviders) getProviders()).getGraph(); + HotSpotNmethod installedPTXCode = installKernel(method, ptxCode); + StructuredGraph wrapper = new PTXWrapperBuilder(method, installedPTXCode, (HotSpotProviders) getProviders()).getGraph(); return super.getCode(method, wrapper); }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Wed Jan 22 21:34:00 2014 -0800 @@ -299,8 +299,8 @@ final ValueNode getResult(String snippet) { processMethod(snippet); - assertEquals(1, graph.getNodes().filter(ReturnNode.class).count()); - return graph.getNodes().filter(ReturnNode.class).first().result(); + assertEquals(1, graph.getNodes(ReturnNode.class).count()); + return graph.getNodes(ReturnNode.class).first().result(); } private void processMethod(final String snippet) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java Wed Jan 22 21:34:00 2014 -0800 @@ -98,11 +98,9 @@ for (int i = 1; i <= 4; i++) { StructuredGraph graph = getCanonicalizedGraph("integerTest" + i); - ValueNode result = getResult(graph); - assertTrue(result instanceof ConditionalNode); - ConditionalNode mat = (ConditionalNode) result; - assertTrue(mat.condition() instanceof IntegerTestNode); - IntegerTestNode test = (IntegerTestNode) mat.condition(); + ReturnNode returnNode = (ReturnNode) graph.start().next(); + ConditionalNode conditional = (ConditionalNode) returnNode.result(); + IntegerTestNode test = (IntegerTestNode) conditional.condition(); ParameterNode param0 = graph.getParameter(0); ParameterNode param1 = graph.getParameter(1); assertTrue((test.x() == param0 && test.y() == param1) || (test.x() == param1 && test.y() == param0)); @@ -133,8 +131,9 @@ assertTrue(result.isConstant() && result.asConstant().asLong() == 1); result = getResult(getCanonicalizedGraph("integerTestCanonicalization2")); assertTrue(result.isConstant() && result.asConstant().asLong() == 1); - result = getResult(getCanonicalizedGraph("integerTestCanonicalization3")); - assertTrue(result instanceof ConditionalNode); + StructuredGraph graph = getCanonicalizedGraph("integerTestCanonicalization3"); + assertEquals(1, graph.getNodes(ReturnNode.class).count()); + assertTrue(graph.getNodes(ReturnNode.class).first().result() instanceof ConditionalNode); } public static int integerTestCanonicalization1(boolean b) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java Wed Jan 22 21:34:00 2014 -0800 @@ -154,14 +154,18 @@ @SuppressWarnings("unused") public static int testDisjunctionSnippet(Object a) { - if (a instanceof Integer) { - if (a == null) { - return -1; + try { + if (a instanceof Integer) { + if (a == null) { + return -1; + } else { + return 2; + } } else { - return 2; + return 3; } - } else { - return 3; + } finally { + field = null; } }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java Wed Jan 22 21:34:00 2014 -0800 @@ -68,6 +68,7 @@ for (Node n : graph.getNodes()) { if (n instanceof ReturnNode) { + assert returnNode == null; returnNode = (ReturnNode) n; } else if (n instanceof MonitorExit) { monitorexit = (MonitorExit) n;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Wed Jan 22 21:34:00 2014 -0800 @@ -172,8 +172,8 @@ protected void assertConstantReturn(StructuredGraph graph, int value) { String graphString = getCanonicalGraphString(graph, false); - Assert.assertEquals("unexpected number of ReturnNodes: " + graphString, graph.getNodes().filter(ReturnNode.class).count(), 1); - ValueNode result = graph.getNodes().filter(ReturnNode.class).first().result(); + Assert.assertEquals("unexpected number of ReturnNodes: " + graphString, graph.getNodes(ReturnNode.class).count(), 1); + ValueNode result = graph.getNodes(ReturnNode.class).first().result(); Assert.assertTrue("unexpected ReturnNode result node: " + graphString, result.isConstant()); Assert.assertEquals("unexpected ReturnNode result kind: " + graphString, result.asConstant().getKind(), Kind.Int); Assert.assertEquals("unexpected ReturnNode result: " + graphString, result.asConstant().asInt(), value);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Wed Jan 22 21:34:00 2014 -0800 @@ -115,7 +115,7 @@ for (TestMode mode : TestMode.values()) { SchedulePhase schedule = getFinalSchedule("testSplit1Snippet", mode); assertReadWithinStartBlock(schedule, true); - assertReadWithinReturnBlock(schedule, false); + assertReadWithinAllReturnBlocks(schedule, false); } } @@ -131,6 +131,7 @@ } else { container.b = 15; } + container.obj = null; } } @@ -138,7 +139,7 @@ public void testSplit2() { SchedulePhase schedule = getFinalSchedule("testSplit2Snippet", TestMode.WITHOUT_FRAMESTATES); assertReadWithinStartBlock(schedule, false); - assertReadWithinReturnBlock(schedule, true); + assertReadWithinAllReturnBlocks(schedule, true); } /** @@ -163,7 +164,7 @@ SchedulePhase schedule = getFinalSchedule("testLoop1Snippet", TestMode.WITHOUT_FRAMESTATES); assertEquals(6, schedule.getCFG().getBlocks().length); assertReadWithinStartBlock(schedule, true); - assertReadWithinReturnBlock(schedule, false); + assertReadWithinAllReturnBlocks(schedule, false); } /** @@ -188,7 +189,7 @@ SchedulePhase schedule = getFinalSchedule("testLoop2Snippet", TestMode.WITHOUT_FRAMESTATES); assertEquals(6, schedule.getCFG().getBlocks().length); assertReadWithinStartBlock(schedule, false); - assertReadWithinReturnBlock(schedule, true); + assertReadWithinAllReturnBlocks(schedule, true); } /** @@ -208,9 +209,9 @@ @Test public void testLoop3() { SchedulePhase schedule = getFinalSchedule("testLoop3Snippet", TestMode.WITHOUT_FRAMESTATES); - assertEquals(7, schedule.getCFG().getBlocks().length); + assertEquals(6, schedule.getCFG().getBlocks().length); assertReadWithinStartBlock(schedule, true); - assertReadWithinReturnBlock(schedule, false); + assertReadWithinAllReturnBlocks(schedule, false); } public String testStringReplaceSnippet(String input) { @@ -246,7 +247,7 @@ SchedulePhase schedule = getFinalSchedule("testLoop5Snippet", TestMode.WITHOUT_FRAMESTATES); assertEquals(7, schedule.getCFG().getBlocks().length); assertReadWithinStartBlock(schedule, false); - assertReadWithinReturnBlock(schedule, false); + assertReadWithinAllReturnBlocks(schedule, false); } /** @@ -261,10 +262,11 @@ public void testArrayCopy() { SchedulePhase schedule = getFinalSchedule("testArrayCopySnippet", TestMode.INLINED_WITHOUT_FRAMESTATES); StructuredGraph graph = schedule.getCFG().getStartBlock().getBeginNode().graph(); - ReturnNode ret = graph.getNodes().filter(ReturnNode.class).first(); + assertEquals(1, graph.getNodes(ReturnNode.class).count()); + ReturnNode ret = graph.getNodes(ReturnNode.class).first(); assertTrue(ret.result() instanceof FloatingReadNode); assertEquals(schedule.getCFG().blockFor(ret), schedule.getCFG().blockFor(ret.result())); - assertReadWithinReturnBlock(schedule, true); + assertReadWithinAllReturnBlocks(schedule, true); } /** @@ -281,7 +283,7 @@ @Test public void testIfRead1() { SchedulePhase schedule = getFinalSchedule("testIfRead1Snippet", TestMode.WITHOUT_FRAMESTATES); - assertEquals(4, schedule.getCFG().getBlocks().length); + assertEquals(3, schedule.getCFG().getBlocks().length); assertReadWithinStartBlock(schedule, true); assertReadAndWriteInSameBlock(schedule, false); } @@ -302,10 +304,10 @@ @Test public void testIfRead2() { SchedulePhase schedule = getFinalSchedule("testIfRead2Snippet", TestMode.WITHOUT_FRAMESTATES); - assertEquals(4, schedule.getCFG().getBlocks().length); + assertEquals(3, schedule.getCFG().getBlocks().length); assertEquals(1, schedule.getCFG().graph.getNodes().filter(FloatingReadNode.class).count()); assertReadWithinStartBlock(schedule, false); - assertReadWithinReturnBlock(schedule, false); + assertReadWithinAllReturnBlocks(schedule, false); assertReadAndWriteInSameBlock(schedule, false); } @@ -326,7 +328,7 @@ SchedulePhase schedule = getFinalSchedule("testIfRead3Snippet", TestMode.WITHOUT_FRAMESTATES); assertEquals(4, schedule.getCFG().getBlocks().length); assertReadWithinStartBlock(schedule, false); - assertReadWithinReturnBlock(schedule, true); + assertReadWithinAllReturnBlocks(schedule, true); } /** @@ -345,9 +347,9 @@ @Test public void testIfRead4() { SchedulePhase schedule = getFinalSchedule("testIfRead4Snippet", TestMode.WITHOUT_FRAMESTATES); - assertEquals(4, schedule.getCFG().getBlocks().length); + assertEquals(3, schedule.getCFG().getBlocks().length); assertReadWithinStartBlock(schedule, false); - assertReadWithinReturnBlock(schedule, false); + assertReadWithinAllReturnBlocks(schedule, false); assertReadAndWriteInSameBlock(schedule, true); } @@ -366,7 +368,7 @@ SchedulePhase schedule = getFinalSchedule("testIfRead5Snippet", TestMode.WITHOUT_FRAMESTATES); assertEquals(4, schedule.getCFG().getBlocks().length); assertReadWithinStartBlock(schedule, false); - assertReadWithinReturnBlock(schedule, true); + assertReadWithinAllReturnBlocks(schedule, true); assertReadAndWriteInSameBlock(schedule, false); } @@ -432,7 +434,7 @@ public void testBlockSchedule2() { SchedulePhase schedule = getFinalSchedule("testBlockSchedule2Snippet", TestMode.WITHOUT_FRAMESTATES, MemoryScheduling.OPTIMAL, SchedulingStrategy.LATEST); assertReadWithinStartBlock(schedule, false); - assertReadWithinReturnBlock(schedule, false); + assertReadWithinAllReturnBlocks(schedule, false); assertReadAndWriteInSameBlock(schedule, false); } @@ -454,7 +456,7 @@ * read of container.b for increment operation should be in return block. TODO: not sure * though, could be replaced by read of container.b of the loop header... */ - assertReadWithinReturnBlock(schedule, true); + assertReadWithinAllReturnBlocks(schedule, true); } public static void testProxy2Snippet() { @@ -476,7 +478,7 @@ public void testProxy2() { SchedulePhase schedule = getFinalSchedule("testProxy2Snippet", TestMode.WITHOUT_FRAMESTATES); assertReadWithinStartBlock(schedule, false); - assertReadWithinReturnBlock(schedule, false); + assertReadWithinAllReturnBlocks(schedule, false); } private int hash = 0; @@ -499,7 +501,7 @@ public void testStringHashCode() { SchedulePhase schedule = getFinalSchedule("testStringHashCodeSnippet", TestMode.WITHOUT_FRAMESTATES); assertReadWithinStartBlock(schedule, true); - assertReadWithinReturnBlock(schedule, false); + assertReadWithinAllReturnBlocks(schedule, false); hash = 0x1337; value[0] = 'a'; @@ -531,30 +533,26 @@ public void testLoop4() { SchedulePhase schedule = getFinalSchedule("testLoop4Snippet", TestMode.WITHOUT_FRAMESTATES); assertReadWithinStartBlock(schedule, false); - assertReadWithinReturnBlock(schedule, false); + assertReadWithinAllReturnBlocks(schedule, false); } - private void assertReadWithinReturnBlock(SchedulePhase schedule, boolean withinReturnBlock) { + private void assertReadWithinAllReturnBlocks(SchedulePhase schedule, boolean withinReturnBlock) { StructuredGraph graph = schedule.getCFG().graph; - assertEquals(graph.getNodes().filter(ReturnNode.class).count(), 1); + assertTrue(graph.getNodes(ReturnNode.class).isNotEmpty()); - Block end = null; - outer: for (Block b : schedule.getCFG().getBlocks()) { - for (Node n : b.getNodes()) { - if (n instanceof ReturnNode) { - end = b; - break outer; + int withRead = 0; + int returnBlocks = 0; + for (ReturnNode returnNode : graph.getNodes(ReturnNode.class)) { + Block block = schedule.getCFG().getNodeToBlock().get(returnNode); + for (Node node : schedule.getBlockToNodesMap().get(block)) { + if (node instanceof FloatingReadNode) { + withRead++; + break; } } + returnBlocks++; } - assertNotNull("no block with ReturnNode found", end); - boolean readEncountered = false; - for (Node node : schedule.getBlockToNodesMap().get(end)) { - if (node instanceof FloatingReadNode) { - readEncountered = true; - } - } - assertEquals(readEncountered, withinReturnBlock); + assertEquals(withRead == returnBlocks, withinReturnBlock); } private void assertReadWithinStartBlock(SchedulePhase schedule, boolean withinStartBlock) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MergeCanonicalizerTest.java Wed Jan 22 21:34:00 2014 -0800 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2011, 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.compiler.test; + +import org.junit.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.tiers.*; + +public class MergeCanonicalizerTest extends GraalCompilerTest { + + public static int staticField; + + private int field; + + @Test + public void testSplitReturn() { + test("testSplitReturnSnippet", 2); + testReturnCount("testSplitReturnSnippet", 2); + } + + public int testSplitReturnSnippet(int b) { + int v; + if (b < 0) { + staticField = 1; + v = 10; + } else { + staticField = 2; + v = 20; + } + int i = field; + i = field + i; + return v; + } + + private void testReturnCount(String snippet, int returnCount) { + StructuredGraph graph = parse(snippet); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false))); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false))); + Debug.dump(graph, "Graph"); + assertEquals(returnCount, graph.getNodes(ReturnNode.class).count()); + } +}
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ScalarTypeSystemTest.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ScalarTypeSystemTest.java Wed Jan 22 21:34:00 2014 -0800 @@ -167,7 +167,6 @@ StructuredGraph graph = parse(snippet); Debug.dump(graph, "Graph"); Assumptions assumptions = new Assumptions(false); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions)); new ConditionalEliminationPhase(getMetaAccess()).apply(graph); new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions)); StructuredGraph referenceGraph = parse(referenceSnippet);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StraighteningTest.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StraighteningTest.java Wed Jan 22 21:34:00 2014 -0800 @@ -76,7 +76,6 @@ test("test1Snippet"); } - @Test(expected = AssertionError.class) public void test2() { test("test2Snippet"); }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java Wed Jan 22 21:34:00 2014 -0800 @@ -98,13 +98,11 @@ test("test4Snippet", "referenceSnippet3"); } - public static final Object constantObject1 = "1"; - public static final Object constantObject2 = "2"; - public static final Object constantObject3 = "3"; - + @SuppressWarnings("unused") public static int test4Snippet(Object o) { if (o == null) { - if (o == constantObject1) { + Object o2 = Integer.class; + if (o == o2) { return 3; } else { return 1; @@ -121,40 +119,41 @@ public static int referenceSnippet5(Object o, Object a) { if (o == null) { - if (a == constantObject1 || a == constantObject2) { + if (a == Integer.class || a == Double.class) { return 1; } } else { - if (a == constantObject2 || a == constantObject3) { + if (a == Double.class || a == Long.class) { return 11; } } - if (a == constantObject1) { + if (a == Integer.class) { return 3; } return 5; } + @SuppressWarnings("unused") public static int test5Snippet(Object o, Object a) { if (o == null) { - if (a == constantObject1 || a == constantObject2) { + if (a == Integer.class || a == Double.class) { if (a == null) { return 10; } return 1; } } else { - if (a == constantObject2 || a == constantObject3) { + if (a == Double.class || a == Long.class) { if (a != null) { return 11; } return 2; } } - if (a == constantObject1) { + if (a == Integer.class) { return 3; } - if (a == constantObject2) { + if (a == Double.class) { return 4; } return 5; @@ -185,7 +184,6 @@ StructuredGraph graph = parse(snippet); Debug.dump(graph, "Graph"); Assumptions assumptions = new Assumptions(false); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions)); new ConditionalEliminationPhase(getMetaAccess()).apply(graph); new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions)); // a second canonicalizer is needed to process nested MaterializeNodes @@ -198,8 +196,8 @@ @Override protected void assertEquals(StructuredGraph expected, StructuredGraph graph) { if (getNodeCountExcludingUnusedConstants(expected) != getNodeCountExcludingUnusedConstants(graph)) { - outputGraph(expected, "expected"); - outputGraph(graph, "actual"); + Debug.dump(expected, "expected (node count)"); + Debug.dump(graph, "graph (node count)"); Assert.fail("Graphs do not have the same number of nodes: " + expected.getNodeCount() + " vs. " + graph.getNodeCount()); } } @@ -239,12 +237,11 @@ private <T extends Node> void testHelper(String snippet, Class<T> clazz) { StructuredGraph graph = parse(snippet); - Debug.dump(graph, "Graph"); Assumptions assumptions = new Assumptions(false); new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions)); new ConditionalEliminationPhase(getMetaAccess()).apply(graph); new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions)); - Debug.dump(graph, "Graph"); + Debug.dump(graph, "Graph " + snippet); Assert.assertFalse("shouldn't have nodes of type " + clazz, graph.getNodes().filter(clazz).iterator().hasNext()); } }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EAMergingTest.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EAMergingTest.java Wed Jan 22 21:34:00 2014 -0800 @@ -33,8 +33,9 @@ @Test public void testSimpleMerge() { testEscapeAnalysis("simpleMergeSnippet", null, false); - assertTrue(returnNode.result() instanceof PhiNode); - PhiNode phi = (PhiNode) returnNode.result(); + assertEquals(1, returnNodes.size()); + assertTrue(returnNodes.get(0).result() instanceof PhiNode); + PhiNode phi = (PhiNode) returnNodes.get(0).result(); assertTrue(phi.valueAt(0) instanceof ParameterNode); assertTrue(phi.valueAt(1) instanceof ParameterNode); }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java Wed Jan 22 21:34:00 2014 -0800 @@ -22,6 +22,8 @@ */ package com.oracle.graal.compiler.test.ea; +import java.util.*; + import org.junit.*; import com.oracle.graal.api.code.*; @@ -119,7 +121,7 @@ protected StructuredGraph graph; protected HighTierContext context; - protected ReturnNode returnNode; + protected List<ReturnNode> returnNodes; /** * Runs Escape Analysis on the given snippet and makes sure that no allocations remain in the @@ -134,8 +136,10 @@ protected void testEscapeAnalysis(String snippet, final Constant expectedConstantResult, final boolean iterativeEscapeAnalysis) { prepareGraph(snippet, iterativeEscapeAnalysis); if (expectedConstantResult != null) { - Assert.assertTrue(returnNode.result().toString(), returnNode.result().isConstant()); - Assert.assertEquals(expectedConstantResult, returnNode.result().asConstant()); + for (ReturnNode returnNode : returnNodes) { + Assert.assertTrue(returnNode.result().toString(), returnNode.result().isConstant()); + Assert.assertEquals(expectedConstantResult, returnNode.result().asConstant()); + } } int newInstanceCount = graph.getNodes().filter(NewInstanceNode.class).count() + graph.getNodes().filter(NewArrayNode.class).count() + graph.getNodes().filter(CommitAllocationNode.class).count(); @@ -153,8 +157,7 @@ new DeadCodeEliminationPhase().apply(graph); new CanonicalizerPhase(true).apply(graph, context); new PartialEscapePhase(iterativeEscapeAnalysis, false, new CanonicalizerPhase(true)).apply(graph, context); - Assert.assertEquals(1, graph.getNodes().filter(ReturnNode.class).count()); - returnNode = graph.getNodes().filter(ReturnNode.class).first(); + returnNodes = graph.getNodes(ReturnNode.class).snapshot(); } catch (Throwable e) { throw Debug.handle(e); }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Wed Jan 22 21:34:00 2014 -0800 @@ -213,8 +213,9 @@ prepareGraph("testFullyUnrolledLoopSnippet", false); new LoopFullUnrollPhase(new CanonicalizerPhase(true)).apply(graph, context); new PartialEscapePhase(false, new CanonicalizerPhase(true)).apply(graph, context); - Assert.assertTrue(returnNode.result() instanceof AllocatedObjectNode); - CommitAllocationNode commit = ((AllocatedObjectNode) returnNode.result()).getCommit(); + Assert.assertEquals(1, returnNodes.size()); + Assert.assertTrue(returnNodes.get(0).result() instanceof AllocatedObjectNode); + CommitAllocationNode commit = ((AllocatedObjectNode) returnNodes.get(0).result()).getCommit(); Assert.assertEquals(2, commit.getValues().size()); Assert.assertEquals(1, commit.getVirtualObjects().size()); Assert.assertTrue("non-cyclic data structure expected", commit.getVirtualObjects().get(0) != commit.getValues().get(0));
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java Wed Jan 22 21:34:00 2014 -0800 @@ -79,8 +79,8 @@ final ReturnNode getReturn(String snippet) { processMethod(snippet); - assertEquals(1, graph.getNodes().filter(ReturnNode.class).count()); - return graph.getNodes().filter(ReturnNode.class).first(); + assertEquals(1, graph.getNodes(ReturnNode.class).count()); + return graph.getNodes(ReturnNode.class).first(); } private void processMethod(final String snippet) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java Wed Jan 22 21:34:00 2014 -0800 @@ -24,6 +24,8 @@ import static org.junit.Assert.*; +import java.util.*; + import org.junit.*; import com.oracle.graal.api.code.*; @@ -194,14 +196,14 @@ @Test public void testPhi() { - ValueNode result = getReturn("testPhiSnippet").result(); + processMethod("testPhiSnippet"); assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty()); - assertTrue(result instanceof PhiNode); - PhiNode phi = (PhiNode) result; - assertTrue(phi.valueAt(0).isConstant()); - assertTrue(phi.valueAt(1).isConstant()); - assertEquals(1, phi.valueAt(0).asConstant().asInt()); - assertEquals(2, phi.valueAt(1).asConstant().asInt()); + List<ReturnNode> returnNodes = graph.getNodes(ReturnNode.class).snapshot(); + assertEquals(2, returnNodes.size()); + assertTrue(returnNodes.get(0).predecessor() instanceof StoreFieldNode); + assertTrue(returnNodes.get(1).predecessor() instanceof StoreFieldNode); + assertTrue(returnNodes.get(0).result().isConstant()); + assertTrue(returnNodes.get(1).result().isConstant()); } @SuppressWarnings("all") @@ -236,8 +238,8 @@ final ReturnNode getReturn(String snippet) { processMethod(snippet); - assertEquals(1, graph.getNodes().filter(ReturnNode.class).count()); - return graph.getNodes().filter(ReturnNode.class).first(); + assertEquals(1, graph.getNodes(ReturnNode.class).count()); + return graph.getNodes(ReturnNode.class).first(); } protected void processMethod(final String snippet) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/UnsafeEATest.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/UnsafeEATest.java Wed Jan 22 21:34:00 2014 -0800 @@ -86,8 +86,9 @@ @Test public void testMergedDouble() { testEscapeAnalysis("testMergedDoubleSnippet", null, false); - Assert.assertTrue(returnNode.result() instanceof PhiNode); - PhiNode phi = (PhiNode) returnNode.result(); + Assert.assertEquals(1, returnNodes.size()); + Assert.assertTrue(returnNodes.get(0).result() instanceof PhiNode); + PhiNode phi = (PhiNode) returnNodes.get(0).result(); Assert.assertTrue(phi.valueAt(0) instanceof LoadFieldNode); Assert.assertTrue(phi.valueAt(1) instanceof LoadFieldNode); }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Wed Jan 22 21:34:00 2014 -0800 @@ -458,7 +458,7 @@ if (c.getKind() == Kind.Long) { return Constant.forIntegerKind(Kind.Int, (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL), c.getPrimitiveAnnotation()); } else if (c.getKind() == Kind.Object) { - return Constant.forIntegerKind(Kind.Int, 0xdeaddead, c.asObject()); + return Constant.forNarrowOop(c.asObject()); } else { throw GraalInternalError.shouldNotReachHere(); }
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java Wed Jan 22 21:34:00 2014 -0800 @@ -141,14 +141,14 @@ public StructuredGraph getGraphFor(ResolvedJavaMethod method) { if (canOffloadToGPU(method)) { ExternalCompilationResult ptxCode = PTXHotSpotBackend.this.compileKernel(method, true); - InstalledCode installedPTXCode = PTXHotSpotBackend.this.installKernel(method, ptxCode); - return new PTXWrapperBuilder(method, installedPTXCode.getStart(), getRuntime().getHostBackend().getProviders()).getGraph(); + HotSpotNmethod installedPTXCode = PTXHotSpotBackend.this.installKernel(method, ptxCode); + return new PTXWrapperBuilder(method, installedPTXCode, getRuntime().getHostBackend().getProviders()).getGraph(); } return null; } private boolean canOffloadToGPU(ResolvedJavaMethod method) { - return method.getName().contains("lambda$main$") & method.isSynthetic(); + return method.getName().contains("lambda$") & method.isSynthetic(); } }; } @@ -181,9 +181,27 @@ } - public InstalledCode installKernel(ResolvedJavaMethod method, ExternalCompilationResult ptxCode) { - assert ptxCode.getEntryPoint() != 0L; - return getProviders().getCodeCache().addExternalMethod(method, ptxCode); + /** + * A list of the {@linkplain #installKernel(ResolvedJavaMethod, ExternalCompilationResult) + * installed} kernels. This is required so that there is a strong reference to each installed + * kernel as long as it is {@linkplain HotSpotNmethod#isValid() valid}. The list is pruned of + * invalid kernels every time a new kernel is installed. + */ + private List<HotSpotNmethod> installedKernels = new LinkedList<>(); + + public final HotSpotNmethod installKernel(ResolvedJavaMethod method, ExternalCompilationResult ptxCode) { + assert OmitDeviceInit || ptxCode.getEntryPoint() != 0L; + HotSpotNmethod kernel = getProviders().getCodeCache().addExternalMethod(method, ptxCode); + synchronized (installedKernels) { + for (Iterator<HotSpotNmethod> i = installedKernels.iterator(); i.hasNext();) { + HotSpotNmethod entry = i.next(); + if (!entry.isValid()) { + i.remove(); + } + } + installedKernels.add(kernel); + } + return kernel; } static final class RegisterAnalysis extends ValueProcedure {
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java Wed Jan 22 21:34:00 2014 -0800 @@ -22,6 +22,7 @@ */ package com.oracle.graal.hotspot.ptx; +import static com.oracle.graal.api.meta.DeoptimizationAction.*; import static com.oracle.graal.api.meta.DeoptimizationReason.*; import static com.oracle.graal.api.meta.LocationIdentity.*; import static com.oracle.graal.api.meta.MetaUtil.*; @@ -53,9 +54,9 @@ import com.oracle.graal.word.*; /** - * Utility for building a graph that "wraps" the PTX binary compiled for a method. Such a wrapper - * handles the transition from the host CPU to the GPU and back. The graph created is something like - * the following pseudo code with UPPER CASE denoting compile-time constants: + * Utility for building a graph that "wraps" a compiled PTX kernel. Such a wrapper handles the + * transition from the host CPU to the GPU and back. The graph created is something like the + * following pseudo code with UPPER CASE denoting compile-time constants: * * <pre> * T kernel(p0, p1, ..., pN) { @@ -65,6 +66,10 @@ * return convert(result); * } * </pre> + * <p> + * The generated graph includes a reference to the {@link HotSpotNmethod} for the kernel. There must + * be another reference to the same {@link HotSpotNmethod} object to ensure that the nmethod is not + * unloaded by the next full GC. */ public class PTXWrapperBuilder extends GraphKit { @@ -97,9 +102,10 @@ * Creates the graph implementing the CPU to GPU transition. * * @param method a method that has been compiled to GPU binary code - * @param kernelAddress the entry point of the GPU binary for {@code kernelMethod} + * @param kernel the installed GPU binary for {@code method} + * @see PTXWrapperBuilder */ - public PTXWrapperBuilder(ResolvedJavaMethod method, long kernelAddress, HotSpotProviders providers) { + public PTXWrapperBuilder(ResolvedJavaMethod method, HotSpotNmethod kernel, HotSpotProviders providers) { super(new StructuredGraph(method), providers); int wordSize = providers.getCodeCache().getTarget().wordSize; Kind wordKind = providers.getCodeCache().getTarget().wordKind; @@ -132,11 +138,13 @@ } } + InvokeNode kernelStart = createInvoke(getClass(), "getKernelStart", ConstantNode.forObject(kernel, providers.getMetaAccess(), getGraph())); + AllocaNode buf = append(new AllocaNode(bufSize / wordSize, objects)); Map<LaunchArg, ValueNode> args = new EnumMap<>(LaunchArg.class); args.put(Thread, append(new ReadRegisterNode(providers.getRegisters().getThreadRegister(), true, false))); - args.put(Kernel, ConstantNode.forLong(kernelAddress, getGraph())); + args.put(Kernel, kernelStart); args.put(DimX, forInt(1, getGraph())); args.put(DimY, forInt(1, getGraph())); args.put(DimZ, forInt(1, getGraph())); @@ -252,6 +260,19 @@ } /** + * Snippet invoked to get the {@linkplain HotSpotNmethod#getStart() entry point} of the kernel, + * deoptimizing if the kernel is invalid. + */ + @Snippet + private static long getKernelStart(HotSpotNmethod ptxKernel) { + long start = ptxKernel.getStart(); + if (start == 0L) { + DeoptimizeNode.deopt(InvalidateRecompile, RuntimeConstraint); + } + return start; + } + + /** * Snippet invoked upon return from the kernel to handle any pending exceptions. */ @Snippet
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Wed Jan 22 21:34:00 2014 -0800 @@ -556,9 +556,8 @@ int id = allocateCompileTaskId(method, entryBCI); HotSpotBackend backend = runtime.getHostBackend(); CompilationTask task = new CompilationTask(backend, method, entryBCI, id); - boolean isLambdaMethod = (method.getName().contains("lambda$main$") & method.isSynthetic()); - if (blocking || isLambdaMethod) { + if (blocking) { task.runCompilation(true); } else { try {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Wed Jan 22 21:34:00 2014 -0800 @@ -26,6 +26,7 @@ import java.util.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.CodeUtil.DefaultRefMapFormatter; import com.oracle.graal.api.code.CodeUtil.RefMapFormatter; import com.oracle.graal.api.code.CompilationResult.Call; import com.oracle.graal.api.code.CompilationResult.DataPatch; @@ -65,7 +66,7 @@ HexCodeFile.addAnnotations(hcf, compResult.getAnnotations()); addExceptionHandlersComment(compResult, hcf); Register fp = regConfig.getFrameRegister(); - RefMapFormatter slotFormatter = new RefMapFormatter(target.arch, target.wordSize, fp, 0); + RefMapFormatter slotFormatter = new DefaultRefMapFormatter(target.arch, target.wordSize, fp, 0); for (Infopoint infopoint : compResult.getInfopoints()) { if (infopoint instanceof Call) { Call call = (Call) infopoint; @@ -190,16 +191,16 @@ return installMethod(hotspotMethod, compResult); } - public InstalledCode addExternalMethod(ResolvedJavaMethod method, CompilationResult compResult) { + public HotSpotNmethod addExternalMethod(ResolvedJavaMethod method, CompilationResult compResult) { HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) method; - HotSpotInstalledCode icode = new HotSpotNmethod(javaMethod, compResult.getName(), false, true); + HotSpotNmethod code = new HotSpotNmethod(javaMethod, compResult.getName(), false, true); HotSpotCompiledNmethod compiled = new HotSpotCompiledNmethod(target.arch, javaMethod, compResult); CompilerToVM vm = runtime.getCompilerToVM(); - CodeInstallResult result = vm.installCode(compiled, icode, null); + CodeInstallResult result = vm.installCode(compiled, code, null); if (result != CodeInstallResult.OK) { return null; } - return icode; + return code; } public boolean needsDataPatch(Constant constant) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassSubstitutions.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassSubstitutions.java Wed Jan 22 21:34:00 2014 -0800 @@ -118,8 +118,8 @@ @MacroSubstitution(macro = ClassIsInstanceNode.class, isStatic = false) @MethodSubstitution(isStatic = false) - public static boolean isInstance(final Class<?> thisObj, Object obj) { - return !isPrimitive(thisObj) && ConditionalNode.materializeIsInstance(thisObj, obj); + public static boolean isInstance(Class<?> thisObj, Object obj) { + return ConditionalNode.materializeIsInstance(thisObj, obj); } @MacroSubstitution(macro = ClassCastNode.class, isStatic = false)
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Wed Jan 22 21:34:00 2014 -0800 @@ -187,7 +187,7 @@ BeginNode anchorNode = BeginNode.anchor(); Word hub = loadWordFromObject(mirror, klassOffset()); Word objectHub = loadHubIntrinsic(object, getWordKind(), anchorNode); - if (!checkUnknownSubType(hub, objectHub)) { + if (hub.equal(0) || !checkUnknownSubType(hub, objectHub)) { return falseValue; } return trueValue;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Wed Jan 22 21:34:00 2014 -0800 @@ -521,7 +521,7 @@ StructuredGraph inlineeGraph = providers.getReplacements().getSnippet(initCounter.getMethod()); InliningUtil.inline(invoke, inlineeGraph, false); - List<ReturnNode> rets = graph.getNodes().filter(ReturnNode.class).snapshot(); + List<ReturnNode> rets = graph.getNodes(ReturnNode.class).snapshot(); for (ReturnNode ret : rets) { returnType = checkCounter.getMethod().getSignature().getReturnType(checkCounter.getMethod().getDeclaringClass()); String msg = "unbalanced monitors in " + MetaUtil.format("%H.%n(%p)", graph.method()) + ", count = %d";
--- a/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAIL.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAIL.java Wed Jan 22 21:34:00 2014 -0800 @@ -29,7 +29,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.Register.RegisterCategory; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; /** * Represents the HSAIL architecture. @@ -166,39 +165,16 @@ Register reg; int encoding = 0; String regPrefix = null; - String argType = arg.getKind().getJavaName(); - if (argType.equals("double") || argType.equals("long")) { + Kind kind = arg.getKind(); + if (kind == Kind.Double || kind == Kind.Long) { regPrefix = "$d"; - } else if (argType.equals("int") || argType.equals("float")) { + } else if (kind == Kind.Int || kind == Kind.Float || kind == Kind.NarrowOop) { regPrefix = "$s"; } else { regPrefix = "$d"; } - switch (argType) { - case "float": - reg = asFloatReg(arg); - encoding = reg.encoding(); - break; - case "int": - reg = asIntReg(arg); - encoding = reg.encoding(); - break; - case "long": - reg = asLongReg(arg); - encoding = reg.encoding(); - break; - case "double": - reg = asDoubleReg(arg); - encoding = reg.encoding(); - break; - case "Object": - reg = asObjectReg(arg); - encoding = reg.encoding(); - break; - default: - GraalInternalError.shouldNotReachHere(); - break; - } + reg = asRegister(arg); + encoding = reg.encoding(); return new String(regPrefix + encoding); } @@ -217,6 +193,7 @@ case Int: case Long: case Object: + case NarrowOop: return true; } } else if (category == FPU) {
--- a/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAILRegisterConfig.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAILRegisterConfig.java Wed Jan 22 21:34:00 2014 -0800 @@ -150,6 +150,7 @@ case Short: case Byte: case Float: + case NarrowOop: return regBitness32.clone(); case Long: case Double:
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Jan 22 21:34:00 2014 -0800 @@ -120,7 +120,6 @@ private ValueNode methodSynchronizedObject; private ExceptionDispatchBlock unwindBlock; - private Block returnBlock; private FixedWithNextNode lastInstr; // the last instruction added @@ -198,7 +197,6 @@ this.stream = new BytecodeStream(method.getCode()); this.constantPool = method.getConstantPool(); unwindBlock = null; - returnBlock = null; methodSynchronizedObject = null; this.currentGraph = graph; this.frameState = new FrameStateBuilder(method, graph, graphBuilderConfig.eagerResolving()); @@ -270,7 +268,6 @@ for (Block block : blockMap.blocks) { processBlock(block); } - processBlock(returnBlock); processBlock(unwindBlock); Debug.dump(currentGraph, "After bytecode parsing"); @@ -305,16 +302,6 @@ return unwindBlock; } - private Block returnBlock(int bci) { - if (returnBlock == null) { - returnBlock = new Block(); - returnBlock.startBci = bci; - returnBlock.endBci = bci; - returnBlock.blockID = Integer.MAX_VALUE; - } - return returnBlock; - } - public BytecodeStream stream() { return stream; } @@ -1264,11 +1251,18 @@ } private void genReturn(ValueNode x) { + frameState.setRethrowException(false); frameState.clearStack(); - if (x != null) { - frameState.push(x.kind(), x); + if (graphBuilderConfig.eagerInfopointMode()) { + append(new InfopointNode(InfopointReason.METHOD_END, frameState.create(bci()))); } - appendGoto(createTarget(returnBlock(bci()), frameState)); + + synchronizedEpilogue(FrameState.AFTER_BCI, x); + if (frameState.lockDepth() != 0) { + throw new BailoutException("unbalanced monitors"); + } + + append(new ReturnNode(x)); } private MonitorEnterNode genMonitorEnter(ValueNode x) { @@ -1648,10 +1642,7 @@ ((MergeNode) lastInstr).setStateAfter(frameState.create(bci)); } - if (block == returnBlock) { - frameState.setRethrowException(false); - createReturn(); - } else if (block == unwindBlock) { + if (block == unwindBlock) { frameState.setRethrowException(false); createUnwind(); } else if (block instanceof ExceptionDispatchBlock) { @@ -1692,26 +1683,12 @@ append(new UnwindNode(exception)); } - private void createReturn() { - Kind returnKind = method.getSignature().getReturnKind().getStackKind(); - ValueNode x = returnKind == Kind.Void ? null : frameState.pop(returnKind); - assert frameState.stackSize() == 0; - - if (graphBuilderConfig.eagerInfopointMode()) { - append(new InfopointNode(InfopointReason.METHOD_END, frameState.create(bci()))); - } - - synchronizedEpilogue(FrameState.AFTER_BCI, x); - if (frameState.lockDepth() != 0) { - throw new BailoutException("unbalanced monitors"); - } - - append(new ReturnNode(x)); - } - private void synchronizedEpilogue(int bci, ValueNode returnValue) { if (Modifier.isSynchronized(method.getModifiers())) { MonitorExitNode monitorExit = genMonitorExit(methodSynchronizedObject, returnValue); + if (returnValue != null) { + frameState.push(returnValue.kind(), returnValue); + } monitorExit.setStateAfter(frameState.create(bci)); assert !frameState.rethrowException(); }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java Wed Jan 22 21:34:00 2014 -0800 @@ -343,24 +343,12 @@ } } - /** - * Initializes a reference map that covers all registers of the target architecture. - */ - public BitSet initRegisterRefMap() { - return new BitSet(target.arch.getRegisterReferenceMapBitCount()); - } - - /** - * Initializes a reference map. Initially, the size is large enough to cover all the slots in - * the frame. If the method has incoming reference arguments on the stack, the reference map - * might grow later when such a reference is set. - */ - public BitSet initFrameRefMap() { - BitSet frameRefMap = new BitSet(frameSize() / target.wordSize); + public ReferenceMap initReferenceMap(boolean canHaveRegisters) { + ReferenceMap refMap = new ReferenceMap(canHaveRegisters ? target.arch.getRegisterReferenceMapBitCount() : 0, frameSize() / target.wordSize); for (StackSlot slot : objectStackSlots) { - setReference(slot, null, frameRefMap); + setReference(slot, refMap); } - return frameRefMap; + return refMap; } /** @@ -369,16 +357,22 @@ * {@link Constant} is automatically tracked. * * @param location The location to be added to the reference map. - * @param registerRefMap A register reference map, as created by {@link #initRegisterRefMap()}. - * @param frameRefMap A frame reference map, as created by {@link #initFrameRefMap()}. + * @param refMap A reference map, as created by {@link #initReferenceMap(boolean)}. */ - public void setReference(Value location, BitSet registerRefMap, BitSet frameRefMap) { - if (location.getKind() == Kind.Object) { + public void setReference(Value location, ReferenceMap refMap) { + Kind kind = location.getKind(); + if (kind == Kind.Object || kind == Kind.NarrowOop) { if (isRegister(location)) { - registerRefMap.set(asRegister(location).number); + refMap.setRegister(asRegister(location).number, kind == Kind.NarrowOop); } else if (isStackSlot(location)) { - int index = indexForStackSlot(asStackSlot(location)); - frameRefMap.set(index); + if (kind == Kind.NarrowOop) { + int offset = offsetForStackSlot(asStackSlot(location)); + assert offset % target.wordSize == 0 || offset % target.wordSize == target.wordSize / 2; + refMap.setStackSlot(offset / target.wordSize, offset % target.wordSize == 0, offset % target.wordSize != 0); + } else { + int index = indexForStackSlot(asStackSlot(location)); + refMap.setStackSlot(index, false, false); + } } else { assert isConstant(location); }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java Wed Jan 22 21:34:00 2014 -0800 @@ -116,8 +116,7 @@ * @param canHaveRegisters True if there can be any register map entries. */ public void initDebugInfo(FrameMap frameMap, boolean canHaveRegisters) { - BitSet registerRefMap = (canHaveRegisters ? frameMap.initRegisterRefMap() : null); - debugInfo = new DebugInfo(topFrame, registerRefMap, frameMap.initFrameRefMap()); + debugInfo = new DebugInfo(topFrame, frameMap.initReferenceMap(canHaveRegisters)); } /** @@ -129,16 +128,7 @@ * @param frameMap The frame map. */ public void markLocation(Value location, FrameMap frameMap) { - if (location.getKind() == Kind.Object) { - if (isRegister(location)) { - debugInfo.getRegisterRefMap().set(asRegister(location).number); - } else if (isStackSlot(location)) { - int index = frameMap.indexForStackSlot(asStackSlot(location)); - debugInfo.getFrameRefMap().set(index); - } else { - assert isConstant(location); - } - } + frameMap.setReference(location, debugInfo.getReferenceMap()); } /**
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Wed Jan 22 21:34:00 2014 -0800 @@ -104,12 +104,16 @@ if (condition() instanceof LogicNegationNode) { LogicNegationNode negation = (LogicNegationNode) condition(); return graph().unique(new GuardNode(negation.getInput(), getGuard(), reason, action, !negated, speculation)); - } - if (condition() instanceof LogicConstantNode) { + } else if (condition() instanceof LogicConstantNode) { LogicConstantNode c = (LogicConstantNode) condition(); if (c.getValue() != negated) { return graph().start(); } + } else if (negated && condition() instanceof ShortCircuitOrNode) { + ShortCircuitOrNode or = (ShortCircuitOrNode) condition(); + GuardNode firstGuard = graph().unique(new GuardNode(or.getX(), getGuard(), reason, action, !or.isXNegated(), speculation)); + GuardNode secondGuard = graph().unique(new GuardNode(or.getY(), firstGuard, reason, action, !or.isYNegated(), speculation)); + return secondGuard; } return this; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Wed Jan 22 21:34:00 2014 -0800 @@ -371,6 +371,29 @@ } } } + if (trueSuccessor().next() instanceof ReturnNode && falseSuccessor().next() instanceof ReturnNode) { + ReturnNode trueEnd = (ReturnNode) trueSuccessor().next(); + ReturnNode falseEnd = (ReturnNode) falseSuccessor().next(); + ValueNode trueValue = trueEnd.result(); + ValueNode falseValue = falseEnd.result(); + ConditionalNode conditional = null; + if (trueValue != null) { + if (trueValue.kind() != falseValue.kind()) { + return false; + } + if (trueValue.kind() != Kind.Int && trueValue.kind() != Kind.Long) { + return false; + } + conditional = canonicalizeConditionalCascade(trueValue, falseValue); + if (conditional == null) { + return false; + } + } + ReturnNode newReturn = graph().add(new ReturnNode(conditional)); + replaceAtPredecessor(newReturn); + GraphUtil.killCFG(this); + return true; + } return false; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMapNode.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMapNode.java Wed Jan 22 21:34:00 2014 -0800 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes; +import java.util.*; + import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; @@ -34,4 +36,6 @@ } public abstract MemoryNode getLastLocationAccess(LocationIdentity locationIdentity); + + public abstract Set<LocationIdentity> getLocations(); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java Wed Jan 22 21:34:00 2014 -0800 @@ -24,6 +24,8 @@ import static com.oracle.graal.graph.iterators.NodePredicates.*; +import java.util.*; + import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; @@ -194,6 +196,35 @@ tool.addToWorkList(newEnd.predecessor()); // ? } graph().reduceTrivialMerge(this); + } else if (next instanceof ReturnNode) { + ReturnNode returnNode = (ReturnNode) next; + if (anchored().isNotEmpty() || returnNode.getMemoryMap() != null) { + return; + } + List<PhiNode> phis = phis().snapshot(); + for (PhiNode phi : phis) { + for (Node usage : phi.usages().filter(isNotA(FrameState.class))) { + if (usage != returnNode) { + return; + } + } + } + + PhiNode returnValuePhi = returnNode.result() == null || !isPhiAtMerge(returnNode.result()) ? null : (PhiNode) returnNode.result(); + List<AbstractEndNode> endNodes = forwardEnds().snapshot(); + for (AbstractEndNode end : endNodes) { + ReturnNode newReturn = graph().add(new ReturnNode(returnValuePhi == null ? returnNode.result() : returnValuePhi.valueAt(end))); + end.replaceAtPredecessor(newReturn); + } + GraphUtil.killCFG(this); + for (AbstractEndNode end : endNodes) { + end.safeDelete(); + } + for (PhiNode phi : phis) { + if (phi.isAlive() && phi.usages().isEmpty()) { + GraphUtil.killWithUnusedFloatingInputs(phi); + } + } } } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ParameterNode.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ParameterNode.java Wed Jan 22 21:34:00 2014 -0800 @@ -28,7 +28,7 @@ /** * The {@code Parameter} instruction is a placeholder for an incoming argument to a function call. */ -@NodeInfo(nameTemplate = "Local({p#index})") +@NodeInfo(nameTemplate = "Param({p#index})") public final class ParameterNode extends AbstractLocalNode implements IterableNodeType { public ParameterNode(int index, Stamp stamp) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ReturnNode.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ReturnNode.java Wed Jan 22 21:34:00 2014 -0800 @@ -22,10 +22,11 @@ */ package com.oracle.graal.nodes; +import com.oracle.graal.graph.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -public final class ReturnNode extends ControlSinkNode implements LIRLowerable { +public final class ReturnNode extends ControlSinkNode implements LIRLowerable, IterableNodeType { @Input private ValueNode result; @Input private MemoryMapNode memoryMap;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java Wed Jan 22 21:34:00 2014 -0800 @@ -62,7 +62,11 @@ if (mirror().isConstant()) { Class clazz = (Class) mirror().asConstant().asObject(); ResolvedJavaType t = tool.getMetaAccess().lookupJavaType(clazz); - return graph().unique(new InstanceOfNode(t, object(), null)); + if (t.isPrimitive()) { + return LogicConstantNode.contradiction(graph()); + } else { + return graph().unique(new InstanceOfNode(t, object(), null)); + } } return this; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java Wed Jan 22 21:34:00 2014 -0800 @@ -60,6 +60,9 @@ @Override public Node canonical(CanonicalizerTool tool) { + if (usages().isEmpty() && (isStatic() || ObjectStamp.isObjectNonNull(object().stamp()))) { + return null; + } MetaAccessProvider metaAccess = tool.getMetaAccess(); if (tool.canonicalizeReads() && metaAccess != null) { ConstantNode constant = asConstant(metaAccess);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Wed Jan 22 21:34:00 2014 -0800 @@ -84,6 +84,7 @@ return false; } + @Override public Set<LocationIdentity> getLocations() { return lastMemorySnapshot.keySet(); } @@ -111,6 +112,46 @@ } } + public static MemoryMapImpl mergeMemoryMaps(MergeNode merge, List<? extends MemoryMapNode> states) { + MemoryMapImpl newState = new MemoryMapImpl(); + + Set<LocationIdentity> keys = new HashSet<>(); + for (MemoryMapNode other : states) { + keys.addAll(other.getLocations()); + } + assert !keys.contains(FINAL_LOCATION); + + for (LocationIdentity key : keys) { + int mergedStatesCount = 0; + boolean isPhi = false; + MemoryNode merged = null; + for (MemoryMapNode state : states) { + MemoryNode last = state.getLastLocationAccess(key); + if (isPhi) { + merged.asMemoryPhi().addInput(ValueNodeUtil.asNode(last)); + } else { + if (merged == last) { + // nothing to do + } else if (merged == null) { + merged = last; + } else { + MemoryPhiNode phi = merge.graph().addWithoutUnique(new MemoryPhiNode(merge, key)); + for (int j = 0; j < mergedStatesCount; j++) { + phi.addInput(ValueNodeUtil.asNode(merged)); + } + phi.addInput(ValueNodeUtil.asNode(last)); + merged = phi; + isPhi = true; + } + } + mergedStatesCount++; + } + newState.lastMemorySnapshot.put(key, merged); + } + return newState; + + } + private static class CollectMemoryCheckpointsClosure extends NodeIteratorClosure<Set<LocationIdentity>> { private final Map<LoopBeginNode, Set<LocationIdentity>> modifiedInLoops; @@ -238,42 +279,7 @@ @Override protected MemoryMapImpl merge(MergeNode merge, List<MemoryMapImpl> states) { - MemoryMapImpl newState = new MemoryMapImpl(); - - Set<LocationIdentity> keys = new HashSet<>(); - for (MemoryMapImpl other : states) { - keys.addAll(other.lastMemorySnapshot.keySet()); - } - assert !keys.contains(FINAL_LOCATION); - - for (LocationIdentity key : keys) { - int mergedStatesCount = 0; - boolean isPhi = false; - MemoryNode merged = null; - for (MemoryMapImpl state : states) { - MemoryNode last = state.getLastLocationAccess(key); - if (isPhi) { - merged.asMemoryPhi().addInput(ValueNodeUtil.asNode(last)); - } else { - if (merged == last) { - // nothing to do - } else if (merged == null) { - merged = last; - } else { - MemoryPhiNode phi = merge.graph().addWithoutUnique(new MemoryPhiNode(merge, key)); - for (int j = 0; j < mergedStatesCount; j++) { - phi.addInput(ValueNodeUtil.asNode(merged)); - } - phi.addInput(ValueNodeUtil.asNode(last)); - merged = phi; - isPhi = true; - } - } - mergedStatesCount++; - } - newState.lastMemorySnapshot.put(key, merged); - } - return newState; + return mergeMemoryMaps(merge, states); } @Override @@ -302,19 +308,21 @@ modifiedLocations.addAll(initialState.lastMemorySnapshot.keySet()); } - Map<LocationIdentity, PhiNode> phis = new HashMap<>(); + Map<LocationIdentity, MemoryPhiNode> phis = new HashMap<>(); for (LocationIdentity location : modifiedLocations) { MemoryPhiNode phi = loop.graph().addWithoutUnique(new MemoryPhiNode(loop, location)); phi.addInput(ValueNodeUtil.asNode(initialState.getLastLocationAccess(location))); phis.put(location, phi); - initialState.lastMemorySnapshot.put(location, phi); + } + for (Map.Entry<LocationIdentity, MemoryPhiNode> entry : phis.entrySet()) { + initialState.lastMemorySnapshot.put(entry.getKey(), entry.getValue()); } LoopInfo<MemoryMapImpl> loopInfo = ReentrantNodeIterator.processLoop(this, loop, initialState); for (Map.Entry<LoopEndNode, MemoryMapImpl> entry : loopInfo.endStates.entrySet()) { int endIndex = loop.phiPredecessorIndex(entry.getKey()); - for (Map.Entry<LocationIdentity, PhiNode> phiEntry : phis.entrySet()) { + for (Map.Entry<LocationIdentity, MemoryPhiNode> phiEntry : phis.entrySet()) { LocationIdentity key = phiEntry.getKey(); PhiNode phi = phiEntry.getValue(); phi.initializeValueAt(endIndex, ValueNodeUtil.asNode(entry.getValue().getLastLocationAccess(key)));
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java Wed Jan 22 21:34:00 2014 -0800 @@ -27,6 +27,7 @@ import java.util.*; import java.util.Map.Entry; +import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -107,7 +108,7 @@ private void processGuard(Node node) { GuardNode guard = (GuardNode) node; - if (guard.negated() && guard.condition() instanceof IsNullNode) { + if (guard.negated() && guard.condition() instanceof IsNullNode && (guard.getSpeculation() == null || guard.getSpeculation().equals(Constant.NULL_OBJECT))) { ValueNode obj = ((IsNullNode) guard.condition()).object(); nullGuarded.put(obj, guard); }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Wed Jan 22 21:34:00 2014 -0800 @@ -1295,8 +1295,10 @@ */ public static Map<Node, Node> inline(Invoke invoke, StructuredGraph inlineGraph, boolean receiverNullCheck) { final NodeInputList<ValueNode> parameters = invoke.callTarget().arguments(); - StructuredGraph graph = invoke.asNode().graph(); + FixedNode invokeNode = invoke.asNode(); + StructuredGraph graph = invokeNode.graph(); assert inlineGraph.getGuardsStage().ordinal() >= graph.getGuardsStage().ordinal(); + Kind returnKind = invokeNode.kind(); FrameState stateAfter = invoke.stateAfter(); assert stateAfter == null || stateAfter.isAlive(); @@ -1305,7 +1307,7 @@ } ArrayList<Node> nodes = new ArrayList<>(inlineGraph.getNodes().count()); - ReturnNode returnNode = null; + ArrayList<ReturnNode> returnNodes = new ArrayList<>(4); UnwindNode unwindNode = null; final StartNode entryPointNode = inlineGraph.start(); FixedNode firstCFGNode = entryPointNode.next(); @@ -1318,8 +1320,7 @@ } else { nodes.add(node); if (node instanceof ReturnNode) { - assert returnNode == null; - returnNode = (ReturnNode) node; + returnNodes.add((ReturnNode) node); } else if (node instanceof UnwindNode) { assert unwindNode == null; unwindNode = (UnwindNode) node; @@ -1327,7 +1328,7 @@ } } - final AbstractBeginNode prevBegin = AbstractBeginNode.prevBegin(invoke.asNode()); + final AbstractBeginNode prevBegin = AbstractBeginNode.prevBegin(invokeNode); DuplicationReplacement localReplacement = new DuplicationReplacement() { public Node replacement(Node node) { @@ -1340,12 +1341,12 @@ } }; - assert invoke.asNode().successors().first() != null : invoke; - assert invoke.asNode().predecessor() != null; + assert invokeNode.successors().first() != null : invoke; + assert invokeNode.predecessor() != null; Map<Node, Node> duplicates = graph.addDuplicates(nodes, inlineGraph, inlineGraph.getNodeCount(), localReplacement); FixedNode firstCFGNodeDuplicate = (FixedNode) duplicates.get(firstCFGNode); - invoke.asNode().replaceAtPredecessor(firstCFGNodeDuplicate); + invokeNode.replaceAtPredecessor(firstCFGNodeDuplicate); FrameState stateAtExceptionEdge = null; if (invoke instanceof InvokeWithExceptionNode) { @@ -1400,7 +1401,8 @@ if (frameState != null) { assert frameState.bci != FrameState.BEFORE_BCI : frameState; if (frameState.bci == FrameState.AFTER_BCI) { - frameState.replaceAndDelete(stateAfter); + frameState.replaceAndDelete(returnKind == Kind.Void ? stateAfter : stateAfter.duplicateModified(stateAfter.bci, stateAfter.rethrowException(), returnKind, + frameState.stackAt(0))); } else if (frameState.bci == FrameState.AFTER_EXCEPTION_BCI) { if (frameState.isAlive()) { assert stateAtExceptionEdge != null; @@ -1413,7 +1415,7 @@ if (frameState.outerFrameState() == null) { assert frameState.bci == FrameState.INVALID_FRAMESTATE_BCI || frameState.method() == inlineGraph.method(); if (outerFrameState == null) { - outerFrameState = stateAfter.duplicateModified(invoke.bci(), stateAfter.rethrowException(), invoke.asNode().kind()); + outerFrameState = stateAfter.duplicateModified(invoke.bci(), stateAfter.rethrowException(), invokeNode.kind()); outerFrameState.setDuringCall(true); } frameState.setOuterFrameState(outerFrameState); @@ -1430,27 +1432,55 @@ } else { assert checkContainsOnlyInvalidOrAfterFrameState(duplicates); } - Node returnValue = null; - if (returnNode != null) { - if (returnNode.result() instanceof ParameterNode) { - returnValue = localReplacement.replacement(returnNode.result()); - } else if (returnNode.result() != null) { - returnValue = duplicates.get(returnNode.result()); + if (!returnNodes.isEmpty()) { + FixedNode n = invoke.next(); + invoke.setNext(null); + if (returnNodes.size() == 1) { + ReturnNode returnNode = (ReturnNode) duplicates.get(returnNodes.get(0)); + Node returnValue = returnNode.result(); + invokeNode.replaceAtUsages(returnValue); + returnNode.clearInputs(); + returnNode.replaceAndDelete(n); + } else { + ArrayList<ReturnNode> returnDuplicates = new ArrayList<>(returnNodes.size()); + for (ReturnNode returnNode : returnNodes) { + returnDuplicates.add((ReturnNode) duplicates.get(returnNode)); + } + MergeNode merge = graph.add(new MergeNode()); + merge.setStateAfter(stateAfter); + ValueNode returnValue = mergeReturns(merge, returnDuplicates); + invokeNode.replaceAtUsages(returnValue); + merge.setNext(n); } - invoke.asNode().replaceAtUsages(returnValue); - Node returnDuplicate = duplicates.get(returnNode); - returnDuplicate.clearInputs(); - Node n = invoke.next(); - invoke.setNext(null); - returnDuplicate.replaceAndDelete(n); } - invoke.asNode().replaceAtUsages(null); - GraphUtil.killCFG(invoke.asNode()); + invokeNode.replaceAtUsages(null); + GraphUtil.killCFG(invokeNode); return duplicates; } + public static ValueNode mergeReturns(MergeNode merge, List<? extends ReturnNode> returnNodes) { + PhiNode returnValuePhi = null; + + for (ReturnNode returnNode : returnNodes) { + // create and wire up a new EndNode + EndNode endNode = merge.graph().add(new EndNode()); + merge.addForwardEnd(endNode); + + if (returnNode.result() != null) { + if (returnValuePhi == null) { + returnValuePhi = merge.graph().addWithoutUnique(new PhiNode(returnNode.result().kind(), merge)); + } + returnValuePhi.addInput(returnNode.result()); + } + returnNode.clearInputs(); + returnNode.replaceAndDelete(endNode); + + } + return returnValuePhi; + } + private static boolean checkContainsOnlyInvalidOrAfterFrameState(Map<Node, Node> duplicates) { for (Node node : duplicates.values()) { if (node instanceof FrameState) {
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java Wed Jan 22 21:34:00 2014 -0800 @@ -153,7 +153,7 @@ } private static boolean doesNotAlwaysDeopt(StructuredGraph graph) { - return graph.getNodes().filter(ReturnNode.class).iterator().hasNext(); + return graph.getNodes(ReturnNode.class).isNotEmpty(); } private void computeLoopFactors() {
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/MergeableState.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/MergeableState.java Wed Jan 22 21:34:00 2014 -0800 @@ -61,4 +61,17 @@ public void afterSplit(AbstractBeginNode node) { // empty default implementation } + + public static final class EmptyState extends MergeableState<EmptyState> { + + @Override + public EmptyState clone() { + return this; + } + + @Override + public boolean merge(MergeNode merge, List<EmptyState> withStates) { + return true; + } + } }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Wed Jan 22 21:34:00 2014 -0800 @@ -262,6 +262,7 @@ @Override protected void run(StructuredGraph graph) { + assert GraphOrder.assertNonCyclicGraph(graph); cfg = ControlFlowGraph.compute(graph, true, true, true, true); earliestCache = graph.createNodeMap(); blockToNodesMap = new BlockMap<>(cfg);
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java Wed Jan 22 21:34:00 2014 -0800 @@ -26,102 +26,88 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.phases.graph.*; -public final class GraphOrder implements Iterable<Node> { - - private final ArrayList<Node> nodes = new ArrayList<>(); +public final class GraphOrder { private GraphOrder() { } - public static GraphOrder forwardGraph(Graph graph) { - GraphOrder result = new GraphOrder(); - + /** + * Asserts that there are no (invalid) cycles in the given graph. First, an ordered list of all + * nodes in the graph (a total ordering) is created. A second run over this list checks whether + * inputs are scheduled before their usages. + * + * @param graph the graph to be checked. + * @throws AssertionError if a cycle was detected. + */ + public static boolean assertNonCyclicGraph(StructuredGraph graph) { + List<Node> order = createOrder(graph); NodeBitMap visited = graph.createNodeBitMap(); + visited.clearAll(); + for (Node node : order) { + if (node instanceof PhiNode && ((PhiNode) node).merge() instanceof LoopBeginNode) { + assert visited.isMarked(((PhiNode) node).valueAt(0)); + // nothing to do + } else { + for (Node input : node.inputs()) { + if (!visited.isMarked(input)) { + if (input instanceof FrameState && node instanceof StateSplit && input == ((StateSplit) node).stateAfter()) { + // nothing to do - after frame states are known, allowed cycles + } else { + assert false : "cycle detected: " + node + " -> " + input; + } + } + } + } + visited.mark(node); + } - for (ControlSinkNode node : graph.getNodes().filter(ControlSinkNode.class)) { - result.visitForward(visited, node); - } - return result; + return true; } - public static GraphOrder backwardGraph(Graph graph) { - GraphOrder result = new GraphOrder(); - - NodeBitMap visited = graph.createNodeBitMap(); + private static List<Node> createOrder(StructuredGraph graph) { + final ArrayList<Node> nodes = new ArrayList<>(); + final NodeBitMap visited = graph.createNodeBitMap(); - for (Node node : forwardGraph(graph)) { - result.visitBackward(visited, node); - } - return result; + new PostOrderNodeIterator<MergeableState.EmptyState>(graph.start(), new MergeableState.EmptyState()) { + @Override + protected void node(FixedNode node) { + visitForward(nodes, visited, node, false); + } + }.apply(); + return nodes; } - private void visitForward(NodeBitMap visited, Node node) { + private static void visitForward(ArrayList<Node> nodes, NodeBitMap visited, Node node, boolean floatingOnly) { if (node != null && !visited.isMarked(node)) { + assert !floatingOnly || !(node instanceof FixedNode) : "unexpected reference to fixed node: " + node; visited.mark(node); - if (node.predecessor() != null) { - visitForward(visited, node.predecessor()); + FrameState stateAfter = null; + if (node instanceof StateSplit) { + stateAfter = ((StateSplit) node).stateAfter(); } - if (node instanceof MergeNode) { - // make sure that the cfg predecessors of a MergeNode are processed first - MergeNode merge = (MergeNode) node; - for (int i = 0; i < merge.forwardEndCount(); i++) { - visitForward(visited, merge.forwardEndAt(i)); + for (Node input : node.inputs()) { + if (input != stateAfter) { + visitForward(nodes, visited, input, true); } } - for (Node input : node.inputs()) { - visitForward(visited, input); - } - if (node instanceof LoopBeginNode) { - LoopBeginNode loopBegin = (LoopBeginNode) node; - for (LoopEndNode loopEnd : loopBegin.loopEnds()) { - visitForward(visited, loopEnd); + if (node instanceof EndNode) { + EndNode end = (EndNode) node; + for (PhiNode phi : end.merge().phis()) { + visitForward(nodes, visited, phi.valueAt(end), true); } } nodes.add(node); - } - } - - private void visitBackward(NodeBitMap visited, Node node) { - if (node != null && !visited.isMarked(node)) { - visited.mark(node); - for (Node successor : node.successors()) { - visitBackward(visited, successor); + if (node instanceof MergeNode) { + for (PhiNode phi : ((MergeNode) node).phis()) { + visited.mark(phi); + nodes.add(phi); + } } - for (Node usage : node.usages()) { - visitBackward(visited, usage); + if (stateAfter != null) { + visitForward(nodes, visited, stateAfter, true); } - nodes.add(node); } } - - @Override - public Iterator<Node> iterator() { - return new Iterator<Node>() { - - private int pos = 0; - - private void removeDeleted() { - while (pos < nodes.size() && nodes.get(pos).isDeleted()) { - pos++; - } - } - - @Override - public boolean hasNext() { - removeDeleted(); - return pos < nodes.size(); - } - - @Override - public Node next() { - return nodes.get(pos++); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } }
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java Wed Jan 22 21:34:00 2014 -0800 @@ -443,9 +443,9 @@ protected void doState(LIRFrameState state) { if (state.hasDebugInfo()) { DebugInfo di = state.debugInfo(); - stateString.append(debugInfoToString(di.getBytecodePosition(), di.getRegisterRefMap(), di.getFrameRefMap(), di.getCalleeSaveInfo(), target.arch)); + stateString.append(debugInfoToString(di.getBytecodePosition(), di.getReferenceMap(), di.getCalleeSaveInfo(), target.arch)); } else { - stateString.append(debugInfoToString(state.topFrame, null, null, null, target.arch)); + stateString.append(debugInfoToString(state.topFrame, null, null, target.arch)); } } });
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java Wed Jan 22 21:34:00 2014 -0800 @@ -28,6 +28,7 @@ import java.util.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.CodeUtil.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; @@ -111,26 +112,38 @@ end("compilation"); } + private static class ArchitectureRegFormatter implements RefMapFormatter { + + private final Register[] registers; + + public ArchitectureRegFormatter(Architecture arch) { + registers = arch.getRegisters(); + } + + public String formatStackSlot(int frameRefMapIndex) { + return null; + } + + public String formatRegister(int regRefMapIndex) { + return registers[regRefMapIndex].toString(); + } + } + /** * Formats given debug info as a multi line string. */ - protected String debugInfoToString(BytecodePosition codePos, BitSet registerRefMap, BitSet frameRefMap, RegisterSaveLayout calleeSaveInfo, Architecture arch) { + protected String debugInfoToString(BytecodePosition codePos, ReferenceMap refMap, RegisterSaveLayout calleeSaveInfo, Architecture arch) { StringBuilder sb = new StringBuilder(); - if (registerRefMap != null) { + if (refMap != null && refMap.hasRegisterRefMap()) { sb.append("reg-ref-map:"); - Register[] registers = arch.getRegisters(); - for (int reg = registerRefMap.nextSetBit(0); reg >= 0; reg = registerRefMap.nextSetBit(reg + 1)) { - sb.append(' ').append(arch == null ? "r" + reg : registers[reg]); - } + refMap.appendRegisterMap(sb, arch != null ? new ArchitectureRegFormatter(arch) : null); sb.append("\n"); } - if (frameRefMap != null) { + if (refMap != null && refMap.hasFrameRefMap()) { sb.append("frame-ref-map:"); - for (int slot = frameRefMap.nextSetBit(0); slot >= 0; slot = frameRefMap.nextSetBit(slot + 1)) { - sb.append(' ').append("s").append(slot); - } + refMap.appendFrameMap(sb, null); sb.append("\n"); }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Wed Jan 22 21:34:00 2014 -0800 @@ -36,9 +36,8 @@ import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.debug.internal.*; +import com.oracle.graal.graph.*; import com.oracle.graal.graph.Graph.Mark; -import com.oracle.graal.graph.*; -import com.oracle.graal.graph.iterators.*; import com.oracle.graal.loop.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.GuardsStage; @@ -623,43 +622,49 @@ assert checkAllVarargPlaceholdersAreDeleted(parameterCount, placeholders); new FloatingReadPhase(FloatingReadPhase.ExecutionMode.ANALYSIS_ONLY).apply(snippetCopy); - this.memoryMap = null; this.snippet = snippetCopy; - ReturnNode retNode = null; + List<ReturnNode> returnNodes = new ArrayList<>(4); + List<MemoryMapNode> memMaps = new ArrayList<>(4); StartNode entryPointNode = snippet.start(); - nodes = new ArrayList<>(snippet.getNodeCount()); - boolean seenReturn = false; - boolean containsMemoryMap = false; - for (Node node : snippet.getNodes()) { - if (node == entryPointNode || node == entryPointNode.stateAfter()) { - // Do nothing. - } else { - nodes.add(node); - if (node instanceof ReturnNode) { - retNode = (ReturnNode) node; - NodeIterable<MemoryMapNode> memstates = retNode.inputs().filter(MemoryMapNode.class); - assert memstates.count() == 1; - memoryMap = memstates.first(); - retNode.replaceFirstInput(memoryMap, null); - memoryMap.safeDelete(); - - assert !seenReturn : "can handle only one ReturnNode"; - seenReturn = true; - } else if (node instanceof MemoryMapNode) { - containsMemoryMap = true; - } + for (ReturnNode retNode : snippet.getNodes(ReturnNode.class)) { + MemoryMapNode memMap = retNode.getMemoryMap(); + memMaps.add(memMap); + retNode.setMemoryMap(null); + returnNodes.add(retNode); + if (memMap.usages().isEmpty()) { + memMap.safeDelete(); } } - assert !containsMemoryMap; + assert snippet.getNodes().filter(MemoryMapNode.class).isEmpty(); + if (returnNodes.isEmpty()) { + this.returnNode = null; + this.memoryMap = null; + } else if (returnNodes.size() == 1) { + this.returnNode = returnNodes.get(0); + this.memoryMap = memMaps.get(0); + } else { + MergeNode merge = snippet.add(new MergeNode()); + ValueNode returnValue = InliningUtil.mergeReturns(merge, returnNodes); + this.returnNode = snippet.add(new ReturnNode(returnValue)); + this.memoryMap = FloatingReadPhase.mergeMemoryMaps(merge, memMaps); + merge.setNext(this.returnNode); + } this.sideEffectNodes = curSideEffectNodes; this.deoptNodes = curDeoptNodes; this.stampNodes = curStampNodes; - this.returnNode = retNode; + + nodes = new ArrayList<>(snippet.getNodeCount()); + for (Node node : snippet.getNodes()) { + if (node != entryPointNode && node != entryPointNode.stateAfter()) { + nodes.add(node); + } + } Debug.metric(debugValueName("SnippetTemplateNodeCount", args)).add(nodes.size()); args.info.notifyNewTemplate(); + Debug.dump(snippet, "SnippetTemplate final state"); } private static boolean checkAllVarargPlaceholdersAreDeleted(int parameterCount, VarargsPlaceholderNode[] placeholders) { @@ -720,7 +725,7 @@ /** * Nodes that inherit the {@link DeoptimizingNode#getDeoptimizationState()} from the replacee - * during insantiation. + * during instantiation. */ private final ArrayList<DeoptimizingNode> deoptNodes; @@ -737,7 +742,7 @@ /** * map of killing locations to memory checkpoints (nodes). */ - private MemoryMapNode memoryMap; + private final MemoryMapNode memoryMap; /** * Times instantiations of this template. @@ -876,7 +881,7 @@ // MemoryCheckPoint inside the snippet graph MemoryNode lastAccess = mmap.getLastLocationAccess(identity); - assert lastAccess != null : "no mapping found for lowerable node " + oldNode + ". (No node in the snippet kill the same location as the lowerable node?)"; + assert lastAccess != null : "no mapping found for lowerable node " + oldNode + ". (No node in the snippet kills the same location as the lowerable node?)"; if (usage instanceof MemoryAccess) { MemoryAccess access = (MemoryAccess) usage; if (access.getLastLocationAccess() == oldNode) { @@ -961,6 +966,11 @@ return (MemoryNode) duplicates.get(ValueNodeUtil.asNode(lastLocationAccess)); } } + + @Override + public Set<LocationIdentity> getLocations() { + return memoryMap.getLocations(); + } } /** @@ -1014,25 +1024,18 @@ } } - for (ValueNode stampNode : stampNodes) { - Node stampDup = duplicates.get(stampNode); - ((ValueNode) stampDup).setStamp(((ValueNode) replacee).stamp()); - } + updateStamps(replacee, duplicates); // Replace all usages of the replacee with the value returned by the snippet ValueNode returnValue = null; if (returnNode != null && !(replacee instanceof ControlSinkNode)) { - if (returnNode.result() instanceof ParameterNode) { - returnValue = (ValueNode) replacements.get(returnNode.result()); - } else if (returnNode.result() != null) { - returnValue = (ValueNode) duplicates.get(returnNode.result()); - } - Node returnDuplicate = duplicates.get(returnNode); + ReturnNode returnDuplicate = (ReturnNode) duplicates.get(returnNode); + returnValue = returnDuplicate.result(); MemoryMapNode mmap = new DuplicateMapper(duplicates, replaceeGraph.start()); if (returnValue == null && replacee.usages().isNotEmpty() && replacee instanceof MemoryCheckpoint) { replacer.replace(replacee, (ValueNode) returnDuplicate.predecessor(), mmap); } else { - assert returnValue != null || replacee.usages().isEmpty() : this + " " + returnValue + " " + returnNode + " " + replacee.usages(); + assert returnValue != null || replacee.usages().isEmpty(); replacer.replace(replacee, returnValue, mmap); } if (returnDuplicate.isAlive()) { @@ -1051,6 +1054,30 @@ } } + private void propagateStamp(Node node) { + if (node instanceof PhiNode) { + PhiNode phi = (PhiNode) node; + if (phi.inferPhiStamp()) { + for (Node usage : node.usages()) { + propagateStamp(usage); + } + } + } + } + + private void updateStamps(ValueNode replacee, Map<Node, Node> duplicates) { + for (ValueNode stampNode : stampNodes) { + Node stampDup = duplicates.get(stampNode); + ((ValueNode) stampDup).setStamp(replacee.stamp()); + } + for (ParameterNode paramNode : snippet.getNodes(ParameterNode.class)) { + for (Node usage : paramNode.usages()) { + Node usageDup = duplicates.get(usage); + propagateStamp(usageDup); + } + } + } + /** * Gets a copy of the specialized graph. */ @@ -1097,23 +1124,14 @@ ((StateSplit) sideEffectDup).setStateAfter(((StateSplit) replacee).stateAfter()); } } - for (ValueNode stampNode : stampNodes) { - Node stampDup = duplicates.get(stampNode); - ((ValueNode) stampDup).setStamp(((ValueNode) replacee).stamp()); - } + updateStamps(replacee, duplicates); // Replace all usages of the replacee with the value returned by the snippet - assert returnNode != null : replaceeGraph; - ValueNode returnValue = null; - if (returnNode.result() instanceof ParameterNode) { - returnValue = (ValueNode) replacements.get(returnNode.result()); - } else { - returnValue = (ValueNode) duplicates.get(returnNode.result()); - } + ReturnNode returnDuplicate = (ReturnNode) duplicates.get(returnNode); + ValueNode returnValue = returnDuplicate.result(); assert returnValue != null || replacee.usages().isEmpty(); replacer.replace(replacee, returnValue, new DuplicateMapper(duplicates, replaceeGraph.start())); - Node returnDuplicate = duplicates.get(returnNode); if (returnDuplicate.isAlive()) { returnDuplicate.clearInputs(); returnDuplicate.replaceAndDelete(next);
--- a/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java Wed Jan 22 21:34:00 2014 -0800 @@ -162,6 +162,7 @@ case Int: case Long: case Object: + case NarrowOop: return true; } } else if (category == FPU) {
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/AssumptionPartialEvaluationTest.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/AssumptionPartialEvaluationTest.java Wed Jan 22 21:34:00 2014 -0800 @@ -42,8 +42,8 @@ FrameDescriptor fd = new FrameDescriptor(); Assumption assumption = Truffle.getRuntime().createAssumption(); AbstractTestNode result = new ConstantWithAssumptionTestNode(assumption, 42); - RootTestNode rootNode = new RootTestNode("constantValue", result); - InstalledCode installedCode = assertPartialEvalEquals("constant42", rootNode, fd); + RootTestNode rootNode = new RootTestNode(fd, "constantValue", result); + InstalledCode installedCode = assertPartialEvalEquals("constant42", rootNode); Assert.assertTrue(installedCode.isValid()); try { assertEquals(42, installedCode.execute(null, null, null));
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Wed Jan 22 21:34:00 2014 -0800 @@ -45,7 +45,6 @@ import com.oracle.graal.truffle.*; import com.oracle.graal.virtual.phases.ea.*; import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; public class PartialEvaluationTest extends GraalCompilerTest { @@ -64,13 +63,13 @@ DebugEnvironment.initialize(System.out); } - protected InstalledCode assertPartialEvalEquals(String methodName, RootNode root, FrameDescriptor descriptor) { - return assertPartialEvalEquals(methodName, root, descriptor, Arguments.EMPTY_ARGUMENTS); + protected InstalledCode assertPartialEvalEquals(String methodName, RootNode root) { + return assertPartialEvalEquals(methodName, root, Arguments.EMPTY_ARGUMENTS); } - protected InstalledCode assertPartialEvalEquals(String methodName, RootNode root, FrameDescriptor descriptor, Arguments arguments) { + protected InstalledCode assertPartialEvalEquals(String methodName, RootNode root, Arguments arguments) { Assumptions assumptions = new Assumptions(true); - StructuredGraph actual = partialEval(root, descriptor, arguments, assumptions, true); + StructuredGraph actual = partialEval(root, arguments, assumptions, true); InstalledCode result = new TruffleCompilerImpl().compileMethodHelper(actual, GraphBuilderConfiguration.getDefault(), assumptions, root.toString()); StructuredGraph expected = parseForComparison(methodName); removeFrameStates(actual); @@ -78,21 +77,21 @@ return result; } - protected void assertPartialEvalNoInvokes(RootNode root, FrameDescriptor descriptor) { - assertPartialEvalNoInvokes(root, descriptor, Arguments.EMPTY_ARGUMENTS); + protected void assertPartialEvalNoInvokes(RootNode root) { + assertPartialEvalNoInvokes(root, Arguments.EMPTY_ARGUMENTS); } - protected void assertPartialEvalNoInvokes(RootNode root, FrameDescriptor descriptor, Arguments arguments) { + protected void assertPartialEvalNoInvokes(RootNode root, Arguments arguments) { Assumptions assumptions = new Assumptions(true); - StructuredGraph actual = partialEval(root, descriptor, arguments, assumptions, true); + StructuredGraph actual = partialEval(root, arguments, assumptions, true); removeFrameStates(actual); for (MethodCallTargetNode node : actual.getNodes(MethodCallTargetNode.class)) { Assert.fail("Found invalid method call target node: " + node); } } - protected StructuredGraph partialEval(RootNode root, FrameDescriptor descriptor, Arguments arguments, final Assumptions assumptions, final boolean canonicalizeReads) { - final OptimizedCallTarget compilable = (OptimizedCallTarget) Truffle.getRuntime().createCallTarget(root, descriptor); + protected StructuredGraph partialEval(RootNode root, Arguments arguments, final Assumptions assumptions, final boolean canonicalizeReads) { + final OptimizedCallTarget compilable = (OptimizedCallTarget) Truffle.getRuntime().createCallTarget(root); // Executed AST so that all classes are loaded and initialized. do {
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/SimplePartialEvaluationTest.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/SimplePartialEvaluationTest.java Wed Jan 22 21:34:00 2014 -0800 @@ -38,28 +38,28 @@ public void constantValue() { FrameDescriptor fd = new FrameDescriptor(); AbstractTestNode result = new ConstantTestNode(42); - assertPartialEvalEquals("constant42", new RootTestNode("constantValue", result), fd); + assertPartialEvalEquals("constant42", new RootTestNode(fd, "constantValue", result)); } @Test public void addConstants() { FrameDescriptor fd = new FrameDescriptor(); AbstractTestNode result = new AddTestNode(new ConstantTestNode(40), new ConstantTestNode(2)); - assertPartialEvalEquals("constant42", new RootTestNode("addConstants", result), fd); + assertPartialEvalEquals("constant42", new RootTestNode(fd, "addConstants", result)); } @Test public void sequenceConstants() { FrameDescriptor fd = new FrameDescriptor(); AbstractTestNode result = new BlockTestNode(new AbstractTestNode[]{new ConstantTestNode(40), new ConstantTestNode(42)}); - assertPartialEvalEquals("constant42", new RootTestNode("sequenceConstants", result), fd); + assertPartialEvalEquals("constant42", new RootTestNode(fd, "sequenceConstants", result)); } @Test public void localVariable() { FrameDescriptor fd = new FrameDescriptor(); AbstractTestNode result = new BlockTestNode(new AbstractTestNode[]{new StoreLocalTestNode("x", fd, new ConstantTestNode(42)), new LoadLocalTestNode("x", fd)}); - assertPartialEvalEquals("constant42", new RootTestNode("localVariable", result), fd); + assertPartialEvalEquals("constant42", new RootTestNode(fd, "localVariable", result)); } @Test @@ -72,7 +72,7 @@ } AbstractTestNode result = new BlockTestNode(children); - assertPartialEvalEquals("constant42", new RootTestNode("longSequenceConstants", result), fd); + assertPartialEvalEquals("constant42", new RootTestNode(fd, "longSequenceConstants", result)); } @Test @@ -82,7 +82,7 @@ for (int i = 0; i < 20; ++i) { result = new AddTestNode(result, new ConstantTestNode(2)); } - assertPartialEvalEquals("constant42", new RootTestNode("longAddConstants", result), fd); + assertPartialEvalEquals("constant42", new RootTestNode(fd, "longAddConstants", result)); } @Test @@ -90,7 +90,7 @@ FrameDescriptor fd = new FrameDescriptor(); AbstractTestNode result = new BlockTestNode(new AbstractTestNode[]{new StoreLocalTestNode("x", fd, new ConstantTestNode(40)), new StoreLocalTestNode("x", fd, new AddTestNode(new LoadLocalTestNode("x", fd), new ConstantTestNode(2))), new LoadLocalTestNode("x", fd)}); - assertPartialEvalEquals("constant42", new RootTestNode("mixLocalAndAdd", result), fd); + assertPartialEvalEquals("constant42", new RootTestNode(fd, "mixLocalAndAdd", result)); } @Test @@ -98,7 +98,7 @@ FrameDescriptor fd = new FrameDescriptor(); AbstractTestNode result = new BlockTestNode(new AbstractTestNode[]{new StoreLocalTestNode("x", fd, new ConstantTestNode(0)), new LoopTestNode(21, new StoreLocalTestNode("x", fd, new AddTestNode(new LoadLocalTestNode("x", fd), new ConstantTestNode(2))))}); - assertPartialEvalEquals("constant42", new RootTestNode("loop", result), fd); + assertPartialEvalEquals("constant42", new RootTestNode(fd, "loop", result)); } @Test @@ -106,6 +106,6 @@ FrameDescriptor fd = new FrameDescriptor(); AbstractTestNode result = new BlockTestNode(new AbstractTestNode[]{new StoreLocalTestNode("x", fd, new ConstantTestNode(0)), new LoopTestNode(42, new StoreLocalTestNode("x", fd, new AddTestNode(new LoadLocalTestNode("x", fd), new ConstantTestNode(1))))}); - assertPartialEvalNoInvokes(new RootTestNode("loop", result), fd); + assertPartialEvalNoInvokes(new RootTestNode(fd, "loop", result)); } }
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/RootTestNode.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/RootTestNode.java Wed Jan 22 21:34:00 2014 -0800 @@ -30,8 +30,8 @@ private final String name; @Child AbstractTestNode node; - public RootTestNode(String name, AbstractTestNode node) { - super(null); + public RootTestNode(FrameDescriptor descriptor, String name, AbstractTestNode node) { + super(null, descriptor); this.name = name; this.node = node; }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java Wed Jan 22 21:34:00 2014 -0800 @@ -26,8 +26,6 @@ public class CompilationProfile { - private static final int MIN_INVOKES_AFTER_INLINING = 2; - private int invokeCounter; private int originalInvokeCounter; private int loopAndInvokeCounter; @@ -102,9 +100,9 @@ loopAndInvokeCounter--; } - void reportInliningPerformed() { - invokeCounter = MIN_INVOKES_AFTER_INLINING; - int inliningReprofileCount = TruffleInliningReprofileCount.getValue(); + void reportInliningPerformed(TruffleInlining inlining) { + invokeCounter = inlining.getInvocationReprofileCount(); + int inliningReprofileCount = inlining.getReprofileCount(); loopAndInvokeCounter = inliningReprofileCount; originalInvokeCounter = inliningReprofileCount; }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java Wed Jan 22 21:34:00 2014 -0800 @@ -74,18 +74,13 @@ } public CallTarget createCallTarget(RootNode rootNode) { - return createCallTarget(rootNode, new FrameDescriptor()); - } - - @Override - public CallTarget createCallTarget(RootNode rootNode, FrameDescriptor frameDescriptor) { if (!acceptForCompilation(rootNode)) { - return new DefaultCallTarget(rootNode, frameDescriptor); + return new DefaultCallTarget(rootNode); } if (truffleCompiler == null) { truffleCompiler = new TruffleCompilerImpl(); } - return new OptimizedCallTarget(rootNode, frameDescriptor, truffleCompiler, TruffleMinInvokeThreshold.getValue(), TruffleCompilationThreshold.getValue()); + return new OptimizedCallTarget(rootNode, truffleCompiler, TruffleMinInvokeThreshold.getValue(), TruffleCompilationThreshold.getValue()); } @Override
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Wed Jan 22 21:34:00 2014 -0800 @@ -51,11 +51,10 @@ private boolean compilationEnabled; private int callCount; - protected OptimizedCallTarget(RootNode rootNode, FrameDescriptor descriptor, TruffleCompiler compiler, int invokeCounter, int compilationThreshold) { - super(rootNode, descriptor); + protected OptimizedCallTarget(RootNode rootNode, TruffleCompiler compiler, int invokeCounter, int compilationThreshold) { + super(rootNode); this.compiler = compiler; this.compilationProfile = new CompilationProfile(compilationThreshold, invokeCounter, rootNode.toString()); - this.inlining = new TruffleInliningImpl(); this.rootNode.setCallTarget(this); if (TruffleUseTimeForCompilationDecision.getValue()) { @@ -68,8 +67,11 @@ if (TruffleCallTargetProfiling.getValue()) { registerCallTarget(this); } + this.inlining = new TruffleInliningImpl(); + } + @CompilerDirectives.SlowPath @Override public Object call(PackedFrame caller, Arguments args) { return callHelper(caller, args); @@ -204,13 +206,13 @@ public boolean inline() { boolean result = inlining.performInlining(this); if (result) { - compilationProfile.reportInliningPerformed(); + compilationProfile.reportInliningPerformed(inlining); } return result; } public Object executeHelper(PackedFrame caller, Arguments args) { - VirtualFrame frame = createFrame(frameDescriptor, caller, args); + VirtualFrame frame = createFrame(rootNode.getFrameDescriptor(), caller, args); return rootNode.execute(frame); }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInlining.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInlining.java Wed Jan 22 21:34:00 2014 -0800 @@ -24,5 +24,18 @@ public interface TruffleInlining { + /** Returns true if reprofiling is required else false. */ boolean performInlining(OptimizedCallTarget callTarget); + + /** + * Returns the minimum number of invocations required until the next inlining can occur. Only + * used if {@link #performInlining(OptimizedCallTarget)} returned true. + */ + int getInvocationReprofileCount(); + + /** + * Returns the number of invocations or loop invocations required until the next inlining can + * occur. Only used if {@link #performInlining(OptimizedCallTarget)} returned true. + */ + int getReprofileCount(); }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningImpl.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningImpl.java Wed Jan 22 21:34:00 2014 -0800 @@ -33,8 +33,18 @@ class TruffleInliningImpl implements TruffleInlining { + private static final int MIN_INVOKES_AFTER_INLINING = 2; + private static final PrintStream OUT = TTY.out().out(); + public int getReprofileCount() { + return TruffleCompilerOptions.TruffleInliningReprofileCount.getValue(); + } + + public int getInvocationReprofileCount() { + return MIN_INVOKES_AFTER_INLINING; + } + @Override public boolean performInlining(OptimizedCallTarget target) { final InliningPolicy policy = new InliningPolicy(target);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java Wed Jan 22 21:34:00 2014 -0800 @@ -34,9 +34,6 @@ public class OptimizedCallTargetSubstitutions { @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false) - public static native Object call(OptimizedCallTarget target, PackedFrame caller, Arguments args); - - @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false) public static native Object callHelper(OptimizedCallTarget target, PackedFrame caller, Arguments args); @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false)
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameSlotTypeSpecializationTest.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameSlotTypeSpecializationTest.java Wed Jan 22 21:34:00 2014 -0800 @@ -49,8 +49,8 @@ TruffleRuntime runtime = Truffle.getRuntime(); FrameDescriptor frameDescriptor = new FrameDescriptor(); FrameSlot slot = frameDescriptor.addFrameSlot("localVar", FrameSlotKind.Int); - TestRootNode rootNode = new TestRootNode(new IntAssignLocal(slot, new StringTestChildNode()), new IntReadLocal(slot)); - CallTarget target = runtime.createCallTarget(rootNode, frameDescriptor); + TestRootNode rootNode = new TestRootNode(frameDescriptor, new IntAssignLocal(slot, new StringTestChildNode()), new IntReadLocal(slot)); + CallTarget target = runtime.createCallTarget(rootNode); Assert.assertEquals(FrameSlotKind.Int, slot.getKind()); Object result = target.call(); Assert.assertEquals("42", result); @@ -62,8 +62,8 @@ @Child TestChildNode left; @Child TestChildNode right; - public TestRootNode(TestChildNode left, TestChildNode right) { - super(null); + public TestRootNode(FrameDescriptor descriptor, TestChildNode left, TestChildNode right) { + super(null, descriptor); this.left = adoptChild(left); this.right = adoptChild(right); }
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java Wed Jan 22 21:34:00 2014 -0800 @@ -65,8 +65,8 @@ TruffleRuntime runtime = Truffle.getRuntime(); FrameDescriptor frameDescriptor = new FrameDescriptor(); FrameSlot slot = frameDescriptor.addFrameSlot("localVar", FrameSlotKind.Int); - TestRootNode rootNode = new TestRootNode(new AssignLocal(slot), new ReadLocal(slot)); - CallTarget target = runtime.createCallTarget(rootNode, frameDescriptor); + TestRootNode rootNode = new TestRootNode(frameDescriptor, new AssignLocal(slot), new ReadLocal(slot)); + CallTarget target = runtime.createCallTarget(rootNode); Object result = target.call(); Assert.assertEquals(42, result); } @@ -76,8 +76,8 @@ @Child TestChildNode left; @Child TestChildNode right; - public TestRootNode(TestChildNode left, TestChildNode right) { - super(null); + public TestRootNode(FrameDescriptor descriptor, TestChildNode left, TestChildNode right) { + super(null, descriptor); this.left = adoptChild(left); this.right = adoptChild(right); }
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReturnTypeSpecializationTest.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReturnTypeSpecializationTest.java Wed Jan 22 21:34:00 2014 -0800 @@ -48,8 +48,8 @@ TruffleRuntime runtime = Truffle.getRuntime(); FrameDescriptor frameDescriptor = new FrameDescriptor(); FrameSlot slot = frameDescriptor.addFrameSlot("localVar", FrameSlotKind.Int); - TestRootNode rootNode = new TestRootNode(new IntAssignLocal(slot, new StringTestChildNode()), new IntReadLocal(slot)); - CallTarget target = runtime.createCallTarget(rootNode, frameDescriptor); + TestRootNode rootNode = new TestRootNode(frameDescriptor, new IntAssignLocal(slot, new StringTestChildNode()), new IntReadLocal(slot)); + CallTarget target = runtime.createCallTarget(rootNode); Assert.assertEquals(FrameSlotKind.Int, slot.getKind()); Object result = target.call(); Assert.assertEquals("42", result); @@ -61,8 +61,8 @@ @Child TestChildNode left; @Child TestChildNode right; - public TestRootNode(TestChildNode left, TestChildNode right) { - super(null); + public TestRootNode(FrameDescriptor descriptor, TestChildNode left, TestChildNode right) { + super(null, descriptor); this.left = adoptChild(left); this.right = adoptChild(right); }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CallTarget.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CallTarget.java Wed Jan 22 21:34:00 2014 -0800 @@ -28,8 +28,7 @@ /** * Represents the target of a call. Instances of this interface can be created using the - * {@link TruffleRuntime#createCallTarget(com.oracle.truffle.api.nodes.RootNode, FrameDescriptor)} - * method. + * {@link TruffleRuntime#createCallTarget(com.oracle.truffle.api.nodes.RootNode)} method. */ public abstract class CallTarget {
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleOptions.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleOptions.java Wed Jan 22 21:34:00 2014 -0800 @@ -32,31 +32,53 @@ */ public class TruffleOptions { - /** Enables/disables the rewriting of traces in the truffle runtime to stdout. */ - public static boolean TraceRewrites = false; + /** + * Enables/disables the rewriting of traces in the truffle runtime to stdout. + * <p> + * Can be set with {@code -Dtruffle.TraceRewrites=true}. + */ + public static boolean TraceRewrites = Boolean.getBoolean("truffle.TraceRewrites"); /** * Enables the generation of detailed rewrite reasons. Enabling this may introduce some overhead * for rewriting nodes. + * <p> + * Can be set with {@code -Dtruffle.DetailedRewriteReasons=true}. */ - public static final boolean DetailedRewriteReasons = false; + public static final boolean DetailedRewriteReasons = Boolean.getBoolean("truffle.DetailedRewriteReasons"); /** * Filters rewrites that do not contain the given string in the qualified name of the source or * target class hierarchy. + * <p> + * Can be set with {@code -Dtruffle.TraceRewritesFilterClass=name}. */ - public static String TraceRewritesFilterClass = null; + public static String TraceRewritesFilterClass = System.getProperty("truffle.TraceRewritesFilterClass"); /** * Filters rewrites which does not contain the {@link Kind} in its source {@link NodeInfo}. If * no {@link NodeInfo} is defined the element is filtered if the filter value is set. + * <p> + * Can be set with + * {@code -Dtruffle.TraceRewritesFilterFromKind=UNINITIALIZED|SPECIALIZED|POLYMORPHIC|GENERIC}. */ - public static NodeInfo.Kind TraceRewritesFilterFromKind = null; + public static NodeInfo.Kind TraceRewritesFilterFromKind = parseNodeInfoKind(System.getProperty("truffle.TraceRewritesFilterFromKind")); /** * Filters rewrites which does not contain the {@link Kind} in its target {@link NodeInfo}. If * no {@link NodeInfo} is defined the element is filtered if the filter value is set. + * <p> + * Can be set with + * {@code -Dtruffle.TraceRewritesFilterToKind=UNINITIALIZED|SPECIALIZED|POLYMORPHIC|GENERIC}. */ - public static NodeInfo.Kind TraceRewritesFilterToKind = null; + public static NodeInfo.Kind TraceRewritesFilterToKind = parseNodeInfoKind(System.getProperty("truffle.TraceRewritesFilterToKind")); + + private static NodeInfo.Kind parseNodeInfoKind(String kind) { + if (kind == null) { + return null; + } + + return NodeInfo.Kind.valueOf(kind); + } }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java Wed Jan 22 21:34:00 2014 -0800 @@ -51,17 +51,6 @@ CallTarget createCallTarget(RootNode rootNode); /** - * Creates a new call target for a given root node and a given frame descriptor. - * - * @param rootNode the root node whose - * {@link RootNode#execute(com.oracle.truffle.api.frame.VirtualFrame)} method - * represents the entry point - * @param frameDescriptor the descriptor used for creating a new frame at each invocation - * @return the new call target object - */ - CallTarget createCallTarget(RootNode rootNode, FrameDescriptor frameDescriptor); - - /** * Creates a new assumption object that can be checked and invalidated. * * @return the newly created assumption object
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java Wed Jan 22 21:34:00 2014 -0800 @@ -31,11 +31,9 @@ public class DefaultCallTarget extends CallTarget { protected final RootNode rootNode; - protected final FrameDescriptor frameDescriptor; - public DefaultCallTarget(RootNode function, FrameDescriptor frameDescriptor) { + public DefaultCallTarget(RootNode function) { this.rootNode = function; - this.frameDescriptor = frameDescriptor; this.rootNode.setCallTarget(this); } @@ -46,14 +44,10 @@ @Override public Object call(PackedFrame caller, Arguments args) { - VirtualFrame frame = new DefaultVirtualFrame(frameDescriptor, caller, args); + VirtualFrame frame = new DefaultVirtualFrame(rootNode.getFrameDescriptor(), caller, args); return rootNode.execute(frame); } - public FrameDescriptor getFrameDescriptor() { - return frameDescriptor; - } - public RootNode getRootNode() { return rootNode; }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java Wed Jan 22 21:34:00 2014 -0800 @@ -41,12 +41,7 @@ @Override public CallTarget createCallTarget(RootNode rootNode) { - return createCallTarget(rootNode, new FrameDescriptor()); - } - - @Override - public CallTarget createCallTarget(RootNode rootNode, FrameDescriptor frameDescriptor) { - return new DefaultCallTarget(rootNode, frameDescriptor); + return new DefaultCallTarget(rootNode); } @Override
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java Wed Jan 22 21:34:00 2014 -0800 @@ -30,15 +30,28 @@ /** * A root node is a node with a method to execute it given only a frame as a parameter. Therefore, a * root node can be used to create a call target using - * {@link TruffleRuntime#createCallTarget(RootNode, FrameDescriptor)}. + * {@link TruffleRuntime#createCallTarget(RootNode)}. */ public abstract class RootNode extends Node { + private CallTarget callTarget; + private final FrameDescriptor frameDescriptor; + protected RootNode() { + this(null, null); } protected RootNode(SourceSection sourceSection) { + this(sourceSection, null); + } + + protected RootNode(SourceSection sourceSection, FrameDescriptor frameDescriptor) { super(sourceSection); + if (frameDescriptor == null) { + this.frameDescriptor = new FrameDescriptor(); + } else { + this.frameDescriptor = frameDescriptor; + } } /** @@ -49,12 +62,14 @@ */ public abstract Object execute(VirtualFrame frame); - private CallTarget callTarget; - public CallTarget getCallTarget() { return callTarget; } + public FrameDescriptor getFrameDescriptor() { + return frameDescriptor; + } + public void setCallTarget(CallTarget callTarget) { this.callTarget = callTarget; }
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/AnnotationProcessor.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/AnnotationProcessor.java Wed Jan 22 21:34:00 2014 -0800 @@ -102,18 +102,18 @@ private static class CodeWriter extends AbstractCodeWriter { - private final Element orignalElement; + private final Element originalElement; private final ProcessingEnvironment env; public CodeWriter(ProcessingEnvironment env, Element originalElement) { this.env = env; - this.orignalElement = originalElement; + this.originalElement = originalElement; } @Override protected Writer createWriter(CodeTypeElement clazz) throws IOException { - JavaFileObject jfo = env.getFiler().createSourceFile(clazz.getQualifiedName(), orignalElement); - return jfo.openWriter(); + JavaFileObject jfo = env.getFiler().createSourceFile(clazz.getQualifiedName(), originalElement); + return new BufferedWriter(jfo.openWriter()); } @Override @@ -121,7 +121,7 @@ if (env == null) { return; } - String comment = CompilerFactory.getCompiler(orignalElement).getHeaderComment(env, orignalElement); + String comment = CompilerFactory.getCompiler(originalElement).getHeaderComment(env, originalElement); if (comment != null) { writeLn(comment); }
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/RubyRootNode.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/RubyRootNode.java Wed Jan 22 21:34:00 2014 -0800 @@ -22,8 +22,8 @@ protected final String indicativeName; @Child protected RubyNode body; - public RubyRootNode(SourceSection sourceSection, String indicativeName, RubyNode body) { - super(sourceSection); + public RubyRootNode(SourceSection sourceSection, FrameDescriptor descriptor, String indicativeName, RubyNode body) { + super(sourceSection, descriptor); assert indicativeName != null; assert body != null;
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/CoreMethodNodeManager.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/CoreMethodNodeManager.java Wed Jan 22 21:34:00 2014 -0800 @@ -174,7 +174,7 @@ final CheckArityNode checkArity = new CheckArityNode(context, sourceSection, arity); final SequenceNode block = new SequenceNode(context, sourceSection, checkArity, methodNode); - return new RubyRootNode(sourceSection, methodDetails.getClassAnnotation().name() + "#" + methodDetails.getMethodAnnotation().names()[0] + "(core)", block); + return new RubyRootNode(sourceSection, null, methodDetails.getClassAnnotation().name() + "#" + methodDetails.getMethodAnnotation().names()[0] + "(core)", block); } public static class MethodDetails {
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ModuleNodes.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ModuleNodes.java Wed Jan 22 21:34:00 2014 -0800 @@ -96,7 +96,7 @@ final SequenceNode block = new SequenceNode(context, sourceSection, checkArity, readInstanceVariable); - final RubyRootNode pristineRoot = new RubyRootNode(sourceSection, name + "(attr_reader)", block); + final RubyRootNode pristineRoot = new RubyRootNode(sourceSection, null, name + "(attr_reader)", block); final CallTarget callTarget = Truffle.getRuntime().createCallTarget(NodeUtil.cloneNode(pristineRoot)); final InlinableMethodImplementation methodImplementation = new InlinableMethodImplementation(callTarget, null, new FrameDescriptor(), pristineRoot, true, false); final RubyMethod method = new RubyMethod(sourceSection, module, new UniqueMethodIdentifier(), null, name, Visibility.PUBLIC, false, methodImplementation); @@ -139,7 +139,7 @@ final SequenceNode block = new SequenceNode(context, sourceSection, checkArity, writeInstanceVariable); - final RubyRootNode pristineRoot = new RubyRootNode(sourceSection, name + "(attr_writer)", block); + final RubyRootNode pristineRoot = new RubyRootNode(sourceSection, null, name + "(attr_writer)", block); final CallTarget callTarget = Truffle.getRuntime().createCallTarget(NodeUtil.cloneNode(pristineRoot)); final InlinableMethodImplementation methodImplementation = new InlinableMethodImplementation(callTarget, null, new FrameDescriptor(), pristineRoot, true, false); final RubyMethod method = new RubyMethod(sourceSection, module, new UniqueMethodIdentifier(), null, name + "=", Visibility.PUBLIC, false, methodImplementation);
--- a/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/JRubyParser.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/JRubyParser.java Wed Jan 22 21:34:00 2014 -0800 @@ -161,11 +161,10 @@ throw new UnsupportedOperationException(); } - final RootNode root = new RubyRootNode(truffleNode.getSourceSection(), indicativeName, truffleNode); + final RootNode root = new RubyRootNode(truffleNode.getSourceSection(), environment.getFrameDescriptor(), indicativeName, truffleNode); // Return the root and the frame descriptor - - return new RubyParserResult(root, environment.getFrameDescriptor()); + return new RubyParserResult(root); } finally { if (debugManager != null) { debugManager.notifyFinishedLoading(source);
--- a/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/MethodTranslator.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/MethodTranslator.java Wed Jan 22 21:34:00 2014 -0800 @@ -59,9 +59,9 @@ body = new CatchNextNode(context, sourceSection, body); } - final RubyRootNode pristineRootNode = new RubyRootNode(sourceSection, methodName, body); + final RubyRootNode pristineRootNode = new RubyRootNode(sourceSection, environment.getFrameDescriptor(), methodName, body); - final CallTarget callTarget = Truffle.getRuntime().createCallTarget(NodeUtil.cloneNode(pristineRootNode), environment.getFrameDescriptor()); + final CallTarget callTarget = Truffle.getRuntime().createCallTarget(NodeUtil.cloneNode(pristineRootNode)); if (isBlock) { return new BlockDefinitionNode(context, sourceSection, methodName, environment.getUniqueMethodIdentifier(), environment.getFrameDescriptor(), environment.needsDeclarationFrame(),
--- a/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/ModuleTranslator.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/ModuleTranslator.java Wed Jan 22 21:34:00 2014 -0800 @@ -57,9 +57,9 @@ body = new CatchReturnNode(context, sourceSection, body, environment.getReturnID()); - final RubyRootNode pristineRootNode = new RubyRootNode(sourceSection, methodName, body); + final RubyRootNode pristineRootNode = new RubyRootNode(sourceSection, environment.getFrameDescriptor(), methodName, body); - final CallTarget callTarget = Truffle.getRuntime().createCallTarget(NodeUtil.cloneNode(pristineRootNode), environment.getFrameDescriptor()); + final CallTarget callTarget = Truffle.getRuntime().createCallTarget(NodeUtil.cloneNode(pristineRootNode)); return new MethodDefinitionNode(context, sourceSection, methodName, environment.getUniqueMethodIdentifier(), environment.getFrameDescriptor(), environment.needsDeclarationFrame(), pristineRootNode, callTarget);
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/RubyContext.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/RubyContext.java Wed Jan 22 21:34:00 2014 -0800 @@ -172,7 +172,7 @@ try { final RubyParserResult parseResult = parser.parse(context, source, parserContext, parentFrame); final RubyArguments arguments = new RubyArguments(parentFrame, self, null); - final CallTarget callTarget = Truffle.getRuntime().createCallTarget(parseResult.getRootNode(), parseResult.getFrameDescriptor()); + final CallTarget callTarget = Truffle.getRuntime().createCallTarget(parseResult.getRootNode()); return callTarget.call(null, arguments); } catch (RaiseException e) {
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/RubyParserResult.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/RubyParserResult.java Wed Jan 22 21:34:00 2014 -0800 @@ -9,7 +9,6 @@ */ package com.oracle.truffle.ruby.runtime; -import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; /** @@ -19,23 +18,15 @@ */ public class RubyParserResult { - private RootNode rootNode; - private FrameDescriptor frameDescriptor; + private final RootNode rootNode; - public RubyParserResult(RootNode rootNode, FrameDescriptor frameDescriptor) { + public RubyParserResult(RootNode rootNode) { assert rootNode != null; - assert frameDescriptor != null; - this.rootNode = rootNode; - this.frameDescriptor = frameDescriptor; } public RootNode getRootNode() { return rootNode; } - public FrameDescriptor getFrameDescriptor() { - return frameDescriptor; - } - }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/CallNode.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/CallNode.java Wed Jan 22 21:34:00 2014 -0800 @@ -189,7 +189,7 @@ InlinedDirectCallNode(InlinableDirectCallNode prev, TypedNode inlinedBody) { super(prev.functionNode, prev.argumentsNode, prev.cachedFunction, prev.nextNode); - this.descriptor = cachedFunction.getFrameDescriptor(); + this.descriptor = cachedFunction.getRootNode().getFrameDescriptor(); this.inlinedBody = adoptChild(inlinedBody); }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FunctionRootNode.java Wed Jan 22 21:02:06 2014 -0800 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FunctionRootNode.java Wed Jan 22 21:34:00 2014 -0800 @@ -37,8 +37,8 @@ private final String name; private final boolean inlineImmediatly; - private FunctionRootNode(TypedNode body, String name, boolean inlineImmediatly) { - super(null); + private FunctionRootNode(FrameDescriptor frameDescriptor, TypedNode body, String name, boolean inlineImmediatly) { + super(null, frameDescriptor); this.uninitializedBody = NodeUtil.cloneNode(body); this.body = adoptChild(body); this.name = name; @@ -52,14 +52,14 @@ arguments[i] = new ReadArgumentNode(i); } BuiltinNode buitinBody = factory.createNode(arguments, context); - FunctionRootNode root = new FunctionRootNode(buitinBody, name, true); + FunctionRootNode root = new FunctionRootNode(new FrameDescriptor(), buitinBody, name, true); return Truffle.getRuntime().createCallTarget(root); } public static CallTarget createFunction(StatementNode body, FrameDescriptor frameDescriptor, String name, TypedNode returnValue, String[] parameterNames) { FunctionBodyNode bodyContainer = new FunctionBodyNode(frameDescriptor, body, returnValue, parameterNames); - FunctionRootNode root = new FunctionRootNode(bodyContainer, name, false); - return Truffle.getRuntime().createCallTarget(root, frameDescriptor); + FunctionRootNode root = new FunctionRootNode(frameDescriptor, bodyContainer, name, false); + return Truffle.getRuntime().createCallTarget(root); } @Override
--- a/make/bsd/makefiles/vm.make Wed Jan 22 21:02:06 2014 -0800 +++ b/make/bsd/makefiles/vm.make Wed Jan 22 21:34:00 2014 -0800 @@ -222,20 +222,22 @@ ifneq ($(INCLUDE_GRAAL), true) GRAAL_SPECIFIC_FILES := graal\* + GRAAL_SPECIFIC_GPU_FILES := gpu\* ptx\* hsail\* else GRAAL_SPECIFIC_FILES := + GRAAL_SPECIFIC_GPU_FILES := endif # Always exclude these. Src_Files_EXCLUDE += jsig.c jvmtiEnvRecommended.cpp jvmtiEnvStub.cpp # Exclude per type. -Src_Files_EXCLUDE/CORE := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) ciTypeFlow.cpp -Src_Files_EXCLUDE/COMPILER1 := $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) ciTypeFlow.cpp -Src_Files_EXCLUDE/COMPILER2 := $(COMPILER1_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) -Src_Files_EXCLUDE/TIERED := $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) -Src_Files_EXCLUDE/ZERO := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) ciTypeFlow.cpp -Src_Files_EXCLUDE/SHARK := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) +Src_Files_EXCLUDE/CORE := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) $(GRAAL_SPECIFIC_GPU_FILES) ciTypeFlow.cpp +Src_Files_EXCLUDE/COMPILER1 := $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) $(GRAAL_SPECIFIC_GPU_FILES) ciTypeFlow.cpp +Src_Files_EXCLUDE/COMPILER2 := $(COMPILER1_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) $(GRAAL_SPECIFIC_GPU_FILES) +Src_Files_EXCLUDE/TIERED := $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) $(GRAAL_SPECIFIC_GPU_FILES) +Src_Files_EXCLUDE/ZERO := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) $(GRAAL_SPECIFIC_GPU_FILES) ciTypeFlow.cpp +Src_Files_EXCLUDE/SHARK := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) $(GRAAL_SPECIFIC_GPU_FILES) Src_Files_EXCLUDE/GRAAL := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) ciTypeFlow.cpp Src_Files_EXCLUDE += $(Src_Files_EXCLUDE/$(TYPE))
--- a/make/linux/makefiles/vm.make Wed Jan 22 21:02:06 2014 -0800 +++ b/make/linux/makefiles/vm.make Wed Jan 22 21:34:00 2014 -0800 @@ -201,21 +201,23 @@ ZERO_SPECIFIC_FILES := zero ifneq ($(INCLUDE_GRAAL), true) - GRAAL_SPECIFIC_FILES := graal\* + GRAAL_SPECIFIC_FILES := graal\* + GRAAL_SPECIFIC_GPU_FILES := gpu\* ptx\* hsail\* else GRAAL_SPECIFIC_FILES := + GRAAL_SPECIFIC_GPU_FILES := endif # Always exclude these. Src_Files_EXCLUDE += jsig.c jvmtiEnvRecommended.cpp jvmtiEnvStub.cpp # Exclude per type. -Src_Files_EXCLUDE/CORE := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) ciTypeFlow.cpp -Src_Files_EXCLUDE/COMPILER1 := $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) ciTypeFlow.cpp -Src_Files_EXCLUDE/COMPILER2 := $(COMPILER1_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) -Src_Files_EXCLUDE/TIERED := $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) -Src_Files_EXCLUDE/ZERO := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) ciTypeFlow.cpp -Src_Files_EXCLUDE/SHARK := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) +Src_Files_EXCLUDE/CORE := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) $(GRAAL_SPECIFIC_GPU_FILES) ciTypeFlow.cpp +Src_Files_EXCLUDE/COMPILER1 := $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) $(GRAAL_SPECIFIC_GPU_FILES) ciTypeFlow.cpp +Src_Files_EXCLUDE/COMPILER2 := $(COMPILER1_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) $(GRAAL_SPECIFIC_GPU_FILES) +Src_Files_EXCLUDE/TIERED := $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) $(GRAAL_SPECIFIC_GPU_FILES) +Src_Files_EXCLUDE/ZERO := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) $(GRAAL_SPECIFIC_GPU_FILES) ciTypeFlow.cpp +Src_Files_EXCLUDE/SHARK := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) $(GRAAL_SPECIFIC_GPU_FILES) Src_Files_EXCLUDE/GRAAL := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) ciTypeFlow.cpp Src_Files_EXCLUDE += $(Src_Files_EXCLUDE/$(TYPE))
--- a/make/solaris/makefiles/vm.make Wed Jan 22 21:02:06 2014 -0800 +++ b/make/solaris/makefiles/vm.make Wed Jan 22 21:34:00 2014 -0800 @@ -219,17 +219,18 @@ SHARK_SPECIFIC_FILES := shark ZERO_SPECIFIC_FILES := zero GRAAL_SPECIFIC_FILES := graal +GRAAL_SPECIFIC_GPU_FILES := gpu\* ptx\* hsail\* # Always exclude these. Src_Files_EXCLUDE := dtrace jsig.c jvmtiEnvRecommended.cpp jvmtiEnvStub.cpp # Exclude per type. -Src_Files_EXCLUDE/CORE := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) ciTypeFlow.cpp -Src_Files_EXCLUDE/COMPILER1 := $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) ciTypeFlow.cpp -Src_Files_EXCLUDE/COMPILER2 := $(COMPILER1_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) -Src_Files_EXCLUDE/TIERED := $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) -Src_Files_EXCLUDE/ZERO := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) ciTypeFlow.cpp -Src_Files_EXCLUDE/SHARK := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) +Src_Files_EXCLUDE/CORE := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) $(GRAAL_SPECIFIC_GPU_FILES) ciTypeFlow.cpp +Src_Files_EXCLUDE/COMPILER1 := $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) $(GRAAL_SPECIFIC_GPU_FILES) ciTypeFlow.cpp +Src_Files_EXCLUDE/COMPILER2 := $(COMPILER1_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) $(GRAAL_SPECIFIC_GPU_FILES) +Src_Files_EXCLUDE/TIERED := $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) $(GRAAL_SPECIFIC_GPU_FILES) +Src_Files_EXCLUDE/ZERO := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) $(GRAAL_SPECIFIC_GPU_FILES) ciTypeFlow.cpp +Src_Files_EXCLUDE/SHARK := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(GRAAL_SPECIFIC_FILES) $(GRAAL_SPECIFIC_GPU_FILES) Src_Files_EXCLUDE/GRAAL := $(COMPILER1_SPECIFIC_FILES) $(COMPILER2_SPECIFIC_FILES) $(ZERO_SPECIFIC_FILES) $(SHARK_SPECIFIC_FILES) ciTypeFlow.cpp Src_Files_EXCLUDE += $(Src_Files_EXCLUDE/$(TYPE))
--- a/mx/mx_graal.py Wed Jan 22 21:02:06 2014 -0800 +++ b/mx/mx_graal.py Wed Jan 22 21:34:00 2014 -0800 @@ -344,10 +344,10 @@ for line in releaseFileLines: if line.startswith("SOURCE="): try: - sourceLine = line[0:-2] # remove last char + sourceLine = line[0:-2] # remove last char hgcfg = mx.HgConfig() hgcfg.check() - revision = hgcfg.tip('.')[:12] # take first 12 chars + revision = hgcfg.tip('.')[:12] # take first 12 chars fp.write(sourceLine + ' graal:' + revision + '\"\n') except: fp.write(line) @@ -793,26 +793,29 @@ if t.startswith('-'): mx.abort('VM option ' + t + ' must precede ' + tests[0]) - candidates = [] + candidates = {} for p in mx.projects_opt_limit_to_suites(): if mx.java().javaCompliance < p.javaCompliance: continue - candidates += _find_classes_with_annotations(p, None, annotations).keys() + for c in _find_classes_with_annotations(p, None, annotations).keys(): + candidates[c] = p classes = [] if len(tests) == 0: - classes = candidates + classes = candidates.keys() + projectscp = mx.classpath([pcp.name for pcp in mx.projects_opt_limit_to_suites() if pcp.javaCompliance <= mx.java().javaCompliance]) else: + projs = set() for t in tests: found = False - for c in candidates: + for c, p in candidates.iteritems(): if t in c: found = True classes.append(c) + projs.add(p.name) if not found: mx.log('warning: no tests matched by substring "' + t) - - projectscp = mx.classpath([pcp.name for pcp in mx.projects_opt_limit_to_suites() if pcp.javaCompliance <= mx.java().javaCompliance]) + projectscp = mx.classpath(projs) if len(classes) != 0: f_testfile = open(testfile, 'w') @@ -1504,11 +1507,11 @@ # gather graal options output = StringIO.StringIO() vm(['-XX:-BootstrapGraal', '-G:+PrintFlags' if optionType == "graal" else '-XX:+PrintFlagsWithComments'], - vm = "graal", - vmbuild = "optimized", - nonZeroIsFatal = False, - out = output.write, - err = subprocess.STDOUT) + vm="graal", + vmbuild="optimized", + nonZeroIsFatal=False, + out=output.write, + err=subprocess.STDOUT) valueMap = parser.parse(output.getvalue()) return valueMap
--- a/mxtool/mx.py Wed Jan 22 21:02:06 2014 -0800 +++ b/mxtool/mx.py Wed Jan 22 21:34:00 2014 -0800 @@ -2751,6 +2751,9 @@ if hasattr(dep, 'eclipse.container'): memento = XMLDoc().element('classpathContainer', {'path' : getattr(dep, 'eclipse.container')}).xml(standalone='no') slm.element('classpathContainer', {'memento' : memento, 'typeId':'org.eclipse.jdt.launching.sourceContainer.classpathContainer'}) + elif dep.get_source_path(resolve=True): + memento = XMLDoc().element('archive', {'detectRoot' : 'true', 'path' : dep.get_source_path(resolve=True)}).xml(standalone='no') + slm.element('container', {'memento' : memento, 'typeId':'org.eclipse.debug.core.containerType.externalArchive'}) else: memento = XMLDoc().element('javaProject', {'name' : dep.name}).xml(standalone='no') slm.element('container', {'memento' : memento, 'typeId':'org.eclipse.jdt.launching.sourceContainer.javaProject'}) @@ -3097,7 +3100,7 @@ update_file(join(p.dir, '.factorypath'), out.xml(indent='\t', newl='\n')) files.append(join(p.dir, '.factorypath')) - _, launchFile = make_eclipse_attach(suite, 'localhost', '8000', deps=projects()) + _, launchFile = make_eclipse_attach(suite, 'localhost', '8000', deps=sorted_deps(projectNames=None, includeLibs=True)) files.append(launchFile) _zip_files(files, suite.dir, configZip.path)
--- a/src/cpu/x86/vm/graalCodeInstaller_x86.hpp Wed Jan 22 21:02:06 2014 -0800 +++ b/src/cpu/x86/vm/graalCodeInstaller_x86.hpp Wed Jan 22 21:34:00 2014 -0800 @@ -72,9 +72,10 @@ case 'b': case 's': case 'c': + case 'i': fatal("int-sized values not expected in DataPatch"); break; - case 'i': { + case 'n': { address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand); Handle obj = Constant::object(inlineData);
--- a/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.java Wed Jan 22 21:02:06 2014 -0800 +++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.java Wed Jan 22 21:34:00 2014 -0800 @@ -171,18 +171,21 @@ @Override public void resultChanged(LookupEvent lookupEvent) { final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//)Utilities.actionsGlobalContext().lookup(InputGraphProvider.class); - if (p != null) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { + if (p != null) { InputGraph graph = p.getGraph(); if (graph != null) { Group g = graph.getGroup(); rootNode.update(graph, g.getMethod()); + return; } } + rootNode.update(null, null); + } }); - } + } final static class ResolvableHelper implements Serializable {
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/GraphNode.java Wed Jan 22 21:02:06 2014 -0800 +++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/GraphNode.java Wed Jan 22 21:34:00 2014 -0800 @@ -38,6 +38,9 @@ import org.openide.actions.OpenAction; import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; +import org.openide.nodes.NodeAdapter; +import org.openide.nodes.NodeEvent; +import org.openide.nodes.NodeMemberEvent; import org.openide.nodes.Sheet; import org.openide.util.ImageUtilities; import org.openide.util.Lookup; @@ -49,7 +52,7 @@ * @author Thomas Wuerthinger */ public class GraphNode extends AbstractNode { - private final InputGraph graph; + private InputGraph graph; /** Creates a new instance of GraphNode */ public GraphNode(InputGraph graph) { @@ -77,6 +80,13 @@ // Action for cloning to the current graph content.add(new GraphCloneCookie(viewer, graph)); + + this.addNodeListener(new NodeAdapter() { + @Override + public void childrenRemoved(NodeMemberEvent ev) { + GraphNode.this.graph = null; + } + }); } @Override
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java Wed Jan 22 21:02:06 2014 -0800 +++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java Wed Jan 22 21:34:00 2014 -0800 @@ -389,4 +389,9 @@ } this.setSelectedNodes(newSelectedNodes); } + + void close() { + filterChain.getChangedEvent().removeListener(filterChainChangedListener); + sequenceFilterChain.getChangedEvent().removeListener(filterChainChangedListener); } +}
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java Wed Jan 22 21:02:06 2014 -0800 +++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java Wed Jan 22 21:34:00 2014 -0800 @@ -408,6 +408,7 @@ @Override public void componentClosed() { + rangeSliderModel.close(); } @Override @@ -580,4 +581,8 @@ return scene.getUndoRedo(); } + @Override + protected Object writeReplace() throws ObjectStreamException { + throw new NotSerializableException(); } +}
--- a/src/share/vm/classfile/systemDictionary.hpp Wed Jan 22 21:02:06 2014 -0800 +++ b/src/share/vm/classfile/systemDictionary.hpp Wed Jan 22 21:34:00 2014 -0800 @@ -212,6 +212,7 @@ do_klass(Assumptions_CallSiteTargetValue_klass, com_oracle_graal_api_code_Assumptions_CallSiteTargetValue, Opt) \ do_klass(BytecodePosition_klass, com_oracle_graal_api_code_BytecodePosition, Opt) \ do_klass(DebugInfo_klass, com_oracle_graal_api_code_DebugInfo, Opt) \ + do_klass(ReferenceMap_klass, com_oracle_graal_api_code_ReferenceMap, Opt) \ do_klass(RegisterSaveLayout_klass, com_oracle_graal_api_code_RegisterSaveLayout, Opt) \ do_klass(BytecodeFrame_klass, com_oracle_graal_api_code_BytecodeFrame, Opt) \ do_klass(CompilationResult_klass, com_oracle_graal_api_code_CompilationResult, Opt) \
--- a/src/share/vm/classfile/vmSymbols.hpp Wed Jan 22 21:02:06 2014 -0800 +++ b/src/share/vm/classfile/vmSymbols.hpp Wed Jan 22 21:34:00 2014 -0800 @@ -342,6 +342,7 @@ template(com_oracle_graal_api_code_BytecodeFrame, "com/oracle/graal/api/code/BytecodeFrame") \ template(com_oracle_graal_api_code_BytecodePosition, "com/oracle/graal/api/code/BytecodePosition") \ template(com_oracle_graal_api_code_DebugInfo, "com/oracle/graal/api/code/DebugInfo") \ + template(com_oracle_graal_api_code_ReferenceMap, "com/oracle/graal/api/code/ReferenceMap") \ template(com_oracle_graal_api_code_Register, "com/oracle/graal/api/code/Register") \ template(com_oracle_graal_api_code_RegisterValue, "com/oracle/graal/api/code/RegisterValue") \ template(com_oracle_graal_api_code_StackSlot, "com/oracle/graal/api/code/StackSlot") \
--- a/src/share/vm/compiler/compileBroker.cpp Wed Jan 22 21:02:06 2014 -0800 +++ b/src/share/vm/compiler/compileBroker.cpp Wed Jan 22 21:34:00 2014 -0800 @@ -1144,7 +1144,9 @@ } #ifdef GRAALVM if (!JavaThread::current()->is_graal_compiling()) { - GraalCompiler::instance()->compile_method(method, osr_bci, is_compile_blocking(method, osr_bci)); + bool blockingCompilation = is_compile_blocking(method, osr_bci) || + CompilationPolicy::can_be_offloaded_to_gpu(method); + GraalCompiler::instance()->compile_method(method, osr_bci, blockingCompilation); } else { // Recursive compile request => ignore. }
--- a/src/share/vm/graal/graalCodeInstaller.cpp Wed Jan 22 21:02:06 2014 -0800 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Wed Jan 22 21:34:00 2014 -0800 @@ -84,28 +84,45 @@ // creates a HotSpot oop map out of the byte arrays provided by DebugInfo static OopMap* create_oop_map(jint total_frame_size, jint parameter_count, oop debug_info) { OopMap* map = new OopMap(total_frame_size, parameter_count); - oop register_map = (oop) DebugInfo::registerRefMap(debug_info); - oop frame_map = (oop) DebugInfo::frameRefMap(debug_info); + oop reference_map = DebugInfo::referenceMap(debug_info); + oop register_map = ReferenceMap::registerRefMap(reference_map); + oop frame_map = ReferenceMap::frameRefMap(reference_map); oop callee_save_info = (oop) DebugInfo::calleeSaveInfo(debug_info); if (register_map != NULL) { for (jint i = 0; i < RegisterImpl::number_of_registers; i++) { - bool is_oop = is_bit_set(register_map, i); + bool is_oop = is_bit_set(register_map, 2 * i); VMReg hotspot_reg = get_hotspot_reg(i); if (is_oop) { - map->set_oop(hotspot_reg); + if (is_bit_set(register_map, 2 * i + 1)) { + map->set_narrowoop(hotspot_reg); + } else { + map->set_oop(hotspot_reg); + } } else { map->set_value(hotspot_reg); } } } - for (jint i = 0; i < bitset_size(frame_map); i++) { - bool is_oop = is_bit_set(frame_map, i); + for (jint i = 0; i < bitset_size(frame_map) / 3; i++) { + bool is_oop = is_bit_set(frame_map, i * 3); // HotSpot stack slots are 4 bytes VMReg reg = VMRegImpl::stack2reg(i * VMRegImpl::slots_per_word); if (is_oop) { - map->set_oop(reg); + bool narrow1 = is_bit_set(frame_map, i * 3 + 1); + bool narrow2 = is_bit_set(frame_map, i * 3 + 2); + if(narrow1 || narrow2) { + if(narrow1) { + map->set_narrowoop(reg); + } + if(narrow2) { + VMReg reg2 = VMRegImpl::stack2reg(i * VMRegImpl::slots_per_word + 1); + map->set_narrowoop(reg2); + } + } else { + map->set_oop(reg); + } } else { map->set_value(reg); }
--- a/src/share/vm/graal/graalCompilerToVM.cpp Wed Jan 22 21:02:06 2014 -0800 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Wed Jan 22 21:34:00 2014 -0800 @@ -688,6 +688,9 @@ HandleMark hm; jlong nmethodValue = HotSpotInstalledCode::codeBlob(hotspotInstalledCode); + if (nmethodValue == 0L) { + THROW_(vmSymbols::com_oracle_graal_api_code_InvalidInstalledCodeException(), NULL); + } nmethod* nm = (nmethod*) (address) nmethodValue; methodHandle mh = nm->method(); Symbol* signature = mh->signature();
--- a/src/share/vm/graal/graalGlobals.hpp Wed Jan 22 21:02:06 2014 -0800 +++ b/src/share/vm/graal/graalGlobals.hpp Wed Jan 22 21:34:00 2014 -0800 @@ -79,6 +79,12 @@ develop(bool, TraceUncollectedSpeculations, false, \ "Print message when a failed speculation was not collected") \ \ + product(bool, GPUOffload, false, \ + "Offload execution to GPU whenever possible") \ + \ + product(bool, TraceGPUInteraction, false, \ + "Trace external GPU Interaction") \ + \ // Read default values for Graal globals
--- a/src/share/vm/graal/graalJavaAccess.hpp Wed Jan 22 21:02:06 2014 -0800 +++ b/src/share/vm/graal/graalJavaAccess.hpp Wed Jan 22 21:34:00 2014 -0800 @@ -173,10 +173,13 @@ end_class \ start_class(DebugInfo) \ oop_field(DebugInfo, bytecodePosition, "Lcom/oracle/graal/api/code/BytecodePosition;") \ - oop_field(DebugInfo, registerRefMap, "Ljava/util/BitSet;") \ - oop_field(DebugInfo, frameRefMap, "Ljava/util/BitSet;") \ + oop_field(DebugInfo, referenceMap, "Lcom/oracle/graal/api/code/ReferenceMap;") \ oop_field(DebugInfo, calleeSaveInfo, "Lcom/oracle/graal/api/code/RegisterSaveLayout;") \ end_class \ + start_class(ReferenceMap) \ + oop_field(ReferenceMap, registerRefMap, "Ljava/util/BitSet;") \ + oop_field(ReferenceMap, frameRefMap, "Ljava/util/BitSet;") \ + end_class \ start_class(RegisterSaveLayout) \ oop_field(RegisterSaveLayout, registers, "[Lcom/oracle/graal/api/code/Register;") \ oop_field(RegisterSaveLayout, slots, "[I") \
--- a/src/share/vm/oops/instanceKlass.cpp Wed Jan 22 21:02:06 2014 -0800 +++ b/src/share/vm/oops/instanceKlass.cpp Wed Jan 22 21:34:00 2014 -0800 @@ -3016,9 +3016,9 @@ if (this == SystemDictionary::String_klass()) { typeArrayOop value = java_lang_String::value(obj); juint offset = java_lang_String::offset(obj); + if (value != NULL) { juint length = java_lang_String::length(obj); - if (value != NULL && - value->is_typeArray() && + if (value->is_typeArray() && offset <= (juint) value->length() && offset + length <= (juint) value->length()) { st->print(BULLET"string: "); @@ -3028,6 +3028,7 @@ if (!WizardMode) return; // that is enough } } + } st->print_cr(BULLET"---- fields (total size %d words):", oop_size(obj)); FieldPrinter print_field(st, obj);
--- a/src/share/vm/oops/method.cpp Wed Jan 22 21:02:06 2014 -0800 +++ b/src/share/vm/oops/method.cpp Wed Jan 22 21:34:00 2014 -0800 @@ -2025,32 +2025,3 @@ guarantee(md == NULL || md->is_methodData(), "should be method data"); } - -#ifdef GRAAL - -// Return true if the name of the method indicates that this is a -// lambda method other than <init>. Lambda method is one with a name -// that starts with lambda$ and is synthetic. - -bool Method::is_lambda() const { - Symbol * klass_name = method_holder()->name(); - Symbol * method_name = name(); - ResourceMark rm; - if (klass_name != NULL) { - if (klass_name != NULL && method_name != NULL) { - const char* lambdaPrefix = "lambda$main$"; - char* methodPrefix = strstr(method_name->as_C_string(), lambdaPrefix); - if (methodPrefix != 0) { - if ((strncmp(lambdaPrefix, methodPrefix, strlen(lambdaPrefix)) == 0) && - is_synthetic()) { - //tty->print_cr("[Check] %s::%s", klass_name->as_C_string(), method_name->as_C_string()); - return true; - } else { - return false; - } - } - } - //} - } -} -#endif
--- a/src/share/vm/oops/method.hpp Wed Jan 22 21:02:06 2014 -0800 +++ b/src/share/vm/oops/method.hpp Wed Jan 22 21:34:00 2014 -0800 @@ -617,11 +617,6 @@ // simultaneously. Use with caution. bool has_compiled_code() const { return code() != NULL; } -#ifdef GRAAL - // Return true if the name of the method indicates that this is a - // lambda method other than <init>. - bool is_lambda() const; -#endif // sizing static int header_size() { return sizeof(Method)/HeapWordSize; } static int size(bool is_native);
--- a/src/share/vm/runtime/compilationPolicy.cpp Wed Jan 22 21:02:06 2014 -0800 +++ b/src/share/vm/runtime/compilationPolicy.cpp Wed Jan 22 21:34:00 2014 -0800 @@ -105,30 +105,7 @@ if (m->has_compiled_code()) return false; // already compiled -#ifdef GRAAL - // Check if this is a Lambda method that can be compiled to a GPU. - if (m->is_lambda()) { - // If GPU is available and the necessary linkage is available - // rerurn true indicatin that this method must be compiled. - if (gpu::is_available() && gpu::has_gpu_linkage()) { - if (TraceGPUInteraction) { - tty->print("Compiling Lambda method"); - m->print_short_name(); - switch (gpu::get_target_il_type()) { - case gpu::PTX : - tty->print_cr(" to PTX"); - break; - case gpu::HSAIL : - tty->print_cr(" to HSAIL"); - break; - default : - tty->print_cr(" to Unknown GPU!!!"); - } - } - return true; - } - } -#endif + if (CompilationPolicy::can_be_offloaded_to_gpu(m)) return true; if (!can_be_compiled(m, comp_level)) return false; @@ -184,6 +161,58 @@ return (result && can_be_compiled(m, comp_level)); } +bool CompilationPolicy::can_be_offloaded_to_gpu(methodHandle m) { +#ifdef GRAAL + if (GPUOffload) { + // Check if this method can be offloaded to GPU. + // 1. Offload it to GPU if it is a Lambda method + if (m->is_synthetic()) { + // A lambda method is a syntheric method. + Symbol * klass_name = m->method_holder()->name(); + Symbol * method_name = m->name(); + bool offloadToGPU = false; + { + ResourceMark rm; + if (klass_name != NULL) { + if (klass_name != NULL && method_name != NULL) { + const char* lambdaPrefix = "lambda$"; + char* methodPrefix = strstr(method_name->as_C_string(), lambdaPrefix); + if (methodPrefix != 0) { + if ((strncmp(lambdaPrefix, methodPrefix, strlen(lambdaPrefix)) == 0)) { + offloadToGPU = true; + } + } + } + } + } + if (offloadToGPU) { + // If GPU is available and the necessary linkage is available + // return true indicatin that this method must be compiled. + if (gpu::is_available() && gpu::has_gpu_linkage()) { + if (TraceGPUInteraction) { + tty->print("Compiling Lambda method "); + m->print_short_name(); + switch (gpu::get_target_il_type()) { + case gpu::PTX : + tty->print_cr("to PTX"); + break; + case gpu::HSAIL : + tty->print_cr("to HSAIL"); + break; + default : + tty->print_cr("to Unknown GPU!!!"); + } + } + return true; + } + } + } + } +#endif + + return false; +} + bool CompilationPolicy::is_compilation_enabled() { // NOTE: CompileBroker::should_compile_new_jobs() checks for UseCompiler return !delay_compilation_during_startup() && CompileBroker::should_compile_new_jobs();
--- a/src/share/vm/runtime/compilationPolicy.hpp Wed Jan 22 21:02:06 2014 -0800 +++ b/src/share/vm/runtime/compilationPolicy.hpp Wed Jan 22 21:34:00 2014 -0800 @@ -58,6 +58,9 @@ static void set_policy(CompilationPolicy* policy) { _policy = policy; } static CompilationPolicy* policy() { return _policy; } + // m is allowed to be offloaded to a gpu + static bool can_be_offloaded_to_gpu(methodHandle m); + // Profiling elapsedTimer* accumulated_time() { return &_accumulated_time; } void print_time() PRODUCT_RETURN;
--- a/src/share/vm/runtime/deoptimization.cpp Wed Jan 22 21:02:06 2014 -0800 +++ b/src/share/vm/runtime/deoptimization.cpp Wed Jan 22 21:34:00 2014 -0800 @@ -1370,6 +1370,7 @@ int trap_bci = trap_scope->bci(); #ifdef GRAAL oop speculation = thread->pending_failed_speculation(); + if (nm->is_compiled_by_graal()) { if (speculation != NULL) { oop speculation_log = nm->speculation_log(); if (speculation_log != NULL) { @@ -1393,6 +1394,11 @@ tty->print_cr("No speculation"); } } + } else { +#ifdef ASSERT + assert(speculation == NULL, "There should not be a speculation for method compiled by other compilers"); +#endif + } if (trap_bci == SynchronizationEntryBCI) { trap_bci = 0;
--- a/src/share/vm/runtime/globals.hpp Wed Jan 22 21:02:06 2014 -0800 +++ b/src/share/vm/runtime/globals.hpp Wed Jan 22 21:34:00 2014 -0800 @@ -3840,9 +3840,6 @@ product(bool , AllowNonVirtualCalls, false, \ "Obey the ACC_SUPER flag and allow invokenonvirtual calls") \ \ - product(bool, TraceGPUInteraction, false, \ - "Trace external GPU Interaction") \ - \ product(bool, UseHSAILSimulator, false, \ "Run code on HSAIL Simulator") \ \
--- a/src/share/vm/runtime/sweeper.cpp Wed Jan 22 21:02:06 2014 -0800 +++ b/src/share/vm/runtime/sweeper.cpp Wed Jan 22 21:34:00 2014 -0800 @@ -233,7 +233,7 @@ void NMethodSweeper::possibly_sweep() { assert(JavaThread::current()->thread_state() == _thread_in_vm, "must run in vm mode"); // Only compiler threads are allowed to sweep - if (!MethodFlushing || !sweep_in_progress() || !Thread::current()->is_Compiler_thread()) { + if (!MethodFlushing || !sweep_in_progress() NOT_GRAAL(|| !Thread::current()->is_Compiler_thread()) GRAAL_ONLY(|| !Thread::current()->is_Java_thread())) { return; }
--- a/src/share/vm/runtime/thread.cpp Wed Jan 22 21:02:06 2014 -0800 +++ b/src/share/vm/runtime/thread.cpp Wed Jan 22 21:34:00 2014 -0800 @@ -3394,9 +3394,13 @@ jint parse_result = Arguments::parse(args); if (parse_result != JNI_OK) return parse_result; - // Probe for existance of supported GPU and initialize it if one - // exists. - gpu::init(); +#ifdef GRAAL + if (GPUOffload) { + // Probe for existance of supported GPU and initialize it if one + // exists. + gpu::init(); + } +#endif os::init_before_ergo();