7047697: MethodHandle.invokeExact call for wrong method causes VM failure if run with -Xcomp

Wed, 08 Jun 2011 17:04:06 -0700

author
jrose
date
Wed, 08 Jun 2011 17:04:06 -0700
changeset 2952
5cf771a79037
parent 2951
642c68c75db9
child 2953
c8f2186acf6d
child 2954
f8c9417e3571

7047697: MethodHandle.invokeExact call for wrong method causes VM failure if run with -Xcomp
Reviewed-by: never, twisti

src/cpu/x86/vm/assembler_x86.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/assembler_x86.hpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/frame_x86.inline.hpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/methodHandles_x86.cpp file | annotate | diff | comparison | revisions
src/share/vm/code/pcDesc.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/cpu/x86/vm/assembler_x86.cpp	Sat Jun 04 10:36:22 2011 -0700
     1.2 +++ b/src/cpu/x86/vm/assembler_x86.cpp	Wed Jun 08 17:04:06 2011 -0700
     1.3 @@ -5891,6 +5891,53 @@
     1.4    call_VM(oop_result, last_java_sp, entry_point, 3, check_exceptions);
     1.5  }
     1.6  
     1.7 +void MacroAssembler::super_call_VM(Register oop_result,
     1.8 +                                   Register last_java_sp,
     1.9 +                                   address entry_point,
    1.10 +                                   int number_of_arguments,
    1.11 +                                   bool check_exceptions) {
    1.12 +  Register thread = LP64_ONLY(r15_thread) NOT_LP64(noreg);
    1.13 +  MacroAssembler::call_VM_base(oop_result, thread, last_java_sp, entry_point, number_of_arguments, check_exceptions);
    1.14 +}
    1.15 +
    1.16 +void MacroAssembler::super_call_VM(Register oop_result,
    1.17 +                                   Register last_java_sp,
    1.18 +                                   address entry_point,
    1.19 +                                   Register arg_1,
    1.20 +                                   bool check_exceptions) {
    1.21 +  pass_arg1(this, arg_1);
    1.22 +  super_call_VM(oop_result, last_java_sp, entry_point, 1, check_exceptions);
    1.23 +}
    1.24 +
    1.25 +void MacroAssembler::super_call_VM(Register oop_result,
    1.26 +                                   Register last_java_sp,
    1.27 +                                   address entry_point,
    1.28 +                                   Register arg_1,
    1.29 +                                   Register arg_2,
    1.30 +                                   bool check_exceptions) {
    1.31 +
    1.32 +  LP64_ONLY(assert(arg_1 != c_rarg2, "smashed arg"));
    1.33 +  pass_arg2(this, arg_2);
    1.34 +  pass_arg1(this, arg_1);
    1.35 +  super_call_VM(oop_result, last_java_sp, entry_point, 2, check_exceptions);
    1.36 +}
    1.37 +
    1.38 +void MacroAssembler::super_call_VM(Register oop_result,
    1.39 +                                   Register last_java_sp,
    1.40 +                                   address entry_point,
    1.41 +                                   Register arg_1,
    1.42 +                                   Register arg_2,
    1.43 +                                   Register arg_3,
    1.44 +                                   bool check_exceptions) {
    1.45 +  LP64_ONLY(assert(arg_1 != c_rarg3, "smashed arg"));
    1.46 +  LP64_ONLY(assert(arg_2 != c_rarg3, "smashed arg"));
    1.47 +  pass_arg3(this, arg_3);
    1.48 +  LP64_ONLY(assert(arg_1 != c_rarg2, "smashed arg"));
    1.49 +  pass_arg2(this, arg_2);
    1.50 +  pass_arg1(this, arg_1);
    1.51 +  super_call_VM(oop_result, last_java_sp, entry_point, 3, check_exceptions);
    1.52 +}
    1.53 +
    1.54  void MacroAssembler::call_VM_base(Register oop_result,
    1.55                                    Register java_thread,
    1.56                                    Register last_java_sp,
     2.1 --- a/src/cpu/x86/vm/assembler_x86.hpp	Sat Jun 04 10:36:22 2011 -0700
     2.2 +++ b/src/cpu/x86/vm/assembler_x86.hpp	Wed Jun 08 17:04:06 2011 -0700
     2.3 @@ -1660,6 +1660,14 @@
     2.4                 Register arg_1, Register arg_2, Register arg_3,
     2.5                 bool check_exceptions = true);
     2.6  
     2.7 +  // These always tightly bind to MacroAssembler::call_VM_base
     2.8 +  // bypassing the virtual implementation
     2.9 +  void super_call_VM(Register oop_result, Register last_java_sp, address entry_point, int number_of_arguments = 0, bool check_exceptions = true);
    2.10 +  void super_call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, bool check_exceptions = true);
    2.11 +  void super_call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2, bool check_exceptions = true);
    2.12 +  void super_call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2, Register arg_3, bool check_exceptions = true);
    2.13 +  void super_call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2, Register arg_3, Register arg_4, bool check_exceptions = true);
    2.14 +
    2.15    void call_VM_leaf(address entry_point,
    2.16                      int number_of_arguments = 0);
    2.17    void call_VM_leaf(address entry_point,
     3.1 --- a/src/cpu/x86/vm/frame_x86.inline.hpp	Sat Jun 04 10:36:22 2011 -0700
     3.2 +++ b/src/cpu/x86/vm/frame_x86.inline.hpp	Wed Jun 08 17:04:06 2011 -0700
     3.3 @@ -45,6 +45,7 @@
     3.4    _pc = pc;
     3.5    assert(pc != NULL, "no pc?");
     3.6    _cb = CodeCache::find_blob(pc);
     3.7 +  adjust_unextended_sp();
     3.8  
     3.9    address original_pc = nmethod::get_deopt_original_pc(this);
    3.10    if (original_pc != NULL) {
    3.11 @@ -92,6 +93,7 @@
    3.12    // assert(_pc != NULL, "no pc?");
    3.13  
    3.14    _cb = CodeCache::find_blob(_pc);
    3.15 +  adjust_unextended_sp();
    3.16  
    3.17    address original_pc = nmethod::get_deopt_original_pc(this);
    3.18    if (original_pc != NULL) {
     4.1 --- a/src/cpu/x86/vm/methodHandles_x86.cpp	Sat Jun 04 10:36:22 2011 -0700
     4.2 +++ b/src/cpu/x86/vm/methodHandles_x86.cpp	Wed Jun 08 17:04:06 2011 -0700
     4.3 @@ -24,6 +24,7 @@
     4.4  
     4.5  #include "precompiled.hpp"
     4.6  #include "interpreter/interpreter.hpp"
     4.7 +#include "interpreter/interpreterRuntime.hpp"
     4.8  #include "memory/allocation.inline.hpp"
     4.9  #include "prims/methodHandles.hpp"
    4.10  
    4.11 @@ -37,6 +38,11 @@
    4.12  
    4.13  #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
    4.14  
    4.15 +// Workaround for C++ overloading nastiness on '0' for RegisterOrConstant.
    4.16 +static RegisterOrConstant constant(int value) {
    4.17 +  return RegisterOrConstant(value);
    4.18 +}
    4.19 +
    4.20  address MethodHandleEntry::start_compiled_entry(MacroAssembler* _masm,
    4.21                                                  address interpreted_entry) {
    4.22    // Just before the actual machine code entry point, allocate space
    4.23 @@ -556,13 +562,11 @@
    4.24    // emit WrongMethodType path first, to enable jccb back-branch from main path
    4.25    Label wrong_method_type;
    4.26    __ bind(wrong_method_type);
    4.27 -  Label invoke_generic_slow_path;
    4.28 +  Label invoke_generic_slow_path, invoke_exact_error_path;
    4.29    assert(methodOopDesc::intrinsic_id_size_in_bytes() == sizeof(u1), "");;
    4.30    __ cmpb(Address(rbx_method, methodOopDesc::intrinsic_id_offset_in_bytes()), (int) vmIntrinsics::_invokeExact);
    4.31    __ jcc(Assembler::notEqual, invoke_generic_slow_path);
    4.32 -  __ push(rax_mtype);       // required mtype
    4.33 -  __ push(rcx_recv);        // bad mh (1st stacked argument)
    4.34 -  __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry()));
    4.35 +  __ jmp(invoke_exact_error_path);
    4.36  
    4.37    // here's where control starts out:
    4.38    __ align(CodeEntryAlignment);
    4.39 @@ -596,6 +600,18 @@
    4.40  
    4.41    __ jump_to_method_handle_entry(rcx_recv, rdi_temp);
    4.42  
    4.43 +  // error path for invokeExact (only)
    4.44 +  __ bind(invoke_exact_error_path);
    4.45 +  // jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry()));
    4.46 +  Register rdx_last_Java_sp = rdx_temp;
    4.47 +  __ lea(rdx_last_Java_sp, __ argument_address(constant(0)));
    4.48 +  __ super_call_VM(noreg,
    4.49 +                   rdx_last_Java_sp,
    4.50 +                   CAST_FROM_FN_PTR(address,
    4.51 +                                    InterpreterRuntime::throw_WrongMethodTypeException),
    4.52 +                   // pass required type, then failing mh object
    4.53 +                   rax_mtype, rcx_recv);
    4.54 +
    4.55    // for invokeGeneric (only), apply argument and result conversions on the fly
    4.56    __ bind(invoke_generic_slow_path);
    4.57  #ifdef ASSERT
    4.58 @@ -633,11 +649,6 @@
    4.59    return entry_point;
    4.60  }
    4.61  
    4.62 -// Workaround for C++ overloading nastiness on '0' for RegisterOrConstant.
    4.63 -static RegisterOrConstant constant(int value) {
    4.64 -  return RegisterOrConstant(value);
    4.65 -}
    4.66 -
    4.67  // Helper to insert argument slots into the stack.
    4.68  // arg_slots must be a multiple of stack_move_unit() and < 0
    4.69  // rax_argslot is decremented to point to the new (shifted) location of the argslot
     5.1 --- a/src/share/vm/code/pcDesc.cpp	Sat Jun 04 10:36:22 2011 -0700
     5.2 +++ b/src/share/vm/code/pcDesc.cpp	Wed Jun 08 17:04:06 2011 -0700
     5.3 @@ -44,7 +44,7 @@
     5.4  void PcDesc::print(nmethod* code) {
     5.5  #ifndef PRODUCT
     5.6    ResourceMark rm;
     5.7 -  tty->print_cr("PcDesc(pc=0x%lx offset=%x):", real_pc(code), pc_offset());
     5.8 +  tty->print_cr("PcDesc(pc=0x%lx offset=%x bits=%x):", real_pc(code), pc_offset(), _flags.bits);
     5.9  
    5.10    if (scope_decode_offset() == DebugInformationRecorder::serialized_null) {
    5.11      return;

mercurial