Mercurial > hg > truffle
comparison graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java @ 5129:51111665eda6
Support for recording a leaf graph id for each deoptimization point in the debug info.
author | Lukas Stadler <lukas.stadler@jku.at> |
---|---|
date | Wed, 21 Mar 2012 10:47:02 +0100 |
parents | e808627bd16f |
children | ab038e0d6b43 |
comparison
equal
deleted
inserted
replaced
5128:e2da6471a9a1 | 5129:51111665eda6 |
---|---|
247 return LabelRef.forSuccessor(currentBlock, suxIndex); | 247 return LabelRef.forSuccessor(currentBlock, suxIndex); |
248 } | 248 } |
249 | 249 |
250 public LIRDebugInfo state() { | 250 public LIRDebugInfo state() { |
251 assert lastState != null : "must have state before instruction"; | 251 assert lastState != null : "must have state before instruction"; |
252 return stateFor(lastState); | 252 return stateFor(lastState, -1); |
253 } | 253 } |
254 | 254 |
255 public LIRDebugInfo stateFor(FrameState state) { | 255 public LIRDebugInfo state(long leafGraphId) { |
256 return stateFor(state, null, null); | 256 assert lastState != null : "must have state before instruction"; |
257 } | 257 return stateFor(lastState, leafGraphId); |
258 | 258 } |
259 public LIRDebugInfo stateFor(FrameState state, List<CiStackSlot> pointerSlots, LabelRef exceptionEdge) { | 259 |
260 return debugInfoBuilder.build(state, curLocks, pointerSlots, exceptionEdge); | 260 public LIRDebugInfo stateFor(FrameState state, long leafGraphId) { |
261 return stateFor(state, null, null, leafGraphId); | |
262 } | |
263 | |
264 public LIRDebugInfo stateFor(FrameState state, List<CiStackSlot> pointerSlots, LabelRef exceptionEdge, long leafGraphId) { | |
265 return debugInfoBuilder.build(state, curLocks, pointerSlots, exceptionEdge, leafGraphId); | |
261 } | 266 } |
262 | 267 |
263 /** | 268 /** |
264 * Gets the ABI specific operand used to return a value of a given kind from a method. | 269 * Gets the ABI specific operand used to return a value of a given kind from a method. |
265 * | 270 * |
526 | 531 |
527 LIRDebugInfo stateBefore = state(); | 532 LIRDebugInfo stateBefore = state(); |
528 // The state before the monitor enter is used for null checks, so it must not contain the newly locked object. | 533 // The state before the monitor enter is used for null checks, so it must not contain the newly locked object. |
529 curLocks = new LockScope(curLocks, x.stateAfter().outerFrameState(), x, lockData); | 534 curLocks = new LockScope(curLocks, x.stateAfter().outerFrameState(), x, lockData); |
530 // The state after the monitor enter is used for deoptimization, after the monitor has blocked, so it must contain the newly locked object. | 535 // The state after the monitor enter is used for deoptimization, after the monitor has blocked, so it must contain the newly locked object. |
531 LIRDebugInfo stateAfter = stateFor(x.stateAfter()); | 536 LIRDebugInfo stateAfter = stateFor(x.stateAfter(), -1); |
532 | 537 |
533 XirSnippet snippet = xir.genMonitorEnter(site(x, x.object()), obj, lockAddress); | 538 XirSnippet snippet = xir.genMonitorEnter(site(x, x.object()), obj, lockAddress); |
534 emitXir(snippet, x, stateBefore, stateAfter, true, null, null); | 539 emitXir(snippet, x, stateBefore, stateAfter, true, null, null); |
535 } | 540 } |
536 | 541 |
743 assert x.defaultSuccessor() == x.falseSuccessor() : "wrong destination"; | 748 assert x.defaultSuccessor() == x.falseSuccessor() : "wrong destination"; |
744 emitBranch(x.compare(), getLIRBlock(x.trueSuccessor()), getLIRBlock(x.falseSuccessor()), null); | 749 emitBranch(x.compare(), getLIRBlock(x.trueSuccessor()), getLIRBlock(x.falseSuccessor()), null); |
745 } | 750 } |
746 | 751 |
747 @Override | 752 @Override |
748 public void emitGuardCheck(BooleanNode comp) { | 753 public void emitGuardCheck(BooleanNode comp, long leafGraphId) { |
749 if (comp instanceof NullCheckNode && !((NullCheckNode) comp).expectedNull) { | 754 if (comp instanceof NullCheckNode && !((NullCheckNode) comp).expectedNull) { |
750 emitNullCheckGuard((NullCheckNode) comp); | 755 emitNullCheckGuard((NullCheckNode) comp, leafGraphId); |
751 } else if (comp instanceof ConstantNode && comp.asConstant().asBoolean()) { | 756 } else if (comp instanceof ConstantNode && comp.asConstant().asBoolean()) { |
752 // True constant, nothing to emit. | 757 // True constant, nothing to emit. |
758 // False constants are handled within emitBranch. | |
753 } else { | 759 } else { |
754 // Fall back to a normal branch. | 760 // Fall back to a normal branch. |
755 LIRDebugInfo info = state(); | 761 LIRDebugInfo info = state(leafGraphId); |
756 LabelRef stubEntry = createDeoptStub(DeoptAction.InvalidateReprofile, info, comp); | 762 LabelRef stubEntry = createDeoptStub(DeoptAction.InvalidateReprofile, info, comp); |
757 emitBranch(comp, null, stubEntry, info); | 763 emitBranch(comp, null, stubEntry, info); |
758 } | 764 } |
759 } | 765 } |
760 | 766 |
761 protected abstract void emitNullCheckGuard(NullCheckNode node); | 767 protected abstract void emitNullCheckGuard(NullCheckNode node, long leafGraphId); |
762 | 768 |
763 public void emitBranch(BooleanNode node, LabelRef trueSuccessor, LabelRef falseSuccessor, LIRDebugInfo info) { | 769 public void emitBranch(BooleanNode node, LabelRef trueSuccessor, LabelRef falseSuccessor, LIRDebugInfo info) { |
764 if (node instanceof NullCheckNode) { | 770 if (node instanceof NullCheckNode) { |
765 emitNullCheckBranch((NullCheckNode) node, trueSuccessor, falseSuccessor, info); | 771 emitNullCheckBranch((NullCheckNode) node, trueSuccessor, falseSuccessor, info); |
766 } else if (node instanceof CompareNode) { | 772 } else if (node instanceof CompareNode) { |
924 | 930 |
925 CiValue destinationAddress = null; | 931 CiValue destinationAddress = null; |
926 if (!target().invokeSnippetAfterArguments) { | 932 if (!target().invokeSnippetAfterArguments) { |
927 // This is the version currently necessary for Maxine: since the invokeinterface-snippet uses a division, it | 933 // This is the version currently necessary for Maxine: since the invokeinterface-snippet uses a division, it |
928 // destroys rdx, which is also used to pass a parameter. Therefore, the snippet must be before the parameters are assigned to their locations. | 934 // destroys rdx, which is also used to pass a parameter. Therefore, the snippet must be before the parameters are assigned to their locations. |
929 LIRDebugInfo addrInfo = stateFor(stateBeforeCallWithArguments(x.stateAfter(), callTarget, x.bci())); | 935 LIRDebugInfo addrInfo = stateFor(stateBeforeCallWithArguments(x.stateAfter(), callTarget, x.bci()), x.leafGraphId()); |
930 destinationAddress = emitXir(snippet, x.node(), addrInfo, false); | 936 destinationAddress = emitXir(snippet, x.node(), addrInfo, false); |
931 } | 937 } |
932 | 938 |
933 CiValue resultOperand = resultOperandFor(x.node().kind()); | 939 CiValue resultOperand = resultOperandFor(x.node().kind()); |
934 | 940 |
937 frameMap.callsMethod(cc, JavaCall); | 943 frameMap.callsMethod(cc, JavaCall); |
938 List<CiValue> argList = visitInvokeArguments(cc, callTarget.arguments()); | 944 List<CiValue> argList = visitInvokeArguments(cc, callTarget.arguments()); |
939 | 945 |
940 if (target().invokeSnippetAfterArguments) { | 946 if (target().invokeSnippetAfterArguments) { |
941 // This is the version currently active for HotSpot. | 947 // This is the version currently active for HotSpot. |
942 LIRDebugInfo addrInfo = stateFor(stateBeforeCallWithArguments(x.stateAfter(), callTarget, x.bci()), null, null); | 948 LIRDebugInfo addrInfo = stateFor(stateBeforeCallWithArguments(x.stateAfter(), callTarget, x.bci()), null, null, x.leafGraphId()); |
943 destinationAddress = emitXir(snippet, x.node(), addrInfo, false); | 949 destinationAddress = emitXir(snippet, x.node(), addrInfo, false); |
944 } | 950 } |
945 | 951 |
946 LIRDebugInfo callInfo = stateFor(x.stateDuring(), null, x instanceof InvokeWithExceptionNode ? getLIRBlock(((InvokeWithExceptionNode) x).exceptionEdge()) : null); | 952 LIRDebugInfo callInfo = stateFor(x.stateDuring(), null, x instanceof InvokeWithExceptionNode ? getLIRBlock(((InvokeWithExceptionNode) x).exceptionEdge()) : null, x.leafGraphId()); |
947 emitCall(targetMethod, resultOperand, argList, destinationAddress, callInfo, snippet.marks); | 953 emitCall(targetMethod, resultOperand, argList, destinationAddress, callInfo, snippet.marks); |
948 | 954 |
949 if (isLegal(resultOperand)) { | 955 if (isLegal(resultOperand)) { |
950 setResult(x.node(), emitMove(resultOperand)); | 956 setResult(x.node(), emitMove(resultOperand)); |
951 } | 957 } |
982 throw GraalInternalError.shouldNotReachHere("I thought we no longer have null entries for two-slot types..."); | 988 throw GraalInternalError.shouldNotReachHere("I thought we no longer have null entries for two-slot types..."); |
983 } | 989 } |
984 } | 990 } |
985 return argList; | 991 return argList; |
986 } | 992 } |
987 | |
988 | 993 |
989 protected abstract LabelRef createDeoptStub(DeoptAction action, LIRDebugInfo info, Object deoptInfo); | 994 protected abstract LabelRef createDeoptStub(DeoptAction action, LIRDebugInfo info, Object deoptInfo); |
990 | 995 |
991 @Override | 996 @Override |
992 public Variable emitCallToRuntime(CiRuntimeCall runtimeCall, boolean canTrap, CiValue... args) { | 997 public Variable emitCallToRuntime(CiRuntimeCall runtimeCall, boolean canTrap, CiValue... args) { |
1044 | 1049 |
1045 stateBeforeReturn = stateAfter.duplicateModified(stateAfter.bci, stateAfter.rethrowException(), x.kind()); | 1050 stateBeforeReturn = stateAfter.duplicateModified(stateAfter.bci, stateAfter.rethrowException(), x.kind()); |
1046 } | 1051 } |
1047 | 1052 |
1048 // TODO is it correct here that the pointerSlots are not passed to the oop map generation? | 1053 // TODO is it correct here that the pointerSlots are not passed to the oop map generation? |
1049 info = stateFor(stateBeforeReturn); | 1054 info = stateFor(stateBeforeReturn, -1); |
1050 } | 1055 } |
1051 | 1056 |
1052 emitCall(x.call(), resultOperand, argList, CiConstant.forLong(0), info, null); | 1057 emitCall(x.call(), resultOperand, argList, CiConstant.forLong(0), info, null); |
1053 | 1058 |
1054 if (isLegal(resultOperand)) { | 1059 if (isLegal(resultOperand)) { |