774 } |
774 } |
775 return NULL; |
775 return NULL; |
776 |
776 |
777 } |
777 } |
778 |
778 |
|
779 // Method entry for java.lang.ref.Reference.get. |
|
780 address InterpreterGenerator::generate_Reference_get_entry(void) { |
|
781 #ifndef SERIALGC |
|
782 // Code: _aload_0, _getfield, _areturn |
|
783 // parameter size = 1 |
|
784 // |
|
785 // The code that gets generated by this routine is split into 2 parts: |
|
786 // 1. The "intrinsified" code for G1 (or any SATB based GC), |
|
787 // 2. The slow path - which is an expansion of the regular method entry. |
|
788 // |
|
789 // Notes:- |
|
790 // * In the G1 code we do not check whether we need to block for |
|
791 // a safepoint. If G1 is enabled then we must execute the specialized |
|
792 // code for Reference.get (except when the Reference object is null) |
|
793 // so that we can log the value in the referent field with an SATB |
|
794 // update buffer. |
|
795 // If the code for the getfield template is modified so that the |
|
796 // G1 pre-barrier code is executed when the current method is |
|
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,: methodOop |
|
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 // SERIALGC |
|
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 |
779 // |
871 // |
780 // Interpreter stub for calling a native method. (asm interpreter) |
872 // Interpreter stub for calling a native method. (asm interpreter) |
781 // This sets up a somewhat different looking stack for calling the native method |
873 // This sets up a somewhat different looking stack for calling the native method |
782 // than the typical interpreter frame setup. |
874 // than the typical interpreter frame setup. |
783 // |
875 // |
1442 case Interpreter::java_lang_math_tan : // fall thru |
1534 case Interpreter::java_lang_math_tan : // fall thru |
1443 case Interpreter::java_lang_math_abs : // fall thru |
1535 case Interpreter::java_lang_math_abs : // fall thru |
1444 case Interpreter::java_lang_math_log : // fall thru |
1536 case Interpreter::java_lang_math_log : // fall thru |
1445 case Interpreter::java_lang_math_log10 : // fall thru |
1537 case Interpreter::java_lang_math_log10 : // fall thru |
1446 case Interpreter::java_lang_math_sqrt : entry_point = ((InterpreterGenerator*)this)->generate_math_entry(kind); break; |
1538 case Interpreter::java_lang_math_sqrt : entry_point = ((InterpreterGenerator*)this)->generate_math_entry(kind); break; |
|
1539 case Interpreter::java_lang_ref_reference_get |
|
1540 : entry_point = ((InterpreterGenerator*)this)->generate_Reference_get_entry(); break; |
1447 default : ShouldNotReachHere(); break; |
1541 default : ShouldNotReachHere(); break; |
1448 } |
1542 } |
1449 |
1543 |
1450 if (entry_point) return entry_point; |
1544 if (entry_point) return entry_point; |
1451 |
1545 |