# HG changeset patch # User Thomas Wuerthinger # Date 1304696837 -7200 # Node ID 008adfd6d850a5e3ba0e8f83f208c086b1f58eb0 # Parent f21f430a6ef25b5aefe24eb8ba031abf66036be7 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. diff -r f21f430a6ef2 -r 008adfd6d850 graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java --- a/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java Fri May 06 16:21:10 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java Fri May 06 17:47:17 2011 +0200 @@ -787,26 +787,29 @@ genResolveClass(RiType.Representation.StaticFields, holder, isInitialized, cpi); } + FrameState stateBefore = curState.immutableCopy(bci()); Value[] args = curState.popArguments(target.signature().argumentSlots(false)); - appendInvoke(INVOKESTATIC, target, args, cpi, constantPool); + appendInvoke(INVOKESTATIC, target, args, cpi, constantPool, stateBefore); } void genInvokeInterface(RiMethod target, int cpi, RiConstantPool constantPool) { + FrameState stateBefore = curState.immutableCopy(bci()); Value[] args = curState.popArguments(target.signature().argumentSlots(true)); - - genInvokeIndirect(INVOKEINTERFACE, target, args, cpi, constantPool); + genInvokeIndirect(INVOKEINTERFACE, target, args, cpi, constantPool, stateBefore); } void genInvokeVirtual(RiMethod target, int cpi, RiConstantPool constantPool) { + FrameState stateBefore = curState.immutableCopy(bci()); Value[] args = curState.popArguments(target.signature().argumentSlots(true)); - genInvokeIndirect(INVOKEVIRTUAL, target, args, cpi, constantPool); + genInvokeIndirect(INVOKEVIRTUAL, target, args, cpi, constantPool, stateBefore); } void genInvokeSpecial(RiMethod target, RiType knownHolder, int cpi, RiConstantPool constantPool) { + FrameState stateBefore = curState.immutableCopy(bci()); Value[] args = curState.popArguments(target.signature().argumentSlots(true)); - invokeDirect(target, args, knownHolder, cpi, constantPool); + invokeDirect(target, args, knownHolder, cpi, constantPool, stateBefore); } @@ -842,7 +845,7 @@ return target; } - private void genInvokeIndirect(int opcode, RiMethod target, Value[] args, int cpi, RiConstantPool constantPool) { + private void genInvokeIndirect(int opcode, RiMethod target, Value[] args, int cpi, RiConstantPool constantPool, FrameState stateBefore) { Value receiver = args[0]; // attempt to devirtualize the call if (target.isResolved()) { @@ -851,14 +854,14 @@ // 0. check for trivial cases if (target.canBeStaticallyBound() && !isAbstract(target.accessFlags())) { // check for trivial cases (e.g. final methods, nonvirtual methods) - invokeDirect(target, args, target.holder(), cpi, constantPool); + invokeDirect(target, args, target.holder(), cpi, constantPool, stateBefore); return; } // 1. check if the exact type of the receiver can be determined RiType exact = getExactType(klass, receiver); if (exact != null && exact.isResolved()) { // either the holder class is exact, or the receiver object has an exact type - invokeDirect(exact.resolveMethodImpl(target), args, exact, cpi, constantPool); + invokeDirect(exact.resolveMethodImpl(target), args, exact, cpi, constantPool, stateBefore); return; } // 2. check if an assumed leaf method can be found @@ -867,7 +870,7 @@ if (C1XOptions.PrintAssumptions) { TTY.println("Optimistic invoke direct because of leaf method to " + leaf); } - invokeDirect(leaf, args, null, cpi, constantPool); + invokeDirect(leaf, args, null, cpi, constantPool, stateBefore); return; } else if (C1XOptions.PrintAssumptions) { TTY.println("Could not make leaf method assumption for target=" + target + " leaf=" + leaf + " receiver.declaredType=" + receiver.declaredType()); @@ -880,27 +883,27 @@ TTY.println("Optimistic invoke direct because of leaf type to " + targetMethod); } // either the holder class is exact, or the receiver object has an exact type - invokeDirect(targetMethod, args, exact, cpi, constantPool); + invokeDirect(targetMethod, args, exact, cpi, constantPool, stateBefore); return; } else if (C1XOptions.PrintAssumptions) { TTY.println("Could not make leaf type assumption for type " + klass); } } // devirtualization failed, produce an actual invokevirtual - appendInvoke(opcode, target, args, cpi, constantPool); + appendInvoke(opcode, target, args, cpi, constantPool, stateBefore); } private CiKind returnKind(RiMethod target) { return target.signature().returnKind(); } - private void invokeDirect(RiMethod target, Value[] args, RiType knownHolder, int cpi, RiConstantPool constantPool) { - appendInvoke(INVOKESPECIAL, target, args, cpi, constantPool); + private void invokeDirect(RiMethod target, Value[] args, RiType knownHolder, int cpi, RiConstantPool constantPool, FrameState stateBefore) { + appendInvoke(INVOKESPECIAL, target, args, cpi, constantPool, stateBefore); } - private void appendInvoke(int opcode, RiMethod target, Value[] args, int cpi, RiConstantPool constantPool) { + private void appendInvoke(int opcode, RiMethod target, Value[] args, int cpi, RiConstantPool constantPool, FrameState stateBefore) { CiKind resultType = returnKind(target); - Value result = append(new Invoke(opcode, resultType.stackKind(), args, target, target.signature().returnType(compilation.method.holder()), null, graph)); + Value result = append(new Invoke(opcode, resultType.stackKind(), args, target, target.signature().returnType(compilation.method.holder()), stateBefore, graph)); pushReturn(resultType, result); } @@ -1040,7 +1043,9 @@ lockAddress = new MonitorAddress(lockNumber, graph); append(lockAddress); } - MonitorEnter monitorEnter = new MonitorEnter(x, lockAddress, lockNumber, null, graph); + curState.push(CiKind.Object, x); + MonitorEnter monitorEnter = new MonitorEnter(x, lockAddress, lockNumber, curState.immutableCopy(bci()), graph); + curState.apop(); appendWithoutOptimization(monitorEnter, bci); curState.lock(ir, x, lockNumber + 1); monitorEnter.setStateAfter(curState.immutableCopy(bci)); diff -r f21f430a6ef2 -r 008adfd6d850 src/cpu/x86/vm/c1_Runtime1_x86.cpp --- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp Fri May 06 16:21:10 2011 +0200 +++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp Fri May 06 17:47:17 2011 +0200 @@ -1924,21 +1924,6 @@ break; } - case c1x_global_implicit_null_id: { - __ push(rax); - __ push(rax); - // move saved fp to make space for the inserted return address - __ get_thread(rax); - __ movptr(rax, Address(rax, JavaThread::saved_exception_pc_offset())); - __ movptr(Address(rsp, HeapWordSize), rax); - __ pop(rax); - - { StubFrame f(sasm, "c1x_global_implicit_null_id", dont_gc_arguments); - oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_null_pointer_exception), false); - } - break; - } - case c1x_throw_div0_exception_id: { __ push(rax); __ push(rax); diff -r f21f430a6ef2 -r 008adfd6d850 src/share/vm/c1/c1_Runtime1.cpp --- a/src/share/vm/c1/c1_Runtime1.cpp Fri May 06 16:21:10 2011 +0200 +++ b/src/share/vm/c1/c1_Runtime1.cpp Fri May 06 17:47:17 2011 +0200 @@ -216,6 +216,7 @@ // All other stubs should have oopmaps default: + tty->print_cr("No oopmap found for %d", id); assert(oop_maps != NULL, "must have an oopmap"); } #endif diff -r f21f430a6ef2 -r 008adfd6d850 src/share/vm/c1/c1_Runtime1.hpp --- a/src/share/vm/c1/c1_Runtime1.hpp Fri May 06 16:21:10 2011 +0200 +++ b/src/share/vm/c1/c1_Runtime1.hpp Fri May 06 17:47:17 2011 +0200 @@ -72,7 +72,6 @@ stub(counter_overflow) \ stub(c1x_unwind_exception_call) \ stub(c1x_handle_exception) \ - stub(c1x_global_implicit_null) \ stub(c1x_throw_div0_exception) \ stub(c1x_slow_subtype_check) \ stub(c1x_arithmetic_frem) \ diff -r f21f430a6ef2 -r 008adfd6d850 src/share/vm/runtime/globals.hpp --- a/src/share/vm/runtime/globals.hpp Fri May 06 16:21:10 2011 +0200 +++ b/src/share/vm/runtime/globals.hpp Fri May 06 17:47:17 2011 +0200 @@ -2878,7 +2878,7 @@ "Prefetch instruction to prefetch ahead") \ \ /* deoptimization */ \ - develop(bool, TraceDeoptimization, false, \ + product(bool, TraceDeoptimization, false, \ "Trace deoptimization") \ \ develop(bool, DebugDeoptimization, false, \ diff -r f21f430a6ef2 -r 008adfd6d850 src/share/vm/runtime/sharedRuntime.cpp --- a/src/share/vm/runtime/sharedRuntime.cpp Fri May 06 16:21:10 2011 +0200 +++ b/src/share/vm/runtime/sharedRuntime.cpp Fri May 06 17:47:17 2011 +0200 @@ -692,6 +692,15 @@ throw_and_post_jvmti_exception(thread, exception); JRT_END +address SharedRuntime::deoptimization_continuation(JavaThread* thread, address pc, nmethod* nm) +{ + if (TraceSignals) { + tty->print_cr(err_msg("Deoptimizing on implicit exception at relative pc=%d in method %s", pc - nm->entry_point(), nm->method()->name()->as_C_string())); + } + thread->_ScratchA = (intptr_t)pc; + return (SharedRuntime::deopt_blob()->jmp_uncommon_trap()); +} + address SharedRuntime::continuation_for_implicit_exception(JavaThread* thread, address pc, SharedRuntime::ImplicitExceptionKind exception_kind) @@ -777,11 +786,7 @@ _implicit_null_throws++; #endif if (UseC1X) { - if (TraceSignals) { - tty->print_cr(err_msg("calling implicit call stub relative pc=%d method name = %s", pc - nm->entry_point(), nm->method()->name()->as_C_string())); - } - thread->_ScratchA = (intptr_t)pc; - target_pc = (SharedRuntime::deopt_blob()->jmp_uncommon_trap());//Runtime1::entry_for(Runtime1::c1x_global_implicit_null_id); + target_pc = deoptimization_continuation(thread, pc, nm); } else { target_pc = nm->continuation_for_implicit_exception(pc); } diff -r f21f430a6ef2 -r 008adfd6d850 src/share/vm/runtime/sharedRuntime.hpp --- a/src/share/vm/runtime/sharedRuntime.hpp Fri May 06 16:21:10 2011 +0200 +++ b/src/share/vm/runtime/sharedRuntime.hpp Fri May 06 17:47:17 2011 +0200 @@ -178,6 +178,7 @@ static void throw_NullPointerException(JavaThread* thread); static void throw_NullPointerException_at_call(JavaThread* thread); static void throw_StackOverflowError(JavaThread* thread); + static address deoptimization_continuation(JavaThread* thread, address pc, nmethod* nm); static address continuation_for_implicit_exception(JavaThread* thread, address faulting_pc, ImplicitExceptionKind exception_kind); diff -r f21f430a6ef2 -r 008adfd6d850 src/share/vm/runtime/vframeArray.cpp --- a/src/share/vm/runtime/vframeArray.cpp Fri May 06 16:21:10 2011 +0200 +++ b/src/share/vm/runtime/vframeArray.cpp Fri May 06 17:47:17 2011 +0200 @@ -304,6 +304,10 @@ iframe()->interpreter_frame_set_mdp(mdp); } } + + if (TraceDeoptimization) { + tty->print_cr("Expressions size: %d", expressions()->size()); + } // Unpack expression stack // If this is an intermediate frame (i.e. not top frame) then this