changeset 59237:35d8d9b65744

8235324: Dying objects are published from users of CollectedHeap::object_iterate Reviewed-by: pliden, eosterlund, sjohanss, rkennke
author stefank
date Wed, 04 Dec 2019 11:30:32 +0100
parents b82209a3f793
children 2aaa8bcb90a9
files src/hotspot/share/gc/g1/g1CollectedHeap.cpp src/hotspot/share/gc/g1/g1CollectedHeap.hpp src/hotspot/share/gc/shared/collectedHeap.hpp src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp src/hotspot/share/gc/z/zBarrier.cpp src/hotspot/share/gc/z/zBarrier.hpp src/hotspot/share/gc/z/zBarrier.inline.hpp src/hotspot/share/gc/z/zCollectedHeap.cpp src/hotspot/share/gc/z/zCollectedHeap.hpp src/hotspot/share/gc/z/zHeap.cpp src/hotspot/share/gc/z/zHeap.hpp src/hotspot/share/memory/heapInspection.cpp src/hotspot/share/prims/jvmtiTagMap.cpp
diffstat 14 files changed, 53 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Mon Dec 09 13:02:07 2019 -0800
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Wed Dec 04 11:30:32 2019 +0100
@@ -2348,6 +2348,10 @@
   heap_region_iterate(&blk);
 }
 
+void G1CollectedHeap::keep_alive(oop obj) {
+  G1BarrierSet::enqueue(obj);
+}
+
 void G1CollectedHeap::heap_region_iterate(HeapRegionClosure* cl) const {
   _hrm->iterate(cl);
 }
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Mon Dec 09 13:02:07 2019 -0800
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Wed Dec 04 11:30:32 2019 +0100
@@ -1170,6 +1170,9 @@
   // Iterate over all objects, calling "cl.do_object" on each.
   virtual void object_iterate(ObjectClosure* cl);
 
+  // Keep alive an object that was loaded with AS_NO_KEEPALIVE.
+  virtual void keep_alive(oop obj);
+
   // Iterate over heap regions, in address order, terminating the
   // iteration early if the "do_heap_region" method returns "true".
   void heap_region_iterate(HeapRegionClosure* blk) const;
--- a/src/hotspot/share/gc/shared/collectedHeap.hpp	Mon Dec 09 13:02:07 2019 -0800
+++ b/src/hotspot/share/gc/shared/collectedHeap.hpp	Wed Dec 04 11:30:32 2019 +0100
@@ -387,6 +387,9 @@
   // Iterate over all objects, calling "cl.do_object" on each.
   virtual void object_iterate(ObjectClosure* cl) = 0;
 
+  // Keep alive an object that was loaded with AS_NO_KEEPALIVE.
+  virtual void keep_alive(oop obj) {}
+
   // Returns the longest time (in ms) that has elapsed since the last
   // time that any part of the heap was examined by a garbage collection.
   virtual jlong millis_since_last_gc() = 0;
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Mon Dec 09 13:02:07 2019 -0800
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Wed Dec 04 11:30:32 2019 +0100
@@ -1327,6 +1327,11 @@
   }
 }
 
+// Keep alive an object that was loaded with AS_NO_KEEPALIVE.
+void ShenandoahHeap::keep_alive(oop obj) {
+  ShenandoahBarrierSet::barrier_set()->enqueue(obj);
+}
+
 void ShenandoahHeap::heap_region_iterate(ShenandoahHeapRegionClosure* blk) const {
   for (size_t i = 0; i < num_regions(); i++) {
     ShenandoahHeapRegion* current = get_region(i);
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp	Mon Dec 09 13:02:07 2019 -0800
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp	Wed Dec 04 11:30:32 2019 +0100
@@ -560,6 +560,9 @@
   // Used for native heap walkers: heap dumpers, mostly
   void object_iterate(ObjectClosure* cl);
 
+  // Keep alive an object that was loaded with AS_NO_KEEPALIVE.
+  void keep_alive(oop obj);
+
   // Used by RMI
   jlong millis_since_last_gc();
 
--- a/src/hotspot/share/gc/z/zBarrier.cpp	Mon Dec 09 13:02:07 2019 -0800
+++ b/src/hotspot/share/gc/z/zBarrier.cpp	Wed Dec 04 11:30:32 2019 +0100
@@ -31,14 +31,6 @@
 #include "runtime/safepoint.hpp"
 #include "utilities/debug.hpp"
 
-bool ZBarrier::during_mark() {
-  return ZGlobalPhase == ZPhaseMark;
-}
-
-bool ZBarrier::during_relocate() {
-  return ZGlobalPhase == ZPhaseRelocate;
-}
-
 template <bool finalizable>
 bool ZBarrier::should_mark_through(uintptr_t addr) {
   // Finalizable marked oops can still exists on the heap after marking
--- a/src/hotspot/share/gc/z/zBarrier.hpp	Mon Dec 09 13:02:07 2019 -0800
+++ b/src/hotspot/share/gc/z/zBarrier.hpp	Wed Dec 04 11:30:32 2019 +0100
@@ -105,6 +105,7 @@
   static void keep_alive_barrier_on_weak_oop_field(volatile oop* p);
   static void keep_alive_barrier_on_phantom_oop_field(volatile oop* p);
   static void keep_alive_barrier_on_phantom_root_oop_field(oop* p);
+  static void keep_alive_barrier_on_oop(oop o);
 
   // Mark barrier
   static void mark_barrier_on_oop_field(volatile oop* p, bool finalizable);
--- a/src/hotspot/share/gc/z/zBarrier.inline.hpp	Mon Dec 09 13:02:07 2019 -0800
+++ b/src/hotspot/share/gc/z/zBarrier.inline.hpp	Wed Dec 04 11:30:32 2019 +0100
@@ -144,6 +144,14 @@
   return ZAddress::is_weak_good_or_null(addr);
 }
 
+inline bool ZBarrier::during_mark() {
+  return ZGlobalPhase == ZPhaseMark;
+}
+
+inline bool ZBarrier::during_relocate() {
+  return ZGlobalPhase == ZPhaseRelocate;
+}
+
 //
 // Load barrier
 //
@@ -291,6 +299,12 @@
   root_barrier<is_good_or_null_fast_path, keep_alive_barrier_on_phantom_oop_slow_path>(p, o);
 }
 
+inline void ZBarrier::keep_alive_barrier_on_oop(oop o) {
+  if (during_mark()) {
+    barrier<is_null_fast_path, mark_barrier_on_oop_slow_path>(NULL, o);
+  }
+}
+
 //
 // Mark barrier
 //
--- a/src/hotspot/share/gc/z/zCollectedHeap.cpp	Mon Dec 09 13:02:07 2019 -0800
+++ b/src/hotspot/share/gc/z/zCollectedHeap.cpp	Wed Dec 04 11:30:32 2019 +0100
@@ -247,6 +247,10 @@
   _heap.object_iterate(cl, true /* visit_weaks */);
 }
 
+void ZCollectedHeap::keep_alive(oop obj) {
+  _heap.keep_alive(obj);
+}
+
 void ZCollectedHeap::register_nmethod(nmethod* nm) {
   ZNMethod::register_nmethod(nm);
 }
--- a/src/hotspot/share/gc/z/zCollectedHeap.hpp	Mon Dec 09 13:02:07 2019 -0800
+++ b/src/hotspot/share/gc/z/zCollectedHeap.hpp	Wed Dec 04 11:30:32 2019 +0100
@@ -99,6 +99,8 @@
 
   virtual void object_iterate(ObjectClosure* cl);
 
+  virtual void keep_alive(oop obj);
+
   virtual void register_nmethod(nmethod* nm);
   virtual void unregister_nmethod(nmethod* nm);
   virtual void flush_nmethod(nmethod* nm);
--- a/src/hotspot/share/gc/z/zHeap.cpp	Mon Dec 09 13:02:07 2019 -0800
+++ b/src/hotspot/share/gc/z/zHeap.cpp	Wed Dec 04 11:30:32 2019 +0100
@@ -322,6 +322,10 @@
   return true;
 }
 
+void ZHeap::keep_alive(oop obj) {
+  ZBarrier::keep_alive_barrier_on_oop(obj);
+}
+
 void ZHeap::set_soft_reference_policy(bool clear) {
   _reference_processor.set_soft_reference_policy(clear);
 }
--- a/src/hotspot/share/gc/z/zHeap.hpp	Mon Dec 09 13:02:07 2019 -0800
+++ b/src/hotspot/share/gc/z/zHeap.hpp	Wed Dec 04 11:30:32 2019 +0100
@@ -137,6 +137,7 @@
   void mark(bool initial);
   void mark_flush_and_free(Thread* thread);
   bool mark_end();
+  void keep_alive(oop obj);
 
   // Relocation set
   void select_relocation_set();
--- a/src/hotspot/share/memory/heapInspection.cpp	Mon Dec 09 13:02:07 2019 -0800
+++ b/src/hotspot/share/memory/heapInspection.cpp	Wed Dec 04 11:30:32 2019 +0100
@@ -778,6 +778,10 @@
 
   void do_object(oop obj) {
     if (obj->is_a(_klass)) {
+      // obj was read with AS_NO_KEEPALIVE, or equivalent.
+      // The object needs to be kept alive when it is published.
+      Universe::heap()->keep_alive(obj);
+
       _result->append(obj);
     }
   }
--- a/src/hotspot/share/prims/jvmtiTagMap.cpp	Mon Dec 09 13:02:07 2019 -0800
+++ b/src/hotspot/share/prims/jvmtiTagMap.cpp	Wed Dec 04 11:30:32 2019 +0100
@@ -483,6 +483,11 @@
 // is returned. Otherwise an new entry is allocated.
 JvmtiTagHashmapEntry* JvmtiTagMap::create_entry(oop ref, jlong tag) {
   assert(Thread::current()->is_VM_thread() || is_locked(), "checking");
+
+  // ref was read with AS_NO_KEEPALIVE, or equivalent.
+  // The object needs to be kept alive when it is published.
+  Universe::heap()->keep_alive(ref);
+
   JvmtiTagHashmapEntry* entry;
   if (_free_entries == NULL) {
     entry = new JvmtiTagHashmapEntry(ref, tag);