changeset 51256:21b96ce2ed10

8205163: ZGC: Keeps finalizable marked PhantomReference referents strongly alive Reviewed-by: pliden, kbarrett
author stefank
date Tue, 19 Jun 2018 08:44:31 +0200
parents 4216de02077e
children 5209d8a6303e
files src/hotspot/share/gc/z/zBarrier.hpp src/hotspot/share/gc/z/zBarrier.inline.hpp src/hotspot/share/gc/z/zReferenceProcessor.cpp src/hotspot/share/gc/z/zReferenceProcessor.hpp
diffstat 4 files changed, 23 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/gc/z/zBarrier.hpp	Thu Jun 07 10:11:36 2018 +0200
+++ b/src/hotspot/share/gc/z/zBarrier.hpp	Tue Jun 19 08:44:31 2018 +0200
@@ -83,6 +83,7 @@
   static  oop load_barrier_on_phantom_oop_field_preloaded(volatile oop* p, oop o);
 
   // Weak load barrier
+  static oop weak_load_barrier_on_oop_field(volatile oop* p);
   static oop weak_load_barrier_on_oop_field_preloaded(volatile oop* p, oop o);
   static oop weak_load_barrier_on_weak_oop(oop o);
   static oop weak_load_barrier_on_weak_oop_field(volatile oop* p);
--- a/src/hotspot/share/gc/z/zBarrier.inline.hpp	Thu Jun 07 10:11:36 2018 +0200
+++ b/src/hotspot/share/gc/z/zBarrier.inline.hpp	Tue Jun 19 08:44:31 2018 +0200
@@ -191,6 +191,12 @@
 //
 // Weak load barrier
 //
+inline oop ZBarrier::weak_load_barrier_on_oop_field(volatile oop* p) {
+  assert(!ZResurrection::is_blocked(), "Should not be called during resurrection blocked phase");
+  const oop o = *p;
+  return weak_load_barrier_on_oop_field_preloaded(p, o);
+}
+
 inline oop ZBarrier::weak_load_barrier_on_oop_field_preloaded(volatile oop* p, oop o) {
   return weak_barrier<is_weak_good_or_null_fast_path, weak_load_barrier_on_oop_slow_path>(p, o);
 }
--- a/src/hotspot/share/gc/z/zReferenceProcessor.cpp	Thu Jun 07 10:11:36 2018 +0200
+++ b/src/hotspot/share/gc/z/zReferenceProcessor.cpp	Tue Jun 19 08:44:31 2018 +0200
@@ -105,19 +105,21 @@
   return *reference_referent_addr(obj);
 }
 
-bool ZReferenceProcessor::is_referent_alive_or_null(oop obj, ReferenceType type) const {
+bool ZReferenceProcessor::is_referent_strongly_alive_or_null(oop obj, ReferenceType type) const {
+  // Check if the referent is strongly alive or null, in which case we don't want to
+  // discover the reference. It can only be null if the application called
+  // Reference.enqueue() or Reference.clear().
+  //
+  // PhantomReferences with finalizable marked referents should technically not have
+  // to be discovered. However, InstanceRefKlass::oop_oop_iterate_ref_processing()
+  // does not know about the finalizable mark concept, and will therefore mark
+  // referents in non-discovered PhantomReferences as strongly live. To prevent
+  // this, we always discover PhantomReferences with finalizable marked referents.
+  // They will automatically be dropped during the reference processing phase.
+
   volatile oop* const p = reference_referent_addr(obj);
-
-  // Check if the referent is alive or null, in which case we don't want to discover
-  // the reference. It can only be null if the application called Reference.enqueue()
-  // or Reference.clear().
-  if (type == REF_PHANTOM) {
-    const oop o = ZBarrier::weak_load_barrier_on_phantom_oop_field(p);
-    return o == NULL || ZHeap::heap()->is_object_live(ZOop::to_address(o));
-  } else {
-    const oop o = ZBarrier::weak_load_barrier_on_weak_oop_field(p);
-    return o == NULL || ZHeap::heap()->is_object_strongly_live(ZOop::to_address(o));
-  }
+  const oop o = ZBarrier::weak_load_barrier_on_oop_field(p);
+  return o == NULL || ZHeap::heap()->is_object_strongly_live(ZOop::to_address(o));
 }
 
 bool ZReferenceProcessor::is_referent_softly_alive(oop obj, ReferenceType type) const {
@@ -191,7 +193,7 @@
   _encountered_count.get()[type]++;
 
   if (is_reference_inactive(obj) ||
-      is_referent_alive_or_null(obj, type) ||
+      is_referent_strongly_alive_or_null(obj, type) ||
       is_referent_softly_alive(obj, type)) {
     // Not discovered
     return false;
--- a/src/hotspot/share/gc/z/zReferenceProcessor.hpp	Thu Jun 07 10:11:36 2018 +0200
+++ b/src/hotspot/share/gc/z/zReferenceProcessor.hpp	Tue Jun 19 08:44:31 2018 +0200
@@ -53,7 +53,7 @@
   volatile oop* reference_referent_addr(oop obj) const;
   oop reference_referent(oop obj) const;
   bool is_reference_inactive(oop obj) const;
-  bool is_referent_alive_or_null(oop obj, ReferenceType type) const;
+  bool is_referent_strongly_alive_or_null(oop obj, ReferenceType type) const;
   bool is_referent_softly_alive(oop obj, ReferenceType type) const;
   bool should_drop_reference(oop obj, ReferenceType type) const;
   bool should_mark_referent(ReferenceType type) const;