hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp
changeset 29208 b570d043f295
parent 28177 318600b0d7db
child 29792 8c6fa07f0869
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp	Fri Feb 20 22:22:39 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp	Fri Feb 20 13:54:42 2015 +0100
@@ -56,7 +56,7 @@
 
 template <class T>
 inline void PSPromotionManager::claim_or_forward_depth(T* p) {
-  assert(PSScavenge::should_scavenge(p, true), "revisiting object?");
+  assert(should_scavenge(p, true), "revisiting object?");
   assert(Universe::heap()->kind() == CollectedHeap::ParallelScavengeHeap,
          "Sanity");
   assert(Universe::heap()->is_in(p), "pointer outside heap");
@@ -98,7 +98,7 @@
 //
 template<bool promote_immediately>
 oop PSPromotionManager::copy_to_survivor_space(oop o) {
-  assert(PSScavenge::should_scavenge(&o), "Sanity");
+  assert(should_scavenge(&o), "Sanity");
 
   oop new_obj = NULL;
 
@@ -257,7 +257,7 @@
   // information.
   if (TraceScavenge) {
     gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
-       PSScavenge::should_scavenge(&new_obj) ? "copying" : "tenuring",
+       should_scavenge(&new_obj) ? "copying" : "tenuring",
        new_obj->klass()->internal_name(), p2i((void *)o), p2i((void *)new_obj), new_obj->size());
   }
 #endif
@@ -265,6 +265,40 @@
   return new_obj;
 }
 
+// Attempt to "claim" oop at p via CAS, push the new obj if successful
+// This version tests the oop* to make sure it is within the heap before
+// attempting marking.
+template <class T, bool promote_immediately>
+inline void PSPromotionManager::copy_and_push_safe_barrier(T* p) {
+  assert(should_scavenge(p, true), "revisiting object?");
+
+  oop o = oopDesc::load_decode_heap_oop_not_null(p);
+  oop new_obj = o->is_forwarded()
+        ? o->forwardee()
+        : copy_to_survivor_space<promote_immediately>(o);
+
+#ifndef PRODUCT
+  // This code must come after the CAS test, or it will print incorrect
+  // information.
+  if (TraceScavenge &&  o->is_forwarded()) {
+    gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
+       "forwarding",
+       new_obj->klass()->internal_name(), p2i((void *)o), p2i((void *)new_obj), new_obj->size());
+  }
+#endif
+
+  oopDesc::encode_store_heap_oop_not_null(p, new_obj);
+
+  // We cannot mark without test, as some code passes us pointers
+  // that are outside the heap. These pointers are either from roots
+  // or from metadata.
+  if ((!PSScavenge::is_obj_in_young((HeapWord*)p)) &&
+      Universe::heap()->is_in_reserved(p)) {
+    if (PSScavenge::is_obj_in_young(new_obj)) {
+      PSScavenge::card_table()->inline_write_ref_field_gc(p, new_obj);
+    }
+  }
+}
 
 inline void PSPromotionManager::process_popped_location_depth(StarTask p) {
   if (is_oop_masked(p)) {
@@ -274,9 +308,9 @@
   } else {
     if (p.is_narrow()) {
       assert(UseCompressedOops, "Error");
-      PSScavenge::copy_and_push_safe_barrier<narrowOop, /*promote_immediately=*/false>(this, p);
+      copy_and_push_safe_barrier<narrowOop, /*promote_immediately=*/false>(p);
     } else {
-      PSScavenge::copy_and_push_safe_barrier<oop, /*promote_immediately=*/false>(this, p);
+      copy_and_push_safe_barrier<oop, /*promote_immediately=*/false>(p);
     }
   }
 }