review for 7055355: JSR 292: crash while throwing WrongMethodTypeException

Tom Rodriguez tom.rodriguez at oracle.com
Thu Jun 16 10:29:59 PDT 2011


> 
> The SPARC logic is broken, I get asserts with John's ThrowExceptionsTest.  The problem is that SPARC's throw exception stub uses a save_frame and O1/O2 then contain some arbitrary values hitting the assert in SharedRuntime::throw_WrongMethodTypeException.  I fixed it using the same logic you added for x86.  I also removed the NULL-checking code I mentioned above.

That's odd.  I was rerunning the JCK tests using jtjck.jar but for some reason it's actually not running the test I was really interested in.  I reran using the runthese setup for it and it showed the problem you saw.  I've adopted your fix (which I had at one point until I decided to make it like normal argument setup) and retested and it looks good.  Thanks for catching this.

tom

> 
> With the patch below applied we hit the unreasonable-stack-move assert at some point:
> 
> #  assert(false) failed: DEBUG MESSAGE: damaged ricochet frame: (L4 - UNREASONABLE_STACK_MOVE) > FP
> 
> -- Christian
> 
> 
> diff -r cfcf2ba8f3eb src/cpu/sparc/vm/methodHandles_sparc.cpp
> --- a/src/cpu/sparc/vm/methodHandles_sparc.cpp
> +++ b/src/cpu/sparc/vm/methodHandles_sparc.cpp
> @@ -546,9 +546,9 @@ address MethodHandles::generate_method_h
>   __ cmp(O1_scratch, (int) vmIntrinsics::_invokeExact);
>   __ brx(Assembler::notEqual, false, Assembler::pt, invoke_generic_slow_path);
>   __ delayed()->nop();
> -  __ mov(O0_mtype, G5_method_type);  // required by throw_WrongMethodType
> +  __ mov(O0_mtype, G5_method_type);            // required by throw_WrongMethodType
>   // mov(G3_method_handle, G3_method_handle);  // already in this register
> -  __ jump_to(AddressLiteral(Interpreter::throw_WrongMethodType_entry()), O1_scratch);
> +  __ jump_to(AddressLiteral(StubRoutines::throw_WrongMethodTypeException_entry()), O1_scratch);
>   __ delayed()->nop();
> 
>   // here's where control starts out:
> @@ -1142,26 +1142,14 @@ void MethodHandles::generate_method_hand
>       __ mov(O5_savedSP, SP);  // Cut the stack back to where the caller started.
> 
>       Label L_no_method;
> -      // FIXME: fill in _raise_exception_method with a suitable java.lang.invoke method
>       __ set(AddressLiteral((address) &_raise_exception_method), G5_method);
>       __ ld_ptr(Address(G5_method, 0), G5_method);
> -      __ tst(G5_method);
> -      __ brx(Assembler::zero, false, Assembler::pn, L_no_method);
> -      __ delayed()->nop();
> 
>       const int jobject_oop_offset = 0;
> -      __ ld_ptr(Address(G5_method, jobject_oop_offset), G5_method);
> -      __ tst(G5_method);
> -      __ brx(Assembler::zero, false, Assembler::pn, L_no_method);
> -      __ delayed()->nop();
> -
> +      __ ld_ptr(Address(G5_method, jobject_oop_offset), G5_method);  // dereference the jobject
>       __ verify_oop(G5_method);
>       __ jump_indirect_to(G5_method_fce, O3_scratch);  // jump to compiled entry
>       __ delayed()->nop();
> -
> -      // Do something that is at least causes a valid throw from the interpreter.
> -      __ bind(L_no_method);
> -      __ unimplemented("call throw_WrongMethodType_entry");
>     }
>     break;
> 
> diff -r cfcf2ba8f3eb src/cpu/sparc/vm/stubGenerator_sparc.cpp
> --- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp
> +++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp
> @@ -440,7 +440,8 @@ class StubGenerator: public StubCodeGene
> #undef __
> #define __ masm->
> 
> -  address generate_throw_exception(const char* name, address runtime_entry, bool restore_saved_exception_pc) {
> +  address generate_throw_exception(const char* name, address runtime_entry,
> +                                   bool restore_saved_exception_pc, Register arg1 = noreg, Register arg2 = noreg) {
> #ifdef ASSERT
>     int insts_size = VerifyThread ? 1 * K : 600;
> #else
> @@ -477,6 +478,13 @@ class StubGenerator: public StubCodeGene
>     if (VerifyThread)  __ mov(G2_thread, O0); // about to be smashed; pass early
>     __ save_thread(noreg);
>     // do the call
> +    if (arg1 != noreg) {
> +      assert(arg2 != O1, "clobbered");
> +      __ mov(arg1, O1);
> +    }
> +    if (arg2 != noreg) {
> +      __ mov(arg2, O2);
> +    }
>     BLOCK_COMMENT("call runtime_entry");
>     __ call(runtime_entry, relocInfo::runtime_call_type);
>     if (!VerifyThread)
> @@ -3240,6 +3248,14 @@ class StubGenerator: public StubCodeGene
>     StubRoutines::_atomic_cmpxchg_long_entry = generate_atomic_cmpxchg_long();
>     StubRoutines::_atomic_add_ptr_entry      = StubRoutines::_atomic_add_entry;
> #endif  // COMPILER2 !=> _LP64
> +
> +    // Build this early so it's available for the interpreter.  The
> +    // stub expects the required and actual type to already be in O1
> +    // and O2 respectively.
> +    StubRoutines::_throw_WrongMethodTypeException_entry =
> +      generate_throw_exception("WrongMethodTypeException throw_exception",
> +                               CAST_FROM_FN_PTR(address, SharedRuntime::throw_WrongMethodTypeException),
> +                               false, G5_method_type, G3_method_handle);
>   }
> 
> 
> 



More information about the hotspot-compiler-dev mailing list