# HG changeset patch # User Lukas Stadler # Date 1309281268 -7200 # Node ID 536528f48708d6293c1670764db1963f2a009706 # Parent 05b8a7787aaf32c83138e057effe4966e280ab13 more escape analysis work: debug info diff -r 05b8a7787aaf -r 536528f48708 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java Mon Jun 27 17:15:12 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java Tue Jun 28 19:14:28 2011 +0200 @@ -55,6 +55,7 @@ public static int MaximumShortLoopSize = 5; // escape analysis settings + public static boolean EscapeAnalysis = ____; public static int ForcedInlineEscapeWeight = 0; public static int MaximumEscapeAnalysisArrayLength = 32; diff -r 05b8a7787aaf -r 536528f48708 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java Mon Jun 27 17:15:12 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java Tue Jun 28 19:14:28 2011 +0200 @@ -36,6 +36,7 @@ import com.oracle.max.graal.compiler.lir.*; import com.oracle.max.graal.compiler.lir.LIRInstruction.*; import com.oracle.max.graal.compiler.observer.*; +import com.oracle.max.graal.compiler.phases.EscapeAnalysisPhase.EscapeField; import com.oracle.max.graal.compiler.util.*; import com.oracle.max.graal.compiler.value.*; import com.oracle.max.graal.compiler.value.FrameState.*; @@ -318,7 +319,7 @@ LIRInstruction instructionForId(int opId) { assert isEven(opId) : "opId not even"; LIRInstruction instr = opIdToInstructionMap[opIdToIndex(opId)]; - assert instr.id == opId; + assert instr.id() == opId; return instr; } @@ -460,7 +461,7 @@ // iterate all instructions of the block. skip the first because it is always a label for (int j = 1; j < numInst; j++) { LIRInstruction op = instructions.get(j); - int opId = op.id; + int opId = op.id(); if (opId == -1) { CiValue resultOperand = op.result(); @@ -568,7 +569,7 @@ int numInst = instructions.size(); for (int j = 0; j < numInst; j++) { LIRInstruction op = instructions.get(j); - op.id = opId; + op.setId(opId); opIdToInstructionMap[index] = op; opIdToBlockMap[index] = block; @@ -616,7 +617,7 @@ if (!liveKill.get(operandNum)) { liveGen.set(operandNum); if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" Setting liveGen for operand %d at instruction %d", operandNum, op.id); + TTY.println(" Setting liveGen for operand %d at instruction %d", operandNum, op.id()); } } if (block.loopIndex() >= 0) { @@ -641,7 +642,7 @@ if (!liveKill.get(operandNum)) { liveGen.set(operandNum); if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println(" Setting liveGen for value %s, LIR opId %d, operand %d because of state for " + op.toString(), Util.valueString(value), op.id, operandNum); + TTY.println(" Setting liveGen for value %s, LIR opId %d, operand %d because of state for " + op.toString(), Util.valueString(value), op.id(), operandNum); } } } else if (operand.isRegister()) { @@ -848,13 +849,13 @@ if (block.liveGen.get(operandNum)) { TTY.println(" used in block B%d", block.blockID()); for (LIRInstruction ins : block.lir().instructionsList()) { - TTY.println(ins.id + ": " + ins.result() + " " + ins.toString()); + TTY.println(ins.id() + ": " + ins.result() + " " + ins.toString()); } } if (block.liveKill.get(operandNum)) { TTY.println(" defined in block B%d", block.blockID()); for (LIRInstruction ins : block.lir().instructionsList()) { - TTY.println(ins.id + ": " + ins.result() + " " + ins.toString()); + TTY.println(ins.id() + ": " + ins.result() + " " + ins.toString()); } } } @@ -1102,8 +1103,8 @@ if (GraalOptions.DetailedAsserts) { int argSlots = compilation.method.signature().argumentSlots(!isStatic(compilation.method.accessFlags())); assert slot.index() >= 0 && slot.index() < argSlots; - assert move.id > 0 : "invalid id"; - assert blockForId(move.id).numberOfPreds() == 0 : "move from stack must be in first block"; + assert move.id() > 0 : "invalid id"; + assert blockForId(move.id()).numberOfPreds() == 0 : "move from stack must be in first block"; assert move.result().isVariable() : "result of move must be a variable"; if (GraalOptions.TraceLinearScanLevel >= 4) { @@ -1137,7 +1138,7 @@ if (from != null && to != null) { to.setLocationHint(from); if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println("operation at opId %d: added hint from interval %d to %d", move.id, from.operandNumber, to.operandNumber); + TTY.println("operation at opId %d: added hint from interval %d to %d", move.id(), from.operandNumber, to.operandNumber); } } } @@ -1155,7 +1156,7 @@ if (from != null && to != null) { to.setLocationHint(from); if (GraalOptions.TraceLinearScanLevel >= 4) { - TTY.println("operation at opId %d: added hint from interval %d to %d", cmove.id, from.operandNumber, to.operandNumber); + TTY.println("operation at opId %d: added hint from interval %d to %d", cmove.id(), from.operandNumber, to.operandNumber); } } } @@ -1179,8 +1180,8 @@ final int blockFrom = block.firstLirInstructionId(); int blockTo = block.lastLirInstructionId(); - assert blockFrom == instructions.get(0).id; - assert blockTo == instructions.get(instructions.size() - 1).id; + assert blockFrom == instructions.get(0).id(); + assert blockTo == instructions.get(instructions.size() - 1).id(); // Update intervals for operands live at the end of this block; BitMap live = block.liveOut; @@ -1208,7 +1209,7 @@ assert !instructions.get(0).hasOperands() : "first operation must always be a label"; for (int j = instructions.size() - 1; j >= 1; j--) { LIRInstruction op = instructions.get(j); - final int opId = op.id; + final int opId = op.id(); // add a temp range for each register if operation destroys caller-save registers if (op.hasCall) { @@ -1269,9 +1270,17 @@ if (info != null) { info.state.forEachLiveStateValue(new ValueProcedure() { public void doValue(Value value) { - CiValue operand = value.operand(); - if (operand.isVariableOrRegister()) { - addUse(operand, blockFrom, (opId + 1), RegisterPriority.None, null); + if (value instanceof VirtualObject) { + VirtualObject obj = (VirtualObject) value; + do { + doValue(obj.input()); + obj = obj.object(); + } while (obj != null); + } else { + CiValue operand = value.operand(); + if (operand.isVariableOrRegister()) { + addUse(operand, blockFrom, (opId + 1), RegisterPriority.None, null); + } } } }); @@ -1315,7 +1324,7 @@ if (GraalOptions.TraceLinearScanLevel >= 2) { TTY.println("killing XMMs for trig"); } - int opId = op.id; + int opId = op.id(); for (CiRegister r : compilation.registerConfig.getCallerSaveRegisters()) { if (r.isFpu()) { @@ -1770,19 +1779,19 @@ void computeOopMap(IntervalWalker iw, LIRInstruction op, LIRDebugInfo info, boolean isCallSite, BitMap frameRefMap, BitMap regRefMap) { if (GraalOptions.TraceLinearScanLevel >= 3) { - TTY.println("creating oop map at opId %d", op.id); + TTY.println("creating oop map at opId %d", op.id()); } // walk before the current operation . intervals that start at // the operation (i.e. output operands of the operation) are not // included in the oop map - iw.walkBefore(op.id); + iw.walkBefore(op.id()); // Iterate through active intervals for (Interval interval = iw.activeLists.get(RegisterBinding.Fixed); interval != Interval.EndMarker; interval = interval.next) { CiValue operand = interval.operand; - assert interval.currentFrom() <= op.id && op.id <= interval.currentTo() : "interval should not be active otherwise"; + assert interval.currentFrom() <= op.id() && op.id() <= interval.currentTo() : "interval should not be active otherwise"; assert interval.operand.isVariable() : "fixed interval found"; // Check if this range covers the instruction. Intervals that @@ -1791,7 +1800,7 @@ // moves, any intervals which end at this instruction are included // in the oop map since we may safepoint while doing the patch // before we've consumed the inputs. - if (op.id < interval.currentTo()) { + if (op.id() < interval.currentTo()) { // caller-save registers must not be included into oop-maps at calls assert !isCallSite || !operand.isRegister() || !isCallerSave(operand) : "interval is in a caller-save register at a call . register will be overwritten"; @@ -1803,7 +1812,7 @@ // Spill optimization: when the stack value is guaranteed to be always correct, // then it must be added to the oop map even if the interval is currently in a register - if (interval.alwaysInMemory() && op.id > interval.spillDefinitionPos() && !interval.location().equals(interval.spillSlot())) { + if (interval.alwaysInMemory() && op.id() > interval.spillDefinitionPos() && !interval.location().equals(interval.spillSlot())) { assert interval.spillDefinitionPos() > 0 : "position not set correctly"; assert interval.spillSlot() != null : "no spill slot assigned"; assert !interval.operand.isRegister() : "interval is on stack : so stack slot is registered twice"; @@ -1837,7 +1846,9 @@ } CiValue toCiValue(int opId, Value value) { - if (value != null && value.operand() != CiValue.IllegalValue) { + if (value instanceof VirtualObject) { + return toCiVirtualObject(opId, (VirtualObject) value); + } else if (value != null && value.operand() != CiValue.IllegalValue) { CiValue operand = value.operand(); Constant con = null; if (value instanceof Constant) { @@ -1884,6 +1895,33 @@ } } + private CiVirtualObject toCiVirtualObject(int opId, VirtualObject obj) { + RiType type = obj.type(); + EscapeField[] escapeFields = obj.fields(); + CiValue[] values = new CiValue[escapeFields.length]; + + VirtualObject current = obj; + do { + boolean found = false; + for (int i = 0; i < escapeFields.length; i++) { + if (escapeFields[i] == current.field() && values[i] == null) { + values[i] = toCiValue(opId, current.input()); + found = true; + break; + } + } + assert found; + current = current.object(); + } while (current != null); + + for (CiValue val : values) { + assert val != null; + } + + CiVirtualObject vobj = CiVirtualObject.get(type, values, obj.id()); + return vobj; + } + CiFrame computeFrameForState(FrameState state, int opId, BitMap frameRefMap) { CiValue[] values = new CiValue[state.valuesSize() + state.locksSize()]; int valueIndex = 0; @@ -1937,11 +1975,11 @@ int frameWords = frameSize / compilation.target.spillSlotSize; BitMap frameRefMap = new BitMap(frameWords); BitMap regRefMap = !op.hasCall ? new BitMap(compilation.target.arch.registerReferenceMapBitCount) : null; - CiFrame frame = compilation.placeholderState != null ? null : computeFrame(info.state, op.id, frameRefMap); + CiFrame frame = compilation.placeholderState != null ? null : computeFrame(info.state, op.id(), frameRefMap); computeOopMap(iw, op, info, frameRefMap, regRefMap); info.debugInfo = new CiDebugInfo(frame, regRefMap, frameRefMap); } else if (GraalOptions.DetailedAsserts) { - assert info.debugInfo.frame().equals(computeFrame(info.state, op.id, new BitMap(info.debugInfo.frameRefMap.size()))); + assert info.debugInfo.frame().equals(computeFrame(info.state, op.id(), new BitMap(info.debugInfo.frameRefMap.size()))); } } } @@ -1970,7 +2008,7 @@ for (int k = 0; k < n; k++) { CiValue operand = op.operandAt(mode, k); if (operand.isVariable()) { - op.setOperandAt(mode, k, colorLirOperand((CiVariable) operand, op.id, mode)); + op.setOperandAt(mode, k, colorLirOperand((CiVariable) operand, op.id(), mode)); } } } @@ -2256,14 +2294,14 @@ LIRInstruction op = instructions.get(j); if (op.info != null) { - iw.walkBefore(op.id); + iw.walkBefore(op.id()); boolean checkLive = true; // Make sure none of the fixed registers is live across an // oopmap since we can't handle that correctly. if (checkLive) { for (Interval interval = iw.activeLists.get(RegisterBinding.Fixed); interval != Interval.EndMarker; interval = interval.next) { - if (interval.currentTo() > op.id + 1) { + if (interval.currentTo() > op.id() + 1) { // This interval is live out of this op so make sure // that this interval represents some value that's // referenced by this op either as an input or output. diff -r 05b8a7787aaf -r 536528f48708 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScanWalker.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScanWalker.java Mon Jun 27 17:15:12 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScanWalker.java Tue Jun 28 19:14:28 2011 +0200 @@ -233,15 +233,15 @@ // When the block already contains spill moves, the index must be increased until the // correct index is reached. List list = opBlock.lir().instructionsList(); - int index = (opId - list.get(0).id) >> 1; - assert list.get(index).id <= opId : "error in calculation"; + int index = (opId - list.get(0).id()) >> 1; + assert list.get(index).id() <= opId : "error in calculation"; - while (list.get(index).id != opId) { + while (list.get(index).id() != opId) { index++; assert 0 <= index && index < list.size() : "index out of bounds"; } assert 1 <= index && index < list.size() : "index out of bounds"; - assert list.get(index).id == opId : "error in calculation"; + assert list.get(index).id() == opId : "error in calculation"; // insert new instruction before instruction at position index moveResolver.moveInsertPosition(opBlock.lir(), index - 1); diff -r 05b8a7787aaf -r 536528f48708 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/RegisterVerifier.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/RegisterVerifier.java Mon Jun 27 17:15:12 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/RegisterVerifier.java Tue Jun 28 19:14:28 2011 +0200 @@ -229,8 +229,8 @@ CiValue operand = op.operandAt(LIRInstruction.OperandMode.Input, j); if (allocator.isProcessed(operand)) { Interval interval = intervalAt(operand); - if (op.id != -1) { - interval = interval.getSplitChildAtOpId(op.id, LIRInstruction.OperandMode.Input, allocator); + if (op.id() != -1) { + interval = interval.getSplitChildAtOpId(op.id(), LIRInstruction.OperandMode.Input, allocator); } assert checkState(inputState, interval.location(), interval.splitParent()); @@ -251,8 +251,8 @@ if (allocator.isProcessed(operand)) { Interval interval = intervalAt(operand); assert interval != null : "Could not find interval for operand " + operand; - if (op.id != -1) { - interval = interval.getSplitChildAtOpId(op.id, LIRInstruction.OperandMode.Temp, allocator); + if (op.id() != -1) { + interval = interval.getSplitChildAtOpId(op.id(), LIRInstruction.OperandMode.Temp, allocator); } statePut(inputState, interval.location(), interval.splitParent()); @@ -265,8 +265,8 @@ CiValue operand = op.operandAt(LIRInstruction.OperandMode.Output, j); if (allocator.isProcessed(operand)) { Interval interval = intervalAt(operand); - if (op.id != -1) { - interval = interval.getSplitChildAtOpId(op.id, LIRInstruction.OperandMode.Output, allocator); + if (op.id() != -1) { + interval = interval.getSplitChildAtOpId(op.id(), LIRInstruction.OperandMode.Output, allocator); } statePut(inputState, interval.location(), interval.splitParent()); diff -r 05b8a7787aaf -r 536528f48708 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/CFGPrinter.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/CFGPrinter.java Mon Jun 27 17:15:12 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/CFGPrinter.java Tue Jun 28 19:14:28 2011 +0200 @@ -479,7 +479,7 @@ out.println("LIR"); for (int i = 0; i < lir.length(); i++) { LIRInstruction inst = lir.at(i); - out.printf("nr %4d ", inst.id).print(COLUMN_END); + out.printf("nr %4d ", inst.id()).print(COLUMN_END); if (inst.info != null) { int level = out.indentationLevel(); diff -r 05b8a7787aaf -r 536528f48708 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java Mon Jun 27 17:15:12 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java Tue Jun 28 19:14:28 2011 +0200 @@ -100,10 +100,12 @@ new DeadCodeEliminationPhase().apply(graph); } - new EscapeAnalysisPhase(compilation, this).apply(graph); - new DeadCodeEliminationPhase().apply(graph); - new CanonicalizerPhase().apply(graph); - new DeadCodeEliminationPhase().apply(graph); + if (GraalOptions.EscapeAnalysis) { + new EscapeAnalysisPhase(compilation, this).apply(graph); + new DeadCodeEliminationPhase().apply(graph); + new CanonicalizerPhase().apply(graph); + new DeadCodeEliminationPhase().apply(graph); + } if (GraalOptions.OptLoops) { new LoopPhase().apply(graph); diff -r 05b8a7787aaf -r 536528f48708 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NewArray.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NewArray.java Mon Jun 27 17:15:12 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NewArray.java Tue Jun 28 19:14:28 2011 +0200 @@ -30,13 +30,14 @@ import com.oracle.max.graal.compiler.value.*; import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; -import com.sun.cri.ri.*; /** * The {@code NewArray} class is the base of all instructions that allocate arrays. */ public abstract class NewArray extends FixedNodeWithNext { + private static final EscapeOp ESCAPE = new NewArrayEscapeOp(); + private static final int INPUT_COUNT = 1; private static final int INPUT_LENGTH = 0; @@ -154,7 +155,6 @@ assert x.array() == node; return false; } else if (usage instanceof VirtualObject) { - VirtualObject x = (VirtualObject) usage; return false; } else { return true; @@ -162,12 +162,24 @@ } @Override + public EscapeField[] fields(Node node) { + NewArray x = (NewArray) node; + int length = x.dimension(0).asConstant().asInt(); + EscapeField[] fields = new EscapeField[length]; + for (int i = 0; i < length; i++) { + Integer representation = i; + fields[i] = new EscapeField("[" + i + "]", representation, ((NewArray) node).elementKind()); + } + return fields; + } + + @Override public void beforeUpdate(Node node, Node usage) { if (usage instanceof IsNonNull) { IsNonNull x = (IsNonNull) usage; if (x.usages().size() == 1 && x.usages().get(0) instanceof FixedGuard) { FixedGuard guard = (FixedGuard) x.usages().get(0); - guard.replace(guard.next()); + guard.replaceAndDelete(guard.next()); } x.delete(); } else if (usage instanceof IsType) { @@ -175,30 +187,15 @@ assert x.type() == ((NewArray) node).exactType(); if (x.usages().size() == 1 && x.usages().get(0) instanceof FixedGuard) { FixedGuard guard = (FixedGuard) x.usages().get(0); - guard.replace(guard.next()); + guard.replaceAndDelete(guard.next()); } x.delete(); } else if (usage instanceof AccessMonitor) { AccessMonitor x = (AccessMonitor) usage; - x.replace(x.next()); + x.replaceAndDelete(x.next()); } else if (usage instanceof ArrayLength) { ArrayLength x = (ArrayLength) usage; - x.replace(((NewArray) node).dimension(0)); - } - } - - @Override - public void collectField(Node node, Node usage, Map fields) { - if (usage instanceof AccessIndexed) { - AccessIndexed x = (AccessIndexed) usage; - CiConstant index = x.index().asConstant(); - CiConstant length = ((NewArray) node).dimension(0).asConstant(); - assert index != null && length != null && index.asInt() >= 0 && index.asInt() < length.asInt(); - - Integer representation = index.asInt(); - if (!fields.containsKey(representation)) { - fields.put(representation, new EscapeField("[" + representation + "]", representation, ((NewArray) node).elementKind())); - } + x.replaceAndDelete(((NewArray) node).dimension(0)); } } @@ -215,14 +212,14 @@ usage.inputs().replace(x, fieldState.get(field)); } assert x.usages().size() == 0; - x.replace(x.next()); + x.replaceAndDelete(x.next()); } } else if (current instanceof StoreIndexed) { StoreIndexed x = (StoreIndexed) current; if (x.array() == node) { fieldState.put(field, x.value()); assert x.usages().size() == 0; - x.replace(x.next()); + x.replaceAndDelete(x.next()); } } } diff -r 05b8a7787aaf -r 536528f48708 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NewInstance.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NewInstance.java Mon Jun 27 17:15:12 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NewInstance.java Tue Jun 28 19:14:28 2011 +0200 @@ -138,7 +138,6 @@ assert x.object() == node; return false; } else if (usage instanceof VirtualObject) { - VirtualObject x = (VirtualObject) usage; return false; } else if (usage instanceof RegisterFinalizer) { RegisterFinalizer x = (RegisterFinalizer) usage; @@ -150,12 +149,24 @@ } @Override + public EscapeField[] fields(Node node) { + NewInstance x = (NewInstance) node; + RiField[] riFields = x.instanceClass().fields(); + EscapeField[] fields = new EscapeField[riFields.length]; + for (int i = 0; i < riFields.length; i++) { + RiField field = riFields[i]; + fields[i] = new EscapeField(field.name(), field, field.kind().stackKind()); + } + return fields; + } + + @Override public void beforeUpdate(Node node, Node usage) { if (usage instanceof IsNonNull) { IsNonNull x = (IsNonNull) usage; if (x.usages().size() == 1 && x.usages().get(0) instanceof FixedGuard) { FixedGuard guard = (FixedGuard) x.usages().get(0); - guard.replace(guard.next()); + guard.replaceAndDelete(guard.next()); } x.delete(); } else if (usage instanceof IsType) { @@ -163,26 +174,15 @@ assert x.type() == ((NewInstance) node).instanceClass(); if (x.usages().size() == 1 && x.usages().get(0) instanceof FixedGuard) { FixedGuard guard = (FixedGuard) x.usages().get(0); - guard.replace(guard.next()); + guard.replaceAndDelete(guard.next()); } x.delete(); } else if (usage instanceof AccessMonitor) { AccessMonitor x = (AccessMonitor) usage; - x.replace(x.next()); + x.replaceAndDelete(x.next()); } else if (usage instanceof RegisterFinalizer) { RegisterFinalizer x = (RegisterFinalizer) usage; - x.replace(x.next()); - } - } - - @Override - public void collectField(Node node, Node usage, Map fields) { - if (usage instanceof AccessField) { - AccessField x = (AccessField) usage; - assert x.object() == node; - if (!fields.containsKey(x.field())) { - fields.put(x.field(), new EscapeField(x.field().name(), x.field(), x.field.kind().stackKind())); - } + x.replaceAndDelete(x.next()); } } @@ -198,14 +198,14 @@ usage.inputs().replace(x, fieldState.get(field)); } assert x.usages().size() == 0; - x.replace(x.next()); + x.replaceAndDelete(x.next()); } } else if (current instanceof StoreField) { StoreField x = (StoreField) current; if (x.object() == node) { fieldState.put(field, x.value()); assert x.usages().size() == 0; - x.replace(x.next()); + x.replaceAndDelete(x.next()); } } } diff -r 05b8a7787aaf -r 536528f48708 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/VirtualObject.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/VirtualObject.java Mon Jun 27 17:15:12 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/VirtualObject.java Tue Jun 28 19:14:28 2011 +0200 @@ -56,7 +56,7 @@ return (VirtualObject) inputs().get(super.inputCount() + INPUT_OBJECT); } - public VirtualObject setObject(VirtualObject n) { + private VirtualObject setObject(VirtualObject n) { return (VirtualObject) inputs().set(super.inputCount() + INPUT_OBJECT, n); } @@ -72,6 +72,7 @@ } private EscapeField field; + private EscapeField[] fields; private RiType type; /** @@ -79,11 +80,13 @@ * @param array the instruction producing the array * @param newFrameState the state after executing this instruction */ - public VirtualObject(VirtualObject object, EscapeField field, RiType type, Graph graph) { + public VirtualObject(VirtualObject object, Value input, EscapeField field, RiType type, EscapeField[] fields, Graph graph) { super(CiKind.Int, INPUT_COUNT, SUCCESSOR_COUNT, graph); this.field = field; this.type = type; + this.fields = fields; setObject(object); + setInput(input); } public EscapeField field() { @@ -94,6 +97,10 @@ return type; } + public EscapeField[] fields() { + return fields; + } + @Override public void accept(ValueVisitor v) { // nothing to do... @@ -119,7 +126,7 @@ @Override public Node copy(Graph into) { - VirtualObject x = new VirtualObject(null, field, type, into); + VirtualObject x = new VirtualObject(null, null, field, type, fields, into); return x; } } diff -r 05b8a7787aaf -r 536528f48708 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRInstruction.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRInstruction.java Mon Jun 27 17:15:12 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRInstruction.java Tue Jun 28 19:14:28 2011 +0200 @@ -90,7 +90,7 @@ /** * Value id for register allocation. */ - public int id; + private int id; /** * Determines if all caller-saved registers are destroyed by this instruction. @@ -198,6 +198,14 @@ assert verifyOperands(); } + public final int id() { + return id; + } + + public final void setId(int id) { + this.id = id; + } + private LIROperand initOutput(CiValue output) { assert output != null; if (output != CiValue.IllegalValue) { diff -r 05b8a7787aaf -r 536528f48708 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java Mon Jun 27 17:15:12 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java Tue Jun 28 19:14:28 2011 +0200 @@ -64,7 +64,7 @@ Boolean result = compare.condition().foldCondition(constX, constY, GraalCompilation.compilation().runtime); if (result != null) { Node actualSuccessor = result ? ifNode.trueSuccessor() : ifNode.falseSuccessor(); - ifNode.replace(actualSuccessor); + ifNode.replaceAndDelete(actualSuccessor); } else { TTY.println("if not removed %s %s %s (%s %s)", constX, compare.condition(), constY, constX.kind, constY.kind); } @@ -74,7 +74,7 @@ // remove unnecessary FixedGuards for (FixedGuard guard : graph.getNodes(FixedGuard.class)) { if (guard.node() instanceof IsNonNull && ((IsNonNull) guard.node()).object() instanceof NewInstance) { - guard.replace(guard.next()); + guard.replaceAndDelete(guard.next()); } } diff -r 05b8a7787aaf -r 536528f48708 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/EscapeAnalysisPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/EscapeAnalysisPhase.java Mon Jun 27 17:15:12 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/EscapeAnalysisPhase.java Tue Jun 28 19:14:28 2011 +0200 @@ -42,6 +42,7 @@ public static class BlockExitState { public final Map fieldState; + public VirtualObject obj; public BlockExitState() { this.fieldState = new HashMap(); @@ -57,6 +58,8 @@ private final EscapeOp op; private Graph graph; private final Node node; + private RiType type; + private EscapeField[] escapeFields; public EscapementFixup(EscapeOp op, Graph graph, Node node) { this.op = op; @@ -77,7 +80,11 @@ final HashMap phis = new HashMap(); final Block startBlock = identifyBlocksPhase.getNodeToBlock().get(node); assert startBlock != null; - final RiType type = ((Value) node).exactType(); + type = ((Value) node).exactType(); + escapeFields = op.fields(node); + for (EscapeField field : escapeFields) { + fields.put(field.representation(), field); + } Block.iteratePostOrder(blocks, new BlockClosure() { @@ -95,8 +102,11 @@ BlockExitState state = new BlockExitState(); if (block == startBlock) { + state.obj = null; for (EscapeField field : fields.values()) { - state.fieldState.put(field, Constant.defaultForKind(field.kind(), graph)); + Constant value = Constant.defaultForKind(field.kind(), graph); + state.fieldState.put(field, value); + state.obj = new VirtualObject(state.obj, value, field, type, escapeFields, graph); } } else { List predecessors = block.getPredecessors(); @@ -122,6 +132,7 @@ Phi phi = new Phi(field.kind().stackKind(), (Merge) block.firstNode(), graph); state.fieldState.put(field, phi); phis.put(phi, field); + state.obj = new VirtualObject(state.obj, phi, field, type, escapeFields, graph); } } } @@ -133,12 +144,12 @@ current = block.firstNode(); } while (current != block.lastNode()) { - Node next = ((Instruction) current).next(); + Node next = ((FixedNodeWithNext) current).next(); op.updateState(node, current, fields, state.fieldState); - if (!current.isDeleted() && current instanceof Instruction) { - FrameState stateAfter = ((Instruction) current).stateAfter(); + if (!current.isDeleted() && current instanceof StateSplit) { + FrameState stateAfter = ((StateSplit) current).stateAfter(); if (stateAfter != null) { - updateFrameState(stateAfter, state, type, null); + updateFrameState(stateAfter, state.obj); } } current = next; @@ -196,50 +207,38 @@ usage.inputs().replace(node, Node.Null); } - if (node instanceof Instruction) { - node.replace(((Instruction) node).next()); + if (node instanceof FixedNodeWithNext) { + node.replaceAndDelete(((FixedNodeWithNext) node).next()); } else { node.delete(); } } - private VirtualObject updateFrameState(FrameState frameState, BlockExitState currentState, RiType type, VirtualObject current) { + private VirtualObject updateFrameState(FrameState frameState, VirtualObject current) { for (int i = 0; i < frameState.inputs().size(); i++) { if (frameState.inputs().get(i) == node) { - if (current == null) { - for (EscapeField field : fields.values()) { - current = new VirtualObject(current, field, type, graph); - current.setInput((Value) currentState.fieldState.get(field)); - } - } frameState.inputs().set(i, current); } else if (frameState.inputs().get(i) instanceof VirtualObject) { VirtualObject obj = (VirtualObject) frameState.inputs().get(i); do { - current = updateVirtualObject(obj, currentState, type, current); + current = updateVirtualObject(obj, current); obj = obj.object(); } while (obj != null); } } if (frameState.outerFrameState() != null) { - current = updateFrameState(frameState.outerFrameState(), currentState, type, current); + current = updateFrameState(frameState.outerFrameState(), current); } return current; } - private VirtualObject updateVirtualObject(VirtualObject obj, BlockExitState currentState, RiType type, VirtualObject current) { + private VirtualObject updateVirtualObject(VirtualObject obj, VirtualObject current) { if (obj.input() == node) { - if (current == null) { - for (EscapeField field : fields.values()) { - current = new VirtualObject(current, field, type, graph); - current.setInput((Value) currentState.fieldState.get(field)); - } - } obj.setInput(current); } else if (obj.input() instanceof VirtualObject) { VirtualObject obj2 = (VirtualObject) obj.input(); do { - current = updateVirtualObject(obj2, currentState, type, current); + current = updateVirtualObject(obj2, current); obj2 = obj2.object(); } while (obj2 != null); } @@ -249,9 +248,6 @@ private void process() { for (Node usage : new ArrayList(node.usages())) { op.beforeUpdate(node, usage); - if (!usage.isDeleted()) { - op.collectField(node, usage, fields); - } } } } @@ -283,7 +279,7 @@ weight = analyze(op, node, exits, invokes); if (exits.size() != 0) { if (GraalOptions.TraceEscapeAnalysis) { - TTY.println("####### escaping object: %d %s in %s", node.id(), node.shortName(), compilation.method); + TTY.println("####### escaping object: %d %s (%s) in %s", node.id(), node.shortName(), ((Value) node).exactType(), compilation.method); TTY.print("%d: new value: %d %s, weight %d, escapes at ", iterations, node.id(), node.shortName(), weight); for (Node n : exits) { TTY.print("%d %s, ", n.id(), n.shortName()); @@ -297,7 +293,7 @@ } if (invokes.size() == 0) { if (GraalOptions.TraceEscapeAnalysis) { - TTY.println("!!!!!!!! non-escaping object: %d %s in %s", node.id(), node.shortName(), compilation.method); + TTY.println("!!!!!!!! non-escaping object: %d %s (%s) in %s", node.id(), node.shortName(), ((Value) node).exactType(), compilation.method); } new EscapementFixup(op, graph, node).apply(); new PhiSimplifier(graph); @@ -375,9 +371,9 @@ boolean escape(Node node, Node usage); - void beforeUpdate(Node node, Node usage); + EscapeField[] fields(Node node); - void collectField(Node node, Node usage, Map fields); + void beforeUpdate(Node node, Node usage); void updateState(Node node, Node current, Map fields, Map fieldState); diff -r 05b8a7787aaf -r 536528f48708 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotTypePrimitive.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotTypePrimitive.java Mon Jun 27 17:15:12 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotTypePrimitive.java Tue Jun 28 19:14:28 2011 +0200 @@ -150,4 +150,8 @@ return null; } + @Override + public RiField[] fields() { + return null; + } } diff -r 05b8a7787aaf -r 536528f48708 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotTypeResolvedImpl.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotTypeResolvedImpl.java Mon Jun 27 17:15:12 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotTypeResolvedImpl.java Tue Jun 28 19:14:28 2011 +0200 @@ -222,4 +222,8 @@ return ((HotSpotMethodResolved) method).uniqueConcreteMethod(); } + @Override + public RiField[] fields() { + return compiler.getVMEntries().RiType_fields(this); + } } diff -r 05b8a7787aaf -r 536528f48708 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotTypeUnresolved.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotTypeUnresolved.java Mon Jun 27 17:15:12 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotTypeUnresolved.java Tue Jun 28 19:14:28 2011 +0200 @@ -201,4 +201,8 @@ throw unresolved("uniqueConcreteMethod"); } + @Override + public RiField[] fields() { + return null; + } } diff -r 05b8a7787aaf -r 536528f48708 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntries.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntries.java Mon Jun 27 17:15:12 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntries.java Tue Jun 28 19:14:28 2011 +0200 @@ -87,9 +87,9 @@ void recordBailout(String reason); - RiType RiType_uniqueConcreteSubtype(HotSpotTypeResolved hotSpotTypeResolved); + RiType RiType_uniqueConcreteSubtype(HotSpotTypeResolved klass); - RiType RiType_superType(HotSpotTypeResolved hotSpotTypeResolved); + RiType RiType_superType(HotSpotTypeResolved klass); int getArrayLength(CiConstant array); @@ -97,5 +97,7 @@ RiType getRiType(CiConstant constant); + RiField[] RiType_fields(HotSpotTypeResolved klass); + // Checkstyle: resume } diff -r 05b8a7787aaf -r 536528f48708 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntriesNative.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntriesNative.java Mon Jun 27 17:15:12 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntriesNative.java Tue Jun 28 19:14:28 2011 +0200 @@ -141,5 +141,8 @@ return getType(o.getClass()); } + @Override + public native RiField[] RiType_fields(HotSpotTypeResolved klass); + // Checkstyle: resume } diff -r 05b8a7787aaf -r 536528f48708 src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Mon Jun 27 17:15:12 2011 +0200 +++ b/src/share/vm/classfile/systemDictionary.hpp Tue Jun 28 19:14:28 2011 +0200 @@ -209,10 +209,12 @@ template(CiRegister_klass, com_sun_cri_ci_CiRegister, Opt) \ template(CiCodePos_klass, com_sun_cri_ci_CiCodePos, Opt) \ template(CiConstant_klass, com_sun_cri_ci_CiConstant, Opt) \ + template(CiVirtualObject_klass, com_sun_cri_ci_CiVirtualObject, Opt) \ template(CiKind_klass, com_sun_cri_ci_CiKind, Opt) \ template(CiRuntimeCall_klass, com_sun_cri_ci_CiRuntimeCall, Opt) \ template(RiMethod_klass, com_sun_cri_ri_RiMethod, Opt) \ template(RiType_klass, com_sun_cri_ri_RiType, Opt) \ + template(RiField_klass, com_sun_cri_ri_RiField, Opt) \ template(RiExceptionHandler_klass, com_sun_cri_ri_RiExceptionHandler, Opt) \ template(RiTypeProfile_klass, com_sun_cri_ri_RiTypeProfile, Opt) \ diff -r 05b8a7787aaf -r 536528f48708 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Mon Jun 27 17:15:12 2011 +0200 +++ b/src/share/vm/classfile/vmSymbols.hpp Tue Jun 28 19:14:28 2011 +0200 @@ -258,18 +258,18 @@ LP64_ONLY( do_alias(machine_word_signature, long_signature) ) \ \ /* support for graal */ \ - template(com_sun_hotspot_graal_VMExits, "com/oracle/max/graal/runtime/VMExits") \ + template(com_sun_hotspot_graal_VMExits, "com/oracle/max/graal/runtime/VMExits") \ template(com_sun_hotspot_graal_HotSpotMethodResolved, "com/oracle/max/graal/runtime/HotSpotMethodResolvedImpl") \ - template(com_sun_hotspot_graal_HotSpotTargetMethod, "com/oracle/max/graal/runtime/HotSpotTargetMethod") \ - template(com_sun_hotspot_graal_HotSpotField, "com/oracle/max/graal/runtime/HotSpotField") \ - template(com_sun_graal_graalOptions, "com/sun/graal/graalOptions") \ - template(com_sun_hotspot_graal_HotSpotOptions, "com/oracle/max/graal/runtime/HotSpotOptions") \ - template(com_sun_hotspot_graal_HotSpotTypeResolved, "com/oracle/max/graal/runtime/HotSpotTypeResolvedImpl") \ - template(com_sun_hotspot_graal_HotSpotType, "com/oracle/max/graal/runtime/HotSpotType") \ + template(com_sun_hotspot_graal_HotSpotTargetMethod, "com/oracle/max/graal/runtime/HotSpotTargetMethod") \ + template(com_sun_hotspot_graal_HotSpotField, "com/oracle/max/graal/runtime/HotSpotField") \ + template(com_sun_graal_graalOptions, "com/sun/graal/graalOptions") \ + template(com_sun_hotspot_graal_HotSpotOptions, "com/oracle/max/graal/runtime/HotSpotOptions") \ + template(com_sun_hotspot_graal_HotSpotTypeResolved, "com/oracle/max/graal/runtime/HotSpotTypeResolvedImpl") \ + template(com_sun_hotspot_graal_HotSpotType, "com/oracle/max/graal/runtime/HotSpotType") \ template(com_sun_hotspot_graal_HotSpotExceptionHandler,"com/oracle/max/graal/runtime/HotSpotExceptionHandler") \ - template(com_sun_hotspot_graal_HotSpotProxy, "com/oracle/max/graal/runtime/HotSpotProxy") \ - template(com_sun_hotspot_graal_Compiler, "com/oracle/max/graal/runtime/Compiler") \ - template(com_sun_hotspot_graal_CompilerImpl, "com/oracle/max/graal/runtime/CompilerImpl") \ + template(com_sun_hotspot_graal_HotSpotProxy, "com/oracle/max/graal/runtime/HotSpotProxy") \ + template(com_sun_hotspot_graal_Compiler, "com/oracle/max/graal/runtime/Compiler") \ + template(com_sun_hotspot_graal_CompilerImpl, "com/oracle/max/graal/runtime/CompilerImpl") \ template(com_sun_cri_ri_RiMethod, "com/sun/cri/ri/RiMethod") \ template(com_sun_cri_ri_RiField, "com/sun/cri/ri/RiField") \ template(com_sun_cri_ri_RiType, "com/sun/cri/ri/RiType") \ @@ -278,7 +278,7 @@ template(com_sun_cri_ri_RiExceptionHandler, "com/sun/cri/ri/RiExceptionHandler") \ template(com_sun_cri_ci_CiAssumptions, "com/sun/cri/ci/CiAssumptions") \ template(com_sun_cri_ci_CiAssumptions_ConcreteSubtype, "com/sun/cri/ci/CiAssumptions$ConcreteSubtype") \ - template(com_sun_cri_ci_CiAssumptions_ConcreteMethod, "com/sun/cri/ci/CiAssumptions$ConcreteMethod") \ + template(com_sun_cri_ci_CiAssumptions_ConcreteMethod, "com/sun/cri/ci/CiAssumptions$ConcreteMethod") \ template(com_sun_cri_ci_CiTargetMethod, "com/sun/cri/ci/CiTargetMethod") \ template(com_sun_cri_ci_CiTargetMethod_Site, "com/sun/cri/ci/CiTargetMethod$Site") \ template(com_sun_cri_ci_CiTargetMethod_Call, "com/sun/cri/ci/CiTargetMethod$Call") \ @@ -295,6 +295,7 @@ template(com_sun_cri_ci_CiRegister, "com/sun/cri/ci/CiRegister") \ template(com_sun_cri_ci_CiCodePos, "com/sun/cri/ci/CiCodePos") \ template(com_sun_cri_ci_CiConstant, "com/sun/cri/ci/CiConstant") \ + template(com_sun_cri_ci_CiVirtualObject, "com/sun/cri/ci/CiVirtualObject") \ template(com_sun_cri_ci_CiKind, "com/sun/cri/ci/CiKind") \ template(com_sun_cri_ci_CiRuntimeCall, "com/sun/cri/ci/CiRuntimeCall") \ template(startCompiler_name, "startCompiler") \ diff -r 05b8a7787aaf -r 536528f48708 src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Mon Jun 27 17:15:12 2011 +0200 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Tue Jun 28 19:14:28 2011 +0200 @@ -107,7 +107,7 @@ } // TODO: finish this - graal doesn't provide any scope values at the moment -static ScopeValue* get_hotspot_value(oop value, int frame_size, ScopeValue* &second) { +static ScopeValue* get_hotspot_value(oop value, int frame_size, GrowableArray* objects, ScopeValue* &second) { second = NULL; if (value == CiValue::IllegalValue()) { return new LocationValue(Location::new_stk_loc(Location::invalid, 0)); @@ -182,6 +182,45 @@ return new ConstantLongValue(prim); } tty->print("%i", type); + } else if (value->is_a(CiVirtualObject::klass())) { + oop type = CiVirtualObject::type(value); + int id = CiVirtualObject::id(value); + ciKlass* klass = (ciKlass*) CURRENT_ENV->get_object(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(type))); + assert(klass->is_instance_klass() || klass->is_array_klass(), "Not supported allocation."); + + for (jint i = 0; i < objects->length(); i++) { + ObjectValue* obj = (ObjectValue*) objects->at(i); + if (obj->id() == id) { + return obj; + } + } + + ObjectValue* sv = new ObjectValue(id, new ConstantOopWriteValue(klass->constant_encoding())); + + arrayOop values = (arrayOop) CiVirtualObject::values(value); + for (jint i = 0; i < values->length(); i++) { + ((oop*) values->base(T_OBJECT))[i]; + } + + for (jint i = 0; i < values->length(); i++) { + ScopeValue* second = NULL; + ScopeValue* value = get_hotspot_value(((oop*) values->base(T_OBJECT))[i], frame_size, objects, second); + +// if (second != NULL) { +// sv->field_values()->append(second); +// } + sv->field_values()->append(value); + } + +// uint first_ind = spobj->first_index(); +// for (uint i = 0; i < spobj->n_fields(); i++) { +// Node* fld_node = sfn->in(first_ind+i); +// (void)FillLocArray(sv->field_values()->length(), sfn, fld_node, sv->field_values(), objs); +// } +// scval = sv; + + objects->append(sv); + return sv; } else { value->klass()->print(); value->print(); @@ -421,10 +460,10 @@ } -void CodeInstaller::record_scope(jint pc_offset, oop code_pos) { +void CodeInstaller::record_scope(jint pc_offset, oop code_pos, GrowableArray* objects) { oop caller_pos = CiCodePos::caller(code_pos); if (caller_pos != NULL) { - record_scope(pc_offset, caller_pos); + record_scope(pc_offset, caller_pos, objects); } oop frame = NULL; if (code_pos->klass()->klass_part()->name() == vmSymbols::com_sun_cri_ci_CiFrame()) { @@ -466,7 +505,7 @@ for (jint i = 0; i < values->length(); i++) { ScopeValue* second = NULL; - ScopeValue* value = get_hotspot_value(((oop*) values->base(T_OBJECT))[i], _frame_size, second); + ScopeValue* value = get_hotspot_value(((oop*) values->base(T_OBJECT))[i], _frame_size, objects, second); if (i < local_count) { if (second != NULL) { @@ -492,6 +531,9 @@ assert(((oop*) values->base(T_OBJECT))[i] == CiValue::IllegalValue(), "double-slot value not followed by CiValue.IllegalValue"); } } + + _debug_recorder->dump_object_pool(objects); + DebugToken* locals_token = _debug_recorder->create_scope_values(locals); DebugToken* expressions_token = _debug_recorder->create_scope_values(expressions); DebugToken* monitors_token = _debug_recorder->create_monitor_values(monitors); @@ -516,7 +558,7 @@ _debug_recorder->add_safepoint(pc_offset, create_oop_map(_frame_size, _parameter_count, debug_info)); oop code_pos = CiDebugInfo::codePos(debug_info); - record_scope(pc_offset, code_pos); + record_scope(pc_offset, code_pos, new GrowableArray()); _debug_recorder->end_safepoint(pc_offset); } @@ -537,7 +579,7 @@ if (debug_info != NULL) { _debug_recorder->add_safepoint(next_pc_offset, create_oop_map(_frame_size, _parameter_count, debug_info)); oop code_pos = CiDebugInfo::codePos(debug_info); - record_scope(next_pc_offset, code_pos); + record_scope(next_pc_offset, code_pos, new GrowableArray()); } if (runtime_call != NULL) { diff -r 05b8a7787aaf -r 536528f48708 src/share/vm/graal/graalCodeInstaller.hpp --- a/src/share/vm/graal/graalCodeInstaller.hpp Mon Jun 27 17:15:12 2011 +0200 +++ b/src/share/vm/graal/graalCodeInstaller.hpp Tue Jun 28 19:14:28 2011 +0200 @@ -99,7 +99,7 @@ void site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site); void site_Mark(CodeBuffer& buffer, jint pc_offset, oop site); - void record_scope(jint pc_offset, oop code_pos); + void record_scope(jint pc_offset, oop code_pos, GrowableArray* objects); void process_exception_handlers(); diff -r 05b8a7787aaf -r 536528f48708 src/share/vm/graal/graalCompiler.cpp --- a/src/share/vm/graal/graalCompiler.cpp Mon Jun 27 17:15:12 2011 +0200 +++ b/src/share/vm/graal/graalCompiler.cpp Tue Jun 28 19:14:28 2011 +0200 @@ -144,8 +144,13 @@ } oop GraalCompiler::get_RiField(ciField *field, ciInstanceKlass* accessor_klass, KlassHandle accessor, Bytecodes::Code byteCode, TRAPS) { - bool will_link = field->will_link_from_vm(accessor_klass, byteCode); - int offset = (field->holder()->is_loaded() && will_link) ? field->offset() : -1; + int offset; + if (byteCode != Bytecodes::_illegal) { + bool will_link = field->will_link_from_vm(accessor_klass, byteCode); + offset = (field->holder()->is_loaded() && will_link) ? field->offset() : -1; + } else { + offset = field->offset(); + } Handle field_name = VmIds::toString(field->name()->get_symbol(), CHECK_0); Handle field_holder = get_RiType(field->holder(), accessor, CHECK_0); Handle field_type = get_RiType(field->type(), accessor, CHECK_0); diff -r 05b8a7787aaf -r 536528f48708 src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Mon Jun 27 17:15:12 2011 +0200 +++ b/src/share/vm/graal/graalJavaAccess.hpp Tue Jun 28 19:14:28 2011 +0200 @@ -207,6 +207,11 @@ start_class(CiStackSlot) \ int_field(CiStackSlot, index) \ end_class \ + start_class(CiVirtualObject) \ + int_field(CiVirtualObject, id) \ + oop_field(CiVirtualObject, type, "Lcom/sun/cri/ri/RiType;") \ + oop_field(CiVirtualObject, values, "[Lcom/sun/cri/ci/CiValue;") \ + end_class \ start_class(RiTypeProfile) \ int_field(RiTypeProfile, count) \ int_field(RiTypeProfile, morphism) \ diff -r 05b8a7787aaf -r 536528f48708 src/share/vm/graal/graalVMEntries.cpp --- a/src/share/vm/graal/graalVMEntries.cpp Mon Jun 27 17:15:12 2011 +0200 +++ b/src/share/vm/graal/graalVMEntries.cpp Tue Jun 28 19:14:28 2011 +0200 @@ -631,6 +631,31 @@ return JNIHandles::make_local(THREAD, GraalCompiler::createHotSpotTypeResolved(array, name, THREAD)); } +// public RiField[] RiType_fields(HotSpotTypeResolved klass); +JNIEXPORT jobject JNICALL Java_com_oracle_graal_runtime_VMEntries_RiType_1fields(JNIEnv *, jobject, jobject klass) { + TRACE_graal_3("VMEntries::RiType_fields"); + KlassHandle klass_handle; + ciInstanceKlass* instance_klass; + { + VM_ENTRY_MARK; + klass_handle = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass)); + instance_klass = (ciInstanceKlass*) CURRENT_ENV->get_object(klass_handle()); + } + GrowableArray* fields = instance_klass->non_static_fields(); + + objArrayHandle fieldsArray; + { + VM_ENTRY_MARK; + fieldsArray = oopFactory::new_objArray(SystemDictionary::RiField_klass(), fields->length(), CHECK_NULL); + for (int i = 0; i < fields->length(); i++) { + ciField* field = fields->at(i); + Handle field_handle = GraalCompiler::get_RiField(field, instance_klass, klass_handle, Bytecodes::_illegal, CHECK_NULL); + fieldsArray->obj_at_put(i, field_handle()); + } + } + return JNIHandles::make_local(fieldsArray()); +} + // public RiType getPrimitiveArrayType(CiKind kind); JNIEXPORT jobject JNICALL Java_com_oracle_graal_runtime_VMEntries_getPrimitiveArrayType(JNIEnv *env, jobject, jobject kind) { TRACE_graal_3("VMEntries::VMEntries_getPrimitiveArrayType"); @@ -847,6 +872,7 @@ {CC"RiType_uniqueConcreteSubtype", CC"("RESOLVED_TYPE")"TYPE, FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiType_1uniqueConcreteSubtype)}, {CC"RiType_superType", CC"("RESOLVED_TYPE")"TYPE, FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiType_1superType)}, {CC"RiType_arrayOf", CC"("RESOLVED_TYPE")"TYPE, FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiType_1arrayOf)}, + {CC"RiType_fields", CC"("RESOLVED_TYPE")["FIELD, FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiType_1fields)}, {CC"RiType_isInitialized", CC"("RESOLVED_TYPE")Z", FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiType_1isInitialized)}, {CC"getPrimitiveArrayType", CC"("CI_KIND")"TYPE, FN_PTR(Java_com_oracle_graal_runtime_VMEntries_getPrimitiveArrayType)}, {CC"getType", CC"("CLASS")"TYPE, FN_PTR(Java_com_oracle_graal_runtime_VMEntries_getType)}, diff -r 05b8a7787aaf -r 536528f48708 src/share/vm/runtime/deoptimization.cpp --- a/src/share/vm/runtime/deoptimization.cpp Mon Jun 27 17:15:12 2011 +0200 +++ b/src/share/vm/runtime/deoptimization.cpp Tue Jun 28 19:14:28 2011 +0200 @@ -206,11 +206,11 @@ assert(vf->is_compiled_frame(), "Wrong frame type"); chunk->push(compiledVFrame::cast(vf)); -#ifdef COMPILER2 +//#ifdef COMPILER2 // Reallocate the non-escaping objects and restore their fields. Then // relock objects if synchronization on them was eliminated. - if (DoEscapeAnalysis) { - if (EliminateAllocations) { +// if (DoEscapeAnalysis) { +// if (EliminateAllocations) { assert (chunk->at(0)->scope() != NULL,"expect only compiled java frames"); GrowableArray* objects = chunk->at(0)->scope()->objects(); @@ -254,8 +254,8 @@ // Restore result. deoptee.set_saved_oop_result(&map, return_value()); } - } - if (EliminateLocks) { +// } +// if (EliminateLocks) { #ifndef PRODUCT bool first = true; #endif @@ -282,9 +282,9 @@ #endif } } - } - } -#endif // COMPILER2 +// } +// } +//#endif // COMPILER2 // Ensure that no safepoint is taken after pointers have been stored // in fields of rematerialized objects. If a safepoint occurs from here on // out the java state residing in the vframeArray will be missed. @@ -709,7 +709,7 @@ } -#ifdef COMPILER2 +//#ifdef COMPILER2 bool Deoptimization::realloc_objects(JavaThread* thread, frame* fr, GrowableArray* objects, TRAPS) { Handle pending_exception(thread->pending_exception()); const char* exception_file = thread->exception_file(); @@ -951,7 +951,7 @@ } } #endif -#endif // COMPILER2 +//#endif // COMPILER2 vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray* chunk) { diff -r 05b8a7787aaf -r 536528f48708 src/share/vm/runtime/deoptimization.hpp --- a/src/share/vm/runtime/deoptimization.hpp Mon Jun 27 17:15:12 2011 +0200 +++ b/src/share/vm/runtime/deoptimization.hpp Tue Jun 28 19:14:28 2011 +0200 @@ -109,7 +109,7 @@ // executing in a particular CodeBlob if UseBiasedLocking is enabled static void revoke_biases_of_monitors(CodeBlob* cb); -#ifdef COMPILER2 +//#ifdef COMPILER2 // Support for restoring non-escaping objects static bool realloc_objects(JavaThread* thread, frame* fr, GrowableArray* objects, TRAPS); static void reassign_type_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, typeArrayOop obj, BasicType type); @@ -117,7 +117,7 @@ static void reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray* objects); static void relock_objects(GrowableArray* monitors, JavaThread* thread); NOT_PRODUCT(static void print_objects(GrowableArray* objects);) -#endif // COMPILER2 +//#endif // COMPILER2 public: static vframeArray* create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray* chunk);