Print this page


Split Close
Expand all
Collapse all
          --- old/src/cpu/x86/vm/c1_Runtime1_x86.cpp
          +++ new/src/cpu/x86/vm/c1_Runtime1_x86.cpp
↓ open down ↓ 680 lines elided ↑ open up ↑
 681  681    __ movptr(Address(rsp, temp_1_off * VMRegImpl::stack_slot_size), real_return_addr);
 682  682  
 683  683    // patch throwing pc into return address (has bci & oop map)
 684  684    __ movptr(Address(rbp, 1*BytesPerWord), exception_pc);
 685  685  
 686  686    // compute the exception handler.
 687  687    // the exception oop and the throwing pc are read from the fields in JavaThread
 688  688    int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc));
 689  689    oop_maps->add_gc_map(call_offset, oop_map);
 690  690  
 691      -  // rax,: handler address or NULL if no handler exists
      691 +  // rax,: handler address
 692  692    //      will be the deopt blob if nmethod was deoptimized while we looked up
 693  693    //      handler regardless of whether handler existed in the nmethod.
 694  694  
 695  695    // only rax, is valid at this time, all other registers have been destroyed by the runtime call
 696  696    __ invalidate_registers(false, true, true, true, true, true);
 697  697  
      698 +#ifdef ASSERT
 698  699    // Do we have an exception handler in the nmethod?
 699      -  Label no_handler;
 700  700    Label done;
 701  701    __ testptr(rax, rax);
 702      -  __ jcc(Assembler::zero, no_handler);
      702 +  __ jcc(Assembler::notZero, done);
      703 +  __ stop("no handler found");
      704 +  __ bind(done);
      705 +#endif
 703  706  
 704  707    // exception handler found
 705  708    // patch the return address -> the stub will directly return to the exception handler
 706  709    __ movptr(Address(rbp, 1*BytesPerWord), rax);
 707  710  
 708  711    // restore registers
 709  712    restore_live_registers(sasm, save_fpu_registers);
 710  713  
 711  714    // return to exception handler
 712  715    __ leave();
 713  716    __ ret(0);
 714  717  
 715      -  __ bind(no_handler);
 716      -  // no exception handler found in this method, so the exception is
 717      -  // forwarded to the caller (using the unwind code of the nmethod)
 718      -  // there is no need to restore the registers
 719      -
 720      -  // restore the real return address that was saved before the RT-call
 721      -  __ movptr(real_return_addr, Address(rsp, temp_1_off * VMRegImpl::stack_slot_size));
 722      -  __ movptr(Address(rbp, 1*BytesPerWord), real_return_addr);
 723      -
 724      -  // load address of JavaThread object for thread-local data
 725      -  NOT_LP64(__ get_thread(thread);)
 726      -  // restore exception oop into rax, (convention for unwind code)
 727      -  __ movptr(exception_oop, Address(thread, JavaThread::exception_oop_offset()));
 728      -
 729      -  // clear exception fields in JavaThread because they are no longer needed
 730      -  // (fields must be cleared because they are processed by GC otherwise)
 731      -  __ movptr(Address(thread, JavaThread::exception_oop_offset()), NULL_WORD);
 732      -  __ movptr(Address(thread, JavaThread::exception_pc_offset()), NULL_WORD);
 733      -
 734      -  // pop the stub frame off
 735      -  __ leave();
 736      -
 737      -  generate_unwind_exception(sasm);
 738      -  __ stop("should not reach here");
 739  718  }
 740  719  
 741  720  
 742  721  void Runtime1::generate_unwind_exception(StubAssembler *sasm) {
 743  722    // incoming parameters
 744  723    const Register exception_oop = rax;
      724 +  // callee-saved copy of exception_oop during runtime call
      725 +  const Register exception_oop_callee_saved = NOT_LP64(rsi);
 745  726    // other registers used in this stub
 746  727    const Register exception_pc = rdx;
 747  728    const Register handler_addr = rbx;
 748  729    const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread);
 749  730  
 750  731    // verify that only rax, is valid at this time
 751  732    __ invalidate_registers(false, true, true, true, true, true);
 752  733  
 753  734  #ifdef ASSERT
 754  735    // check that fields in JavaThread for exception oop and issuing pc are empty
↓ open down ↓ 7 lines elided ↑ open up ↑
 762  743    Label pc_empty;
 763  744    __ cmpptr(Address(thread, JavaThread::exception_pc_offset()), 0);
 764  745    __ jcc(Assembler::equal, pc_empty);
 765  746    __ stop("exception pc must be empty");
 766  747    __ bind(pc_empty);
 767  748  #endif
 768  749  
 769  750    // clear the FPU stack in case any FPU results are left behind
 770  751    __ empty_FPU_stack();
 771  752  
 772      -  // leave activation of nmethod
 773      -  __ leave();
 774      -  // store return address (is on top of stack after leave)
 775      -  __ movptr(exception_pc, Address(rsp, 0));
 776      -
 777      -  __ verify_oop(exception_oop);
      753 +  // save exception_oop in callee-saved register to preserve it during runtime calls
      754 +  __ verify_not_null_oop(exception_oop);
      755 +  __ movptr(exception_oop_callee_saved, exception_oop);
 778  756  
 779      -  // save exception oop from rax, to stack before call
 780      -  __ push(exception_oop);
      757 +  NOT_LP64(__ get_thread(thread);)
      758 +  // Get return address (is on top of stack after leave).
      759 +  __ movptr(exception_pc, Address(rsp, 0));
 781  760  
 782  761    // search the exception handler address of the caller (using the return address)
 783      -  __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), exception_pc);
 784      -  // rax,: exception handler address of the caller
      762 +  __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, exception_pc);
      763 +  // rax: exception handler address of the caller
 785  764  
 786      -  // only rax, is valid at this time, all other registers have been destroyed by the call
 787      -  __ invalidate_registers(false, true, true, true, true, true);
      765 +  // Only RAX and RSI are valid at this time, all other registers have been destroyed by the call.
      766 +  __ invalidate_registers(false, true, true, true, false, true);
 788  767  
 789  768    // move result of call into correct register
 790  769    __ movptr(handler_addr, rax);
 791  770  
 792      -  // restore exception oop in rax, (required convention of exception handler)
 793      -  __ pop(exception_oop);
      771 +  // Restore exception oop to RAX (required convention of exception handler).
      772 +  __ movptr(exception_oop, exception_oop_callee_saved);
 794  773  
 795      -  __ verify_oop(exception_oop);
      774 +  // verify that there is really a valid exception in rax
      775 +  __ verify_not_null_oop(exception_oop);
 796  776  
 797  777    // get throwing pc (= return address).
 798  778    // rdx has been destroyed by the call, so it must be set again
 799  779    // the pop is also necessary to simulate the effect of a ret(0)
 800  780    __ pop(exception_pc);
 801  781  
 802      -  // verify that that there is really a valid exception in rax,
 803      -  __ verify_not_null_oop(exception_oop);
      782 +  // Restore SP from BP if the exception PC is a MethodHandle call site.
      783 +  NOT_LP64(__ get_thread(thread);)
      784 +  __ cmpl(Address(thread, JavaThread::is_method_handle_exception_offset()), 0);
      785 +  __ cmovptr(Assembler::notEqual, rsp, rbp);
 804  786  
 805  787    // continue at exception handler (return address removed)
 806  788    // note: do *not* remove arguments when unwinding the
 807  789    //       activation since the caller assumes having
 808  790    //       all arguments on the stack when entering the
 809  791    //       runtime to determine the exception handler
 810  792    //       (GC happens at call site with arguments!)
 811      -  // rax,: exception oop
      793 +  // rax: exception oop
 812  794    // rdx: throwing pc
 813      -  // rbx,: exception handler
      795 +  // rbx: exception handler
 814  796    __ jmp(handler_addr);
 815  797  }
 816  798  
 817  799  
 818  800  OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) {
 819  801    // use the maximum number of runtime-arguments here because it is difficult to
 820  802    // distinguish each RT-Call.
 821  803    // Note: This number affects also the RT-Call in generate_handle_exception because
 822  804    //       the oop-map is shared for all calls.
 823  805    const int num_rt_args = 2;  // thread + dummy
↓ open down ↓ 937 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX