src/cpu/x86/vm/methodHandles_x86.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 7012914 Sdiff src/cpu/x86/vm

src/cpu/x86/vm/methodHandles_x86.cpp

Print this page




 402   const Register rcx_recv    = rcx;
 403   const Register rax_argslot = rax;
 404   const Register rbx_temp    = rbx;
 405   const Register rdx_temp    = rdx;
 406 
 407   // This guy is set up by prepare_to_jump_from_interpreted (from interpreted calls)
 408   // and gen_c2i_adapter (from compiled calls):
 409   const Register saved_last_sp = LP64_ONLY(r13) NOT_LP64(rsi);
 410 
 411   // Argument registers for _raise_exception.
 412   // 32-bit: Pass first two oop/int args in registers ECX and EDX.
 413   const Register rarg0_code     = LP64_ONLY(j_rarg0) NOT_LP64(rcx);
 414   const Register rarg1_actual   = LP64_ONLY(j_rarg1) NOT_LP64(rdx);
 415   const Register rarg2_required = LP64_ONLY(j_rarg2) NOT_LP64(rdi);
 416   assert_different_registers(rarg0_code, rarg1_actual, rarg2_required, saved_last_sp);
 417 
 418   guarantee(java_dyn_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets");
 419 
 420   // some handy addresses
 421   Address rbx_method_fie(     rbx,      methodOopDesc::from_interpreted_offset() );

 422 
 423   Address rcx_mh_vmtarget(    rcx_recv, java_dyn_MethodHandle::vmtarget_offset_in_bytes() );
 424   Address rcx_dmh_vmindex(    rcx_recv, sun_dyn_DirectMethodHandle::vmindex_offset_in_bytes() );
 425 
 426   Address rcx_bmh_vmargslot(  rcx_recv, sun_dyn_BoundMethodHandle::vmargslot_offset_in_bytes() );
 427   Address rcx_bmh_argument(   rcx_recv, sun_dyn_BoundMethodHandle::argument_offset_in_bytes() );
 428 
 429   Address rcx_amh_vmargslot(  rcx_recv, sun_dyn_AdapterMethodHandle::vmargslot_offset_in_bytes() );
 430   Address rcx_amh_argument(   rcx_recv, sun_dyn_AdapterMethodHandle::argument_offset_in_bytes() );
 431   Address rcx_amh_conversion( rcx_recv, sun_dyn_AdapterMethodHandle::conversion_offset_in_bytes() );
 432   Address vmarg;                // __ argument_address(vmargslot)
 433 
 434   const int java_mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes();
 435 
 436   if (have_entry(ek)) {
 437     __ nop();                   // empty stubs make SG sick
 438     return;
 439   }
 440 
 441   address interp_entry = __ pc();
 442 
 443   trace_method_handle(_masm, entry_name(ek));
 444 
 445   BLOCK_COMMENT(entry_name(ek));
 446 
 447   switch ((int) ek) {
 448   case _raise_exception:
 449     {
 450       // Not a real MH entry, but rather shared code for raising an
 451       // exception.  Since we use a C2I adapter to set up the
 452       // interpreter state, arguments are expected in compiler
 453       // argument registers.
 454       assert(raise_exception_method(), "must be set");
 455       address c2i_entry = raise_exception_method()->get_c2i_entry();
 456       assert(c2i_entry, "method must be linked");
 457 
 458       const Register rdi_pc = rax;
 459       __ pop(rdi_pc);  // caller PC
 460       __ mov(rsp, saved_last_sp);  // cut the stack back to where the caller started
 461 
 462       Register rbx_method = rbx_temp;
 463       Label L_no_method;
 464       // FIXME: fill in _raise_exception_method with a suitable sun.dyn method
 465       __ movptr(rbx_method, ExternalAddress((address) &_raise_exception_method));
 466       __ testptr(rbx_method, rbx_method);
 467       __ jccb(Assembler::zero, L_no_method);
 468 
 469       const int jobject_oop_offset = 0;
 470       __ movptr(rbx_method, Address(rbx_method, jobject_oop_offset));  // dereference the jobject
 471       __ testptr(rbx_method, rbx_method);
 472       __ jccb(Assembler::zero, L_no_method);
 473       __ verify_oop(rbx_method);
 474 
 475       // 32-bit: push remaining arguments as if coming from the compiler.
 476       NOT_LP64(__ push(rarg2_required));
 477 
 478       __ push(rdi_pc);  // restore caller PC
 479       __ jump(ExternalAddress(c2i_entry));  // do C2I transition
 480 
 481       // If we get here, the Java runtime did not do its job of creating the exception.
 482       // Do something that is at least causes a valid throw from the interpreter.
 483       __ bind(L_no_method);
 484       __ push(rarg2_required);
 485       __ push(rarg1_actual);
 486       __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry()));
 487     }
 488     break;
 489 
 490   case _invokestatic_mh:
 491   case _invokespecial_mh:
 492     {
 493       Register rbx_method = rbx_temp;
 494       __ load_heap_oop(rbx_method, rcx_mh_vmtarget); // target is a methodOop
 495       __ verify_oop(rbx_method);
 496       // same as TemplateTable::invokestatic or invokespecial,
 497       // minus the CP setup and profiling:
 498       if (ek == _invokespecial_mh) {
 499         // Must load & check the first argument before entering the target method.
 500         __ load_method_handle_vmslots(rax_argslot, rcx_recv, rdx_temp);
 501         __ movptr(rcx_recv, __ argument_address(rax_argslot, -1));




 402   const Register rcx_recv    = rcx;
 403   const Register rax_argslot = rax;
 404   const Register rbx_temp    = rbx;
 405   const Register rdx_temp    = rdx;
 406 
 407   // This guy is set up by prepare_to_jump_from_interpreted (from interpreted calls)
 408   // and gen_c2i_adapter (from compiled calls):
 409   const Register saved_last_sp = LP64_ONLY(r13) NOT_LP64(rsi);
 410 
 411   // Argument registers for _raise_exception.
 412   // 32-bit: Pass first two oop/int args in registers ECX and EDX.
 413   const Register rarg0_code     = LP64_ONLY(j_rarg0) NOT_LP64(rcx);
 414   const Register rarg1_actual   = LP64_ONLY(j_rarg1) NOT_LP64(rdx);
 415   const Register rarg2_required = LP64_ONLY(j_rarg2) NOT_LP64(rdi);
 416   assert_different_registers(rarg0_code, rarg1_actual, rarg2_required, saved_last_sp);
 417 
 418   guarantee(java_dyn_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets");
 419 
 420   // some handy addresses
 421   Address rbx_method_fie(     rbx,      methodOopDesc::from_interpreted_offset() );
 422   Address rbx_method_fce(     rbx,      methodOopDesc::from_compiled_offset() );
 423 
 424   Address rcx_mh_vmtarget(    rcx_recv, java_dyn_MethodHandle::vmtarget_offset_in_bytes() );
 425   Address rcx_dmh_vmindex(    rcx_recv, sun_dyn_DirectMethodHandle::vmindex_offset_in_bytes() );
 426 
 427   Address rcx_bmh_vmargslot(  rcx_recv, sun_dyn_BoundMethodHandle::vmargslot_offset_in_bytes() );
 428   Address rcx_bmh_argument(   rcx_recv, sun_dyn_BoundMethodHandle::argument_offset_in_bytes() );
 429 
 430   Address rcx_amh_vmargslot(  rcx_recv, sun_dyn_AdapterMethodHandle::vmargslot_offset_in_bytes() );
 431   Address rcx_amh_argument(   rcx_recv, sun_dyn_AdapterMethodHandle::argument_offset_in_bytes() );
 432   Address rcx_amh_conversion( rcx_recv, sun_dyn_AdapterMethodHandle::conversion_offset_in_bytes() );
 433   Address vmarg;                // __ argument_address(vmargslot)
 434 
 435   const int java_mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes();
 436 
 437   if (have_entry(ek)) {
 438     __ nop();                   // empty stubs make SG sick
 439     return;
 440   }
 441 
 442   address interp_entry = __ pc();
 443 
 444   trace_method_handle(_masm, entry_name(ek));
 445 
 446   BLOCK_COMMENT(entry_name(ek));
 447 
 448   switch ((int) ek) {
 449   case _raise_exception:
 450     {
 451       // Not a real MH entry, but rather shared code for raising an
 452       // exception.  Since we use the compiled entry, arguments are
 453       // expected in compiler argument registers.

 454       assert(raise_exception_method(), "must be set");
 455       assert(raise_exception_method()->from_compiled_entry(), "method must be linked");

 456 
 457       const Register rdi_pc = rax;
 458       __ pop(rdi_pc);  // caller PC
 459       __ mov(rsp, saved_last_sp);  // cut the stack back to where the caller started
 460 
 461       Register rbx_method = rbx_temp;
 462       Label L_no_method;
 463       // FIXME: fill in _raise_exception_method with a suitable sun.dyn method
 464       __ movptr(rbx_method, ExternalAddress((address) &_raise_exception_method));
 465       __ testptr(rbx_method, rbx_method);
 466       __ jccb(Assembler::zero, L_no_method);
 467 
 468       const int jobject_oop_offset = 0;
 469       __ movptr(rbx_method, Address(rbx_method, jobject_oop_offset));  // dereference the jobject
 470       __ testptr(rbx_method, rbx_method);
 471       __ jccb(Assembler::zero, L_no_method);
 472       __ verify_oop(rbx_method);
 473 

 474       NOT_LP64(__ push(rarg2_required));

 475       __ push(rdi_pc);         // restore caller PC
 476       __ jmp(rbx_method_fce);  // jump to compiled entry
 477 

 478       // Do something that is at least causes a valid throw from the interpreter.
 479       __ bind(L_no_method);
 480       __ push(rarg2_required);
 481       __ push(rarg1_actual);
 482       __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry()));
 483     }
 484     break;
 485 
 486   case _invokestatic_mh:
 487   case _invokespecial_mh:
 488     {
 489       Register rbx_method = rbx_temp;
 490       __ load_heap_oop(rbx_method, rcx_mh_vmtarget); // target is a methodOop
 491       __ verify_oop(rbx_method);
 492       // same as TemplateTable::invokestatic or invokespecial,
 493       // minus the CP setup and profiling:
 494       if (ek == _invokespecial_mh) {
 495         // Must load & check the first argument before entering the target method.
 496         __ load_method_handle_vmslots(rax_argslot, rcx_recv, rdx_temp);
 497         __ movptr(rcx_recv, __ argument_address(rax_argslot, -1));


src/cpu/x86/vm/methodHandles_x86.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File