hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp
changeset 8495 a4959965eaa3
parent 8069 412054470e89
child 10252 0981ce1c3eef
equal deleted inserted replaced
8494:4258c78226d9 8495:a4959965eaa3
   146 static int reg_save_size_in_words;
   146 static int reg_save_size_in_words;
   147 static int frame_size_in_bytes = -1;
   147 static int frame_size_in_bytes = -1;
   148 
   148 
   149 static OopMap* generate_oop_map(StubAssembler* sasm, bool save_fpu_registers) {
   149 static OopMap* generate_oop_map(StubAssembler* sasm, bool save_fpu_registers) {
   150   assert(frame_size_in_bytes == __ total_frame_size_in_bytes(reg_save_size_in_words),
   150   assert(frame_size_in_bytes == __ total_frame_size_in_bytes(reg_save_size_in_words),
   151          " mismatch in calculation");
   151          "mismatch in calculation");
   152   sasm->set_frame_size(frame_size_in_bytes / BytesPerWord);
   152   sasm->set_frame_size(frame_size_in_bytes / BytesPerWord);
   153   int frame_size_in_slots = frame_size_in_bytes / sizeof(jint);
   153   int frame_size_in_slots = frame_size_in_bytes / sizeof(jint);
   154   OopMap* oop_map = new OopMap(frame_size_in_slots, 0);
   154   OopMap* oop_map = new OopMap(frame_size_in_slots, 0);
   155 
   155 
   156   int i;
   156   int i;
   174   return oop_map;
   174   return oop_map;
   175 }
   175 }
   176 
   176 
   177 static OopMap* save_live_registers(StubAssembler* sasm, bool save_fpu_registers = true) {
   177 static OopMap* save_live_registers(StubAssembler* sasm, bool save_fpu_registers = true) {
   178   assert(frame_size_in_bytes == __ total_frame_size_in_bytes(reg_save_size_in_words),
   178   assert(frame_size_in_bytes == __ total_frame_size_in_bytes(reg_save_size_in_words),
   179          " mismatch in calculation");
   179          "mismatch in calculation");
   180   __ save_frame_c1(frame_size_in_bytes);
   180   __ save_frame_c1(frame_size_in_bytes);
   181   sasm->set_frame_size(frame_size_in_bytes / BytesPerWord);
       
   182 
   181 
   183   // Record volatile registers as callee-save values in an OopMap so their save locations will be
   182   // Record volatile registers as callee-save values in an OopMap so their save locations will be
   184   // propagated to the caller frame's RegisterMap during StackFrameStream construction (needed for
   183   // propagated to the caller frame's RegisterMap during StackFrameStream construction (needed for
   185   // deoptimization; see compiledVFrame::create_stack_value).  The caller's I, L and O registers
   184   // deoptimization; see compiledVFrame::create_stack_value).  The caller's I, L and O registers
   186   // are saved in register windows - I's and L's in the caller's frame and O's in the stub frame
   185   // are saved in register windows - I's and L's in the caller's frame and O's in the stub frame
   365 
   364 
   366   // stub code & info for the different stubs
   365   // stub code & info for the different stubs
   367   switch (id) {
   366   switch (id) {
   368     case forward_exception_id:
   367     case forward_exception_id:
   369       {
   368       {
   370         // we're handling an exception in the context of a compiled
   369         oop_maps = generate_handle_exception(id, sasm);
   371         // frame.  The registers have been saved in the standard
       
   372         // places.  Perform an exception lookup in the caller and
       
   373         // dispatch to the handler if found.  Otherwise unwind and
       
   374         // dispatch to the callers exception handler.
       
   375 
       
   376         oop_maps = new OopMapSet();
       
   377         OopMap* oop_map = generate_oop_map(sasm, true);
       
   378 
       
   379         // transfer the pending exception to the exception_oop
       
   380         __ ld_ptr(G2_thread, in_bytes(JavaThread::pending_exception_offset()), Oexception);
       
   381         __ ld_ptr(Oexception, 0, G0);
       
   382         __ st_ptr(G0, G2_thread, in_bytes(JavaThread::pending_exception_offset()));
       
   383         __ add(I7, frame::pc_return_offset, Oissuing_pc);
       
   384 
       
   385         generate_handle_exception(sasm, oop_maps, oop_map);
       
   386         __ should_not_reach_here();
       
   387       }
   370       }
   388       break;
   371       break;
   389 
   372 
   390     case new_instance_id:
   373     case new_instance_id:
   391     case fast_new_instance_id:
   374     case fast_new_instance_id:
   669         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_null_pointer_exception), false);
   652         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_null_pointer_exception), false);
   670       }
   653       }
   671       break;
   654       break;
   672 
   655 
   673     case handle_exception_id:
   656     case handle_exception_id:
   674       {
   657       { __ set_info("handle_exception", dont_gc_arguments);
   675         __ set_info("handle_exception", dont_gc_arguments);
   658         oop_maps = generate_handle_exception(id, sasm);
   676         // make a frame and preserve the caller's caller-save registers
   659       }
   677 
   660       break;
   678         oop_maps = new OopMapSet();
   661 
   679         OopMap* oop_map = save_live_registers(sasm);
   662     case handle_exception_from_callee_id:
   680         __ mov(Oexception->after_save(),  Oexception);
   663       { __ set_info("handle_exception_from_callee", dont_gc_arguments);
   681         __ mov(Oissuing_pc->after_save(), Oissuing_pc);
   664         oop_maps = generate_handle_exception(id, sasm);
   682         generate_handle_exception(sasm, oop_maps, oop_map);
       
   683       }
   665       }
   684       break;
   666       break;
   685 
   667 
   686     case unwind_exception_id:
   668     case unwind_exception_id:
   687       {
   669       {
   694 
   676 
   695         __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address),
   677         __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address),
   696                         G2_thread, Oissuing_pc->after_save());
   678                         G2_thread, Oissuing_pc->after_save());
   697         __ verify_not_null_oop(Oexception->after_save());
   679         __ verify_not_null_oop(Oexception->after_save());
   698 
   680 
   699         // Restore SP from L7 if the exception PC is a MethodHandle call site.
   681         // Restore SP from L7 if the exception PC is a method handle call site.
   700         __ mov(O0, G5);  // Save the target address.
   682         __ mov(O0, G5);  // Save the target address.
   701         __ lduw(Address(G2_thread, JavaThread::is_method_handle_return_offset()), L0);
   683         __ lduw(Address(G2_thread, JavaThread::is_method_handle_return_offset()), L0);
   702         __ tst(L0);  // Condition codes are preserved over the restore.
   684         __ tst(L0);  // Condition codes are preserved over the restore.
   703         __ restore();
   685         __ restore();
   704 
   686 
  1004   }
   986   }
  1005   return oop_maps;
   987   return oop_maps;
  1006 }
   988 }
  1007 
   989 
  1008 
   990 
  1009 void Runtime1::generate_handle_exception(StubAssembler* sasm, OopMapSet* oop_maps, OopMap* oop_map, bool) {
   991 OopMapSet* Runtime1::generate_handle_exception(StubID id, StubAssembler* sasm) {
  1010   Label no_deopt;
   992   __ block_comment("generate_handle_exception");
       
   993 
       
   994   // Save registers, if required.
       
   995   OopMapSet* oop_maps = new OopMapSet();
       
   996   OopMap* oop_map = NULL;
       
   997   switch (id) {
       
   998   case forward_exception_id:
       
   999     // We're handling an exception in the context of a compiled frame.
       
  1000     // The registers have been saved in the standard places.  Perform
       
  1001     // an exception lookup in the caller and dispatch to the handler
       
  1002     // if found.  Otherwise unwind and dispatch to the callers
       
  1003     // exception handler.
       
  1004      oop_map = generate_oop_map(sasm, true);
       
  1005 
       
  1006      // transfer the pending exception to the exception_oop
       
  1007      __ ld_ptr(G2_thread, in_bytes(JavaThread::pending_exception_offset()), Oexception);
       
  1008      __ ld_ptr(Oexception, 0, G0);
       
  1009      __ st_ptr(G0, G2_thread, in_bytes(JavaThread::pending_exception_offset()));
       
  1010      __ add(I7, frame::pc_return_offset, Oissuing_pc);
       
  1011     break;
       
  1012   case handle_exception_id:
       
  1013     // At this point all registers MAY be live.
       
  1014     oop_map = save_live_registers(sasm);
       
  1015     __ mov(Oexception->after_save(),  Oexception);
       
  1016     __ mov(Oissuing_pc->after_save(), Oissuing_pc);
       
  1017     break;
       
  1018   case handle_exception_from_callee_id:
       
  1019     // At this point all registers except exception oop (Oexception)
       
  1020     // and exception pc (Oissuing_pc) are dead.
       
  1021     oop_map = new OopMap(frame_size_in_bytes / sizeof(jint), 0);
       
  1022     sasm->set_frame_size(frame_size_in_bytes / BytesPerWord);
       
  1023     __ save_frame_c1(frame_size_in_bytes);
       
  1024     __ mov(Oexception->after_save(),  Oexception);
       
  1025     __ mov(Oissuing_pc->after_save(), Oissuing_pc);
       
  1026     break;
       
  1027   default:  ShouldNotReachHere();
       
  1028   }
  1011 
  1029 
  1012   __ verify_not_null_oop(Oexception);
  1030   __ verify_not_null_oop(Oexception);
  1013 
  1031 
  1014   // save the exception and issuing pc in the thread
  1032   // save the exception and issuing pc in the thread
  1015   __ st_ptr(Oexception, G2_thread, in_bytes(JavaThread::exception_oop_offset()));
  1033   __ st_ptr(Oexception,  G2_thread, in_bytes(JavaThread::exception_oop_offset()));
  1016   __ st_ptr(Oissuing_pc, G2_thread, in_bytes(JavaThread::exception_pc_offset()));
  1034   __ st_ptr(Oissuing_pc, G2_thread, in_bytes(JavaThread::exception_pc_offset()));
  1017 
  1035 
  1018   // save the real return address and use the throwing pc as the return address to lookup (has bci & oop map)
  1036   // use the throwing pc as the return address to lookup (has bci & oop map)
  1019   __ mov(I7, L0);
       
  1020   __ mov(Oissuing_pc, I7);
  1037   __ mov(Oissuing_pc, I7);
  1021   __ sub(I7, frame::pc_return_offset, I7);
  1038   __ sub(I7, frame::pc_return_offset, I7);
  1022   int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc));
  1039   int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc));
       
  1040   oop_maps->add_gc_map(call_offset, oop_map);
  1023 
  1041 
  1024   // Note: if nmethod has been deoptimized then regardless of
  1042   // Note: if nmethod has been deoptimized then regardless of
  1025   // whether it had a handler or not we will deoptimize
  1043   // whether it had a handler or not we will deoptimize
  1026   // by entering the deopt blob with a pending exception.
  1044   // by entering the deopt blob with a pending exception.
  1027 
  1045 
  1028 #ifdef ASSERT
  1046   // Restore the registers that were saved at the beginning, remove
  1029   Label done;
  1047   // the frame and jump to the exception handler.
  1030   __ tst(O0);
  1048   switch (id) {
  1031   __ br(Assembler::notZero, false, Assembler::pn, done);
  1049   case forward_exception_id:
  1032   __ delayed()->nop();
  1050   case handle_exception_id:
  1033   __ stop("should have found address");
  1051     restore_live_registers(sasm);
  1034   __ bind(done);
  1052     __ jmp(O0, 0);
  1035 #endif
  1053     __ delayed()->restore();
  1036 
  1054     break;
  1037   // restore the registers that were saved at the beginning and jump to the exception handler.
  1055   case handle_exception_from_callee_id:
  1038   restore_live_registers(sasm);
  1056     // Restore SP from L7 if the exception PC is a method handle call site.
  1039 
  1057     __ mov(O0, G5);  // Save the target address.
  1040   __ jmp(O0, 0);
  1058     __ lduw(Address(G2_thread, JavaThread::is_method_handle_return_offset()), L0);
  1041   __ delayed()->restore();
  1059     __ tst(L0);  // Condition codes are preserved over the restore.
  1042 
  1060     __ restore();
  1043   oop_maps->add_gc_map(call_offset, oop_map);
  1061 
       
  1062     __ jmp(G5, 0);  // jump to the exception handler
       
  1063     __ delayed()->movcc(Assembler::notZero, false, Assembler::icc, L7_mh_SP_save, SP);  // Restore SP if required.
       
  1064     break;
       
  1065   default:  ShouldNotReachHere();
       
  1066   }
       
  1067 
       
  1068   return oop_maps;
  1044 }
  1069 }
  1045 
  1070 
  1046 
  1071 
  1047 #undef __
  1072 #undef __
  1048 
       
  1049 #define __ masm->
       
  1050 
  1073 
  1051 const char *Runtime1::pd_name_for_address(address entry) {
  1074 const char *Runtime1::pd_name_for_address(address entry) {
  1052   return "<unknown function>";
  1075   return "<unknown function>";
  1053 }
  1076 }