755 } |
755 } |
756 |
756 |
757 return entry_point; |
757 return entry_point; |
758 } |
758 } |
759 |
759 |
|
760 // Method entry for java.lang.ref.Reference.get. |
|
761 address InterpreterGenerator::generate_Reference_get_entry(void) { |
|
762 #ifndef SERIALGC |
|
763 // Code: _aload_0, _getfield, _areturn |
|
764 // parameter size = 1 |
|
765 // |
|
766 // The code that gets generated by this routine is split into 2 parts: |
|
767 // 1. The "intrinsified" code for G1 (or any SATB based GC), |
|
768 // 2. The slow path - which is an expansion of the regular method entry. |
|
769 // |
|
770 // Notes:- |
|
771 // * In the G1 code we do not check whether we need to block for |
|
772 // a safepoint. If G1 is enabled then we must execute the specialized |
|
773 // code for Reference.get (except when the Reference object is null) |
|
774 // so that we can log the value in the referent field with an SATB |
|
775 // update buffer. |
|
776 // If the code for the getfield template is modified so that the |
|
777 // G1 pre-barrier code is executed when the current method is |
|
778 // Reference.get() then going through the normal method entry |
|
779 // will be fine. |
|
780 // * The G1 code can, however, check the receiver object (the instance |
|
781 // of java.lang.Reference) and jump to the slow path if null. If the |
|
782 // Reference object is null then we obviously cannot fetch the referent |
|
783 // and so we don't need to call the G1 pre-barrier. Thus we can use the |
|
784 // regular method entry code to generate the NPE. |
|
785 // |
|
786 // This code is based on generate_accessor_enty. |
|
787 // |
|
788 // rbx: methodOop |
|
789 |
|
790 // r13: senderSP must preserve for slow path, set SP to it on fast path |
|
791 |
|
792 address entry = __ pc(); |
|
793 |
|
794 const int referent_offset = java_lang_ref_Reference::referent_offset; |
|
795 guarantee(referent_offset > 0, "referent offset not initialized"); |
|
796 |
|
797 if (UseG1GC) { |
|
798 Label slow_path; |
|
799 // rbx: method |
|
800 |
|
801 // Check if local 0 != NULL |
|
802 // If the receiver is null then it is OK to jump to the slow path. |
|
803 __ movptr(rax, Address(rsp, wordSize)); |
|
804 |
|
805 __ testptr(rax, rax); |
|
806 __ jcc(Assembler::zero, slow_path); |
|
807 |
|
808 // rax: local 0 |
|
809 // rbx: method (but can be used as scratch now) |
|
810 // rdx: scratch |
|
811 // rdi: scratch |
|
812 |
|
813 // Generate the G1 pre-barrier code to log the value of |
|
814 // the referent field in an SATB buffer. |
|
815 |
|
816 // Load the value of the referent field. |
|
817 const Address field_address(rax, referent_offset); |
|
818 __ load_heap_oop(rax, field_address); |
|
819 |
|
820 // Generate the G1 pre-barrier code to log the value of |
|
821 // the referent field in an SATB buffer. |
|
822 __ g1_write_barrier_pre(noreg /* obj */, |
|
823 rax /* pre_val */, |
|
824 r15_thread /* thread */, |
|
825 rbx /* tmp */, |
|
826 true /* tosca_live */, |
|
827 true /* expand_call */); |
|
828 |
|
829 // _areturn |
|
830 __ pop(rdi); // get return address |
|
831 __ mov(rsp, r13); // set sp to sender sp |
|
832 __ jmp(rdi); |
|
833 __ ret(0); |
|
834 |
|
835 // generate a vanilla interpreter entry as the slow path |
|
836 __ bind(slow_path); |
|
837 (void) generate_normal_entry(false); |
|
838 |
|
839 return entry; |
|
840 } |
|
841 #endif // SERIALGC |
|
842 |
|
843 // If G1 is not enabled then attempt to go through the accessor entry point |
|
844 // Reference.get is an accessor |
|
845 return generate_accessor_entry(); |
|
846 } |
|
847 |
|
848 |
760 // Interpreter stub for calling a native method. (asm interpreter) |
849 // Interpreter stub for calling a native method. (asm interpreter) |
761 // This sets up a somewhat different looking stack for calling the |
850 // This sets up a somewhat different looking stack for calling the |
762 // native method than the typical interpreter frame setup. |
851 // native method than the typical interpreter frame setup. |
763 address InterpreterGenerator::generate_native_entry(bool synchronized) { |
852 address InterpreterGenerator::generate_native_entry(bool synchronized) { |
764 // determine code generation flags |
853 // determine code generation flags |
1461 case Interpreter::java_lang_math_tan : // fall thru |
1550 case Interpreter::java_lang_math_tan : // fall thru |
1462 case Interpreter::java_lang_math_abs : // fall thru |
1551 case Interpreter::java_lang_math_abs : // fall thru |
1463 case Interpreter::java_lang_math_log : // fall thru |
1552 case Interpreter::java_lang_math_log : // fall thru |
1464 case Interpreter::java_lang_math_log10 : // fall thru |
1553 case Interpreter::java_lang_math_log10 : // fall thru |
1465 case Interpreter::java_lang_math_sqrt : entry_point = ((InterpreterGenerator*) this)->generate_math_entry(kind); break; |
1554 case Interpreter::java_lang_math_sqrt : entry_point = ((InterpreterGenerator*) this)->generate_math_entry(kind); break; |
|
1555 case Interpreter::java_lang_ref_reference_get |
|
1556 : entry_point = ((InterpreterGenerator*)this)->generate_Reference_get_entry(); break; |
1466 default : ShouldNotReachHere(); break; |
1557 default : ShouldNotReachHere(); break; |
1467 } |
1558 } |
1468 |
1559 |
1469 if (entry_point) { |
1560 if (entry_point) { |
1470 return entry_point; |
1561 return entry_point; |