inline void G1ParScanClosure::do_oop_nv(T* p) { T heap_oop = oopDesc::load_heap_oop(p); if (!oopDesc::is_null(heap_oop)) { oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); const InCSetState state = _g1->in_cset_state(obj); if (state.is_in_cset()) { // We're not going to even bother checking whether the object is // already forwarded or not, as this usually causes an immediate // stall. We'll try to prefetch the object (for write, given that // we might need to install the forwarding reference) and we'll // get back to it when pop it from the queue Prefetch::write(obj->mark_addr(), 0); Prefetch::read(obj->mark_addr(), (HeapWordSize*2)); // slightly paranoid test; I'm trying to catch potential // problems before we go into push_on_queue to know where the // problem is coming from assert((obj == oopDesc::load_decode_heap_oop(p)) || (obj->is_forwarded() && obj->forwardee() == oopDesc::load_decode_heap_oop(p)), "p should still be pointing to obj or to its forwardee"); _par_scan_state->push_on_queue(p); } else { if (state.is_humongous()) { _g1->set_humongous_is_live(obj); } else if (state.is_ext()) { _par_scan_state->do_oop_ext(p); } _par_scan_state->update_rs(_from, p, obj); } } }
void G1ParCopyClosure<barrier, do_mark_object, use_ext>::do_oop_work(T* p) { T heap_oop = oopDesc::load_heap_oop(p); if (oopDesc::is_null(heap_oop)) { return; } oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); assert(_worker_id == _par_scan_state->worker_id(), "sanity"); const InCSetState state = _g1->in_cset_state(obj); if (state.is_in_cset()) { oop forwardee; markOop m = obj->mark(); if (m->is_marked()) { forwardee = (oop) m->decode_pointer(); } else { forwardee = _par_scan_state->copy_to_survivor_space(state, obj, m); } assert(forwardee != NULL, "forwardee should not be NULL"); oopDesc::encode_store_heap_oop(p, forwardee); if (do_mark_object != G1MarkNone && forwardee != obj) { // If the object is self-forwarded we don't need to explicitly // mark it, the evacuation failure protocol will do so. mark_forwarded_object(obj, forwardee); } if (barrier == G1BarrierKlass) { do_klass_barrier(p, forwardee); } } else { if (state.is_humongous()) { _g1->set_humongous_is_live(obj); } if (use_ext && state.is_ext()) { _par_scan_state->do_oop_ext(p); } // The object is not in collection set. If we're a root scanning // closure during an initial mark pause then attempt to mark the object. if (do_mark_object == G1MarkFromRoot) { mark_object(obj); } } }