src/cpu/x86/vm/c1_Runtime1_x86.cpp

Print this page




  61     jcc(Assembler::equal, L);
  62     int3();
  63     stop("StubAssembler::call_RT: rdi not callee saved?");
  64     bind(L);
  65   }
  66   pop(rax);
  67 #endif
  68   reset_last_Java_frame(thread, true, false);
  69 
  70   // discard thread and arguments
  71   NOT_LP64(addptr(rsp, num_rt_args()*BytesPerWord));
  72 
  73   // check for pending exceptions
  74   { Label L;
  75     cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
  76     jcc(Assembler::equal, L);
  77     // exception pending => remove activation and forward to exception handler
  78     movptr(rax, Address(thread, Thread::pending_exception_offset()));
  79     // make sure that the vm_results are cleared
  80     if (oop_result1->is_valid()) {
  81       movptr(Address(thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD);
  82     }
  83     if (oop_result2->is_valid()) {
  84       movptr(Address(thread, JavaThread::vm_result_2_offset()), (int32_t)NULL_WORD);
  85     }
  86     if (frame_size() == no_frame_size) {
  87       leave();
  88       jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
  89     } else if (_stub_id == Runtime1::forward_exception_id) {
  90       should_not_reach_here();
  91     } else {
  92       jump(RuntimeAddress(Runtime1::entry_for(Runtime1::forward_exception_id)));
  93     }
  94     bind(L);
  95   }
  96   // get oop results if there are any and reset the values in the thread
  97   if (oop_result1->is_valid()) {
  98     movptr(oop_result1, Address(thread, JavaThread::vm_result_offset()));
  99     movptr(Address(thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD);
 100     verify_oop(oop_result1);
 101   }
 102   if (oop_result2->is_valid()) {
 103     movptr(oop_result2, Address(thread, JavaThread::vm_result_2_offset()));
 104     movptr(Address(thread, JavaThread::vm_result_2_offset()), (int32_t)NULL_WORD);
 105     verify_oop(oop_result2);
 106   }
 107   return call_offset;
 108 }
 109 
 110 
 111 int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1) {
 112 #ifdef _LP64
 113   mov(c_rarg1, arg1);
 114 #else
 115   push(arg1);
 116 #endif // _LP64
 117   return call_RT(oop_result1, oop_result2, entry, 1);
 118 }
 119 
 120 
 121 int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1, Register arg2) {
 122 #ifdef _LP64
 123   if (c_rarg1 == arg2) {
 124     if (c_rarg2 == arg1) {


 711   // return to exception handler
 712   __ leave();
 713   __ ret(0);
 714 
 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()), (int32_t)NULL_WORD);
 732   __ movptr(Address(thread, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD);
 733 
 734   // pop the stub frame off
 735   __ leave();
 736 
 737   generate_unwind_exception(sasm);
 738   __ stop("should not reach here");
 739 }
 740 
 741 
 742 void Runtime1::generate_unwind_exception(StubAssembler *sasm) {
 743   // incoming parameters
 744   const Register exception_oop = rax;
 745   // other registers used in this stub
 746   const Register exception_pc = rdx;
 747   const Register handler_addr = rbx;
 748   const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread);
 749 
 750   // verify that only rax, is valid at this time
 751   __ invalidate_registers(false, true, true, true, true, true);
 752 


 861 #ifndef _LP64
 862   __ pop(rcx); // discard thread arg
 863   __ pop(rcx); // discard dummy
 864 #endif // _LP64
 865 
 866   // check for pending exceptions
 867   { Label L;
 868     __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
 869     __ jcc(Assembler::equal, L);
 870     // exception pending => remove activation and forward to exception handler
 871 
 872     __ testptr(rax, rax);                                   // have we deoptimized?
 873     __ jump_cc(Assembler::equal,
 874                RuntimeAddress(Runtime1::entry_for(Runtime1::forward_exception_id)));
 875 
 876     // the deopt blob expects exceptions in the special fields of
 877     // JavaThread, so copy and clear pending exception.
 878 
 879     // load and clear pending exception
 880     __ movptr(rax, Address(thread, Thread::pending_exception_offset()));
 881     __ movptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
 882 
 883     // check that there is really a valid exception
 884     __ verify_not_null_oop(rax);
 885 
 886     // load throwing pc: this is the return address of the stub
 887     __ movptr(rdx, Address(rsp, return_off * VMRegImpl::stack_slot_size));
 888 
 889 #ifdef ASSERT
 890     // check that fields in JavaThread for exception oop and issuing pc are empty
 891     Label oop_empty;
 892     __ cmpptr(Address(thread, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD);
 893     __ jcc(Assembler::equal, oop_empty);
 894     __ stop("exception oop must be empty");
 895     __ bind(oop_empty);
 896 
 897     Label pc_empty;
 898     __ cmpptr(Address(thread, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD);
 899     __ jcc(Assembler::equal, pc_empty);
 900     __ stop("exception pc must be empty");
 901     __ bind(pc_empty);


 954   bool save_fpu_registers = true;
 955 
 956   // stub code & info for the different stubs
 957   OopMapSet* oop_maps = NULL;
 958   switch (id) {
 959     case forward_exception_id:
 960       {
 961         // we're handling an exception in the context of a compiled
 962         // frame.  The registers have been saved in the standard
 963         // places.  Perform an exception lookup in the caller and
 964         // dispatch to the handler if found.  Otherwise unwind and
 965         // dispatch to the callers exception handler.
 966 
 967         const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread);
 968         const Register exception_oop = rax;
 969         const Register exception_pc = rdx;
 970 
 971         // load pending exception oop into rax,
 972         __ movptr(exception_oop, Address(thread, Thread::pending_exception_offset()));
 973         // clear pending exception
 974         __ movptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
 975 
 976         // load issuing PC (the return address for this stub) into rdx
 977         __ movptr(exception_pc, Address(rbp, 1*BytesPerWord));
 978 
 979         // make sure that the vm_results are cleared (may be unnecessary)
 980         __ movptr(Address(thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD);
 981         __ movptr(Address(thread, JavaThread::vm_result_2_offset()), (int32_t)NULL_WORD);
 982 
 983         // verify that that there is really a valid exception in rax,
 984         __ verify_not_null_oop(exception_oop);
 985 
 986 
 987         oop_maps = new OopMapSet();
 988         OopMap* oop_map = generate_oop_map(sasm, 1);
 989         generate_handle_exception(sasm, oop_maps, oop_map);
 990         __ stop("should not reach here");
 991       }
 992       break;
 993 
 994     case new_instance_id:
 995     case fast_new_instance_id:
 996     case fast_new_instance_init_check_id:
 997       {
 998         Register klass = rdx; // Incoming
 999         Register obj   = rax; // Result
1000 
1001         if (id == new_instance_id) {




  61     jcc(Assembler::equal, L);
  62     int3();
  63     stop("StubAssembler::call_RT: rdi not callee saved?");
  64     bind(L);
  65   }
  66   pop(rax);
  67 #endif
  68   reset_last_Java_frame(thread, true, false);
  69 
  70   // discard thread and arguments
  71   NOT_LP64(addptr(rsp, num_rt_args()*BytesPerWord));
  72 
  73   // check for pending exceptions
  74   { Label L;
  75     cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
  76     jcc(Assembler::equal, L);
  77     // exception pending => remove activation and forward to exception handler
  78     movptr(rax, Address(thread, Thread::pending_exception_offset()));
  79     // make sure that the vm_results are cleared
  80     if (oop_result1->is_valid()) {
  81       movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD);
  82     }
  83     if (oop_result2->is_valid()) {
  84       movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD);
  85     }
  86     if (frame_size() == no_frame_size) {
  87       leave();
  88       jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
  89     } else if (_stub_id == Runtime1::forward_exception_id) {
  90       should_not_reach_here();
  91     } else {
  92       jump(RuntimeAddress(Runtime1::entry_for(Runtime1::forward_exception_id)));
  93     }
  94     bind(L);
  95   }
  96   // get oop results if there are any and reset the values in the thread
  97   if (oop_result1->is_valid()) {
  98     movptr(oop_result1, Address(thread, JavaThread::vm_result_offset()));
  99     movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD);
 100     verify_oop(oop_result1);
 101   }
 102   if (oop_result2->is_valid()) {
 103     movptr(oop_result2, Address(thread, JavaThread::vm_result_2_offset()));
 104     movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD);
 105     verify_oop(oop_result2);
 106   }
 107   return call_offset;
 108 }
 109 
 110 
 111 int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1) {
 112 #ifdef _LP64
 113   mov(c_rarg1, arg1);
 114 #else
 115   push(arg1);
 116 #endif // _LP64
 117   return call_RT(oop_result1, oop_result2, entry, 1);
 118 }
 119 
 120 
 121 int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1, Register arg2) {
 122 #ifdef _LP64
 123   if (c_rarg1 == arg2) {
 124     if (c_rarg2 == arg1) {


 711   // return to exception handler
 712   __ leave();
 713   __ ret(0);
 714 
 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 }
 740 
 741 
 742 void Runtime1::generate_unwind_exception(StubAssembler *sasm) {
 743   // incoming parameters
 744   const Register exception_oop = rax;
 745   // other registers used in this stub
 746   const Register exception_pc = rdx;
 747   const Register handler_addr = rbx;
 748   const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread);
 749 
 750   // verify that only rax, is valid at this time
 751   __ invalidate_registers(false, true, true, true, true, true);
 752 


 861 #ifndef _LP64
 862   __ pop(rcx); // discard thread arg
 863   __ pop(rcx); // discard dummy
 864 #endif // _LP64
 865 
 866   // check for pending exceptions
 867   { Label L;
 868     __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
 869     __ jcc(Assembler::equal, L);
 870     // exception pending => remove activation and forward to exception handler
 871 
 872     __ testptr(rax, rax);                                   // have we deoptimized?
 873     __ jump_cc(Assembler::equal,
 874                RuntimeAddress(Runtime1::entry_for(Runtime1::forward_exception_id)));
 875 
 876     // the deopt blob expects exceptions in the special fields of
 877     // JavaThread, so copy and clear pending exception.
 878 
 879     // load and clear pending exception
 880     __ movptr(rax, Address(thread, Thread::pending_exception_offset()));
 881     __ movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD);
 882 
 883     // check that there is really a valid exception
 884     __ verify_not_null_oop(rax);
 885 
 886     // load throwing pc: this is the return address of the stub
 887     __ movptr(rdx, Address(rsp, return_off * VMRegImpl::stack_slot_size));
 888 
 889 #ifdef ASSERT
 890     // check that fields in JavaThread for exception oop and issuing pc are empty
 891     Label oop_empty;
 892     __ cmpptr(Address(thread, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD);
 893     __ jcc(Assembler::equal, oop_empty);
 894     __ stop("exception oop must be empty");
 895     __ bind(oop_empty);
 896 
 897     Label pc_empty;
 898     __ cmpptr(Address(thread, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD);
 899     __ jcc(Assembler::equal, pc_empty);
 900     __ stop("exception pc must be empty");
 901     __ bind(pc_empty);


 954   bool save_fpu_registers = true;
 955 
 956   // stub code & info for the different stubs
 957   OopMapSet* oop_maps = NULL;
 958   switch (id) {
 959     case forward_exception_id:
 960       {
 961         // we're handling an exception in the context of a compiled
 962         // frame.  The registers have been saved in the standard
 963         // places.  Perform an exception lookup in the caller and
 964         // dispatch to the handler if found.  Otherwise unwind and
 965         // dispatch to the callers exception handler.
 966 
 967         const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread);
 968         const Register exception_oop = rax;
 969         const Register exception_pc = rdx;
 970 
 971         // load pending exception oop into rax,
 972         __ movptr(exception_oop, Address(thread, Thread::pending_exception_offset()));
 973         // clear pending exception
 974         __ movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD);
 975 
 976         // load issuing PC (the return address for this stub) into rdx
 977         __ movptr(exception_pc, Address(rbp, 1*BytesPerWord));
 978 
 979         // make sure that the vm_results are cleared (may be unnecessary)
 980         __ movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD);
 981         __ movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD);
 982 
 983         // verify that that there is really a valid exception in rax,
 984         __ verify_not_null_oop(exception_oop);
 985 
 986 
 987         oop_maps = new OopMapSet();
 988         OopMap* oop_map = generate_oop_map(sasm, 1);
 989         generate_handle_exception(sasm, oop_maps, oop_map);
 990         __ stop("should not reach here");
 991       }
 992       break;
 993 
 994     case new_instance_id:
 995     case fast_new_instance_id:
 996     case fast_new_instance_init_check_id:
 997       {
 998         Register klass = rdx; // Incoming
 999         Register obj   = rax; // Result
1000 
1001         if (id == new_instance_id) {