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 }