Mercurial > hg > graal-compiler
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 |