comparison src/cpu/sparc/vm/templateInterpreter_sparc.cpp @ 3249:e1162778c1c8

7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error Summary: A referent object that is only weakly reachable at the start of concurrent marking but is re-attached to the strongly reachable object graph during marking may not be marked as live. This can cause the reference object to be processed prematurely and leave dangling pointers to the referent object. Implement a read barrier for the java.lang.ref.Reference::referent field by intrinsifying the Reference.get() method, and intercepting accesses though JNI, reflection, and Unsafe, so that when a non-null referent object is read it is also logged in an SATB buffer. Reviewed-by: kvn, iveresov, never, tonyp, dholmes
author johnc
date Thu, 07 Apr 2011 09:53:20 -0700
parents dd031b2226de
children 2e038ad0c1d0
comparison
equal deleted inserted replaced
3248:e6beb62de02d 3249:e1162778c1c8
759 __ bind(slow_path); 759 __ bind(slow_path);
760 (void) generate_normal_entry(false); 760 (void) generate_normal_entry(false);
761 return entry; 761 return entry;
762 } 762 }
763 return NULL; 763 return NULL;
764 }
765
766 // Method entry for java.lang.ref.Reference.get.
767 address InterpreterGenerator::generate_Reference_get_entry(void) {
768 #ifndef SERIALGC
769 // Code: _aload_0, _getfield, _areturn
770 // parameter size = 1
771 //
772 // The code that gets generated by this routine is split into 2 parts:
773 // 1. The "intrinsified" code for G1 (or any SATB based GC),
774 // 2. The slow path - which is an expansion of the regular method entry.
775 //
776 // Notes:-
777 // * In the G1 code we do not check whether we need to block for
778 // a safepoint. If G1 is enabled then we must execute the specialized
779 // code for Reference.get (except when the Reference object is null)
780 // so that we can log the value in the referent field with an SATB
781 // update buffer.
782 // If the code for the getfield template is modified so that the
783 // G1 pre-barrier code is executed when the current method is
784 // Reference.get() then going through the normal method entry
785 // will be fine.
786 // * The G1 code can, however, check the receiver object (the instance
787 // of java.lang.Reference) and jump to the slow path if null. If the
788 // Reference object is null then we obviously cannot fetch the referent
789 // and so we don't need to call the G1 pre-barrier. Thus we can use the
790 // regular method entry code to generate the NPE.
791 //
792 // This code is based on generate_accessor_enty.
793
794 address entry = __ pc();
795
796 const int referent_offset = java_lang_ref_Reference::referent_offset;
797 guarantee(referent_offset > 0, "referent offset not initialized");
798
799 if (UseG1GC) {
800 Label slow_path;
801
802 // In the G1 code we don't check if we need to reach a safepoint. We
803 // continue and the thread will safepoint at the next bytecode dispatch.
804
805 // Check if local 0 != NULL
806 // If the receiver is null then it is OK to jump to the slow path.
807 __ ld_ptr(Gargs, G0, Otos_i ); // get local 0
808 __ tst(Otos_i); // check if local 0 == NULL and go the slow path
809 __ brx(Assembler::zero, false, Assembler::pn, slow_path);
810 __ delayed()->nop();
811
812
813 // Load the value of the referent field.
814 if (Assembler::is_simm13(referent_offset)) {
815 __ load_heap_oop(Otos_i, referent_offset, Otos_i);
816 } else {
817 __ set(referent_offset, G3_scratch);
818 __ load_heap_oop(Otos_i, G3_scratch, Otos_i);
819 }
820
821 // Generate the G1 pre-barrier code to log the value of
822 // the referent field in an SATB buffer. Note with
823 // these parameters the pre-barrier does not generate
824 // the load of the previous value
825
826 __ g1_write_barrier_pre(noreg /* obj */, noreg /* index */, 0 /* offset */,
827 Otos_i /* pre_val */,
828 G3_scratch /* tmp */,
829 true /* preserve_o_regs */);
830
831 // _areturn
832 __ retl(); // return from leaf routine
833 __ delayed()->mov(O5_savedSP, SP);
834
835 // Generate regular method entry
836 __ bind(slow_path);
837 (void) generate_normal_entry(false);
838 return entry;
839 }
840 #endif // SERIALGC
841
842 // If G1 is not enabled then attempt to go through the accessor entry point
843 // Reference.get is an accessor
844 return generate_accessor_entry();
764 } 845 }
765 846
766 // 847 //
767 // Interpreter stub for calling a native method. (asm interpreter) 848 // Interpreter stub for calling a native method. (asm interpreter)
768 // This sets up a somewhat different looking stack for calling the native method 849 // This sets up a somewhat different looking stack for calling the native method