inline void PSScavenge::copy_and_push_safe_barrier(PSPromotionManager* pm,
                                                   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()
        : pm->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(), o, 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((HeapWord*)new_obj)) {
      card_table()->inline_write_ref_field_gc(p, new_obj);
    }
  }
}
inline void PSScavenge::copy_and_push_safe_barrier(PSPromotionManager* pm,
                                                   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()
        : pm->copy_to_survivor_space(o);
  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.
  if ((!PSScavenge::is_obj_in_young((HeapWord*)p)) &&
      Universe::heap()->is_in_reserved(p)) {
    if (PSScavenge::is_obj_in_young((HeapWord*)new_obj)) {
      card_table()->inline_write_ref_field_gc(p, 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.
inline void PSScavenge::copy_and_push_safe_barrier(PSPromotionManager* pm, oop* p) {
  assert(should_scavenge(*p), "Sanity");
  assert(Universe::heap()->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
  assert(!((ParallelScavengeHeap*)Universe::heap())->young_gen()->to_space()->contains(*p),"Attempt to rescan object");

  oop o = *p;
  if (o->is_forwarded()) {
    *p = o->forwardee();
  } else {
    *p = pm->copy_to_survivor_space(o);
  }
  
  // We cannot mark without test, as some code passes us pointers that are outside the heap.
  if (((HeapWord*)p >= _eden_boundary) &&  Universe::heap()->is_in_reserved(p)) {
    o = *p;
    if ((HeapWord*)o < _eden_boundary) {
      card_table()->inline_write_ref_field_gc(p, o);
    }
  }
}