< prev index next >
src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp
Print this page
*** 30,39 ****
--- 30,42 ----
#include "gc_implementation/shared/gcTrace.hpp"
#include "gc_implementation/shared/mutableSpace.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/memRegion.hpp"
#include "memory/padded.inline.hpp"
+ #include "oops/instanceKlass.inline.hpp"
+ #include "oops/instanceMirrorKlass.inline.hpp"
+ #include "oops/objArrayKlass.inline.hpp"
#include "oops/oop.inline.hpp"
#include "utilities/stack.inline.hpp"
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
*** 308,317 ****
--- 311,432 ----
} else {
process_array_chunk_work<oop>(obj, start, end);
}
}
+ class PushContentsClosure : public ExtendedOopClosure {
+ PSPromotionManager* _pm;
+ public:
+ PushContentsClosure(PSPromotionManager* pm) : _pm(pm) {}
+
+ template <typename T> void do_oop_nv(T* p) {
+ if (PSScavenge::should_scavenge(p)) {
+ _pm->claim_or_forward_depth(p);
+ }
+ }
+
+ virtual void do_oop(oop* p) { do_oop_nv(p); }
+ virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
+
+ // Don't use the oop verification code in the oop_oop_iterate framework.
+ debug_only(virtual bool should_verify_oops() { return false; })
+ };
+
+ void InstanceKlass::oop_ps_push_contents(oop obj, PSPromotionManager* pm) {
+ PushContentsClosure cl(pm);
+ oop_oop_iterate_oop_maps_reverse<true>(obj, &cl);
+ }
+
+ void InstanceMirrorKlass::oop_ps_push_contents(oop obj, PSPromotionManager* pm) {
+ // Note that we don't have to follow the mirror -> klass pointer, since all
+ // klasses that are dirty will be scavenged when we iterate over the
+ // ClassLoaderData objects.
+
+ InstanceKlass::oop_ps_push_contents(obj, pm);
+
+ PushContentsClosure cl(pm);
+ oop_oop_iterate_statics<true>(obj, &cl);
+ }
+
+ void InstanceClassLoaderKlass::oop_ps_push_contents(oop obj, PSPromotionManager* pm) {
+ InstanceKlass::oop_ps_push_contents(obj, pm);
+
+ // This is called by the young collector. It will already have taken care of
+ // all class loader data. So, we don't have to follow the class loader ->
+ // class loader data link.
+ }
+
+ template <class T>
+ static void oop_ps_push_contents_specialized(oop obj, InstanceRefKlass *klass, PSPromotionManager* pm) {
+ T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
+ if (PSScavenge::should_scavenge(referent_addr)) {
+ ReferenceProcessor* rp = PSScavenge::reference_processor();
+ if (rp->discover_reference(obj, klass->reference_type())) {
+ // reference already enqueued, referent and next will be traversed later
+ klass->InstanceKlass::oop_ps_push_contents(obj, pm);
+ return;
+ } else {
+ // treat referent as normal oop
+ pm->claim_or_forward_depth(referent_addr);
+ }
+ }
+ // Treat discovered as normal oop, if ref is not "active",
+ // i.e. if next is non-NULL.
+ T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
+ if (ReferenceProcessor::pending_list_uses_discovered_field()) {
+ T next_oop = oopDesc::load_heap_oop(next_addr);
+ if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
+ T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
+ debug_only(
+ if(TraceReferenceGC && PrintGCDetails) {
+ gclog_or_tty->print_cr(" Process discovered as normal "
+ PTR_FORMAT, p2i(discovered_addr));
+ }
+ )
+ if (PSScavenge::should_scavenge(discovered_addr)) {
+ pm->claim_or_forward_depth(discovered_addr);
+ }
+ }
+ } else {
+ #ifdef ASSERT
+ // In the case of older JDKs which do not use the discovered
+ // field for the pending list, an inactive ref (next != NULL)
+ // must always have a NULL discovered field.
+ oop next = oopDesc::load_decode_heap_oop(next_addr);
+ oop discovered = java_lang_ref_Reference::discovered(obj);
+ assert(oopDesc::is_null(next) || oopDesc::is_null(discovered),
+ err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field",
+ (oopDesc*)obj));
+ #endif
+ }
+
+ // Treat next as normal oop; next is a link in the reference queue.
+ if (PSScavenge::should_scavenge(next_addr)) {
+ pm->claim_or_forward_depth(next_addr);
+ }
+ klass->InstanceKlass::oop_ps_push_contents(obj, pm);
+ }
+
+ void InstanceRefKlass::oop_ps_push_contents(oop obj, PSPromotionManager* pm) {
+ if (UseCompressedOops) {
+ oop_ps_push_contents_specialized<narrowOop>(obj, this, pm);
+ } else {
+ oop_ps_push_contents_specialized<oop>(obj, this, pm);
+ }
+ }
+
+ void ObjArrayKlass::oop_ps_push_contents(oop obj, PSPromotionManager* pm) {
+ assert(obj->is_objArray(), "obj must be obj array");
+ PushContentsClosure cl(pm);
+ oop_oop_iterate_elements<true>(objArrayOop(obj), &cl);
+ }
+
+ void TypeArrayKlass::oop_ps_push_contents(oop obj, PSPromotionManager* pm) {
+ assert(obj->is_typeArray(),"must be a type array");
+ ShouldNotReachHere();
+ }
+
oop PSPromotionManager::oop_promotion_failed(oop obj, markOop obj_mark) {
assert(_old_gen_is_full || PromotionFailureALot, "Sanity");
// Attempt to CAS in the header.
// This tests if the header is still the same as when
< prev index next >