< prev index next >

src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp

Print this page
rev 7858 : 8073543: Circular include dependency between psScavenge.inline.hpp and psPromotionManager.inline.hpp

@@ -54,11 +54,11 @@
   }
 }
 
 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");
 
   claim_or_forward_internal_depth(p);

@@ -96,11 +96,11 @@
 // into smaller submethods, but we need to be careful not to hurt
 // performance.
 //
 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;
 
   // NOTE! We must be very careful with any methods that access the mark
   // in o. There may be multiple threads racing on it, and it may be forwarded

@@ -255,30 +255,64 @@
 #ifndef PRODUCT
   // This code must come after the CAS test, or it will print incorrect
   // 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
 
   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)) {
     assert(PSChunkLargeArrays, "invariant");
     oop const old = unmask_chunked_array_oop(p);
     process_array_chunk(old);
   } 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);
     }
   }
 }
 
 #if TASKQUEUE_STATS
< prev index next >