Mercurial > hg > graal-compiler
comparison graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java @ 2607:008adfd6d850
Fixed the stateBefore of invokes and monitorenter instructions to include the arguments of the instruction.
This is necessary to ensure correct continuation in the interpreter when the stateBefore is used as a deoptimization point.
author | Thomas Wuerthinger <thomas@wuerthinger.net> |
---|---|
date | Fri, 06 May 2011 17:47:17 +0200 |
parents | 01c5c0443158 |
children | 2523de4d378e |
comparison
equal
deleted
inserted
replaced
2606:f21f430a6ef2 | 2607:008adfd6d850 |
---|---|
785 // the result of resolution is not used by the invocation (only the side effect | 785 // the result of resolution is not used by the invocation (only the side effect |
786 // of initialization is required), it can be commoned with static field accesses. | 786 // of initialization is required), it can be commoned with static field accesses. |
787 genResolveClass(RiType.Representation.StaticFields, holder, isInitialized, cpi); | 787 genResolveClass(RiType.Representation.StaticFields, holder, isInitialized, cpi); |
788 } | 788 } |
789 | 789 |
790 FrameState stateBefore = curState.immutableCopy(bci()); | |
790 Value[] args = curState.popArguments(target.signature().argumentSlots(false)); | 791 Value[] args = curState.popArguments(target.signature().argumentSlots(false)); |
791 appendInvoke(INVOKESTATIC, target, args, cpi, constantPool); | 792 appendInvoke(INVOKESTATIC, target, args, cpi, constantPool, stateBefore); |
792 } | 793 } |
793 | 794 |
794 void genInvokeInterface(RiMethod target, int cpi, RiConstantPool constantPool) { | 795 void genInvokeInterface(RiMethod target, int cpi, RiConstantPool constantPool) { |
796 FrameState stateBefore = curState.immutableCopy(bci()); | |
795 Value[] args = curState.popArguments(target.signature().argumentSlots(true)); | 797 Value[] args = curState.popArguments(target.signature().argumentSlots(true)); |
796 | 798 genInvokeIndirect(INVOKEINTERFACE, target, args, cpi, constantPool, stateBefore); |
797 genInvokeIndirect(INVOKEINTERFACE, target, args, cpi, constantPool); | |
798 | 799 |
799 } | 800 } |
800 | 801 |
801 void genInvokeVirtual(RiMethod target, int cpi, RiConstantPool constantPool) { | 802 void genInvokeVirtual(RiMethod target, int cpi, RiConstantPool constantPool) { |
803 FrameState stateBefore = curState.immutableCopy(bci()); | |
802 Value[] args = curState.popArguments(target.signature().argumentSlots(true)); | 804 Value[] args = curState.popArguments(target.signature().argumentSlots(true)); |
803 genInvokeIndirect(INVOKEVIRTUAL, target, args, cpi, constantPool); | 805 genInvokeIndirect(INVOKEVIRTUAL, target, args, cpi, constantPool, stateBefore); |
804 | 806 |
805 } | 807 } |
806 | 808 |
807 void genInvokeSpecial(RiMethod target, RiType knownHolder, int cpi, RiConstantPool constantPool) { | 809 void genInvokeSpecial(RiMethod target, RiType knownHolder, int cpi, RiConstantPool constantPool) { |
810 FrameState stateBefore = curState.immutableCopy(bci()); | |
808 Value[] args = curState.popArguments(target.signature().argumentSlots(true)); | 811 Value[] args = curState.popArguments(target.signature().argumentSlots(true)); |
809 invokeDirect(target, args, knownHolder, cpi, constantPool); | 812 invokeDirect(target, args, knownHolder, cpi, constantPool, stateBefore); |
810 | 813 |
811 } | 814 } |
812 | 815 |
813 /** | 816 /** |
814 * Temporary work-around to support the @ACCESSOR Maxine annotation. | 817 * Temporary work-around to support the @ACCESSOR Maxine annotation. |
840 target = newTarget; | 843 target = newTarget; |
841 } | 844 } |
842 return target; | 845 return target; |
843 } | 846 } |
844 | 847 |
845 private void genInvokeIndirect(int opcode, RiMethod target, Value[] args, int cpi, RiConstantPool constantPool) { | 848 private void genInvokeIndirect(int opcode, RiMethod target, Value[] args, int cpi, RiConstantPool constantPool, FrameState stateBefore) { |
846 Value receiver = args[0]; | 849 Value receiver = args[0]; |
847 // attempt to devirtualize the call | 850 // attempt to devirtualize the call |
848 if (target.isResolved()) { | 851 if (target.isResolved()) { |
849 RiType klass = target.holder(); | 852 RiType klass = target.holder(); |
850 | 853 |
851 // 0. check for trivial cases | 854 // 0. check for trivial cases |
852 if (target.canBeStaticallyBound() && !isAbstract(target.accessFlags())) { | 855 if (target.canBeStaticallyBound() && !isAbstract(target.accessFlags())) { |
853 // check for trivial cases (e.g. final methods, nonvirtual methods) | 856 // check for trivial cases (e.g. final methods, nonvirtual methods) |
854 invokeDirect(target, args, target.holder(), cpi, constantPool); | 857 invokeDirect(target, args, target.holder(), cpi, constantPool, stateBefore); |
855 return; | 858 return; |
856 } | 859 } |
857 // 1. check if the exact type of the receiver can be determined | 860 // 1. check if the exact type of the receiver can be determined |
858 RiType exact = getExactType(klass, receiver); | 861 RiType exact = getExactType(klass, receiver); |
859 if (exact != null && exact.isResolved()) { | 862 if (exact != null && exact.isResolved()) { |
860 // either the holder class is exact, or the receiver object has an exact type | 863 // either the holder class is exact, or the receiver object has an exact type |
861 invokeDirect(exact.resolveMethodImpl(target), args, exact, cpi, constantPool); | 864 invokeDirect(exact.resolveMethodImpl(target), args, exact, cpi, constantPool, stateBefore); |
862 return; | 865 return; |
863 } | 866 } |
864 // 2. check if an assumed leaf method can be found | 867 // 2. check if an assumed leaf method can be found |
865 RiMethod leaf = getAssumedLeafMethod(target, receiver); | 868 RiMethod leaf = getAssumedLeafMethod(target, receiver); |
866 if (leaf != null && leaf.isResolved() && !isAbstract(leaf.accessFlags()) && leaf.holder().isResolved()) { | 869 if (leaf != null && leaf.isResolved() && !isAbstract(leaf.accessFlags()) && leaf.holder().isResolved()) { |
867 if (C1XOptions.PrintAssumptions) { | 870 if (C1XOptions.PrintAssumptions) { |
868 TTY.println("Optimistic invoke direct because of leaf method to " + leaf); | 871 TTY.println("Optimistic invoke direct because of leaf method to " + leaf); |
869 } | 872 } |
870 invokeDirect(leaf, args, null, cpi, constantPool); | 873 invokeDirect(leaf, args, null, cpi, constantPool, stateBefore); |
871 return; | 874 return; |
872 } else if (C1XOptions.PrintAssumptions) { | 875 } else if (C1XOptions.PrintAssumptions) { |
873 TTY.println("Could not make leaf method assumption for target=" + target + " leaf=" + leaf + " receiver.declaredType=" + receiver.declaredType()); | 876 TTY.println("Could not make leaf method assumption for target=" + target + " leaf=" + leaf + " receiver.declaredType=" + receiver.declaredType()); |
874 } | 877 } |
875 // 3. check if the either of the holder or declared type of receiver can be assumed to be a leaf | 878 // 3. check if the either of the holder or declared type of receiver can be assumed to be a leaf |
878 RiMethod targetMethod = exact.resolveMethodImpl(target); | 881 RiMethod targetMethod = exact.resolveMethodImpl(target); |
879 if (C1XOptions.PrintAssumptions) { | 882 if (C1XOptions.PrintAssumptions) { |
880 TTY.println("Optimistic invoke direct because of leaf type to " + targetMethod); | 883 TTY.println("Optimistic invoke direct because of leaf type to " + targetMethod); |
881 } | 884 } |
882 // either the holder class is exact, or the receiver object has an exact type | 885 // either the holder class is exact, or the receiver object has an exact type |
883 invokeDirect(targetMethod, args, exact, cpi, constantPool); | 886 invokeDirect(targetMethod, args, exact, cpi, constantPool, stateBefore); |
884 return; | 887 return; |
885 } else if (C1XOptions.PrintAssumptions) { | 888 } else if (C1XOptions.PrintAssumptions) { |
886 TTY.println("Could not make leaf type assumption for type " + klass); | 889 TTY.println("Could not make leaf type assumption for type " + klass); |
887 } | 890 } |
888 } | 891 } |
889 // devirtualization failed, produce an actual invokevirtual | 892 // devirtualization failed, produce an actual invokevirtual |
890 appendInvoke(opcode, target, args, cpi, constantPool); | 893 appendInvoke(opcode, target, args, cpi, constantPool, stateBefore); |
891 } | 894 } |
892 | 895 |
893 private CiKind returnKind(RiMethod target) { | 896 private CiKind returnKind(RiMethod target) { |
894 return target.signature().returnKind(); | 897 return target.signature().returnKind(); |
895 } | 898 } |
896 | 899 |
897 private void invokeDirect(RiMethod target, Value[] args, RiType knownHolder, int cpi, RiConstantPool constantPool) { | 900 private void invokeDirect(RiMethod target, Value[] args, RiType knownHolder, int cpi, RiConstantPool constantPool, FrameState stateBefore) { |
898 appendInvoke(INVOKESPECIAL, target, args, cpi, constantPool); | 901 appendInvoke(INVOKESPECIAL, target, args, cpi, constantPool, stateBefore); |
899 } | 902 } |
900 | 903 |
901 private void appendInvoke(int opcode, RiMethod target, Value[] args, int cpi, RiConstantPool constantPool) { | 904 private void appendInvoke(int opcode, RiMethod target, Value[] args, int cpi, RiConstantPool constantPool, FrameState stateBefore) { |
902 CiKind resultType = returnKind(target); | 905 CiKind resultType = returnKind(target); |
903 Value result = append(new Invoke(opcode, resultType.stackKind(), args, target, target.signature().returnType(compilation.method.holder()), null, graph)); | 906 Value result = append(new Invoke(opcode, resultType.stackKind(), args, target, target.signature().returnType(compilation.method.holder()), stateBefore, graph)); |
904 pushReturn(resultType, result); | 907 pushReturn(resultType, result); |
905 } | 908 } |
906 | 909 |
907 private RiType getExactType(RiType staticType, Value receiver) { | 910 private RiType getExactType(RiType staticType, Value receiver) { |
908 RiType exact = staticType.exactType(); | 911 RiType exact = staticType.exactType(); |
1038 MonitorAddress lockAddress = null; | 1041 MonitorAddress lockAddress = null; |
1039 if (compilation.runtime.sizeOfBasicObjectLock() != 0) { | 1042 if (compilation.runtime.sizeOfBasicObjectLock() != 0) { |
1040 lockAddress = new MonitorAddress(lockNumber, graph); | 1043 lockAddress = new MonitorAddress(lockNumber, graph); |
1041 append(lockAddress); | 1044 append(lockAddress); |
1042 } | 1045 } |
1043 MonitorEnter monitorEnter = new MonitorEnter(x, lockAddress, lockNumber, null, graph); | 1046 curState.push(CiKind.Object, x); |
1047 MonitorEnter monitorEnter = new MonitorEnter(x, lockAddress, lockNumber, curState.immutableCopy(bci()), graph); | |
1048 curState.apop(); | |
1044 appendWithoutOptimization(monitorEnter, bci); | 1049 appendWithoutOptimization(monitorEnter, bci); |
1045 curState.lock(ir, x, lockNumber + 1); | 1050 curState.lock(ir, x, lockNumber + 1); |
1046 monitorEnter.setStateAfter(curState.immutableCopy(bci)); | 1051 monitorEnter.setStateAfter(curState.immutableCopy(bci)); |
1047 killMemoryMap(); // prevent any optimizations across synchronization | 1052 killMemoryMap(); // prevent any optimizations across synchronization |
1048 } | 1053 } |