comparison src/share/vm/prims/jni.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 c7f3d0b4570f
children be4ca325525a 04760e41b01e
comparison
equal deleted inserted replaced
3248:e6beb62de02d 3249:e1162778c1c8
27 #include "classfile/javaClasses.hpp" 27 #include "classfile/javaClasses.hpp"
28 #include "classfile/symbolTable.hpp" 28 #include "classfile/symbolTable.hpp"
29 #include "classfile/systemDictionary.hpp" 29 #include "classfile/systemDictionary.hpp"
30 #include "classfile/vmSymbols.hpp" 30 #include "classfile/vmSymbols.hpp"
31 #include "interpreter/linkResolver.hpp" 31 #include "interpreter/linkResolver.hpp"
32 #ifndef SERIALGC
33 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
34 #endif // SERIALGC
32 #include "memory/allocation.inline.hpp" 35 #include "memory/allocation.inline.hpp"
33 #include "memory/gcLocker.inline.hpp" 36 #include "memory/gcLocker.inline.hpp"
34 #include "memory/oopFactory.hpp" 37 #include "memory/oopFactory.hpp"
35 #include "memory/universe.inline.hpp" 38 #include "memory/universe.inline.hpp"
36 #include "oops/instanceKlass.hpp" 39 #include "oops/instanceKlass.hpp"
1722 // jni_GetField_probe() assumes that is okay to create handles. 1725 // jni_GetField_probe() assumes that is okay to create handles.
1723 if (JvmtiExport::should_post_field_access()) { 1726 if (JvmtiExport::should_post_field_access()) {
1724 o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false); 1727 o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
1725 } 1728 }
1726 jobject ret = JNIHandles::make_local(env, o->obj_field(offset)); 1729 jobject ret = JNIHandles::make_local(env, o->obj_field(offset));
1730 #ifndef SERIALGC
1731 // If G1 is enabled and we are accessing the value of the referent
1732 // field in a reference object then we need to register a non-null
1733 // referent with the SATB barrier.
1734 if (UseG1GC) {
1735 bool needs_barrier = false;
1736
1737 if (ret != NULL &&
1738 offset == java_lang_ref_Reference::referent_offset &&
1739 instanceKlass::cast(k)->reference_type() != REF_NONE) {
1740 assert(instanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
1741 needs_barrier = true;
1742 }
1743
1744 if (needs_barrier) {
1745 oop referent = JNIHandles::resolve(ret);
1746 G1SATBCardTableModRefBS::enqueue(referent);
1747 }
1748 }
1749 #endif // SERIALGC
1727 DTRACE_PROBE1(hotspot_jni, GetObjectField__return, ret); 1750 DTRACE_PROBE1(hotspot_jni, GetObjectField__return, ret);
1728 return ret; 1751 return ret;
1729 JNI_END 1752 JNI_END
1730 1753
1731 1754