< prev index next >

src/share/vm/gc/g1/g1CollectedHeap.cpp

Print this page

        

*** 318,333 **** // This will be the "starts humongous" region. HeapRegion* first_hr = region_at(first); // The header of the new object will be placed at the bottom of // the first region. HeapWord* new_obj = first_hr->bottom(); ! // This will be the new end of the first region in the series that ! // should also match the end of the last region in the series. ! HeapWord* new_end = new_obj + word_size_sum; ! // This will be the new top of the first region that will reflect ! // this allocation. ! HeapWord* new_top = new_obj + word_size; // First, we need to zero the header of the space that we will be // allocating. When we update top further down, some refinement // threads might try to scan the region. By zeroing the header we // ensure that any thread that will try to scan the region will --- 318,329 ---- // This will be the "starts humongous" region. HeapRegion* first_hr = region_at(first); // The header of the new object will be placed at the bottom of // the first region. HeapWord* new_obj = first_hr->bottom(); ! // This will be the new top of the new object. ! HeapWord* obj_top = new_obj + word_size; // First, we need to zero the header of the space that we will be // allocating. When we update top further down, some refinement // threads might try to scan the region. By zeroing the header we // ensure that any thread that will try to scan the region will
*** 344,366 **** // We will set up the first region as "starts humongous". This // will also update the BOT covering all the regions to reflect // that there is a single object that starts at the bottom of the // first region. ! first_hr->set_starts_humongous(new_top, new_end); first_hr->set_allocation_context(context); // Then, if there are any, we will set up the "continues // humongous" regions. HeapRegion* hr = NULL; for (uint i = first + 1; i < last; ++i) { hr = region_at(i); hr->set_continues_humongous(first_hr); hr->set_allocation_context(context); } - // If we have "continues humongous" regions (hr != NULL), then the - // end of the last one should match new_end. - assert(hr == NULL || hr->end() == new_end, "sanity"); // Up to this point no concurrent thread would have been able to // do any scanning on any region in this series. All the top // fields still point to bottom, so the intersection between // [bottom,top] and [card_start,card_end] will be empty. Before we --- 340,359 ---- // We will set up the first region as "starts humongous". This // will also update the BOT covering all the regions to reflect // that there is a single object that starts at the bottom of the // first region. ! first_hr->set_starts_humongous(obj_top); first_hr->set_allocation_context(context); // Then, if there are any, we will set up the "continues // humongous" regions. HeapRegion* hr = NULL; for (uint i = first + 1; i < last; ++i) { hr = region_at(i); hr->set_continues_humongous(first_hr); hr->set_allocation_context(context); } // Up to this point no concurrent thread would have been able to // do any scanning on any region in this series. All the top // fields still point to bottom, so the intersection between // [bottom,top] and [card_start,card_end] will be empty. Before we
*** 369,390 **** // object header and the BOT initialization. OrderAccess::storestore(); // Now that the BOT and the object header have been initialized, // we can update top of the "starts humongous" region. ! assert(first_hr->bottom() < new_top && new_top <= first_hr->end(), ! "new_top should be in this region"); ! first_hr->set_top(new_top); if (_hr_printer.is_active()) { - HeapWord* bottom = first_hr->bottom(); - HeapWord* end = first_hr->orig_end(); if ((first + 1) == last) { // the series has a single humongous region ! _hr_printer.alloc(G1HRPrinter::SingleHumongous, first_hr, new_top); } else { // the series has more than one humongous regions ! _hr_printer.alloc(G1HRPrinter::StartsHumongous, first_hr, end); } } // Now, we will update the top fields of the "continues humongous" // regions. The reason we need to do this is that, otherwise, --- 362,379 ---- // object header and the BOT initialization. OrderAccess::storestore(); // Now that the BOT and the object header have been initialized, // we can update top of the "starts humongous" region. ! first_hr->set_top(MIN2(first_hr->end(), obj_top)); if (_hr_printer.is_active()) { if ((first + 1) == last) { // the series has a single humongous region ! _hr_printer.alloc(G1HRPrinter::SingleHumongous, first_hr, obj_top); } else { // the series has more than one humongous regions ! _hr_printer.alloc(G1HRPrinter::StartsHumongous, first_hr, first_hr->end()); } } // Now, we will update the top fields of the "continues humongous" // regions. The reason we need to do this is that, otherwise,
*** 400,430 **** hr = NULL; for (uint i = first + 1; i < last; ++i) { hr = region_at(i); if ((i + 1) == last) { // last continues humongous region ! assert(hr->bottom() < new_top && new_top <= hr->end(), "new_top should fall on this region"); ! hr->set_top(new_top); ! _hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, new_top); } else { // not last one ! assert(new_top > hr->end(), "new_top should be above this region"); hr->set_top(hr->end()); _hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, hr->end()); } } ! // If we have continues humongous regions (hr != NULL), then the ! // end of the last one should match new_end and its top should ! // match new_top. ! assert(hr == NULL || ! (hr->end() == new_end && hr->top() == new_top), "sanity"); check_bitmaps("Humongous Region Allocation", first_hr); ! assert(first_hr->used() == word_size * HeapWordSize, "invariant"); ! increase_used(first_hr->used()); ! _humongous_set.add(first_hr); return new_obj; } // If could fit into free regions w/o expansion, try. --- 389,419 ---- hr = NULL; for (uint i = first + 1; i < last; ++i) { hr = region_at(i); if ((i + 1) == last) { // last continues humongous region ! assert(hr->bottom() < obj_top && obj_top <= hr->end(), "new_top should fall on this region"); ! hr->set_top(obj_top); ! _hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, obj_top); } else { // not last one ! assert(obj_top > hr->end(), "obj_top should be above this region"); hr->set_top(hr->end()); _hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, hr->end()); } } ! // If we have continues humongous regions (hr != NULL), its top should ! // match obj_top. ! assert(hr == NULL || (hr->top() == obj_top), "sanity"); check_bitmaps("Humongous Region Allocation", first_hr); ! increase_used(word_size * HeapWordSize); ! ! for (uint i = first; i < last; ++i) { ! _humongous_set.add(region_at(i)); ! } return new_obj; } // If could fit into free regions w/o expansion, try.
*** 1137,1154 **** _g1h(g1h), _mr_bs(mr_bs) {} bool doHeapRegion(HeapRegion* r) { HeapRegionRemSet* hrrs = r->rem_set(); if (r->is_continues_humongous()) { // We'll assert that the strong code root list and RSet is empty assert(hrrs->strong_code_roots_list_length() == 0, "sanity"); assert(hrrs->occupied() == 0, "RSet should be empty"); return false; } - _g1h->reset_gc_time_stamps(r); hrrs->clear(); // You might think here that we could clear just the cards // corresponding to the used region. But no: if we leave a dirty card // in a region we might allocate into, then it would prevent that card // from being enqueued, and cause it to be missed. --- 1126,1144 ---- _g1h(g1h), _mr_bs(mr_bs) {} bool doHeapRegion(HeapRegion* r) { HeapRegionRemSet* hrrs = r->rem_set(); + _g1h->reset_gc_time_stamps(r); + if (r->is_continues_humongous()) { // We'll assert that the strong code root list and RSet is empty assert(hrrs->strong_code_roots_list_length() == 0, "sanity"); assert(hrrs->occupied() == 0, "RSet should be empty"); return false; } hrrs->clear(); // You might think here that we could clear just the cards // corresponding to the used region. But no: if we leave a dirty card // in a region we might allocate into, then it would prevent that card // from being enqueued, and cause it to be missed.
*** 1203,1218 **** bool doHeapRegion(HeapRegion* hr) { assert(!hr->is_young(), "not expecting to find young regions"); if (hr->is_free()) { // We only generate output for non-empty regions. } else if (hr->is_starts_humongous()) { - if (hr->region_num() == 1) { - // single humongous region - _hr_printer->post_compaction(hr, G1HRPrinter::SingleHumongous); - } else { _hr_printer->post_compaction(hr, G1HRPrinter::StartsHumongous); - } } else if (hr->is_continues_humongous()) { _hr_printer->post_compaction(hr, G1HRPrinter::ContinuesHumongous); } else if (hr->is_archive()) { _hr_printer->post_compaction(hr, G1HRPrinter::Archive); } else if (hr->is_old()) { --- 1193,1203 ----
*** 2220,2240 **** size_t G1CollectedHeap::capacity() const { return _hrm.length() * HeapRegion::GrainBytes; } void G1CollectedHeap::reset_gc_time_stamps(HeapRegion* hr) { - assert(!hr->is_continues_humongous(), "pre-condition"); hr->reset_gc_time_stamp(); - if (hr->is_starts_humongous()) { - uint first_index = hr->hrm_index() + 1; - uint last_index = hr->last_hc_index(); - for (uint i = first_index; i < last_index; i += 1) { - HeapRegion* chr = region_at(i); - assert(chr->is_continues_humongous(), "sanity"); - chr->reset_gc_time_stamp(); - } - } } #ifndef PRODUCT class CheckGCTimeStampsHRClosure : public HeapRegionClosure { --- 2205,2215 ----
*** 2298,2310 **** class SumUsedClosure: public HeapRegionClosure { size_t _used; public: SumUsedClosure() : _used(0) {} bool doHeapRegion(HeapRegion* r) { - if (!r->is_continues_humongous()) { _used += r->used(); - } return false; } size_t result() { return _used; } }; --- 2273,2283 ----
*** 2521,2533 **** } bool G1CollectedHeap::is_in(const void* p) const { if (_hrm.reserved().contains(p)) { // Given that we know that p is in the reserved space, ! // heap_region_containing_raw() should successfully // return the containing region. ! HeapRegion* hr = heap_region_containing_raw(p); return hr->is_in(p); } else { return false; } } --- 2494,2506 ---- } bool G1CollectedHeap::is_in(const void* p) const { if (_hrm.reserved().contains(p)) { // Given that we know that p is in the reserved space, ! // heap_region_containing() should successfully // return the containing region. ! HeapRegion* hr = heap_region_containing(p); return hr->is_in(p); } else { return false; } }
*** 3060,3070 **** if (!r->is_continues_humongous()) { bool failures = false; r->verify(_vo, &failures); if (failures) { _failures = true; ! } else { VerifyObjsInRegionClosure not_dead_yet_cl(r, _vo); r->object_iterate(&not_dead_yet_cl); if (_vo != VerifyOption_G1UseNextMarking) { if (r->max_live_bytes() < not_dead_yet_cl.live_bytes()) { gclog_or_tty->print_cr("[" PTR_FORMAT "," PTR_FORMAT "] " --- 3033,3043 ---- if (!r->is_continues_humongous()) { bool failures = false; r->verify(_vo, &failures); if (failures) { _failures = true; ! } else if (!r->is_starts_humongous()) { VerifyObjsInRegionClosure not_dead_yet_cl(r, _vo); r->object_iterate(&not_dead_yet_cl); if (_vo != VerifyOption_G1UseNextMarking) { if (r->max_live_bytes() < not_dead_yet_cl.live_bytes()) { gclog_or_tty->print_cr("[" PTR_FORMAT "," PTR_FORMAT "] "
*** 5314,5341 **** } void G1CollectedHeap::free_humongous_region(HeapRegion* hr, FreeRegionList* free_list, bool par) { ! assert(hr->is_starts_humongous(), "this is only for starts humongous regions"); assert(free_list != NULL, "pre-condition"); - - size_t hr_capacity = hr->capacity(); - // We need to read this before we make the region non-humongous, - // otherwise the information will be gone. - uint last_index = hr->last_hc_index(); hr->clear_humongous(); free_region(hr, free_list, par); - - uint i = hr->hrm_index() + 1; - while (i < last_index) { - HeapRegion* curr_hr = region_at(i); - assert(curr_hr->is_continues_humongous(), "invariant"); - curr_hr->clear_humongous(); - free_region(curr_hr, free_list, par); - i += 1; - } } void G1CollectedHeap::remove_from_old_sets(const HeapRegionSetCount& old_regions_removed, const HeapRegionSetCount& humongous_regions_removed) { if (old_regions_removed.length() > 0 || humongous_regions_removed.length() > 0) { --- 5287,5300 ---- } void G1CollectedHeap::free_humongous_region(HeapRegion* hr, FreeRegionList* free_list, bool par) { ! assert(hr->is_humongous(), "this is only for humongous regions"); assert(free_list != NULL, "pre-condition"); hr->clear_humongous(); free_region(hr, free_list, par); } void G1CollectedHeap::remove_from_old_sets(const HeapRegionSetCount& old_regions_removed, const HeapRegionSetCount& humongous_regions_removed) { if (old_regions_removed.length() > 0 || humongous_regions_removed.length() > 0) {
*** 5495,5506 **** _caller(caller), _g1h(g1h), _failures(false) { } bool failures() { return _failures; } virtual bool doHeapRegion(HeapRegion* hr) { - if (hr->is_continues_humongous()) return false; - bool result = _g1h->verify_bitmaps(_caller, hr); if (!result) { _failures = true; } return false; --- 5454,5463 ----
*** 5770,5784 **** uint region_idx = r->hrm_index(); if (!g1h->is_humongous_reclaim_candidate(region_idx) || !r->rem_set()->is_empty()) { if (G1TraceEagerReclaimHumongousObjects) { ! gclog_or_tty->print_cr("Live humongous region %u size " SIZE_FORMAT " start " PTR_FORMAT " length %u with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d", region_idx, (size_t)obj->size() * HeapWordSize, p2i(r->bottom()), - r->region_num(), r->rem_set()->occupied(), r->rem_set()->strong_code_roots_list_length(), next_bitmap->isMarked(r->bottom()), g1h->is_humongous_reclaim_candidate(region_idx), obj->is_typeArray() --- 5727,5740 ---- uint region_idx = r->hrm_index(); if (!g1h->is_humongous_reclaim_candidate(region_idx) || !r->rem_set()->is_empty()) { if (G1TraceEagerReclaimHumongousObjects) { ! gclog_or_tty->print_cr("Live humongous region %u object size " SIZE_FORMAT " start " PTR_FORMAT " with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d", region_idx, (size_t)obj->size() * HeapWordSize, p2i(r->bottom()), r->rem_set()->occupied(), r->rem_set()->strong_code_roots_list_length(), next_bitmap->isMarked(r->bottom()), g1h->is_humongous_reclaim_candidate(region_idx), obj->is_typeArray()
*** 5791,5805 **** guarantee(obj->is_typeArray(), "Only eagerly reclaiming type arrays is supported, but the object " PTR_FORMAT " is not.", p2i(r->bottom())); if (G1TraceEagerReclaimHumongousObjects) { ! gclog_or_tty->print_cr("Dead humongous region %u size " SIZE_FORMAT " start " PTR_FORMAT " length %u with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d", region_idx, (size_t)obj->size() * HeapWordSize, p2i(r->bottom()), - r->region_num(), r->rem_set()->occupied(), r->rem_set()->strong_code_roots_list_length(), next_bitmap->isMarked(r->bottom()), g1h->is_humongous_reclaim_candidate(region_idx), obj->is_typeArray() --- 5747,5760 ---- guarantee(obj->is_typeArray(), "Only eagerly reclaiming type arrays is supported, but the object " PTR_FORMAT " is not.", p2i(r->bottom())); if (G1TraceEagerReclaimHumongousObjects) { ! gclog_or_tty->print_cr("Dead humongous region %u object size " SIZE_FORMAT " start " PTR_FORMAT " with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d", region_idx, (size_t)obj->size() * HeapWordSize, p2i(r->bottom()), r->rem_set()->occupied(), r->rem_set()->strong_code_roots_list_length(), next_bitmap->isMarked(r->bottom()), g1h->is_humongous_reclaim_candidate(region_idx), obj->is_typeArray()
*** 5807,5820 **** --- 5762,5779 ---- } // Need to clear mark bit of the humongous object if already set. if (next_bitmap->isMarked(r->bottom())) { next_bitmap->clear(r->bottom()); } + do { + HeapRegion* next = g1h->next_region_by_index(r); _freed_bytes += r->used(); r->set_containing_set(NULL); _humongous_regions_removed.increment(1u, r->capacity()); g1h->free_humongous_region(r, _free_region_list, false); + r = next; + } while (r != NULL && r->is_continues_humongous()); return false; } HeapRegionSetCount& humongous_free_count() {
*** 6045,6058 **** assert(_old_set->is_empty(), "pre-condition"); } } bool doHeapRegion(HeapRegion* r) { - if (r->is_continues_humongous()) { - return false; - } - if (r->is_empty()) { // Add free regions to the free list r->set_free(); r->set_allocation_context(AllocationContext::system()); _hrm->insert_into_free_list(r); --- 6004,6013 ----
*** 6236,6253 **** HeapRegionManager* hrm) : _old_set(old_set), _humongous_set(humongous_set), _hrm(hrm), _old_count(), _humongous_count(), _free_count(){ } bool doHeapRegion(HeapRegion* hr) { - if (hr->is_continues_humongous()) { - return false; - } - if (hr->is_young()) { // TODO ! } else if (hr->is_starts_humongous()) { ! assert(hr->containing_set() == _humongous_set, "Heap region %u is starts humongous but not in humongous set.", hr->hrm_index()); _humongous_count.increment(1u, hr->capacity()); } else if (hr->is_empty()) { assert(_hrm->is_free(hr), "Heap region %u is empty but not on the free list.", hr->hrm_index()); _free_count.increment(1u, hr->capacity()); } else if (hr->is_old()) { --- 6191,6204 ---- HeapRegionManager* hrm) : _old_set(old_set), _humongous_set(humongous_set), _hrm(hrm), _old_count(), _humongous_count(), _free_count(){ } bool doHeapRegion(HeapRegion* hr) { if (hr->is_young()) { // TODO ! } else if (hr->is_humongous()) { ! assert(hr->containing_set() == _humongous_set, "Heap region %u is humongous but not in humongous set.", hr->hrm_index()); _humongous_count.increment(1u, hr->capacity()); } else if (hr->is_empty()) { assert(_hrm->is_free(hr), "Heap region %u is empty but not on the free list.", hr->hrm_index()); _free_count.increment(1u, hr->capacity()); } else if (hr->is_old()) {
< prev index next >