src/share/vm/gc_implementation/g1/heapRegion.cpp

Print this page
rev 4801 : imported patch code-movement
rev 4802 : imported patch optimize-nmethod-scanning
rev 4803 : imported patch thomas-comments-2

*** 21,40 **** * questions. * */ #include "precompiled.hpp" #include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp" #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/g1OopClosures.inline.hpp" #include "gc_implementation/g1/heapRegion.inline.hpp" #include "gc_implementation/g1/heapRegionRemSet.hpp" #include "gc_implementation/g1/heapRegionSeq.inline.hpp" #include "memory/genOopClosures.inline.hpp" #include "memory/iterator.hpp" #include "oops/oop.inline.hpp" - #include "utilities/growableArray.hpp" int HeapRegion::LogOfHRGrainBytes = 0; int HeapRegion::LogOfHRGrainWords = 0; size_t HeapRegion::GrainBytes = 0; size_t HeapRegion::GrainWords = 0; --- 21,40 ---- * questions. * */ #include "precompiled.hpp" + #include "code/nmethod.hpp" #include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp" #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/g1OopClosures.inline.hpp" #include "gc_implementation/g1/heapRegion.inline.hpp" #include "gc_implementation/g1/heapRegionRemSet.hpp" #include "gc_implementation/g1/heapRegionSeq.inline.hpp" #include "memory/genOopClosures.inline.hpp" #include "memory/iterator.hpp" #include "oops/oop.inline.hpp" int HeapRegion::LogOfHRGrainBytes = 0; int HeapRegion::LogOfHRGrainWords = 0; size_t HeapRegion::GrainBytes = 0; size_t HeapRegion::GrainWords = 0;
*** 224,247 **** reset_pre_dummy_top(); if (!par) { // If this is parallel, this will be done later. HeapRegionRemSet* hrrs = rem_set(); ! if (hrrs != NULL) hrrs->clear(); _claimed = InitialClaimValue; } zero_marked_bytes(); _offsets.resize(HeapRegion::GrainWords); init_top_at_mark_start(); - - if (_strong_code_root_list != NULL) { - delete _strong_code_root_list; - } - _strong_code_root_list = new (ResourceObj::C_HEAP, mtGC) - GrowableArray<nmethod*>(10, 0, NULL, true); - if (clear_space) clear(SpaceDecorator::Mangle); } void HeapRegion::par_clear() { assert(used() == 0, "the region should have been already cleared"); --- 224,240 ---- reset_pre_dummy_top(); if (!par) { // If this is parallel, this will be done later. HeapRegionRemSet* hrrs = rem_set(); ! hrrs->clear(); _claimed = InitialClaimValue; } zero_marked_bytes(); _offsets.resize(HeapRegion::GrainWords); init_top_at_mark_start(); if (clear_space) clear(SpaceDecorator::Mangle); } void HeapRegion::par_clear() { assert(used() == 0, "the region should have been already cleared");
*** 366,386 **** #ifdef ASSERT _containing_set(NULL), #endif // ASSERT _young_index_in_cset(-1), _surv_rate_group(NULL), _age_index(-1), _rem_set(NULL), _recorded_rs_length(0), _predicted_elapsed_time_ms(0), ! _predicted_bytes_to_copy(0), _strong_code_root_list(NULL) { _orig_end = mr.end(); // Note that initialize() will set the start of the unmarked area of the // region. hr_clear(false /*par*/, false /*clear_space*/); set_top(bottom()); set_saved_mark(); - _rem_set = new HeapRegionRemSet(sharedOffsetArray, this); - assert(HeapRegionRemSet::num_par_rem_sets() > 0, "Invariant."); } CompactibleSpace* HeapRegion::next_compaction_space() const { // We're not using an iterator given that it will wrap around when --- 359,378 ---- #ifdef ASSERT _containing_set(NULL), #endif // ASSERT _young_index_in_cset(-1), _surv_rate_group(NULL), _age_index(-1), _rem_set(NULL), _recorded_rs_length(0), _predicted_elapsed_time_ms(0), ! _predicted_bytes_to_copy(0) { + _rem_set = new HeapRegionRemSet(sharedOffsetArray, this); _orig_end = mr.end(); // Note that initialize() will set the start of the unmarked area of the // region. hr_clear(false /*par*/, false /*clear_space*/); set_top(bottom()); set_saved_mark(); assert(HeapRegionRemSet::num_par_rem_sets() > 0, "Invariant."); } CompactibleSpace* HeapRegion::next_compaction_space() const { // We're not using an iterator given that it will wrap around when
*** 599,713 **** } // Code roots support void HeapRegion::add_strong_code_root(nmethod* nm) { ! assert(nm != NULL, "sanity"); ! // Search for the code blob from the RHS to avoid ! // duplicate entries as much as possible ! if (_strong_code_root_list->find_from_end(nm) < 0) { ! // Code blob isn't already in the list ! _strong_code_root_list->push(nm); ! } } void HeapRegion::remove_strong_code_root(nmethod* nm) { ! assert(nm != NULL, "sanity"); ! int idx = _strong_code_root_list->find(nm); ! while (idx >= 0) { ! _strong_code_root_list->remove_at(idx); ! idx = _strong_code_root_list->find(nm); ! } } - class NMethodMigrationOopClosure : public OopClosure { - G1CollectedHeap* _g1h; - HeapRegion* _from; - nmethod* _nm; - - uint _num_self_forwarded; - - template <class T> void do_oop_work(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); - if (_from->is_in(obj)) { - // Reference still points into the source region. - // Since roots are immediately evacuated this means that - // we must have self forwarded the object - assert(obj->is_forwarded(), - err_msg("code roots should be immediately evacuated. " - "Ref: "PTR_FORMAT", " - "Obj: "PTR_FORMAT", " - "Region: "HR_FORMAT, - p, (void*) obj, HR_FORMAT_PARAMS(_from))); - assert(obj->forwardee() == obj, - err_msg("not self forwarded? obj = "PTR_FORMAT, (void*)obj)); - - // The object has been self forwarded. - // Note, if we're during an initial mark pause, there is - // no need to explicitly mark object. It will be marked - // during the regular evacuation failure handling code. - _num_self_forwarded++; - } else { - // The reference points into a promotion or to-space region - HeapRegion* to = _g1h->heap_region_containing(obj); - to->add_strong_code_root(_nm); - } - } - } - - public: - NMethodMigrationOopClosure(G1CollectedHeap* g1h, HeapRegion* from, nmethod* nm): - _g1h(g1h), _from(from), _nm(nm), _num_self_forwarded(0) {} - - void do_oop(narrowOop* p) { do_oop_work(p); } - void do_oop(oop* p) { do_oop_work(p); } - - uint retain() { return _num_self_forwarded > 0; } - }; - void HeapRegion::migrate_strong_code_roots() { assert(in_collection_set(), "only collection set regions"); assert(!isHumongous(), "not humongous regions"); ! ResourceMark rm; ! ! // List of code blobs to retain for this region ! GrowableArray<nmethod*> to_be_retained(10); ! G1CollectedHeap* g1h = G1CollectedHeap::heap(); ! ! while (strong_code_root_list()->is_nonempty()) { ! nmethod *nm = strong_code_root_list()->pop(); ! if (nm != NULL) { ! NMethodMigrationOopClosure oop_cl(g1h, this, nm); ! nm->oops_do(&oop_cl); ! if (oop_cl.retain()) { ! to_be_retained.push(nm); ! } ! } ! } ! ! // Now push any code roots we need to retain ! // FIXME: assert that region got an evacuation failure if non-empty ! while (to_be_retained.is_nonempty()) { ! nmethod* nm = to_be_retained.pop(); ! assert(nm != NULL, "sanity"); ! add_strong_code_root(nm); ! } } void HeapRegion::strong_code_roots_do(CodeBlobClosure* blk) const { ! for (int i = 0; i < _strong_code_root_list->length(); i += 1) { ! nmethod* nm = _strong_code_root_list->at(i); ! blk->do_code_blob(nm); ! } ! } ! ! size_t HeapRegion::strong_code_root_mem_size() { ! return sizeof(GrowableArray<nmethod*>) + ! _strong_code_root_list->max_length() * sizeof(nmethod*); } class VerifyStrongCodeRootOopClosure: public OopClosure { const HeapRegion* _hr; nmethod* _nm; --- 591,620 ---- } // Code roots support void HeapRegion::add_strong_code_root(nmethod* nm) { ! HeapRegionRemSet* hrrs = rem_set(); ! hrrs->add_strong_code_root(nm); } void HeapRegion::remove_strong_code_root(nmethod* nm) { ! HeapRegionRemSet* hrrs = rem_set(); ! hrrs->remove_strong_code_root(nm); } void HeapRegion::migrate_strong_code_roots() { assert(in_collection_set(), "only collection set regions"); assert(!isHumongous(), "not humongous regions"); ! HeapRegionRemSet* hrrs = rem_set(); ! hrrs->migrate_strong_code_roots(); } void HeapRegion::strong_code_roots_do(CodeBlobClosure* blk) const { ! HeapRegionRemSet* hrrs = rem_set(); ! hrrs->strong_code_roots_do(blk); } class VerifyStrongCodeRootOopClosure: public OopClosure { const HeapRegion* _hr; nmethod* _nm;
*** 801,828 **** // time. assert(VerifyDuringGC, "only way to get here"); return; } // if this region is empty then there should be no entries // on its strong code root list if (is_empty()) { ! if (!_strong_code_root_list->is_empty()) { gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] is empty " "but has "INT32_FORMAT" code root entries", ! bottom(), end(), _strong_code_root_list->length()); *failures = true; } return; } // An H-region should have an empty strong code root list if (isHumongous()) { ! if (!_strong_code_root_list->is_empty()) { gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] is humongous " "but has "INT32_FORMAT" code root entries", ! bottom(), end(), _strong_code_root_list->length()); *failures = true; } return; } --- 708,738 ---- // time. assert(VerifyDuringGC, "only way to get here"); return; } + HeapRegionRemSet* hrrs = rem_set(); + int strong_code_roots_length = hrrs->strong_code_roots_list_length(); + // if this region is empty then there should be no entries // on its strong code root list if (is_empty()) { ! if (strong_code_roots_length > 0) { gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] is empty " "but has "INT32_FORMAT" code root entries", ! bottom(), end(), strong_code_roots_length); *failures = true; } return; } // An H-region should have an empty strong code root list if (isHumongous()) { ! if (strong_code_roots_length > 0) { gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] is humongous " "but has "INT32_FORMAT" code root entries", ! bottom(), end(), strong_code_roots_length); *failures = true; } return; }