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)) {