729
730 __ bind(notByte);
731 __ cmpl(rdx, ztos);
732 __ jcc(Assembler::notEqual, notBool);
733 __ load_signed_byte(rax, field_address);
734 __ jmp(xreturn_path);
735
736 __ bind(notBool);
737 __ cmpl(rdx, stos);
738 __ jcc(Assembler::notEqual, notShort);
739 __ load_signed_short(rax, field_address);
740 __ jmp(xreturn_path);
741
742 __ bind(notShort);
743 __ cmpl(rdx, ctos);
744 __ jcc(Assembler::notEqual, notChar);
745 __ load_unsigned_short(rax, field_address);
746 __ jmp(xreturn_path);
747
748 __ bind(notChar);
749 #ifdef ASSERT
750 Label okay;
751 __ cmpl(rdx, atos);
752 __ jcc(Assembler::equal, okay);
753 __ cmpl(rdx, itos);
754 __ jcc(Assembler::equal, okay);
755 __ stop("what type is this?");
756 __ bind(okay);
757 #endif // ASSERT
758 // All the rest are a 32 bit wordsize
759 // This is ok for now. Since fast accessors should be going away
760 __ movptr(rax, field_address);
761
762 __ bind(xreturn_path);
763
764 // _ireturn/_areturn
765 __ pop(rdi); // get return address
766 __ mov(rsp, rsi); // set sp to sender sp
767 __ jmp(rdi);
768
797 // Reference.get() then going through the normal method entry
798 // will be fine.
799 // * The G1 code below can, however, check the receiver object (the instance
800 // of java.lang.Reference) and jump to the slow path if null. If the
801 // Reference object is null then we obviously cannot fetch the referent
802 // and so we don't need to call the G1 pre-barrier. Thus we can use the
803 // regular method entry code to generate the NPE.
804 //
805 // This code is based on generate_accessor_enty.
806
807 // rbx,: Method*
808 // rcx: receiver (preserve for slow entry into asm interpreter)
809
810 // rsi: senderSP must preserved for slow path, set SP to it on fast path
811
812 address entry = __ pc();
813
814 const int referent_offset = java_lang_ref_Reference::referent_offset;
815 guarantee(referent_offset > 0, "referent offset not initialized");
816
817 if (UseG1GC) {
818 Label slow_path;
819
820 // Check if local 0 != NULL
821 // If the receiver is null then it is OK to jump to the slow path.
822 __ movptr(rax, Address(rsp, wordSize));
823 __ testptr(rax, rax);
824 __ jcc(Assembler::zero, slow_path);
825
826 // rax: local 0 (must be preserved across the G1 barrier call)
827 //
828 // rbx: method (at this point it's scratch)
829 // rcx: receiver (at this point it's scratch)
830 // rdx: scratch
831 // rdi: scratch
832 //
833 // rsi: sender sp
834
835 // Preserve the sender sp in case the pre-barrier
836 // calls the runtime
837 __ push(rsi);
838
839 // Load the value of the referent field.
840 const Address field_address(rax, referent_offset);
841 __ movptr(rax, field_address);
842
843 // Generate the G1 pre-barrier code to log the value of
844 // the referent field in an SATB buffer.
845 __ get_thread(rcx);
846 __ g1_write_barrier_pre(noreg /* obj */,
847 rax /* pre_val */,
848 rcx /* thread */,
849 rbx /* tmp */,
850 true /* tosca_save */,
851 true /* expand_call */);
852
853 // _areturn
854 __ pop(rsi); // get sender sp
855 __ pop(rdi); // get return address
856 __ mov(rsp, rsi); // set sp to sender sp
857 __ jmp(rdi);
858
859 __ bind(slow_path);
860 (void) generate_normal_entry(false);
861
862 return entry;
863 }
864 #endif // INCLUDE_ALL_GCS
865
866 // If G1 is not enabled then attempt to go through the accessor entry point
867 // Reference.get is an accessor
868 return generate_accessor_entry();
869 }
870
871 /**
|
729
730 __ bind(notByte);
731 __ cmpl(rdx, ztos);
732 __ jcc(Assembler::notEqual, notBool);
733 __ load_signed_byte(rax, field_address);
734 __ jmp(xreturn_path);
735
736 __ bind(notBool);
737 __ cmpl(rdx, stos);
738 __ jcc(Assembler::notEqual, notShort);
739 __ load_signed_short(rax, field_address);
740 __ jmp(xreturn_path);
741
742 __ bind(notShort);
743 __ cmpl(rdx, ctos);
744 __ jcc(Assembler::notEqual, notChar);
745 __ load_unsigned_short(rax, field_address);
746 __ jmp(xreturn_path);
747
748 __ bind(notChar);
749
750 #if INCLUDE_ALL_GCS
751 if (UseShenandoahGC) {
752 Label notObj;
753
754 // Needs GC barriers
755 __ cmpl(rdx, atos);
756 __ jcc(Assembler::notEqual, notObj);
757 __ load_heap_oop(rax, field_address);
758 __ jmp(xreturn_path);
759
760 __ bind(notObj);
761 }
762 #endif
763
764 #ifdef ASSERT
765 Label okay;
766 __ cmpl(rdx, atos);
767 __ jcc(Assembler::equal, okay);
768 __ cmpl(rdx, itos);
769 __ jcc(Assembler::equal, okay);
770 __ stop("what type is this?");
771 __ bind(okay);
772 #endif // ASSERT
773 // All the rest are a 32 bit wordsize
774 // This is ok for now. Since fast accessors should be going away
775 __ movptr(rax, field_address);
776
777 __ bind(xreturn_path);
778
779 // _ireturn/_areturn
780 __ pop(rdi); // get return address
781 __ mov(rsp, rsi); // set sp to sender sp
782 __ jmp(rdi);
783
812 // Reference.get() then going through the normal method entry
813 // will be fine.
814 // * The G1 code below can, however, check the receiver object (the instance
815 // of java.lang.Reference) and jump to the slow path if null. If the
816 // Reference object is null then we obviously cannot fetch the referent
817 // and so we don't need to call the G1 pre-barrier. Thus we can use the
818 // regular method entry code to generate the NPE.
819 //
820 // This code is based on generate_accessor_enty.
821
822 // rbx,: Method*
823 // rcx: receiver (preserve for slow entry into asm interpreter)
824
825 // rsi: senderSP must preserved for slow path, set SP to it on fast path
826
827 address entry = __ pc();
828
829 const int referent_offset = java_lang_ref_Reference::referent_offset;
830 guarantee(referent_offset > 0, "referent offset not initialized");
831
832 if (UseG1GC || UseShenandoahGC) {
833 Label slow_path;
834
835 // Check if local 0 != NULL
836 // If the receiver is null then it is OK to jump to the slow path.
837 __ movptr(rax, Address(rsp, wordSize));
838 __ testptr(rax, rax);
839 __ jcc(Assembler::zero, slow_path);
840
841 // rax: local 0 (must be preserved across the G1 barrier call)
842 //
843 // rbx: method (at this point it's scratch)
844 // rcx: receiver (at this point it's scratch)
845 // rdx: scratch
846 // rdi: scratch
847 //
848 // rsi: sender sp
849
850 // Preserve the sender sp in case the pre-barrier
851 // calls the runtime
852 __ push(rsi);
853
854 // Load the value of the referent field.
855 const Address field_address(rax, referent_offset);
856 #if INCLUDE_ALL_GCS
857 if (UseShenandoahGC) {
858 // Needs GC barriers
859 __ load_heap_oop(rax, field_address);
860 } else
861 #endif
862 __ movptr(rax, field_address);
863
864 // Generate the G1 pre-barrier code to log the value of
865 // the referent field in an SATB buffer.
866 if (!UseShenandoahGC || ShenandoahSATBBarrier) {
867 __ get_thread(rcx);
868 __ g1_write_barrier_pre(noreg /* obj */,
869 rax /* pre_val */,
870 rcx /* thread */,
871 rbx /* tmp */,
872 true /* tosca_save */,
873 true /* expand_call */);
874 }
875
876 // _areturn
877 __ pop(rsi); // get sender sp
878 __ pop(rdi); // get return address
879 __ mov(rsp, rsi); // set sp to sender sp
880 __ jmp(rdi);
881
882 __ bind(slow_path);
883 (void) generate_normal_entry(false);
884
885 return entry;
886 }
887 #endif // INCLUDE_ALL_GCS
888
889 // If G1 is not enabled then attempt to go through the accessor entry point
890 // Reference.get is an accessor
891 return generate_accessor_entry();
892 }
893
894 /**
|