Mercurial > hg > graal-compiler
comparison src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @ 13086:096c224171c4
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 20 Nov 2013 00:10:38 +0100 |
parents | 9acbfe04b5c3 |
children | 9bcf7b329013 |
comparison
equal
deleted
inserted
replaced
12782:92b7ec34ddfa | 13086:096c224171c4 |
---|---|
430 #endif | 430 #endif |
431 | 431 |
432 int offset = code_offset(); | 432 int offset = code_offset(); |
433 | 433 |
434 // Fetch the exception from TLS and clear out exception related thread state | 434 // Fetch the exception from TLS and clear out exception related thread state |
435 __ get_thread(rsi); | 435 Register thread = NOT_LP64(rsi) LP64_ONLY(r15_thread); |
436 __ movptr(rax, Address(rsi, JavaThread::exception_oop_offset())); | 436 NOT_LP64(__ get_thread(rsi)); |
437 __ movptr(Address(rsi, JavaThread::exception_oop_offset()), (intptr_t)NULL_WORD); | 437 __ movptr(rax, Address(thread, JavaThread::exception_oop_offset())); |
438 __ movptr(Address(rsi, JavaThread::exception_pc_offset()), (intptr_t)NULL_WORD); | 438 __ movptr(Address(thread, JavaThread::exception_oop_offset()), (intptr_t)NULL_WORD); |
439 __ movptr(Address(thread, JavaThread::exception_pc_offset()), (intptr_t)NULL_WORD); | |
439 | 440 |
440 __ bind(_unwind_handler_entry); | 441 __ bind(_unwind_handler_entry); |
441 __ verify_not_null_oop(rax); | 442 __ verify_not_null_oop(rax); |
442 if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) { | 443 if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) { |
443 __ mov(rsi, rax); // Preserve the exception | 444 __ mov(rbx, rax); // Preserve the exception (rbx is always callee-saved) |
444 } | 445 } |
445 | 446 |
446 // Preform needed unlocking | 447 // Preform needed unlocking |
447 MonitorExitStub* stub = NULL; | 448 MonitorExitStub* stub = NULL; |
448 if (method()->is_synchronized()) { | 449 if (method()->is_synchronized()) { |
449 monitor_address(0, FrameMap::rax_opr); | 450 monitor_address(0, FrameMap::rax_opr); |
450 stub = new MonitorExitStub(FrameMap::rax_opr, true, 0); | 451 stub = new MonitorExitStub(FrameMap::rax_opr, true, 0); |
451 __ unlock_object(rdi, rbx, rax, *stub->entry()); | 452 __ unlock_object(rdi, rsi, rax, *stub->entry()); |
452 __ bind(*stub->continuation()); | 453 __ bind(*stub->continuation()); |
453 } | 454 } |
454 | 455 |
455 if (compilation()->env()->dtrace_method_probes()) { | 456 if (compilation()->env()->dtrace_method_probes()) { |
457 #ifdef _LP64 | |
458 __ mov(rdi, r15_thread); | |
459 __ mov_metadata(rsi, method()->constant_encoding()); | |
460 #else | |
456 __ get_thread(rax); | 461 __ get_thread(rax); |
457 __ movptr(Address(rsp, 0), rax); | 462 __ movptr(Address(rsp, 0), rax); |
458 __ mov_metadata(Address(rsp, sizeof(void*)), method()->constant_encoding()); | 463 __ mov_metadata(Address(rsp, sizeof(void*)), method()->constant_encoding()); |
464 #endif | |
459 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit))); | 465 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit))); |
460 } | 466 } |
461 | 467 |
462 if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) { | 468 if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) { |
463 __ mov(rax, rsi); // Restore the exception | 469 __ mov(rax, rbx); // Restore the exception |
464 } | 470 } |
465 | 471 |
466 // remove the activation and dispatch to the unwind handler | 472 // remove the activation and dispatch to the unwind handler |
467 __ remove_frame(initial_frame_size_in_bytes()); | 473 __ remove_frame(initial_frame_size_in_bytes()); |
468 __ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id))); | 474 __ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id))); |
1203 assert(src->is_address(), "should not call otherwise"); | 1209 assert(src->is_address(), "should not call otherwise"); |
1204 assert(dest->is_register(), "should not call otherwise"); | 1210 assert(dest->is_register(), "should not call otherwise"); |
1205 | 1211 |
1206 LIR_Address* addr = src->as_address_ptr(); | 1212 LIR_Address* addr = src->as_address_ptr(); |
1207 Address from_addr = as_Address(addr); | 1213 Address from_addr = as_Address(addr); |
1214 | |
1215 if (addr->base()->type() == T_OBJECT) { | |
1216 __ verify_oop(addr->base()->as_pointer_register()); | |
1217 } | |
1208 | 1218 |
1209 switch (type) { | 1219 switch (type) { |
1210 case T_BOOLEAN: // fall through | 1220 case T_BOOLEAN: // fall through |
1211 case T_BYTE: // fall through | 1221 case T_BYTE: // fall through |
1212 case T_CHAR: // fall through | 1222 case T_CHAR: // fall through |
3630 // Static call | 3640 // Static call |
3631 __ addptr(counter_addr, DataLayout::counter_increment); | 3641 __ addptr(counter_addr, DataLayout::counter_increment); |
3632 } | 3642 } |
3633 } | 3643 } |
3634 | 3644 |
3645 void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { | |
3646 Register obj = op->obj()->as_register(); | |
3647 Register tmp = op->tmp()->as_pointer_register(); | |
3648 Address mdo_addr = as_Address(op->mdp()->as_address_ptr()); | |
3649 ciKlass* exact_klass = op->exact_klass(); | |
3650 intptr_t current_klass = op->current_klass(); | |
3651 bool not_null = op->not_null(); | |
3652 bool no_conflict = op->no_conflict(); | |
3653 | |
3654 Label update, next, none; | |
3655 | |
3656 bool do_null = !not_null; | |
3657 bool exact_klass_set = exact_klass != NULL && ciTypeEntries::valid_ciklass(current_klass) == exact_klass; | |
3658 bool do_update = !TypeEntries::is_type_unknown(current_klass) && !exact_klass_set; | |
3659 | |
3660 assert(do_null || do_update, "why are we here?"); | |
3661 assert(!TypeEntries::was_null_seen(current_klass) || do_update, "why are we here?"); | |
3662 | |
3663 __ verify_oop(obj); | |
3664 | |
3665 if (tmp != obj) { | |
3666 __ mov(tmp, obj); | |
3667 } | |
3668 if (do_null) { | |
3669 __ testptr(tmp, tmp); | |
3670 __ jccb(Assembler::notZero, update); | |
3671 if (!TypeEntries::was_null_seen(current_klass)) { | |
3672 __ orptr(mdo_addr, TypeEntries::null_seen); | |
3673 } | |
3674 if (do_update) { | |
3675 #ifndef ASSERT | |
3676 __ jmpb(next); | |
3677 } | |
3678 #else | |
3679 __ jmp(next); | |
3680 } | |
3681 } else { | |
3682 __ testptr(tmp, tmp); | |
3683 __ jccb(Assembler::notZero, update); | |
3684 __ stop("unexpect null obj"); | |
3685 #endif | |
3686 } | |
3687 | |
3688 __ bind(update); | |
3689 | |
3690 if (do_update) { | |
3691 #ifdef ASSERT | |
3692 if (exact_klass != NULL) { | |
3693 Label ok; | |
3694 __ load_klass(tmp, tmp); | |
3695 __ push(tmp); | |
3696 __ mov_metadata(tmp, exact_klass->constant_encoding()); | |
3697 __ cmpptr(tmp, Address(rsp, 0)); | |
3698 __ jccb(Assembler::equal, ok); | |
3699 __ stop("exact klass and actual klass differ"); | |
3700 __ bind(ok); | |
3701 __ pop(tmp); | |
3702 } | |
3703 #endif | |
3704 if (!no_conflict) { | |
3705 if (exact_klass == NULL || TypeEntries::is_type_none(current_klass)) { | |
3706 if (exact_klass != NULL) { | |
3707 __ mov_metadata(tmp, exact_klass->constant_encoding()); | |
3708 } else { | |
3709 __ load_klass(tmp, tmp); | |
3710 } | |
3711 | |
3712 __ xorptr(tmp, mdo_addr); | |
3713 __ testptr(tmp, TypeEntries::type_klass_mask); | |
3714 // klass seen before, nothing to do. The unknown bit may have been | |
3715 // set already but no need to check. | |
3716 __ jccb(Assembler::zero, next); | |
3717 | |
3718 __ testptr(tmp, TypeEntries::type_unknown); | |
3719 __ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore. | |
3720 | |
3721 if (TypeEntries::is_type_none(current_klass)) { | |
3722 __ cmpptr(mdo_addr, 0); | |
3723 __ jccb(Assembler::equal, none); | |
3724 __ cmpptr(mdo_addr, TypeEntries::null_seen); | |
3725 __ jccb(Assembler::equal, none); | |
3726 // There is a chance that the checks above (re-reading profiling | |
3727 // data from memory) fail if another thread has just set the | |
3728 // profiling to this obj's klass | |
3729 __ xorptr(tmp, mdo_addr); | |
3730 __ testptr(tmp, TypeEntries::type_klass_mask); | |
3731 __ jccb(Assembler::zero, next); | |
3732 } | |
3733 } else { | |
3734 assert(ciTypeEntries::valid_ciklass(current_klass) != NULL && | |
3735 ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "conflict only"); | |
3736 | |
3737 __ movptr(tmp, mdo_addr); | |
3738 __ testptr(tmp, TypeEntries::type_unknown); | |
3739 __ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore. | |
3740 } | |
3741 | |
3742 // different than before. Cannot keep accurate profile. | |
3743 __ orptr(mdo_addr, TypeEntries::type_unknown); | |
3744 | |
3745 if (TypeEntries::is_type_none(current_klass)) { | |
3746 __ jmpb(next); | |
3747 | |
3748 __ bind(none); | |
3749 // first time here. Set profile type. | |
3750 __ movptr(mdo_addr, tmp); | |
3751 } | |
3752 } else { | |
3753 // There's a single possible klass at this profile point | |
3754 assert(exact_klass != NULL, "should be"); | |
3755 if (TypeEntries::is_type_none(current_klass)) { | |
3756 __ mov_metadata(tmp, exact_klass->constant_encoding()); | |
3757 __ xorptr(tmp, mdo_addr); | |
3758 __ testptr(tmp, TypeEntries::type_klass_mask); | |
3759 #ifdef ASSERT | |
3760 __ jcc(Assembler::zero, next); | |
3761 | |
3762 { | |
3763 Label ok; | |
3764 __ push(tmp); | |
3765 __ cmpptr(mdo_addr, 0); | |
3766 __ jcc(Assembler::equal, ok); | |
3767 __ cmpptr(mdo_addr, TypeEntries::null_seen); | |
3768 __ jcc(Assembler::equal, ok); | |
3769 // may have been set by another thread | |
3770 __ mov_metadata(tmp, exact_klass->constant_encoding()); | |
3771 __ xorptr(tmp, mdo_addr); | |
3772 __ testptr(tmp, TypeEntries::type_mask); | |
3773 __ jcc(Assembler::zero, ok); | |
3774 | |
3775 __ stop("unexpected profiling mismatch"); | |
3776 __ bind(ok); | |
3777 __ pop(tmp); | |
3778 } | |
3779 #else | |
3780 __ jccb(Assembler::zero, next); | |
3781 #endif | |
3782 // first time here. Set profile type. | |
3783 __ movptr(mdo_addr, tmp); | |
3784 } else { | |
3785 assert(ciTypeEntries::valid_ciklass(current_klass) != NULL && | |
3786 ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "inconsistent"); | |
3787 | |
3788 __ movptr(tmp, mdo_addr); | |
3789 __ testptr(tmp, TypeEntries::type_unknown); | |
3790 __ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore. | |
3791 | |
3792 __ orptr(mdo_addr, TypeEntries::type_unknown); | |
3793 } | |
3794 } | |
3795 | |
3796 __ bind(next); | |
3797 } | |
3798 } | |
3799 | |
3635 void LIR_Assembler::emit_delay(LIR_OpDelay*) { | 3800 void LIR_Assembler::emit_delay(LIR_OpDelay*) { |
3636 Unimplemented(); | 3801 Unimplemented(); |
3637 } | 3802 } |
3638 | 3803 |
3639 | 3804 |