src/cpu/x86/vm/c1_LIRAssembler_x86.cpp

changeset 1813
9f5b60a14736
parent 1804
0a43776437b6
child 1833
314e17ca2c23
child 1844
cff162798819
equal deleted inserted replaced
1812:ef74d6d1ac1e 1813:9f5b60a14736
448 448
449 __ stop("should not reach here"); 449 __ stop("should not reach here");
450 450
451 assert(code_offset() - offset <= exception_handler_size, "overflow"); 451 assert(code_offset() - offset <= exception_handler_size, "overflow");
452 __ end_a_stub(); 452 __ end_a_stub();
453
454 return offset;
455 }
456
457
458 // Emit the code to remove the frame from the stack in the exception
459 // unwind path.
460 int LIR_Assembler::emit_unwind_handler() {
461 #ifndef PRODUCT
462 if (CommentedAssembly) {
463 _masm->block_comment("Unwind handler");
464 }
465 #endif
466
467 int offset = code_offset();
468
469 // Fetch the exception from TLS and clear out exception related thread state
470 __ get_thread(rsi);
471 __ movptr(rax, Address(rsi, JavaThread::exception_oop_offset()));
472 __ movptr(Address(rsi, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD);
473 __ movptr(Address(rsi, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD);
474
475 __ bind(_unwind_handler_entry);
476 __ verify_not_null_oop(rax);
477 if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) {
478 __ mov(rsi, rax); // Preserve the exception
479 }
480
481 // Preform needed unlocking
482 MonitorExitStub* stub = NULL;
483 if (method()->is_synchronized()) {
484 monitor_address(0, FrameMap::rax_opr);
485 stub = new MonitorExitStub(FrameMap::rax_opr, true, 0);
486 __ unlock_object(rdi, rbx, rax, *stub->entry());
487 __ bind(*stub->continuation());
488 }
489
490 if (compilation()->env()->dtrace_method_probes()) {
491 __ movoop(Address(rsp, 0), method()->constant_encoding());
492 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit)));
493 }
494
495 if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) {
496 __ mov(rax, rsi); // Restore the exception
497 }
498
499 // remove the activation and dispatch to the unwind handler
500 __ remove_frame(initial_frame_size_in_bytes());
501 __ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id)));
502
503 // Emit the slow path assembly
504 if (stub != NULL) {
505 stub->emit_code(this);
506 }
453 507
454 return offset; 508 return offset;
455 } 509 }
456 510
457 511
2793 assert(__ offset() - start <= call_stub_size, "stub too big") 2847 assert(__ offset() - start <= call_stub_size, "stub too big")
2794 __ end_a_stub(); 2848 __ end_a_stub();
2795 } 2849 }
2796 2850
2797 2851
2798 void LIR_Assembler::throw_op(LIR_Opr exceptionPC, LIR_Opr exceptionOop, CodeEmitInfo* info, bool unwind) { 2852 void LIR_Assembler::throw_op(LIR_Opr exceptionPC, LIR_Opr exceptionOop, CodeEmitInfo* info) {
2799 assert(exceptionOop->as_register() == rax, "must match"); 2853 assert(exceptionOop->as_register() == rax, "must match");
2800 assert(unwind || exceptionPC->as_register() == rdx, "must match"); 2854 assert(exceptionPC->as_register() == rdx, "must match");
2801 2855
2802 // exception object is not added to oop map by LinearScan 2856 // exception object is not added to oop map by LinearScan
2803 // (LinearScan assumes that no oops are in fixed registers) 2857 // (LinearScan assumes that no oops are in fixed registers)
2804 info->add_register_oop(exceptionOop); 2858 info->add_register_oop(exceptionOop);
2805 Runtime1::StubID unwind_id; 2859 Runtime1::StubID unwind_id;
2806 2860
2807 if (!unwind) { 2861 // get current pc information
2808 // get current pc information 2862 // pc is only needed if the method has an exception handler, the unwind code does not need it.
2809 // pc is only needed if the method has an exception handler, the unwind code does not need it. 2863 int pc_for_athrow_offset = __ offset();
2810 int pc_for_athrow_offset = __ offset(); 2864 InternalAddress pc_for_athrow(__ pc());
2811 InternalAddress pc_for_athrow(__ pc()); 2865 __ lea(exceptionPC->as_register(), pc_for_athrow);
2812 __ lea(exceptionPC->as_register(), pc_for_athrow); 2866 add_call_info(pc_for_athrow_offset, info); // for exception handler
2813 add_call_info(pc_for_athrow_offset, info); // for exception handler 2867
2814 2868 __ verify_not_null_oop(rax);
2815 __ verify_not_null_oop(rax); 2869 // search an exception handler (rax: exception oop, rdx: throwing pc)
2816 // search an exception handler (rax: exception oop, rdx: throwing pc) 2870 if (compilation()->has_fpu_code()) {
2817 if (compilation()->has_fpu_code()) { 2871 unwind_id = Runtime1::handle_exception_id;
2818 unwind_id = Runtime1::handle_exception_id;
2819 } else {
2820 unwind_id = Runtime1::handle_exception_nofpu_id;
2821 }
2822 __ call(RuntimeAddress(Runtime1::entry_for(unwind_id)));
2823 } else { 2872 } else {
2824 // remove the activation 2873 unwind_id = Runtime1::handle_exception_nofpu_id;
2825 __ remove_frame(initial_frame_size_in_bytes()); 2874 }
2826 __ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id))); 2875 __ call(RuntimeAddress(Runtime1::entry_for(unwind_id)));
2827 }
2828 2876
2829 // enough room for two byte trap 2877 // enough room for two byte trap
2830 __ nop(); 2878 __ nop();
2879 }
2880
2881
2882 void LIR_Assembler::unwind_op(LIR_Opr exceptionOop) {
2883 assert(exceptionOop->as_register() == rax, "must match");
2884
2885 __ jmp(_unwind_handler_entry);
2831 } 2886 }
2832 2887
2833 2888
2834 void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, LIR_Opr count, LIR_Opr dest, LIR_Opr tmp) { 2889 void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, LIR_Opr count, LIR_Opr dest, LIR_Opr tmp) {
2835 2890

mercurial