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); } } }