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 } |