< prev index next >

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

Print this page

        

*** 1042,1052 **** curr_region = NULL; } } // Notify mark-sweep of the archive range. ! G1MarkSweep::mark_range_archive(curr_range); } return true; } void G1CollectedHeap::fill_archive_regions(MemRegion* ranges, size_t count) { --- 1042,1052 ---- curr_region = NULL; } } // Notify mark-sweep of the archive range. ! G1MarkSweep::mark_range_archive(curr_range, true); } return true; } void G1CollectedHeap::fill_archive_regions(MemRegion* ranges, size_t count) {
*** 1107,1116 **** --- 1107,1182 ---- increase_used(fill_size * HeapWordSize); } } } + void G1CollectedHeap::free_archive_regions(MemRegion* ranges, size_t count) { + assert(ranges != NULL, "MemRegion array NULL"); + assert(count != 0, "No MemRegions provided"); + MemRegion reserved = _hrm.reserved(); + HeapWord* prev_last_addr = NULL; + HeapRegion* prev_last_region = NULL; + FreeRegionList local_free_list("Local List for Freeing Archive Regions"); + size_t size_used = 0; + + // For each Memregion, free the G1 regions that constitute it, and + // notify mark-sweep that the range is no longer to be considered 'archive.' + MutexLockerEx x(Heap_lock); + for (size_t i = 0; i < count; i++) { + HeapWord* start_address = ranges[i].start(); + HeapWord* last_address = ranges[i].last(); + + assert(reserved.contains(start_address) && reserved.contains(last_address), + err_msg("MemRegion outside of heap [" PTR_FORMAT ", " PTR_FORMAT "]", + p2i(start_address), p2i(last_address))); + assert(start_address > prev_last_addr, + err_msg("Ranges not in ascending order: " PTR_FORMAT " <= " PTR_FORMAT , + p2i(start_address), p2i(prev_last_addr))); + size_used += ranges[i].word_size() * HeapWordSize; + prev_last_addr = last_address; + + HeapRegion* start_region = _hrm.addr_to_region(start_address); + HeapRegion* last_region = _hrm.addr_to_region(last_address); + + // Check for ranges that start in the same G1 region in which the previous + // range ended, and adjust the start address so we don't try to free + // the same region again. If the current range is entirely within that + // region, skip it. + if ((prev_last_region != NULL) && (start_region == prev_last_region)) { + start_address = start_region->end(); + if (start_address > last_address) { + continue; + } + start_region = _hrm.addr_to_region(start_address); + } + prev_last_region = last_region; + + // After verifying that each region was marked as an archive region by + // alloc_archive_regions, free it. + HeapRegion* curr_region = start_region; + while (curr_region != NULL) { + guarantee(curr_region->is_archive(), + err_msg("Expected archive region at index %u", curr_region->hrm_index())); + + _old_set.remove(curr_region); + free_region(curr_region, &local_free_list, false /* par */, true /* locked */); + if (curr_region != last_region) { + curr_region = _hrm.next_region_in_heap(curr_region); + } else { + curr_region = NULL; + } + } + + // Notify mark-sweep that this is no longer an archive range. + G1MarkSweep::mark_range_archive(ranges[i], false); + } + + prepend_to_freelist(&local_free_list); + decrease_used(size_used); + } + + HeapWord* G1CollectedHeap::attempt_allocation_humongous(size_t word_size, uint* gc_count_before_ret, uint* gclocker_retry_count_ret) { // The structure of this method has a lot of similarities to // attempt_allocation_slow(). The reason these two were not merged
< prev index next >