Mercurial > hg > graal-compiler
changeset 3050:3ed1b2a5d071
Merge
line wrap: on
line diff
--- a/.hgtags Fri Jun 17 19:21:53 2011 +0200 +++ b/.hgtags Mon Jun 20 14:29:42 2011 +0200 @@ -166,3 +166,4 @@ 0930dc920c185afbf40fed9a655290b8e5b16783 hs21-b08 611e19a16519d6fb5deea9ab565336e6e6ee475d jdk7-b139 611e19a16519d6fb5deea9ab565336e6e6ee475d hs21-b09 +a197fd9e273c692767407654c4caf858460a413f Tested with fop, lusearch, eclipse and jtt with Xcomp flag
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java Fri Jun 17 19:21:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java Mon Jun 20 14:29:42 2011 +0200 @@ -95,7 +95,7 @@ this.method = method; this.stats = stats == null ? new CiStatistics() : stats; this.registerConfig = method == null ? compiler.globalStubRegisterConfig : runtime.getRegisterConfig(method); - this.placeholderState = method != null && method.minimalDebugInfo() ? new FrameState(method, 0, 0, 0, 0, graph) : null; + this.placeholderState = method != null && method.minimalDebugInfo() ? new FrameState(method, 0, 0, 0, 0, false, graph) : null; if (compiler.isObserved()) { compiler.fireCompilationStarted(new CompilationEvent(this));
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java Fri Jun 17 19:21:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java Mon Jun 20 14:29:42 2011 +0200 @@ -38,6 +38,7 @@ // inlining settings public static boolean Inline = true; + public static boolean CacheGraphs = ____; public static boolean InlineWithTypeCheck = ____; public static int MaximumInstructionCount = 37000; public static float MaximumInlineRatio = 0.90f;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java Fri Jun 17 19:21:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java Mon Jun 20 14:29:42 2011 +0200 @@ -835,10 +835,10 @@ if (instr instanceof Phi) { Phi phi = (Phi) instr; TTY.println("phi block begin: " + phi.merge()); - TTY.println("pred count on blockbegin: " + phi.merge().phiPointPredecessorCount()); + TTY.println("pred count on blockbegin: " + phi.merge().phiPredecessorCount()); TTY.println("phi values: " + phi.valueCount()); TTY.println("phi block preds:"); - for (Node n : phi.merge().phiPointPredecessors()) { + for (Node n : phi.merge().phiPredecessors()) { TTY.println(n.toString()); } } @@ -1914,7 +1914,7 @@ if (state.outerFrameState() != null) { caller = computeFrameForState(state.outerFrameState(), opId, frameRefMap); } - return new CiFrame(caller, state.method, state.bci, values, state.localsSize(), state.stackSize(), state.locksSize()); + return new CiFrame(caller, state.method, state.bci, state.rethrowException(), values, state.localsSize(), state.stackSize(), state.locksSize()); } private void computeDebugInfo(IntervalWalker iw, LIRInstruction op) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java Fri Jun 17 19:21:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java Mon Jun 20 14:29:42 2011 +0200 @@ -119,6 +119,7 @@ schedule.apply(graph); } catch (Throwable t) { // nothing to do here... + t.printStackTrace(); } stream.println(" <nodes>"); @@ -239,7 +240,7 @@ if (nodes.size() > 0) { // if this is the first block: add all locals to this block - if (block.getInstructions() == graph.start()) { + if (block.getInstructions().size() > 0 && block.getInstructions().get(0) == graph.start()) { for (Node node : graph.getNodes()) { if (node instanceof Local) { nodes.add(node); @@ -253,12 +254,6 @@ nodes.add(((Instruction) node).stateAfter()); } if (node instanceof Merge) { - Merge merge = (Merge) node; - if (merge.stateAfter() != null) { - nodes.add(merge.stateAfter()); - } - } - if (node instanceof PhiPoint) { for (Node usage : node.usages()) { if (usage instanceof Phi || usage instanceof LoopCounter) { nodes.add(usage);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Fri Jun 17 19:21:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Mon Jun 20 14:29:42 2011 +0200 @@ -260,15 +260,10 @@ } } } - if (block.blockSuccessors().size() == 1 && !(block.lastInstruction() instanceof LoopEnd)) { - Node firstInstruction = block.blockSuccessors().get(0).firstInstruction(); - //System.out.println("suxSz == 1, fst=" + firstInstruction); - if (firstInstruction instanceof LoopBegin) { - moveToPhi((LoopBegin) firstInstruction, block.lastInstruction()); - } - } if (block.blockSuccessors().size() >= 1 && !block.endsWithJump()) { - block.lir().jump(getLIRBlock((FixedNode) block.lastInstruction().successors().get(0))); + NodeArray successors = block.lastInstruction().successors(); + assert successors.size() >= 1 : "should have at least one successor : " + block.lastInstruction(); + block.lir().jump(getLIRBlock((FixedNode) successors.get(0))); } if (GraalOptions.TraceLIRGeneratorLevel >= 1) { @@ -315,7 +310,7 @@ slot += arguments[arg].sizeInSlots(); } - FrameState fs = new FrameState(compilation.method, bci, compilation.method.maxLocals(), 0, 0, compilation.graph); + FrameState fs = new FrameState(compilation.method, bci, compilation.method.maxLocals(), 0, 0, false, compilation.graph); for (Node node : compilation.graph.start().usages()) { if (node instanceof Local) { Local local = (Local) node; @@ -549,7 +544,7 @@ } protected FrameState stateBeforeInvokeReturn(Invoke invoke) { - return invoke.stateAfter().duplicateModified(getBeforeInvokeBci(invoke), invoke.kind); + return invoke.stateAfter().duplicateModified(getBeforeInvokeBci(invoke), invoke.stateAfter().rethrowException(), invoke.kind); } protected FrameState stateBeforeInvokeWithArguments(Invoke invoke) { @@ -557,7 +552,7 @@ for (int i = 0; i < invoke.argumentCount(); i++) { args[i] = invoke.argument(i); } - return invoke.stateAfter().duplicateModified(getBeforeInvokeBci(invoke), invoke.kind, args); + return invoke.stateAfter().duplicateModified(getBeforeInvokeBci(invoke), invoke.stateAfter().rethrowException(), invoke.kind, args); } private int getBeforeInvokeBci(Invoke invoke) { @@ -995,6 +990,7 @@ @Override public void visitDeoptimize(Deoptimize deoptimize) { assert lastState != null : "deoptimize always needs a state"; + assert lastState.bci != Instruction.SYNCHRONIZATION_ENTRY_BCI : "bci must not be -1 for deopt framestate"; DeoptimizationStub stub = new DeoptimizationStub(deoptimize.action(), lastState); addDeoptimizationStub(stub); lir.branch(Condition.TRUE, stub.label, stub.info); @@ -1437,8 +1433,8 @@ lir.jump(getLIRBlock(x.loopBegin())); } - private void moveToPhi(PhiPoint merge, Node pred) { - int nextSuccIndex = merge.phiPointPredecessorIndex(pred); + private void moveToPhi(Merge merge, Node pred) { + int nextSuccIndex = merge.phiPredecessorIndex(pred); PhiResolver resolver = new PhiResolver(this); for (Phi phi : merge.phis()) { if (!phi.isDead()) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java Fri Jun 17 19:21:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java Mon Jun 20 14:29:42 2011 +0200 @@ -132,6 +132,7 @@ public static class ExceptionBlock extends Block { public RiExceptionHandler handler; public Block next; + public int deoptBci; } public static class DeoptBlock extends Block { @@ -157,6 +158,8 @@ private final RiMethod method; + private final RiExceptionHandler[] exceptionHandlers; + public final HashMap<Integer, BranchOverride> branchOverride; private Block[] blockMap; @@ -169,6 +172,7 @@ */ public BlockMap(RiMethod method) { this.method = method; + exceptionHandlers = method.exceptionHandlers(); this.blockMap = new Block[method.codeSize()]; if (method.exceptionHandlers().length != 0) { this.canTrap = new BitSet(blockMap.length); @@ -178,6 +182,10 @@ branchOverride = new HashMap<Integer, BranchOverride>(); } + public RiExceptionHandler[] exceptionHandlers() { + return exceptionHandlers; + } + /** * Builds the block map and conservative CFG and numbers blocks. */ @@ -202,7 +210,7 @@ private void makeExceptionEntries() { // start basic blocks at all exception handler blocks and mark them as exception entries - for (RiExceptionHandler h : method.exceptionHandlers()) { + for (RiExceptionHandler h : this.exceptionHandlers) { Block xhandler = makeBlock(h.handlerBCI()); xhandler.isExceptionEntry = true; } @@ -427,7 +435,7 @@ private ExceptionBlock unwindBlock; - private Block makeExceptionDispatch(List<RiExceptionHandler> handlers, int index) { + private Block makeExceptionDispatch(List<RiExceptionHandler> handlers, int index, int bci) { RiExceptionHandler handler = handlers.get(index); if (handler.isCatchAll()) { return blockMap[handler.handlerBCI()]; @@ -437,10 +445,11 @@ block = new ExceptionBlock(); block.startBci = -1; block.endBci = -1; + block.deoptBci = bci; block.handler = handler; block.successors.add(blockMap[handler.handlerBCI()]); if (index < handlers.size() - 1) { - block.next = makeExceptionDispatch(handlers, index + 1); + block.next = makeExceptionDispatch(handlers, index + 1, bci); block.successors.add(block.next); } exceptionDispatch.put(handler, block); @@ -457,7 +466,7 @@ Block block = blockMap[bci]; ArrayList<RiExceptionHandler> handlers = null; - for (RiExceptionHandler h : method.exceptionHandlers()) { + for (RiExceptionHandler h : this.exceptionHandlers) { if (h.startBCI() <= bci && bci < h.endBCI()) { if (handlers == null) { handlers = new ArrayList<RiExceptionHandler>(); @@ -469,7 +478,7 @@ } } if (handlers != null) { - Block dispatch = makeExceptionDispatch(handlers, 0); + Block dispatch = makeExceptionDispatch(handlers, 0, bci); block.successors.add(dispatch); } }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java Fri Jun 17 19:21:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java Mon Jun 20 14:29:42 2011 +0200 @@ -79,11 +79,15 @@ new GraphBuilderPhase(compilation, compilation.method, false, false).apply(compilation.graph); // } + //printGraph("After GraphBuilding", compilation.graph); + if (GraalOptions.TestGraphDuplication) { new DuplicationPhase().apply(compilation.graph); + //printGraph("After Duplication", compilation.graph); } new DeadCodeEliminationPhase().apply(compilation.graph); + //printGraph("After DeadCodeElimination", compilation.graph); if (GraalOptions.Inline) { new InliningPhase(compilation, this, GraalOptions.TraceInlining).apply(compilation.graph); @@ -96,7 +100,6 @@ new DeadCodeEliminationPhase().apply(graph); } - new LoopEdgeSplitingPhase().apply(graph); if (GraalOptions.OptLoops) { new LoopPhase().apply(graph); } @@ -106,9 +109,6 @@ IdentifyBlocksPhase schedule = new IdentifyBlocksPhase(true); schedule.apply(graph); - if (GraalOptions.Time) { - GraalTimers.COMPUTE_LINEAR_SCAN_ORDER.start(); - } List<Block> blocks = schedule.getBlocks(); List<LIRBlock> lirBlocks = new ArrayList<LIRBlock>(); @@ -145,6 +145,11 @@ assert startBlock != null; assert startBlock.blockPredecessors().size() == 0; + + if (GraalOptions.Time) { + GraalTimers.COMPUTE_LINEAR_SCAN_ORDER.start(); + } + ComputeLinearScanOrder clso = new ComputeLinearScanOrder(lirBlocks.size(), startBlock); orderedBlocks = clso.linearScanOrder(); this.compilation.stats.loopCount = clso.numLoops();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessField.java Fri Jun 17 19:21:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessField.java Mon Jun 20 14:29:42 2011 +0200 @@ -76,7 +76,7 @@ this.field = field; setObject(object); assert field.isResolved(); - assert field.holder().isResolved(); + assert field.holder().isInitialized(); } /**
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoopBegin.java Fri Jun 17 19:21:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoopBegin.java Mon Jun 20 14:29:42 2011 +0200 @@ -27,15 +27,11 @@ import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.compiler.util.*; import com.oracle.max.graal.graph.*; -import com.sun.cri.ci.*; -public class LoopBegin extends StateSplit implements PhiPoint{ - - private static final int INPUT_COUNT = 0; - private static final int SUCCESSOR_COUNT = 0; - +public class LoopBegin extends Merge{ public LoopBegin(Graph graph) { - super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph); + super(graph); + this.addEnd(new EndNode(graph)); } public LoopEnd loopEnd() { @@ -73,34 +69,18 @@ } @Override - public int phiPointPredecessorCount() { + public int phiPredecessorCount() { return 2; } @Override - public int phiPointPredecessorIndex(Node pred) { - Node singlePredecessor = this.singlePredecessor(); - if (pred == singlePredecessor) { + public int phiPredecessorIndex(Node pred) { + if (pred == forwardEdge()) { return 0; } else if (pred == this.loopEnd()) { return 1; - } else if (singlePredecessor instanceof Placeholder) { - singlePredecessor = singlePredecessor.singlePredecessor(); - if (pred == singlePredecessor) { - return 0; - } } - throw Util.shouldNotReachHere("unknown pred : " + pred + "(sp=" + singlePredecessor + ", le=" + this.loopEnd() + ")"); - } - - @Override - public Node asNode() { - return this; - } - - @Override - public Collection<Phi> phis() { - return Util.filter(this.usages(), Phi.class); + throw Util.shouldNotReachHere("unknown pred : " + pred + "(sp=" + forwardEdge() + ", le=" + this.loopEnd() + ")"); } public Collection<LoopCounter> counters() { @@ -108,7 +88,18 @@ } @Override - public List<Node> phiPointPredecessors() { - return Arrays.asList(new Node[]{this.singlePredecessor(), this.loopEnd()}); + public List<Node> phiPredecessors() { + return Arrays.asList(new Node[]{this.forwardEdge(), this.loopEnd()}); + } + + public EndNode forwardEdge() { + return this.endAt(0); + } + + @Override + public boolean verify() { + assertTrue(loopEnd() != null); + assertTrue(forwardEdge() != null); + return true; } }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Merge.java Fri Jun 17 19:21:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Merge.java Mon Jun 20 14:29:42 2011 +0200 @@ -35,7 +35,7 @@ * about the basic block, including the successor and * predecessor blocks, exception handlers, liveness information, etc. */ -public class Merge extends StateSplit implements PhiPoint{ +public class Merge extends StateSplit{ private static final int INPUT_COUNT = 0; @@ -92,6 +92,29 @@ return (EndNode) inputs().variablePart().get(index); } + public Iterable<Node> mergePredecessors() { + return new Iterable<Node>() { + @Override + public Iterator<Node> iterator() { + return new Iterator<Node>() { + int i = 0; + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + @Override + public Node next() { + return Merge.this.endAt(i++); + } + @Override + public boolean hasNext() { + return i < Merge.this.endCount(); + } + }; + } + }; + } + @Override public String toString() { StringBuilder builder = new StringBuilder(); @@ -292,34 +315,27 @@ for (Node usage : usages()) { if (usage instanceof Phi) { Phi phi = (Phi) usage; - phi.removeInput(predIndex); + if (!phi.isDead()) { + phi.removeInput(predIndex); + } } } } - @Override - public int phiPointPredecessorCount() { + public int phiPredecessorCount() { return endCount(); } - @Override - public int phiPointPredecessorIndex(Node pred) { + public int phiPredecessorIndex(Node pred) { EndNode end = (EndNode) pred; return endIndex(end); } - @Override - public Node asNode() { - return this; - } - - @Override public Collection<Phi> phis() { return Util.filter(this.usages(), Phi.class); } - @Override - public List<Node> phiPointPredecessors() { + public List<Node> phiPredecessors() { return Collections.unmodifiableList(inputs().variablePart()); } }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java Fri Jun 17 19:21:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java Mon Jun 20 14:29:42 2011 +0200 @@ -54,24 +54,32 @@ /** * The merge node for this phi. */ - public PhiPoint merge() { - return (PhiPoint) inputs().get(super.inputCount() + INPUT_MERGE); + public Merge merge() { + return (Merge) inputs().get(super.inputCount() + INPUT_MERGE); } - public void setMerge(Node n) { - assert n instanceof PhiPoint; + public void setMerge(Merge n) { inputs().set(super.inputCount() + INPUT_MERGE, n); } - public Phi(CiKind kind, PhiPoint merge, Graph graph) { + public Phi(CiKind kind, Merge merge, Graph graph) { super(kind, INPUT_COUNT, SUCCESSOR_COUNT, graph); - setMerge(merge.asNode()); + setMerge(merge); } Phi(CiKind kind, Graph graph) { super(kind, INPUT_COUNT, SUCCESSOR_COUNT, graph); } + @Override + public boolean verify() { + assertTrue(merge() != null); + if (!isDead()) { + assertTrue(merge().phiPredecessorCount() == valueCount()); + } + return true; + } + /** * Get the instruction that produces the value associated with the i'th predecessor * of the join block.
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/PhiPoint.java Fri Jun 17 19:21:53 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -/* - * 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.compiler.ir; - -import java.util.*; - -import com.oracle.max.graal.graph.*; - -/** - * A marker interface for nodes from which Phi can hang. - */ -public interface PhiPoint { - int phiPointPredecessorCount(); - int phiPointPredecessorIndex(Node pred); - List<Node> phiPointPredecessors(); - Node asNode(); - Collection<Phi> phis(); -}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java Fri Jun 17 19:21:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java Mon Jun 20 14:29:42 2011 +0200 @@ -29,7 +29,6 @@ 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 class DeadCodeEliminationPhase extends Phase { @@ -46,7 +45,7 @@ // remove chained Merges for (Merge merge : graph.getNodes(Merge.class)) { - if (merge.endCount() == 1 && merge.usages().size() == 0 && !(merge instanceof LoopEnd)) { + if (merge.endCount() == 1 && merge.usages().size() == 0 && !(merge instanceof LoopEnd || merge instanceof LoopBegin)) { FixedNode next = merge.next(); EndNode endNode = merge.endAt(0); merge.delete(); @@ -54,20 +53,20 @@ } } // remove if nodes with constant-value comparison - for (If ifNode : graph.getNodes(If.class)) { - Compare compare = ifNode.compare(); - if (compare.x().isConstant() && compare.y().isConstant()) { - CiConstant constX = compare.x().asConstant(); - CiConstant constY = compare.y().asConstant(); - Boolean result = compare.condition().foldCondition(constX, constY, GraalCompilation.compilation().runtime); - if (result != null) { - Node actualSuccessor = result ? ifNode.trueSuccessor() : ifNode.falseSuccessor(); - ifNode.replace(actualSuccessor); - } else { - TTY.println("if not removed %s %s %s (%s %s)", constX, compare.condition(), constY, constX.kind, constY.kind); - } - } - } +// for (If ifNode : graph.getNodes(If.class)) { +// Compare compare = ifNode.compare(); +// if (compare.x().isConstant() && compare.y().isConstant()) { +// CiConstant constX = compare.x().asConstant(); +// CiConstant constY = compare.y().asConstant(); +// Boolean result = compare.condition().foldCondition(constX, constY, GraalCompilation.compilation().runtime); +// if (result != null) { +// Node actualSuccessor = result ? ifNode.trueSuccessor() : ifNode.falseSuccessor(); +// ifNode.replace(actualSuccessor); +// } else { +// TTY.println("if not removed %s %s %s (%s %s)", constX, compare.condition(), constY, constX.kind, constY.kind); +// } +// } +// } flood.add(graph.start());
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java Fri Jun 17 19:21:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java Mon Jun 20 14:29:42 2011 +0200 @@ -31,8 +31,10 @@ import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.compiler.graph.*; -import com.oracle.max.graal.compiler.graph.BlockMap.*; import com.oracle.max.graal.compiler.graph.BlockMap.Block; +import com.oracle.max.graal.compiler.graph.BlockMap.BranchOverride; +import com.oracle.max.graal.compiler.graph.BlockMap.DeoptBlock; +import com.oracle.max.graal.compiler.graph.BlockMap.ExceptionBlock; import com.oracle.max.graal.compiler.ir.*; import com.oracle.max.graal.compiler.ir.Deoptimize.DeoptAction; import com.oracle.max.graal.compiler.schedule.*; @@ -42,7 +44,7 @@ import com.sun.cri.bytecode.*; import com.sun.cri.ci.*; import com.sun.cri.ri.*; -import com.sun.cri.ri.RiType.*; +import com.sun.cri.ri.RiType.Representation; /** * The {@code GraphBuilder} class parses the bytecode of a method and builds the IR graph. @@ -70,6 +72,7 @@ private final RiRuntime runtime; private final RiMethod method; private final RiConstantPool constantPool; + private RiExceptionHandler[] exceptionHandlers; private final BytecodeStream stream; // the bytecode stream private final LogStream log; @@ -85,7 +88,7 @@ private Value methodSynchronizedObject; private CiExceptionHandler unwindHandler; - private Block unwindBlock; + private ExceptionBlock unwindBlock; private Block returnBlock; private boolean storeResultGraph; @@ -125,7 +128,7 @@ this.constantPool = runtime.getConstantPool(method); this.createUnwind = createUnwind; - this.storeResultGraph = true; + this.storeResultGraph = GraalOptions.CacheGraphs; } @Override @@ -152,6 +155,7 @@ BlockMap blockMap = compilation.getBlockMap(method); this.branchOverride = blockMap.branchOverride; + exceptionHandlers = blockMap.exceptionHandlers(); blockList = new ArrayList<Block>(blockMap.blocks); blockFromBci = new Block[method.codeSize()]; for (int i = 0; i < blockList.size(); i++) { @@ -234,11 +238,12 @@ return block; } - private Block unwindBlock() { + private Block unwindBlock(int bci) { if (unwindBlock == null) { - unwindBlock = new Block(); - unwindBlock.startBci = Instruction.SYNCHRONIZATION_ENTRY_BCI; - unwindBlock.endBci = Instruction.SYNCHRONIZATION_ENTRY_BCI; + unwindBlock = new ExceptionBlock(); + unwindBlock.startBci = -1; + unwindBlock.endBci = -1; + unwindBlock.deoptBci = bci; unwindBlock.blockID = nextBlockNumber(); addToWorkList(unwindBlock); } @@ -281,17 +286,23 @@ StateSplit first = (StateSplit) target.firstInstruction; if (target.isLoopHeader && isVisited(target)) { - first = ((LoopBegin) target.firstInstruction.next()).loopEnd(); + first = loopBegin(target).loopEnd(); } + + int bci = target.startBci; + if (target instanceof ExceptionBlock) { + bci = ((ExceptionBlock) target).deoptBci; + } + FrameState existingState = first.stateAfter(); if (existingState == null) { // copy state because it is modified - FrameState duplicate = newState.duplicate(target.startBci); + FrameState duplicate = newState.duplicate(bci); // if the block is a loop header, insert all necessary phis if (target.isLoopHeader && !isVisited(target)) { - LoopBegin loopBegin = (LoopBegin) target.firstInstruction.next(); + LoopBegin loopBegin = loopBegin(target); assert target.firstInstruction instanceof Placeholder && loopBegin != null; //System.out.println("insertLoopPhis with " + target.loopHeaderState); insertLoopPhis(loopBegin, loopBegin.stateAfter()); @@ -310,7 +321,7 @@ if (first instanceof Placeholder) { Placeholder p = (Placeholder) first; if (p.predecessors().size() == 0) { - p.setStateAfter(newState.duplicate(target.startBci)); + p.setStateAfter(newState.duplicate(bci)); return; } else { Merge merge = new Merge(graph); @@ -376,7 +387,6 @@ assert bci == Instruction.SYNCHRONIZATION_ENTRY_BCI || bci == bci() : "invalid bci"; RiExceptionHandler firstHandler = null; - RiExceptionHandler[] exceptionHandlers = method.exceptionHandlers(); // join with all potential exception handlers if (exceptionHandlers != null) { for (RiExceptionHandler handler : exceptionHandlers) { @@ -410,7 +420,7 @@ assert isCatchAll(firstHandler); int handlerBCI = firstHandler.handlerBCI(); if (handlerBCI == Instruction.SYNCHRONIZATION_ENTRY_BCI) { - dispatchBlock = unwindBlock(); + dispatchBlock = unwindBlock(bci); } else { dispatchBlock = blockFromBci[handlerBCI]; } @@ -428,7 +438,7 @@ currentNext = exception; currentExceptionObject = exception; } - FrameState stateWithException = entryState.duplicateModified(bci, CiKind.Void, currentExceptionObject); + FrameState stateWithException = entryState.duplicateWithException(bci, currentExceptionObject); currentNext.setNext(createTarget(dispatchBlock, stateWithException)); return entry; @@ -711,7 +721,7 @@ } else { frameState.clearStack(); frameState.apush(exception); - appendGoto(createTarget(unwindBlock(), frameState)); + appendGoto(createTarget(unwindBlock(bci), frameState)); } } @@ -794,7 +804,7 @@ private void genGetField(int cpi, RiField field) { CiKind kind = field.kind(); Value receiver = frameState.apop(); - if (field.isResolved()) { + if (field.isResolved() && field.holder().isInitialized()) { LoadField load = new LoadField(receiver, field, graph); appendOptimizedLoadField(kind, load); } else { @@ -807,7 +817,7 @@ private void genPutField(int cpi, RiField field) { Value value = frameState.pop(field.kind().stackKind()); Value receiver = frameState.apop(); - if (field.isResolved()) { + if (field.isResolved() && field.holder().isInitialized()) { StoreField store = new StoreField(receiver, field, value, graph); appendOptimizedStoreField(store); } else { @@ -818,7 +828,7 @@ private void genGetStatic(int cpi, RiField field) { RiType holder = field.holder(); - boolean isInitialized = field.isResolved(); + boolean isInitialized = field.isResolved() && field.holder().isInitialized(); CiConstant constantValue = null; if (isInitialized) { constantValue = field.constantValue(null); @@ -840,7 +850,7 @@ private void genPutStatic(int cpi, RiField field) { RiType holder = field.holder(); - Value container = genTypeOrDeopt(RiType.Representation.StaticFields, holder, field.isResolved(), cpi); + Value container = genTypeOrDeopt(RiType.Representation.StaticFields, holder, field.isResolved() && field.holder().isInitialized(), cpi); Value value = frameState.pop(field.kind().stackKind()); if (container != null) { StoreField store = new StoreField(container, field, value, graph); @@ -1045,11 +1055,11 @@ } private void genJsr(int dest) { - throw new CiBailout("jsr/ret not supported"); + throw new JSRNotSupportedBailout(); } private void genRet(int localIndex) { - throw new CiBailout("jsr/ret not supported"); + throw new JSRNotSupportedBailout(); } private void genTableswitch() { @@ -1151,7 +1161,7 @@ LoopEnd loopEnd = new LoopEnd(graph); loopEnd.setLoopBegin(loopBegin); Placeholder p = new Placeholder(graph); - p.setNext(loopBegin); + p.setNext(loopBegin.forwardEdge()); loopBegin.setStateAfter(stateAfter.duplicate(block.startBci)); block.firstInstruction = p; } else { @@ -1163,7 +1173,7 @@ FixedNode result = null; if (block.isLoopHeader && isVisited(block)) { - result = ((LoopBegin) block.firstInstruction.next()).loopEnd(); + result = loopBegin(block).loopEnd(); } else { result = block.firstInstruction; } @@ -1171,11 +1181,15 @@ assert result instanceof Merge || result instanceof Placeholder : result; if (result instanceof Merge) { - EndNode end = new EndNode(graph); - //end.setNext(result); - ((Merge) result).addEnd(end); - result = end; + if (result instanceof LoopBegin) { + result = ((LoopBegin) result).forwardEdge(); + } else { + EndNode end = new EndNode(graph); + ((Merge) result).addEnd(end); + result = end; + } } + assert !(result instanceof LoopBegin || result instanceof Merge); return result; } @@ -1202,7 +1216,7 @@ markVisited(block); // now parse the block if (block.isLoopHeader) { - lastInstr = (LoopBegin) block.firstInstruction.next(); + lastInstr = loopBegin(block); } else { lastInstr = block.firstInstruction; } @@ -1224,8 +1238,7 @@ } for (Block b : blocksVisited) { if (b.isLoopHeader) { - Instruction loopHeaderInstr = b.firstInstruction; - LoopBegin begin = (LoopBegin) loopHeaderInstr.next(); + LoopBegin begin = loopBegin(b); LoopEnd loopEnd = begin.loopEnd(); // This can happen with degenerated loops like this one: @@ -1242,10 +1255,7 @@ } else { loopEnd.delete(); Merge merge = new Merge(graph); - EndNode end = new EndNode(graph); - int nbrReplacement = begin.singlePredecessor().successors().replace(begin, end); - assert nbrReplacement > 0; - merge.addEnd(end); + merge.addEnd(begin.forwardEdge()); merge.setNext(begin.next()); merge.setStateAfter(begin.stateAfter()); begin.replace(merge); @@ -1254,6 +1264,12 @@ } } + private static LoopBegin loopBegin(Block block) { + EndNode endNode = (EndNode) block.firstInstruction.next(); + LoopBegin loopBegin = (LoopBegin) endNode.merge(); + return loopBegin; + } + private void createDeoptBlock(DeoptBlock block) { storeResultGraph = false; append(new Deoptimize(DeoptAction.InvalidateReprofile, graph)); @@ -1289,9 +1305,9 @@ assert frameState.stackSize() == 1 : "only exception object expected on stack, actual size: " + frameState.stackSize(); createUnwindBlock(block); } else { - assert frameState.stackSize() == 1; + assert frameState.stackSize() == 1 : frameState; - Block nextBlock = block.next == null ? unwindBlock() : block.next; + Block nextBlock = block.next == null ? unwindBlock(block.deoptBci) : block.next; if (block.handler.catchType().isResolved()) { FixedNode catchSuccessor = createTarget(blockFromBci[block.handler.handlerBCI()], frameState); FixedNode nextDispatch = createTarget(nextBlock, frameState); @@ -1300,16 +1316,14 @@ Deoptimize deopt = new Deoptimize(DeoptAction.InvalidateRecompile, graph); deopt.setMessage("unresolved " + block.handler.catchType().name()); append(deopt); - FixedNode nextDispatch = createTarget(nextBlock, frameState); - appendGoto(nextDispatch); } } } private void appendGoto(FixedNode target) { if (lastInstr != null) { - lastInstr.setNext(target); - } + lastInstr.setNext(target); + } } private void iterateBytecodesForBlock(Block block) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Fri Jun 17 19:21:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Mon Jun 20 14:29:42 2011 +0200 @@ -411,7 +411,7 @@ // adjust all frame states that were copied if (frameStates.size() > 0) { - FrameState outerFrameState = stateAfter.duplicateModified(invoke.bci, invoke.kind); + FrameState outerFrameState = stateAfter.duplicateModified(invoke.bci, stateAfter.rethrowException(), invoke.kind); for (Node node : frameStates) { FrameState frameState = (FrameState) duplicates.get(node); if (!frameState.isDeleted()) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoopEdgeSplitingPhase.java Fri Jun 17 19:21:53 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * 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.max.graal.compiler.phases; - -import com.oracle.max.graal.compiler.ir.*; -import com.oracle.max.graal.compiler.schedule.*; -import com.oracle.max.graal.graph.*; - -/** - * Does critical edge spliting on LoopBegin. - */ -public class LoopEdgeSplitingPhase extends Phase { - - @Override - protected void run(Graph graph) { - for (LoopBegin loopBegin : graph.getNodes(LoopBegin.class)) { - Node pred = loopBegin.singlePredecessor(); - if (IdentifyBlocksPhase.trueSuccessorCount(pred) > 1) { - Anchor anchor = new Anchor(graph); - anchor.setNext(loopBegin); - pred.successors().replace(loopBegin, anchor); - } - } - } -}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java Fri Jun 17 19:21:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java Mon Jun 20 14:29:42 2011 +0200 @@ -31,17 +31,24 @@ private final String name; private static final ThreadLocal<Phase> currentPhase = new ThreadLocal<Phase>(); + private final boolean shouldVerify; public Phase() { this.name = this.getClass().getSimpleName(); + this.shouldVerify = true; } public Phase(String name) { + this(name, true); + } + + public Phase(String name, boolean shouldVerify) { this.name = name; + this.shouldVerify = shouldVerify; } public final void apply(Graph graph) { - assert graph != null && graph.verify(); + assert graph != null && (!shouldVerify || graph.verify()); int startDeletedNodeCount = graph.getDeletedNodeCount(); int startNodeCount = graph.getNodeCount(); @@ -76,7 +83,7 @@ compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After " + getName(), graph, true, false)); } - assert graph.verify(); + assert !shouldVerify || graph.verify(); // (Item|Graph|Phase|Value) }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java Fri Jun 17 19:21:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java Mon Jun 20 14:29:42 2011 +0200 @@ -33,14 +33,13 @@ public class IdentifyBlocksPhase extends Phase { - private static final int MAX_DOMINATOR_ITER = 50; private final List<Block> blocks = new ArrayList<Block>(); private NodeMap<Block> nodeToBlock; private Graph graph; private boolean scheduleAllNodes; public IdentifyBlocksPhase(boolean scheduleAllNodes) { - super(scheduleAllNodes ? "FullSchedule" : "PartSchedule"); + super(scheduleAllNodes ? "FullSchedule" : "PartSchedule", false); this.scheduleAllNodes = scheduleAllNodes; } @@ -119,7 +118,7 @@ Block block = null; Node currentNode = n; while (nodeToBlock.get(currentNode) == null) { - if (block != null && IdentifyBlocksPhase.trueSuccessorCount(currentNode) > 1) { + if (block != null && (currentNode instanceof ControlSplit || trueSuccessorCount(currentNode) > 1)) { // We are at a split node => start a new block. block = null; } @@ -128,24 +127,18 @@ // Either dead code or at a merge node => stop iteration. break; } - if (currentNode instanceof LoopBegin) { - block = null; - } currentNode = currentNode.singlePredecessor(); } } } } - //System.out.println("identify blocks"); -// print(); - // Connect blocks. for (Block block : blocks) { Node n = block.firstNode(); - if (n instanceof Merge) { + if (n instanceof Merge) { Merge m = (Merge) n; - for (Node pred : m.phiPointPredecessors()) { + for (Node pred : m.mergePredecessors()) { Block predBlock = nodeToBlock.get(pred); predBlock.addSuccessor(block); } @@ -158,8 +151,6 @@ } } } - //System.out.println("connect"); - //print(); computeDominators(); @@ -176,15 +167,8 @@ } } - //System.out.println("dom + cycles"); -// print(); - assignLatestPossibleBlockToNodes(); - //System.out.println("assign last"); -// print(); sortNodesWithinBlocks(); - //System.out.println("sort"); -// print(); } else { computeJavaBlocks(); } @@ -264,7 +248,7 @@ } if (n instanceof Phi) { - Block block = nodeToBlock.get(((Phi) n).merge().asNode()); + Block block = nodeToBlock.get(((Phi) n).merge()); nodeToBlock.set(n, block); } @@ -272,6 +256,7 @@ Block block = nodeToBlock.get(((LoopCounter) n).loopBegin()); nodeToBlock.set(n, block); } + Block block = null; for (Node succ : n.successors()) { block = getCommonDominator(block, assignLatestPossibleBlockToNode(succ)); @@ -279,23 +264,23 @@ for (Node usage : n.usages()) { if (usage instanceof Phi) { Phi phi = (Phi) usage; - PhiPoint merge = phi.merge(); - Block mergeBlock = nodeToBlock.get(merge.asNode()); - assert mergeBlock != null : "no block for merge " + merge.asNode().id(); + Merge merge = phi.merge(); + Block mergeBlock = nodeToBlock.get(merge); + assert mergeBlock != null : "no block for merge " + merge.id(); for (int i = 0; i < phi.valueCount(); ++i) { if (phi.valueAt(i) == n) { if (mergeBlock.getPredecessors().size() == 0) { TTY.println(merge.toString()); TTY.println(phi.toString()); - TTY.println(merge.phiPointPredecessors().toString()); + TTY.println(merge.phiPredecessors().toString()); TTY.println("value count: " + phi.valueCount()); } block = getCommonDominator(block, mergeBlock.getPredecessors().get(i)); } } } else if (usage instanceof FrameState && ((FrameState) usage).block() != null) { - PhiPoint merge = ((FrameState) usage).block(); - for (Node pred : merge.phiPointPredecessors()) { + Merge merge = ((FrameState) usage).block(); + for (Node pred : merge.mergePredecessors()) { block = getCommonDominator(block, nodeToBlock.get(pred)); } } else if (usage instanceof LoopCounter) { @@ -413,15 +398,13 @@ CiBitMap visited = new CiBitMap(blocks.size()); visited.set(dominatorRoot.blockID()); LinkedList<Block> workList = new LinkedList<Block>(); - workList.add(dominatorRoot); - int iter = 0; - int maxIter = MAX_DOMINATOR_ITER * blocks.size(); + for (Block block : blocks) { + if (block.getPredecessors().size() == 0) { + workList.add(block); + } + } + while (!workList.isEmpty()) { - if (iter++ >= maxIter) { - System.out.println("Reached maxIter(" + maxIter + ") !!"); - print(); - throw new CiBailout("Max iteration for dominator computation reached, Cycles in the block graph?"); - } Block b = workList.remove(); List<Block> predecessors = b.getPredecessors();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameState.java Fri Jun 17 19:21:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameState.java Mon Jun 20 14:29:42 2011 +0200 @@ -49,6 +49,8 @@ protected final int locksSize; + private final boolean rethrowException; + private static final int SUCCESSOR_COUNT = 0; @Override @@ -90,19 +92,20 @@ * @param stackSize size of the stack * @param lockSize number of locks */ - public FrameState(RiMethod method, int bci, int localsSize, int stackSize, int locksSize, Graph graph) { + public FrameState(RiMethod method, int bci, int localsSize, int stackSize, int locksSize, boolean rethrowException, Graph graph) { super(CiKind.Illegal, localsSize + stackSize + locksSize + INPUT_COUNT, SUCCESSOR_COUNT, graph); this.method = method; this.bci = bci; this.localsSize = localsSize; this.stackSize = stackSize; this.locksSize = locksSize; + this.rethrowException = rethrowException; GraalMetrics.FrameStatesCreated++; GraalMetrics.FrameStateValuesCreated += localsSize + stackSize + locksSize; } - FrameState(RiMethod method, int bci, Value[] locals, Value[] stack, int stackSize, ArrayList<Value> locks, Graph graph) { - this(method, bci, locals.length, stackSize, locks.size(), graph); + FrameState(RiMethod method, int bci, Value[] locals, Value[] stack, int stackSize, ArrayList<Value> locks, boolean rethrowException, Graph graph) { + this(method, bci, locals.length, stackSize, locks.size(), rethrowException, graph); for (int i = 0; i < locals.length; i++) { setValueAt(i, locals[i]); } @@ -114,6 +117,10 @@ } } + public boolean rethrowException() { + return rethrowException; + } + /** * Gets a copy of this frame state. */ @@ -128,7 +135,7 @@ */ @Override public FrameState duplicateWithEmptyStack(int bci) { - FrameState other = new FrameState(method, bci, localsSize, 0, locksSize(), graph()); + FrameState other = new FrameState(method, bci, localsSize, 0, locksSize(), rethrowException, graph()); for (int i = 0; i < localsSize; i++) { other.setValueAt(i, localAt(i)); } @@ -139,15 +146,19 @@ return other; } + public FrameState duplicateWithException(int bci, Value exceptionObject) { + return duplicateModified(bci, true, CiKind.Void, exceptionObject); + } + /** * Creates a copy of this frame state with one stack element of type popKind popped from the stack and the * values in pushedValues pushed on the stack. The pushedValues are expected to be in slot encoding: a long * or double is followed by a null slot. */ - public FrameState duplicateModified(int bci, CiKind popKind, Value... pushedValues) { + public FrameState duplicateModified(int bci, boolean rethrowException, CiKind popKind, Value... pushedValues) { int popSlots = popKind.sizeInSlots(); int pushSlots = pushedValues.length; - FrameState other = new FrameState(method, bci, localsSize, stackSize - popSlots + pushSlots, locksSize(), graph()); + FrameState other = new FrameState(method, bci, localsSize, stackSize - popSlots + pushSlots, locksSize(), rethrowException, graph()); for (int i = 0; i < localsSize; i++) { other.setValueAt(i, localAt(i)); } @@ -304,7 +315,7 @@ * @param block the block begin for which we are creating the phi * @param i the index into the stack for which to create a phi */ - public Phi setupPhiForStack(PhiPoint block, int i) { + public Phi setupPhiForStack(Merge block, int i) { Value p = stackAt(i); if (p != null) { if (p instanceof Phi) { @@ -325,7 +336,7 @@ * @param block the block begin for which we are creating the phi * @param i the index of the local variable for which to create the phi */ - public Phi setupPhiForLocal(PhiPoint block, int i) { + public Phi setupPhiForLocal(Merge block, int i) { Value p = localAt(i); if (p instanceof Phi) { Phi phi = (Phi) p; @@ -373,7 +384,7 @@ } } - public void merge(PhiPoint block, FrameStateAccess other) { + public void merge(Merge block, FrameStateAccess other) { checkSize(other); for (int i = 0; i < valuesSize(); i++) { Value x = valueAt(i); @@ -400,7 +411,7 @@ } if (phi.valueCount() == 0) { - int size = block.phiPointPredecessorCount(); + int size = block.phiPredecessorCount(); for (int j = 0; j < size; ++j) { phi.addInput(x); } @@ -409,16 +420,16 @@ phi.addInput((x == y) ? phi : y); } - assert phi.valueCount() == block.phiPointPredecessorCount() + (block instanceof LoopBegin ? 0 : 1) : "valueCount=" + phi.valueCount() + " predSize= " + block.phiPointPredecessorCount(); + assert phi.valueCount() == block.phiPredecessorCount() + (block instanceof LoopBegin ? 0 : 1) : "valueCount=" + phi.valueCount() + " predSize= " + block.phiPredecessorCount(); } } } } - public PhiPoint block() { + public Merge block() { for (Node n : usages()) { - if (n instanceof PhiPoint) { - return (PhiPoint) n; + if (n instanceof Merge) { + return (Merge) n; } } return null; @@ -499,14 +510,9 @@ out.print("FrameState"); } - @Override - public FrameState copy() { - return new FrameState(method, bci, localsSize, stackSize, locksSize, graph()); - } - private FrameState copy(int newBci) { - return new FrameState(method, newBci, localsSize, stackSize, locksSize, graph()); + return new FrameState(method, newBci, localsSize, stackSize, locksSize, rethrowException, graph()); } @Override @@ -538,12 +544,12 @@ str.append(i == 0 ? "" : ", ").append(lockAt(i) == null ? "_" : lockAt(i).id()); } properties.put("locks", str.toString()); + properties.put("rethrowException", rethrowException); return properties; } @Override public Node copy(Graph into) { - FrameState x = new FrameState(method, bci, localsSize, stackSize, locksSize, into); - return x; + return new FrameState(method, bci, localsSize, stackSize, locksSize, rethrowException, into); } }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameStateBuilder.java Fri Jun 17 19:21:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameStateBuilder.java Mon Jun 20 14:29:42 2011 +0200 @@ -81,6 +81,11 @@ this.locks = new ArrayList<Value>(); } + @Override + public String toString() { + return String.format("FrameStateBuilder[stackSize=%d]", stackIndex); + } + public void initializeFrom(FrameState other) { assert locals.length == other.localsSize() : "expected: " + locals.length + ", actual: " + other.localsSize(); assert stack.length >= other.stackSize() : "expected: <=" + stack.length + ", actual: " + other.stackSize(); @@ -99,12 +104,12 @@ } public FrameState create(int bci) { - return new FrameState(method, bci, locals, stack, stackIndex, locks, graph); + return new FrameState(method, bci, locals, stack, stackIndex, locks, false, graph); } @Override public FrameState duplicateWithEmptyStack(int bci) { - FrameState frameState = new FrameState(method, bci, locals, new Value[0], 0, locks, graph); + FrameState frameState = new FrameState(method, bci, locals, new Value[0], 0, locks, false, graph); frameState.setOuterFrameState(outerFrameState()); return frameState; }
--- a/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java Fri Jun 17 19:21:53 2011 +0200 +++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java Mon Jun 20 14:29:42 2011 +0200 @@ -88,7 +88,7 @@ } public Node replace(Node other) { - assert !isDeleted() && (other == null || !other.isDeleted()) : "id: " + id() + ", other: " + other; + assert !isDeleted() && (other == null || !other.isDeleted()) && other != this : "id: " + id() + ", other: " + other; assert other == null || other.graph == graph; for (Node usage : usages) { usage.inputs.replaceFirstOccurrence(this, other); @@ -165,7 +165,7 @@ return true; } - public Node copy() { + public final Node copy() { return copy(graph); }
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotConstantPool.java Fri Jun 17 19:21:53 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotConstantPool.java Mon Jun 20 14:29:42 2011 +0200 @@ -128,7 +128,9 @@ RiType result = typeCache.get(cpi); if (result == null) { result = compiler.getVMEntries().RiConstantPool_lookupType(vmId, cpi); - typeCache.add(cpi, result); + if (result.isResolved()) { + typeCache.add(cpi, result); + } } return result; }
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolvedImpl.java Fri Jun 17 19:21:53 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolvedImpl.java Mon Jun 20 14:29:42 2011 +0200 @@ -33,7 +33,9 @@ */ public final class HotSpotMethodResolvedImpl extends HotSpotMethod implements HotSpotMethodResolved { - private AccessibleObject javaMirror; + // Do not use as a Java object! + @Deprecated + private Object javaMirror; // cached values private final int codeSize; @@ -80,10 +82,7 @@ @Override public RiExceptionHandler[] exceptionHandlers() { - if (exceptionHandlers == null) { - exceptionHandlers = compiler.getVMEntries().RiMethod_exceptionHandlers(this); - } - return exceptionHandlers; + return compiler.getVMEntries().RiMethod_exceptionHandlers(this); } @Override
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMExitsNative.java Fri Jun 17 19:21:53 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMExitsNative.java Mon Jun 20 14:29:42 2011 +0200 @@ -29,6 +29,7 @@ import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.debug.*; +import com.oracle.max.graal.compiler.graph.*; import com.oracle.max.graal.runtime.logging.*; import com.oracle.max.graal.runtime.server.*; import com.sun.cri.ci.*; @@ -152,10 +153,10 @@ if (result.bailout() != null) { Throwable cause = result.bailout().getCause(); - if (!GraalOptions.QuietBailout) { + if (!GraalOptions.QuietBailout && !(result.bailout() instanceof JSRNotSupportedBailout)) { StringWriter out = new StringWriter(); result.bailout().printStackTrace(new PrintWriter(out)); - TTY.println("Bailout:\n" + out.toString()); + TTY.println("Bailout while compiling " + method + " :\n" + out.toString()); if (cause != null) { Logger.info("Trace for cause: "); for (StackTraceElement e : cause.getStackTrace()) { @@ -179,7 +180,7 @@ } catch (Throwable t) { StringWriter out = new StringWriter(); t.printStackTrace(new PrintWriter(out)); - TTY.println("Compilation interrupted: (" + method.name() + ")\n" + out.toString()); + TTY.println("Compilation interrupted: (" + method + ")\n" + out.toString()); throw t; } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/runavrora.sh Mon Jun 20 14:29:42 2011 +0200 @@ -0,0 +1,21 @@ +#!/bin/bash +if [ -z "${JDK7}" ]; then + echo "JDK7 is not defined." + exit 1; +fi +if [ -z "${MAXINE}" ]; then + echo "MAXINE is not defined. It must point to a maxine repository directory." + exit 1; +fi +if [ -z "${GRAAL}" ]; then + echo "GRAAL is not defined. It must point to a maxine repository directory." + exit 1; +fi +if [ -z "${DACAPO}" ]; then + echo "DACAPO is not defined. It must point to a Dacapo benchmark directory." + exit 1; +fi +COMMAND="${JDK7G}/bin/java -client -d64 -graal -Xms1g -Xmx2g -esa -classpath ${DACAPO}/dacapo-9.12-bach.jar -XX:-GraalBailoutIsFatal -G:-QuietBailout $* Harness --preserve -n 5 avrora" +echo $COMMAND +$COMMAND +echo $COMMAND
--- a/rundacapo.sh Fri Jun 17 19:21:53 2011 +0200 +++ b/rundacapo.sh Mon Jun 20 14:29:42 2011 +0200 @@ -15,4 +15,4 @@ echo "DACAPO is not defined. It must point to a Dacapo benchmark directory." exit 1; fi -${JDK7}/bin/java -client -d64 -graal -G:+PrintCompilation -G:+DetailedAsserts -G:PrintIdealGraphLevel=4 "-G:PrintFilter=~.*(fill|findBundle).*" -XX:CompileCommand=compileonly,java.io.BufferedReader::fill -XX:-GraalBailoutIsFatal -XX:+PrintCompilation -Xms1g -Xmx2g -esa -classpath ${DACAPO}/dacapo-9.12-bach.jar Harness --preserve $* +${JDK7}/bin/java -client -d64 -graal -XX:-GraalBailoutIsFatal -XX:MaxPermSize=512m -XX:+PrintCompilation -Xms1g -Xmx2g -esa -classpath ${DACAPO}/dacapo-9.12-bach.jar Harness --preserve $*
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/runeclipse.sh Mon Jun 20 14:29:42 2011 +0200 @@ -0,0 +1,21 @@ +#!/bin/bash +if [ -z "${JDK7}" ]; then + echo "JDK7 is not defined." + exit 1; +fi +if [ -z "${MAXINE}" ]; then + echo "MAXINE is not defined. It must point to a maxine repository directory." + exit 1; +fi +if [ -z "${GRAAL}" ]; then + echo "GRAAL is not defined. It must point to a maxine repository directory." + exit 1; +fi +if [ -z "${DACAPO}" ]; then + echo "DACAPO is not defined. It must point to a Dacapo benchmark directory." + exit 1; +fi +COMMAND="${JDK7}/bin/java -client -d64 -graal -Xms1g -Xmx2g -esa -classpath ${DACAPO}/dacapo-9.12-bach.jar -XX:-GraalBailoutIsFatal -G:-QuietBailout $* Harness --preserve -n 5 eclipse" +echo $COMMAND +$COMMAND +echo $COMMAND
--- a/runfop.sh Fri Jun 17 19:21:53 2011 +0200 +++ b/runfop.sh Mon Jun 20 14:29:42 2011 +0200 @@ -15,4 +15,4 @@ echo "DACAPO is not defined. It must point to a Dacapo benchmark directory." exit 1; fi -${JDK7}/bin/java -client -d64 -graal -Xms1g -Xmx2g -esa -classpath ${DACAPO}/dacapo-9.12-bach.jar $* Harness --preserve -n 5 fop +${JDK7}/bin/java -client -d64 -graal -Xms1g -Xmx2g -esa -classpath ${DACAPO}/dacapo-9.12-bach.jar -XX:-GraalBailoutIsFatal $* Harness --preserve -n 5 fop
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/runlusearch.sh Mon Jun 20 14:29:42 2011 +0200 @@ -0,0 +1,21 @@ +#!/bin/bash +if [ -z "${JDK7}" ]; then + echo "JDK7 is not defined." + exit 1; +fi +if [ -z "${MAXINE}" ]; then + echo "MAXINE is not defined. It must point to a maxine repository directory." + exit 1; +fi +if [ -z "${GRAAL}" ]; then + echo "GRAAL is not defined. It must point to a maxine repository directory." + exit 1; +fi +if [ -z "${DACAPO}" ]; then + echo "DACAPO is not defined. It must point to a Dacapo benchmark directory." + exit 1; +fi +COMMAND="${JDK7}/bin/java -client -d64 -graal -Xms1g -Xmx2g -esa -classpath ${DACAPO}/dacapo-9.12-bach.jar -XX:-GraalBailoutIsFatal -G:-QuietBailout $* Harness --preserve -n 5 lusearch" +echo $COMMAND +$COMMAND +echo $COMMAND
--- a/runtests.sh Fri Jun 17 19:21:53 2011 +0200 +++ b/runtests.sh Mon Jun 20 14:29:42 2011 +0200 @@ -12,4 +12,4 @@ exit 1; fi TESTDIR=${MAXINE}/com.oracle.max.vm/test -${JDK7}/bin/java -client -d64 -graal -ea -esa -Xcomp -XX:+PrintCompilation -XX:CompileOnly=jtt -Xbootclasspath/p:"${MAXINE}/com.oracle.max.vm/bin" -Xbootclasspath/p:"${MAXINE}/com.oracle.max.base/bin" $@ test.com.sun.max.vm.compiler.JavaTester -verbose=1 -gen-run-scheme=false -run-scheme-package=all ${TESTDIR}/jtt/bytecode ${TESTDIR}/jtt/except ${TESTDIR}/jtt/hotpath ${TESTDIR}/jtt/jdk ${TESTDIR}/jtt/lang ${TESTDIR}/jtt/loop ${TESTDIR}/jtt/micro ${TESTDIR}/jtt/optimize ${TESTDIR}/jtt/reflect ${TESTDIR}/jtt/threads +${JDK7}/bin/java -client -d64 -graal -ea -esa -Xcomp -XX:+PrintCompilation -XX:CompileOnly=jtt $@ -Xbootclasspath/p:"${MAXINE}/com.oracle.max.vm/bin" -Xbootclasspath/p:"${MAXINE}/com.oracle.max.base/bin" $@ test.com.sun.max.vm.compiler.JavaTester -verbose=1 -gen-run-scheme=false -run-scheme-package=all ${TESTDIR}/jtt/bytecode ${TESTDIR}/jtt/except ${TESTDIR}/jtt/hotpath ${TESTDIR}/jtt/jdk ${TESTDIR}/jtt/lang ${TESTDIR}/jtt/loop ${TESTDIR}/jtt/micro ${TESTDIR}/jtt/optimize ${TESTDIR}/jtt/reflect ${TESTDIR}/jtt/threads
--- a/src/share/vm/c1/c1_IR.hpp Fri Jun 17 19:21:53 2011 +0200 +++ b/src/share/vm/c1/c1_IR.hpp Mon Jun 20 14:29:42 2011 +0200 @@ -237,7 +237,7 @@ // reexecute allowed only for the topmost frame bool reexecute = topmost ? should_reexecute() : false; bool return_oop = false; // This flag will be ignored since it used only for C2 with escape analysis. - recorder->describe_scope(pc_offset, scope()->method(), bci(), reexecute, is_method_handle_invoke, return_oop, locvals, expvals, monvals); + recorder->describe_scope(pc_offset, scope()->method(), bci(), reexecute, false, is_method_handle_invoke, return_oop, locvals, expvals, monvals); } };
--- a/src/share/vm/c1/c1_LIRAssembler.cpp Fri Jun 17 19:21:53 2011 +0200 +++ b/src/share/vm/c1/c1_LIRAssembler.cpp Mon Jun 20 14:29:42 2011 +0200 @@ -405,7 +405,7 @@ if (s == NULL) break; IRScope* scope = s->scope(); //Always pass false for reexecute since these ScopeDescs are never used for deopt - debug_info->describe_scope(pc_offset, scope->method(), s->bci(), false/*reexecute*/); + debug_info->describe_scope(pc_offset, scope->method(), s->bci(), false/*reexecute*/, false/*rethrow_exception*/); } debug_info->end_non_safepoint(pc_offset);
--- a/src/share/vm/code/debugInfoRec.cpp Fri Jun 17 19:21:53 2011 +0200 +++ b/src/share/vm/code/debugInfoRec.cpp Mon Jun 20 14:29:42 2011 +0200 @@ -283,6 +283,7 @@ ciMethod* method, int bci, bool reexecute, + bool rethrow_exception, bool is_method_handle_invoke, bool return_oop, DebugToken* locals, @@ -298,6 +299,7 @@ // Record flags into pcDesc. last_pd->set_should_reexecute(reexecute); + last_pd->set_rethrow_exception(rethrow_exception); last_pd->set_is_method_handle_invoke(is_method_handle_invoke); last_pd->set_return_oop(return_oop);
--- a/src/share/vm/code/debugInfoRec.hpp Fri Jun 17 19:21:53 2011 +0200 +++ b/src/share/vm/code/debugInfoRec.hpp Mon Jun 20 14:29:42 2011 +0200 @@ -101,6 +101,7 @@ ciMethod* method, int bci, bool reexecute, + bool rethrow_exception, bool is_method_handle_invoke = false, bool return_oop = false, DebugToken* locals = NULL,
--- a/src/share/vm/code/nmethod.cpp Fri Jun 17 19:21:53 2011 +0200 +++ b/src/share/vm/code/nmethod.cpp Mon Jun 20 14:29:42 2011 +0200 @@ -1079,7 +1079,7 @@ PcDesc* pd = pc_desc_at(pc); guarantee(pd != NULL, "scope must be present"); return new ScopeDesc(this, pd->scope_decode_offset(), - pd->obj_decode_offset(), pd->should_reexecute(), + pd->obj_decode_offset(), pd->should_reexecute(), pd->rethrow_exception(), pd->return_oop()); } @@ -2267,7 +2267,7 @@ PcDesc* pd = pc_desc_at(ic->end_of_call()); assert(pd != NULL, "PcDesc must exist"); for (ScopeDesc* sd = new ScopeDesc(this, pd->scope_decode_offset(), - pd->obj_decode_offset(), pd->should_reexecute(), + pd->obj_decode_offset(), pd->should_reexecute(), pd->rethrow_exception(), pd->return_oop()); !sd->is_top(); sd = sd->sender()) { sd->verify(); @@ -2533,7 +2533,7 @@ PcDesc* p = pc_desc_near(begin+1); if (p != NULL && p->real_pc(this) <= end) { return new ScopeDesc(this, p->scope_decode_offset(), - p->obj_decode_offset(), p->should_reexecute(), + p->obj_decode_offset(), p->should_reexecute(), p->rethrow_exception(), p->return_oop()); } return NULL;
--- a/src/share/vm/code/pcDesc.hpp Fri Jun 17 19:21:53 2011 +0200 +++ b/src/share/vm/code/pcDesc.hpp Mon Jun 20 14:29:42 2011 +0200 @@ -43,6 +43,7 @@ int word; struct { unsigned int reexecute: 1; + unsigned int rethrow_exception: 1; unsigned int is_method_handle_invoke: 1; unsigned int return_oop: 1; } bits; @@ -71,6 +72,8 @@ // Flags bool should_reexecute() const { return _flags.bits.reexecute; } void set_should_reexecute(bool z) { _flags.bits.reexecute = z; } + bool rethrow_exception() const { return _flags.bits.rethrow_exception; } + void set_rethrow_exception(bool z) { _flags.bits.rethrow_exception = z; } // Does pd refer to the same information as pd? bool is_same_info(const PcDesc* pd) {
--- a/src/share/vm/code/scopeDesc.cpp Fri Jun 17 19:21:53 2011 +0200 +++ b/src/share/vm/code/scopeDesc.cpp Mon Jun 20 14:29:42 2011 +0200 @@ -31,21 +31,23 @@ #include "runtime/handles.inline.hpp" -ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool return_oop) { +ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool rethrow_exception, bool return_oop) { _code = code; _decode_offset = decode_offset; _objects = decode_object_values(obj_decode_offset); _reexecute = reexecute; _return_oop = return_oop; + _rethrow_exception = rethrow_exception; decode_body(); } -ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool return_oop) { +ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool rethrow_exception, bool return_oop) { _code = code; _decode_offset = decode_offset; _objects = decode_object_values(DebugInformationRecorder::serialized_null); _reexecute = reexecute; _return_oop = return_oop; + _rethrow_exception = rethrow_exception; decode_body(); } @@ -55,6 +57,7 @@ _decode_offset = parent->_sender_decode_offset; _objects = parent->_objects; _reexecute = false; //reexecute only applies to the first scope + _rethrow_exception = false; _return_oop = false; decode_body(); }
--- a/src/share/vm/code/scopeDesc.hpp Fri Jun 17 19:21:53 2011 +0200 +++ b/src/share/vm/code/scopeDesc.hpp Mon Jun 20 14:29:42 2011 +0200 @@ -60,17 +60,18 @@ class ScopeDesc : public ResourceObj { public: // Constructor - ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool return_oop); + ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool rethrow_exception, bool return_oop); // Calls above, giving default value of "serialized_null" to the // "obj_decode_offset" argument. (We don't use a default argument to // avoid a .hpp-.hpp dependency.) - ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool return_oop); + ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool rethrow_exception, bool return_oop); // JVM state methodHandle method() const { return _method; } int bci() const { return _bci; } bool should_reexecute() const { return _reexecute; } + bool rethrow_exception() const { return _rethrow_exception; } bool return_oop() const { return _return_oop; } GrowableArray<ScopeValue*>* locals(); @@ -97,6 +98,7 @@ methodHandle _method; int _bci; bool _reexecute; + bool _rethrow_exception; bool _return_oop; // Decoding offsets
--- a/src/share/vm/graal/graalCodeInstaller.cpp Fri Jun 17 19:21:53 2011 +0200 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Mon Jun 20 14:29:42 2011 +0200 @@ -496,9 +496,14 @@ DebugToken* expressions_token = _debug_recorder->create_scope_values(expressions); DebugToken* monitors_token = _debug_recorder->create_monitor_values(monitors); - _debug_recorder->describe_scope(pc_offset, cimethod, bci, reexecute, false, false, locals_token, expressions_token, monitors_token); + bool throw_exception = false; + if (CiFrame::rethrowException(frame)) { + throw_exception = true; + } + + _debug_recorder->describe_scope(pc_offset, cimethod, bci, reexecute, throw_exception, false, false, locals_token, expressions_token, monitors_token); } else { - _debug_recorder->describe_scope(pc_offset, cimethod, bci, reexecute, false, false, NULL, NULL, NULL); + _debug_recorder->describe_scope(pc_offset, cimethod, bci, reexecute, false, false, false, NULL, NULL, NULL); } }
--- a/src/share/vm/graal/graalCompiler.cpp Fri Jun 17 19:21:53 2011 +0200 +++ b/src/share/vm/graal/graalCompiler.cpp Mon Jun 20 14:29:42 2011 +0200 @@ -206,23 +206,24 @@ instanceKlass::cast(HotSpotMethodResolved::klass())->initialize(CHECK_NULL); Handle obj = instanceKlass::cast(HotSpotMethodResolved::klass())->allocate_instance(CHECK_NULL); assert(obj() != NULL, "must succeed in allocating instance"); - + HotSpotMethodResolved::set_compiler(obj, VMExits::compilerInstance()()); - oop reflected = getReflectedMethod(method(), CHECK_NULL); - HotSpotMethodResolved::set_javaMirror(obj, reflected); + // (tw) Cannot use reflection here, because the compiler thread could dead lock with the running application. + // oop reflected = getReflectedMethod(method(), CHECK_NULL); + HotSpotMethodResolved::set_javaMirror(obj, method()); HotSpotMethodResolved::set_name(obj, name()); - + KlassHandle klass = method->method_holder(); Handle holder_name = VmIds::toString<Handle>(klass->name(), CHECK_NULL); oop holder = GraalCompiler::createHotSpotTypeResolved(klass, holder_name, CHECK_NULL); HotSpotMethodResolved::set_holder(obj, holder); - + HotSpotMethodResolved::set_codeSize(obj, method->code_size()); HotSpotMethodResolved::set_accessFlags(obj, method->access_flags().as_int()); HotSpotMethodResolved::set_maxLocals(obj, method->max_locals()); HotSpotMethodResolved::set_maxStackSize(obj, method->max_stack()); HotSpotMethodResolved::set_invocationCount(obj, method->invocation_count()); - + method->set_graal_mirror(obj()); return obj(); }
--- a/src/share/vm/graal/graalJavaAccess.hpp Fri Jun 17 19:21:53 2011 +0200 +++ b/src/share/vm/graal/graalJavaAccess.hpp Mon Jun 20 14:29:42 2011 +0200 @@ -63,7 +63,7 @@ oop_field(HotSpotMethodResolved, compiler, "Lcom/oracle/max/graal/runtime/Compiler;") \ oop_field(HotSpotMethodResolved, name, "Ljava/lang/String;") \ oop_field(HotSpotMethodResolved, holder, "Lcom/sun/cri/ri/RiType;") \ - oop_field(HotSpotMethodResolved, javaMirror, "Ljava/lang/reflect/AccessibleObject;") \ + oop_field(HotSpotMethodResolved, javaMirror, "Ljava/lang/Object;") \ int_field(HotSpotMethodResolved, codeSize) \ int_field(HotSpotMethodResolved, accessFlags) \ int_field(HotSpotMethodResolved, maxLocals) \ @@ -153,6 +153,7 @@ int_field(CiFrame, numLocals) \ int_field(CiFrame, numStack) \ int_field(CiFrame, numLocks) \ + boolean_field(CiFrame, rethrowException) \ end_class \ start_class(CiCodePos) \ oop_field(CiCodePos, caller, "Lcom/sun/cri/ci/CiCodePos;") \
--- a/src/share/vm/graal/graalVMEntries.cpp Fri Jun 17 19:21:53 2011 +0200 +++ b/src/share/vm/graal/graalVMEntries.cpp Mon Jun 20 14:29:42 2011 +0200 @@ -39,7 +39,10 @@ methodOop getMethodFromHotSpotMethod(oop hotspot_method) { oop reflected = HotSpotMethodResolved::javaMirror(hotspot_method); assert(reflected != NULL, "NULL not expected"); + return (methodOop)reflected; + // (tw) Cannot use reflection code, because then the compiler can dead lock with the user application (test using -Xcomp). + /* // method is a handle to a java.lang.reflect.Method object oop mirror = NULL; int slot = 0; @@ -58,7 +61,7 @@ // assert(instanceKlass::cast(k)->is_initialized(), "only initialized classes expected"); methodOop m = instanceKlass::cast(k)->method_with_idnum(slot); assert(m != NULL, "deleted method?"); - return m; + return m;*/ } oop getReflectedMethod(methodOop method, TRAPS) { @@ -368,7 +371,6 @@ JNIEXPORT jobject JNICALL Java_com_oracle_graal_runtime_VMEntries_RiConstantPool_1lookupMethod(JNIEnv *env, jobject, jlong vmId, jint index, jbyte byteCode) { TRACE_graal_3("VMEntries::RiConstantPool_lookupMethod"); VM_ENTRY_MARK; - index = GraalCompiler::to_cp_index_u2(index); constantPoolHandle cp = VmIds::get<constantPoolOop>(vmId);
--- a/src/share/vm/prims/jvmtiCodeBlobEvents.cpp Fri Jun 17 19:21:53 2011 +0200 +++ b/src/share/vm/prims/jvmtiCodeBlobEvents.cpp Mon Jun 20 14:29:42 2011 +0200 @@ -251,7 +251,7 @@ address scopes_data = nm->scopes_data_begin(); for( pcd = nm->scopes_pcs_begin(); pcd < nm->scopes_pcs_end(); ++pcd ) { - ScopeDesc sc0(nm, pcd->scope_decode_offset(), pcd->should_reexecute(), pcd->return_oop()); + ScopeDesc sc0(nm, pcd->scope_decode_offset(), pcd->should_reexecute(), pcd->rethrow_exception(), pcd->return_oop()); ScopeDesc *sd = &sc0; while( !sd->is_top() ) { sd = sd->sender(); } int bci = sd->bci();
--- a/src/share/vm/runtime/deoptimization.cpp Fri Jun 17 19:21:53 2011 +0200 +++ b/src/share/vm/runtime/deoptimization.cpp Mon Jun 20 14:29:42 2011 +0200 @@ -1223,17 +1223,32 @@ // tty->print_cr("trap_request: %08x, cpi: %i, pc: %016x", trap_request, unloaded_class_index, fr.pc()); + Events::log("Uncommon trap occurred @" INTPTR_FORMAT " unloaded_class_index = %d", fr.pc(), (int) trap_request); vframe* vf = vframe::new_vframe(&fr, ®_map, thread); compiledVFrame* cvf = compiledVFrame::cast(vf); - + nmethod* nm = cvf->code(); + ScopeDesc* trap_scope = cvf->scope(); + + if (TraceDeoptimization) { + tty->print_cr("Deoptimization: bci=%d pc=%d, relative_pc=%d, method=%s", trap_scope->bci(), fr.pc(), fr.pc() - nm->code_begin(), trap_scope->method()->name()->as_C_string()); + } - ScopeDesc* trap_scope = cvf->scope(); methodHandle trap_method = trap_scope->method(); int trap_bci = trap_scope->bci(); Bytecodes::Code trap_bc = trap_method->java_code_at(trap_bci); + if (trap_scope->rethrow_exception()) { + if (TraceDeoptimization) { + tty->print_cr("Exception to be rethrown in the interpreter"); + } + GrowableArray<ScopeValue*>* expressions = trap_scope->expressions(); + ScopeValue* topOfStack = expressions->top(); + Handle topOfStackObj = cvf->create_stack_value(topOfStack)->get_obj(); + THREAD->set_pending_exception(topOfStackObj(), NULL, 0); + } + // Record this event in the histogram. gather_statistics(reason, action, trap_bc);
--- a/src/share/vm/runtime/vframe_hp.hpp Fri Jun 17 19:21:53 2011 +0200 +++ b/src/share/vm/runtime/vframe_hp.hpp Mon Jun 20 14:29:42 2011 +0200 @@ -66,7 +66,7 @@ // Returns SynchronizationEntryBCI or bci() (used for synchronization) int raw_bci() const; - protected: + //protected: ScopeDesc* _scope;