comparison src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @ 1295:3cf667df43ef

6919934: JSR 292 needs to support x86 C1 Summary: This implements JSR 292 support for C1 x86. Reviewed-by: never, jrose, kvn
author twisti
date Tue, 09 Mar 2010 20:16:19 +0100
parents 7b4415a18c8a
children c466efa608d5
comparison
equal deleted inserted replaced
1293:51db1e4b379d 1295:3cf667df43ef
434 return -1; 434 return -1;
435 } 435 }
436 436
437 int offset = code_offset(); 437 int offset = code_offset();
438 438
439 // if the method does not have an exception handler, then there is 439 // the exception oop and pc are in rax, and rdx
440 // no reason to search for one
441 if (compilation()->has_exception_handlers() || compilation()->env()->jvmti_can_post_on_exceptions()) {
442 // the exception oop and pc are in rax, and rdx
443 // no other registers need to be preserved, so invalidate them
444 __ invalidate_registers(false, true, true, false, true, true);
445
446 // check that there is really an exception
447 __ verify_not_null_oop(rax);
448
449 // search an exception handler (rax: exception oop, rdx: throwing pc)
450 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::handle_exception_nofpu_id)));
451
452 // if the call returns here, then the exception handler for particular
453 // exception doesn't exist -> unwind activation and forward exception to caller
454 }
455
456 // the exception oop is in rax,
457 // no other registers need to be preserved, so invalidate them 440 // no other registers need to be preserved, so invalidate them
458 __ invalidate_registers(false, true, true, true, true, true); 441 __ invalidate_registers(false, true, true, false, true, true);
459 442
460 // check that there is really an exception 443 // check that there is really an exception
461 __ verify_not_null_oop(rax); 444 __ verify_not_null_oop(rax);
462 445
463 // unlock the receiver/klass if necessary 446 // search an exception handler (rax: exception oop, rdx: throwing pc)
464 // rax,: exception 447 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::handle_exception_nofpu_id)));
465 ciMethod* method = compilation()->method(); 448
466 if (method->is_synchronized() && GenerateSynchronizationCode) { 449 __ stop("should not reach here");
467 monitorexit(FrameMap::rbx_oop_opr, FrameMap::rcx_opr, SYNC_header, 0, rax); 450
468 }
469
470 // unwind activation and forward exception to caller
471 // rax,: exception
472 __ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id)));
473 assert(code_offset() - offset <= exception_handler_size, "overflow"); 451 assert(code_offset() - offset <= exception_handler_size, "overflow");
474 __ end_a_stub(); 452 __ end_a_stub();
475 453
476 return offset; 454 return offset;
477 } 455 }
493 return -1; 471 return -1;
494 } 472 }
495 473
496 int offset = code_offset(); 474 int offset = code_offset();
497 InternalAddress here(__ pc()); 475 InternalAddress here(__ pc());
476
498 __ pushptr(here.addr()); 477 __ pushptr(here.addr());
499 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 478 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
479
500 assert(code_offset() - offset <= deopt_handler_size, "overflow"); 480 assert(code_offset() - offset <= deopt_handler_size, "overflow");
501 __ end_a_stub(); 481 __ end_a_stub();
502 482
503 return offset; 483 return offset;
504 } 484 }
591 if (!result->is_illegal() && result->is_float_kind() && !result->is_xmm_register()) { 571 if (!result->is_illegal() && result->is_float_kind() && !result->is_xmm_register()) {
592 assert(result->fpu() == 0, "result must already be on TOS"); 572 assert(result->fpu() == 0, "result must already be on TOS");
593 } 573 }
594 574
595 // Pop the stack before the safepoint code 575 // Pop the stack before the safepoint code
596 __ leave(); 576 __ remove_frame(initial_frame_size_in_bytes());
597 577
598 bool result_is_oop = result->is_valid() ? result->is_oop() : false; 578 bool result_is_oop = result->is_valid() ? result->is_oop() : false;
599 579
600 // Note: we do not need to round double result; float result has the right precision 580 // Note: we do not need to round double result; float result has the right precision
601 // the poll sets the condition code, but no data registers 581 // the poll sets the condition code, but no data registers
2736 // make sure that the displacement word of the call ends up word aligned 2716 // make sure that the displacement word of the call ends up word aligned
2737 int offset = __ offset(); 2717 int offset = __ offset();
2738 switch (code) { 2718 switch (code) {
2739 case lir_static_call: 2719 case lir_static_call:
2740 case lir_optvirtual_call: 2720 case lir_optvirtual_call:
2721 case lir_dynamic_call:
2741 offset += NativeCall::displacement_offset; 2722 offset += NativeCall::displacement_offset;
2742 break; 2723 break;
2743 case lir_icvirtual_call: 2724 case lir_icvirtual_call:
2744 offset += NativeCall::displacement_offset + NativeMovConstReg::instruction_size; 2725 offset += NativeCall::displacement_offset + NativeMovConstReg::instruction_size;
2745 break; 2726 break;
2751 } 2732 }
2752 } 2733 }
2753 } 2734 }
2754 2735
2755 2736
2756 void LIR_Assembler::call(address entry, relocInfo::relocType rtype, CodeEmitInfo* info) { 2737 void LIR_Assembler::call(LIR_OpJavaCall* op, relocInfo::relocType rtype) {
2757 assert(!os::is_MP() || (__ offset() + NativeCall::displacement_offset) % BytesPerWord == 0, 2738 assert(!os::is_MP() || (__ offset() + NativeCall::displacement_offset) % BytesPerWord == 0,
2758 "must be aligned"); 2739 "must be aligned");
2759 __ call(AddressLiteral(entry, rtype)); 2740 __ call(AddressLiteral(op->addr(), rtype));
2760 add_call_info(code_offset(), info); 2741 add_call_info(code_offset(), op->info(), op->is_method_handle_invoke());
2761 } 2742 }
2762 2743
2763 2744
2764 void LIR_Assembler::ic_call(address entry, CodeEmitInfo* info) { 2745 void LIR_Assembler::ic_call(LIR_OpJavaCall* op) {
2765 RelocationHolder rh = virtual_call_Relocation::spec(pc()); 2746 RelocationHolder rh = virtual_call_Relocation::spec(pc());
2766 __ movoop(IC_Klass, (jobject)Universe::non_oop_word()); 2747 __ movoop(IC_Klass, (jobject)Universe::non_oop_word());
2767 assert(!os::is_MP() || 2748 assert(!os::is_MP() ||
2768 (__ offset() + NativeCall::displacement_offset) % BytesPerWord == 0, 2749 (__ offset() + NativeCall::displacement_offset) % BytesPerWord == 0,
2769 "must be aligned"); 2750 "must be aligned");
2770 __ call(AddressLiteral(entry, rh)); 2751 __ call(AddressLiteral(op->addr(), rh));
2771 add_call_info(code_offset(), info); 2752 add_call_info(code_offset(), op->info(), op->is_method_handle_invoke());
2772 } 2753 }
2773 2754
2774 2755
2775 /* Currently, vtable-dispatch is only enabled for sparc platforms */ 2756 /* Currently, vtable-dispatch is only enabled for sparc platforms */
2776 void LIR_Assembler::vtable_call(int vtable_offset, CodeEmitInfo* info) { 2757 void LIR_Assembler::vtable_call(LIR_OpJavaCall* op) {
2777 ShouldNotReachHere(); 2758 ShouldNotReachHere();
2778 } 2759 }
2760
2761
2762 void LIR_Assembler::preserve_SP() {
2763 __ movptr(rbp, rsp);
2764 }
2765
2766
2767 void LIR_Assembler::restore_SP() {
2768 __ movptr(rsp, rbp);
2769 }
2770
2779 2771
2780 void LIR_Assembler::emit_static_call_stub() { 2772 void LIR_Assembler::emit_static_call_stub() {
2781 address call_pc = __ pc(); 2773 address call_pc = __ pc();
2782 address stub = __ start_a_stub(call_stub_size); 2774 address stub = __ start_a_stub(call_stub_size);
2783 if (stub == NULL) { 2775 if (stub == NULL) {
2827 if (compilation()->has_fpu_code()) { 2819 if (compilation()->has_fpu_code()) {
2828 unwind_id = Runtime1::handle_exception_id; 2820 unwind_id = Runtime1::handle_exception_id;
2829 } else { 2821 } else {
2830 unwind_id = Runtime1::handle_exception_nofpu_id; 2822 unwind_id = Runtime1::handle_exception_nofpu_id;
2831 } 2823 }
2824 __ call(RuntimeAddress(Runtime1::entry_for(unwind_id)));
2832 } else { 2825 } else {
2833 unwind_id = Runtime1::unwind_exception_id; 2826 // remove the activation
2834 } 2827 __ remove_frame(initial_frame_size_in_bytes());
2835 __ call(RuntimeAddress(Runtime1::entry_for(unwind_id))); 2828 __ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id)));
2829 }
2836 2830
2837 // enough room for two byte trap 2831 // enough room for two byte trap
2838 __ nop(); 2832 __ nop();
2839 } 2833 }
2840 2834