# HG changeset patch # User Thomas Wuerthinger # Date 1309867920 -7200 # Node ID 906a2e39495b1df82e5b98b88789cd8699a8f8a4 # Parent 2c07f39c2f4db546257c691073b7d24163a0f2ae# Parent 03aca60eb99fc08be356ff9856aeaf1e68afb9a4 Merge. diff -r 03aca60eb99f -r 906a2e39495b graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Tue Jul 05 11:42:28 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Tue Jul 05 14:12:00 2011 +0200 @@ -1097,7 +1097,7 @@ * @return the operand that is guaranteed to be a stack location when it is * initially defined a by move from {@code value} */ - CiValue forceToSpill(CiValue value, CiKind kind, boolean mustStayOnStack) { + public CiValue forceToSpill(CiValue value, CiKind kind, boolean mustStayOnStack) { assert value.isLegal() : "value should not be illegal"; assert kind.jvmSlots == value.kind.jvmSlots : "size mismatch"; if (!value.isVariableOrRegister()) { diff -r 03aca60eb99f -r 906a2e39495b graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java Tue Jul 05 11:42:28 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java Tue Jul 05 14:12:00 2011 +0200 @@ -126,7 +126,7 @@ final HashSet successors = new LinkedHashSet(); private boolean visited; private boolean active; - private int loops; + private long loops; } public static class ExceptionBlock extends Block { @@ -485,7 +485,7 @@ } private void computeBlockOrder() { - int loop = computeBlockOrder(blockMap[0]); + long loop = computeBlockOrder(blockMap[0]); if (loop != 0) { // There is a path from a loop end to the method entry that does not pass the loop header. @@ -501,7 +501,7 @@ /** * The next available loop number. */ - private int nextLoop = 0; + private int nextLoop; /** * Mark the block as a loop header, using the next available loop number. @@ -516,7 +516,7 @@ // Don't compile such methods for now, until we see a concrete case that allows checking for correctness. throw new CiBailout("Loop formed by an exception handler"); } - if (nextLoop >= Integer.SIZE) { + if (nextLoop >= Long.SIZE) { // This restriction can be removed by using a fall-back to a BitSet in case we have more than 32 loops // Don't compile such methods for now, until we see a concrete case that allows checking for correctness. throw new CiBailout("Too many loops in method"); @@ -526,7 +526,7 @@ block.loops = 1 << nextLoop; nextLoop++; } - assert Integer.bitCount(block.loops) == 1; + assert Long.bitCount(block.loops) == 1; } /** @@ -534,7 +534,7 @@ * visit every block only once. The flag {@linkplain Block#active} is used to detect cycles (backward * edges). */ - private int computeBlockOrder(Block block) { + private long computeBlockOrder(Block block) { if (block.visited) { if (block.active) { // Reached block via backward branch. @@ -557,7 +557,7 @@ processLoopBlock(block); } if (block.isLoopHeader) { - assert Integer.bitCount(block.loops) == 1; + assert Long.bitCount(block.loops) == 1; loops &= ~block.loops; } @@ -694,6 +694,6 @@ } out.println(); - out.print("loop_depth ").println(Integer.bitCount(block.loops)); + out.print("loop_depth ").println(Long.bitCount(block.loops)); } } diff -r 03aca60eb99f -r 906a2e39495b graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java Tue Jul 05 11:42:28 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java Tue Jul 05 14:12:00 2011 +0200 @@ -118,7 +118,7 @@ * @param graph */ public GraphBuilderPhase(GraalCompilation compilation, RiMethod method, boolean createUnwind, boolean inline) { - super(inline ? "BuildInlineGraph" : "BuildGraph"); + super(inline ? "BuildInlineGraph " + method.holder().name() + "." + method.name() + method.signature().asString() : "BuildGraph"); this.compilation = compilation; this.runtime = compilation.runtime; @@ -732,9 +732,7 @@ if (entry != null) { append(entry); } else { - frameState.clearStack(); - frameState.apush(exception); - appendGoto(createTarget(unwindBlock(bci), frameState)); + appendGoto(createTarget(unwindBlock(bci), frameState.duplicateWithException(bci, exception))); } } diff -r 03aca60eb99f -r 906a2e39495b graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameStateBuilder.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameStateBuilder.java Tue Jul 05 11:42:28 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameStateBuilder.java Tue Jul 05 14:12:00 2011 +0200 @@ -42,6 +42,7 @@ private final ArrayList locks; private int stackIndex; + private boolean rethrowException; private final RiMethod method; @@ -101,10 +102,11 @@ for (int i = 0; i < other.locksSize(); i++) { locks.add(other.lockAt(i)); } + this.rethrowException = other.rethrowException(); } public FrameState create(int bci) { - return new FrameState(method, bci, locals, stack, stackIndex, locks, false, graph); + return new FrameState(method, bci, locals, stack, stackIndex, locks, rethrowException, graph); } public FrameState duplicateWithException(int bci, Value exceptionObject) { diff -r 03aca60eb99f -r 906a2e39495b graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java Tue Jul 05 11:42:28 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java Tue Jul 05 14:12:00 2011 +0200 @@ -304,7 +304,7 @@ Local srcPos = new Local(CiKind.Int, 1, graph); Local dest = new Local(CiKind.Object, 2, graph); Local destPos = new Local(CiKind.Int, 3, graph); - Local length = new Local(CiKind.Int, 4, graph); + Value length = new Local(CiKind.Int, 4, graph); src.setDeclaredType(((Value) parameters.get(0)).declaredType()); dest.setDeclaredType(((Value) parameters.get(2)).declaredType()); @@ -379,6 +379,42 @@ graph.setReturn(ret); return graph; } + } else if (holderName.equals("Ljava/lang/Float;")) { + if (fullName.equals("floatToRawIntBits(F)I") || fullName.equals("floatToIntBits(F)I")) { + CompilerGraph graph = new CompilerGraph(this); + Return ret = new Return(new FPConversionNode(CiKind.Int, new Local(CiKind.Float, 0, graph), graph), graph); + graph.start().setNext(ret); + graph.setReturn(ret); + intrinsicGraphs.put(method, graph); + } else if (fullName.equals("intBitsToFloat(I)F")) { + CompilerGraph graph = new CompilerGraph(this); + Return ret = new Return(new FPConversionNode(CiKind.Float, new Local(CiKind.Int, 0, graph), graph), graph); + graph.start().setNext(ret); + graph.setReturn(ret); + intrinsicGraphs.put(method, graph); + } + } else if (holderName.equals("Ljava/lang/Double;")) { + if (fullName.equals("doubleToRawLongBits(D)J") || fullName.equals("doubleToLongBits(D)J")) { + CompilerGraph graph = new CompilerGraph(this); + Return ret = new Return(new FPConversionNode(CiKind.Long, new Local(CiKind.Double, 0, graph), graph), graph); + graph.start().setNext(ret); + graph.setReturn(ret); + intrinsicGraphs.put(method, graph); + } else if (fullName.equals("longBitsToDouble(J)D")) { + CompilerGraph graph = new CompilerGraph(this); + Return ret = new Return(new FPConversionNode(CiKind.Double, new Local(CiKind.Long, 0, graph), graph), graph); + graph.start().setNext(ret); + graph.setReturn(ret); + intrinsicGraphs.put(method, graph); + } + } else if (holderName.equals("Ljava/lang/Thread;")) { + if (fullName.equals("currentThread()Ljava/lang/Thread;")) { + CompilerGraph graph = new CompilerGraph(this); + Return ret = new Return(new CurrentThread(config.threadObjectOffset, graph), graph); + graph.start().setNext(ret); + graph.setReturn(ret); + intrinsicGraphs.put(method, graph); + } } if (!intrinsicGraphs.containsKey(method)) { diff -r 03aca60eb99f -r 906a2e39495b graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/CurrentThread.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/CurrentThread.java Tue Jul 05 14:12:00 2011 +0200 @@ -0,0 +1,73 @@ +/* + * 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.max.graal.runtime.nodes; + +import com.oracle.max.asm.target.amd64.*; +import com.oracle.max.graal.compiler.debug.*; +import com.oracle.max.graal.compiler.gen.*; +import com.oracle.max.graal.compiler.ir.*; +import com.oracle.max.graal.graph.*; +import com.sun.cri.ci.*; + + +public final class CurrentThread extends FloatingNode { + private static final int INPUT_COUNT = 0; + private static final int SUCCESSOR_COUNT = 0; + private int threadObjectOffset; + + public CurrentThread(int threadObjectOffset, Graph graph) { + super(CiKind.Object, INPUT_COUNT, SUCCESSOR_COUNT, graph); + this.threadObjectOffset = threadObjectOffset; + } + + @SuppressWarnings("unchecked") + @Override + public T lookup(Class clazz) { + if (clazz == LIRGenerator.LIRGeneratorOp.class) { + return (T) new LIRGenerator.LIRGeneratorOp() { + @Override + public void generate(Node n, LIRGenerator generator) { + CurrentThread conv = (CurrentThread) n; + CiValue result = generator.createResultVariable(conv); + generator.lir().move(new CiAddress(CiKind.Object, AMD64.r15.asValue(CiKind.Word), threadObjectOffset), result); + } + }; + } + return super.lookup(clazz); + } + + @Override + public boolean valueEqual(Node i) { + return i instanceof CurrentThread; + } + + @Override + public void print(LogStream out) { + out.print("currentThread"); + } + + @Override + public Node copy(Graph into) { + return new CurrentThread(threadObjectOffset, into); + } +} diff -r 03aca60eb99f -r 906a2e39495b graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/FPConversionNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/FPConversionNode.java Tue Jul 05 14:12:00 2011 +0200 @@ -0,0 +1,94 @@ +/* + * 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.max.graal.runtime.nodes; + +import com.oracle.max.graal.compiler.debug.*; +import com.oracle.max.graal.compiler.gen.*; +import com.oracle.max.graal.compiler.ir.*; +import com.oracle.max.graal.compiler.lir.*; +import com.oracle.max.graal.graph.*; +import com.oracle.max.graal.runtime.*; +import com.sun.cri.ci.*; + + +public final class FPConversionNode extends FloatingNode { + private static final int INPUT_COUNT = 1; + private static final int INPUT_OBJECT = 0; + + private static final int SUCCESSOR_COUNT = 0; + + @Override + protected int inputCount() { + return super.inputCount() + INPUT_COUNT; + } + + /** + * The instruction that produces the object tested against null. + */ + public Value value() { + return (Value) inputs().get(super.inputCount() + INPUT_OBJECT); + } + + public void setValue(Value n) { + inputs().set(super.inputCount() + INPUT_OBJECT, n); + } + + public FPConversionNode(CiKind kind, Value value, Graph graph) { + super(kind, INPUT_COUNT, SUCCESSOR_COUNT, graph); + this.setValue(value); + } + + + @SuppressWarnings("unchecked") + @Override + public T lookup(Class clazz) { + if (clazz == LIRGenerator.LIRGeneratorOp.class) { + return (T) new LIRGenerator.LIRGeneratorOp() { + @Override + public void generate(Node n, LIRGenerator generator) { + FPConversionNode conv = (FPConversionNode) n; + CiValue reg = generator.createResultVariable(conv); + CiValue value = generator.load(conv.value()); + CiValue tmp = generator.forceToSpill(value, conv.kind, false); + generator.lir().move(tmp, reg); + } + }; + } + return super.lookup(clazz); + } + + @Override + public boolean valueEqual(Node i) { + return i instanceof FPConversionNode && ((FPConversionNode) i).kind == kind; + } + + @Override + public void print(LogStream out) { + out.print("fp conversion node ").print(value()); + } + + @Override + public Node copy(Graph into) { + return new FPConversionNode(kind, null, into); + } +}