631 __ ret(0); // jump to next address
632
633 return start;
634 }
635
636
637 //----------------------------------------------------------------------------------------------------
638 // Non-destructive plausibility checks for oops
639
640 address generate_verify_oop() {
641 StubCodeMark mark(this, "StubRoutines", "verify_oop");
642 address start = __ pc();
643
644 // Incoming arguments on stack after saving rax,:
645 //
646 // [tos ]: saved rdx
647 // [tos + 1]: saved EFLAGS
648 // [tos + 2]: return address
649 // [tos + 3]: char* error message
650 // [tos + 4]: oop object to verify
651 // [tos + 5]: saved rax, - saved by caller and bashed
652
653 Label exit, error;
654 __ pushf();
655 __ incrementl(ExternalAddress((address) StubRoutines::verify_oop_count_addr()));
656 __ push(rdx); // save rdx
657 // make sure object is 'reasonable'
658 __ movptr(rax, Address(rsp, 4 * wordSize)); // get object
659 __ testptr(rax, rax);
660 __ jcc(Assembler::zero, exit); // if obj is NULL it is ok
661
662 // Check if the oop is in the right area of memory
663 const int oop_mask = Universe::verify_oop_mask();
664 const int oop_bits = Universe::verify_oop_bits();
665 __ mov(rdx, rax);
666 __ andptr(rdx, oop_mask);
667 __ cmpptr(rdx, oop_bits);
668 __ jcc(Assembler::notZero, error);
669
670 // make sure klass is 'reasonable'
671 __ movptr(rax, Address(rax, oopDesc::klass_offset_in_bytes())); // get klass
679 __ andptr(rdx, klass_mask);
680 __ cmpptr(rdx, klass_bits);
681 __ jcc(Assembler::notZero, error);
682
683 // make sure klass' klass is 'reasonable'
684 __ movptr(rax, Address(rax, oopDesc::klass_offset_in_bytes())); // get klass' klass
685 __ testptr(rax, rax);
686 __ jcc(Assembler::zero, error); // if klass' klass is NULL it is broken
687
688 __ mov(rdx, rax);
689 __ andptr(rdx, klass_mask);
690 __ cmpptr(rdx, klass_bits);
691 __ jcc(Assembler::notZero, error); // if klass not in right area
692 // of memory it is broken too.
693
694 // return if everything seems ok
695 __ bind(exit);
696 __ movptr(rax, Address(rsp, 5 * wordSize)); // get saved rax, back
697 __ pop(rdx); // restore rdx
698 __ popf(); // restore EFLAGS
699 __ ret(3 * wordSize); // pop arguments
700
701 // handle errors
702 __ bind(error);
703 __ movptr(rax, Address(rsp, 5 * wordSize)); // get saved rax, back
704 __ pop(rdx); // get saved rdx back
705 __ popf(); // get saved EFLAGS off stack -- will be ignored
706 __ pusha(); // push registers (eip = return address & msg are already pushed)
707 BLOCK_COMMENT("call MacroAssembler::debug");
708 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug32)));
709 __ popa();
710 __ ret(3 * wordSize); // pop arguments
711 return start;
712 }
713
714 //
715 // Generate pre-barrier for array stores
716 //
717 // Input:
718 // start - starting address
719 // count - element count
720 void gen_write_ref_array_pre_barrier(Register start, Register count) {
721 assert_different_registers(start, count);
722 BarrierSet* bs = Universe::heap()->barrier_set();
723 switch (bs->kind()) {
724 case BarrierSet::G1SATBCT:
725 case BarrierSet::G1SATBCTLogging:
726 {
727 __ pusha(); // push registers
728 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre),
729 start, count);
730 __ popa();
|
631 __ ret(0); // jump to next address
632
633 return start;
634 }
635
636
637 //----------------------------------------------------------------------------------------------------
638 // Non-destructive plausibility checks for oops
639
640 address generate_verify_oop() {
641 StubCodeMark mark(this, "StubRoutines", "verify_oop");
642 address start = __ pc();
643
644 // Incoming arguments on stack after saving rax,:
645 //
646 // [tos ]: saved rdx
647 // [tos + 1]: saved EFLAGS
648 // [tos + 2]: return address
649 // [tos + 3]: char* error message
650 // [tos + 4]: oop object to verify
651 // [tos + 5]: saved rax, - saved by caller
652
653 Label exit, error;
654 __ pushf();
655 __ incrementl(ExternalAddress((address) StubRoutines::verify_oop_count_addr()));
656 __ push(rdx); // save rdx
657 // make sure object is 'reasonable'
658 __ movptr(rax, Address(rsp, 4 * wordSize)); // get object
659 __ testptr(rax, rax);
660 __ jcc(Assembler::zero, exit); // if obj is NULL it is ok
661
662 // Check if the oop is in the right area of memory
663 const int oop_mask = Universe::verify_oop_mask();
664 const int oop_bits = Universe::verify_oop_bits();
665 __ mov(rdx, rax);
666 __ andptr(rdx, oop_mask);
667 __ cmpptr(rdx, oop_bits);
668 __ jcc(Assembler::notZero, error);
669
670 // make sure klass is 'reasonable'
671 __ movptr(rax, Address(rax, oopDesc::klass_offset_in_bytes())); // get klass
679 __ andptr(rdx, klass_mask);
680 __ cmpptr(rdx, klass_bits);
681 __ jcc(Assembler::notZero, error);
682
683 // make sure klass' klass is 'reasonable'
684 __ movptr(rax, Address(rax, oopDesc::klass_offset_in_bytes())); // get klass' klass
685 __ testptr(rax, rax);
686 __ jcc(Assembler::zero, error); // if klass' klass is NULL it is broken
687
688 __ mov(rdx, rax);
689 __ andptr(rdx, klass_mask);
690 __ cmpptr(rdx, klass_bits);
691 __ jcc(Assembler::notZero, error); // if klass not in right area
692 // of memory it is broken too.
693
694 // return if everything seems ok
695 __ bind(exit);
696 __ movptr(rax, Address(rsp, 5 * wordSize)); // get saved rax, back
697 __ pop(rdx); // restore rdx
698 __ popf(); // restore EFLAGS
699 __ ret(2 * wordSize); // pop arguments
700
701 // handle errors
702 __ bind(error);
703 __ movptr(rax, Address(rsp, 5 * wordSize)); // get saved rax, back
704 __ pop(rdx); // get saved rdx back
705 __ popf(); // get saved EFLAGS off stack -- will be ignored
706 __ pusha(); // push registers (eip = return address & msg are already pushed)
707 BLOCK_COMMENT("call MacroAssembler::debug");
708 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug32)));
709 __ popa();
710 __ ret(2 * wordSize); // pop arguments
711 return start;
712 }
713
714 //
715 // Generate pre-barrier for array stores
716 //
717 // Input:
718 // start - starting address
719 // count - element count
720 void gen_write_ref_array_pre_barrier(Register start, Register count) {
721 assert_different_registers(start, count);
722 BarrierSet* bs = Universe::heap()->barrier_set();
723 switch (bs->kind()) {
724 case BarrierSet::G1SATBCT:
725 case BarrierSet::G1SATBCTLogging:
726 {
727 __ pusha(); // push registers
728 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre),
729 start, count);
730 __ popa();
|