comparison src/cpu/sparc/vm/c1_Runtime1_sparc.cpp @ 2321:1b4e6a5d98e0

7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc Reviewed-by: never, bdelsart
author twisti
date Mon, 28 Feb 2011 06:07:12 -0800
parents 635b068a7224
children 3d42f82cd811
comparison
equal deleted inserted replaced
2320:41d4973cf100 2321:1b4e6a5d98e0
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 }