Mercurial > hg > graal-compiler
diff src/share/vm/gc_implementation/g1/heapRegionSeq.hpp @ 20336:6701abbc4441
8054818: Refactor HeapRegionSeq to manage heap region and auxiliary data
Summary: Let HeapRegionSeq manage the heap region and auxiliary data to decrease the amount of responsibilities of G1CollectedHeap, and encapsulate this work from other code.
Reviewed-by: jwilhelm, jmasa, mgerdin, brutisso
author | tschatzl |
---|---|
date | Tue, 19 Aug 2014 10:50:27 +0200 |
parents | eec72fa4b108 |
children | 1f1d373cd044 |
line wrap: on
line diff
--- a/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp Tue Aug 19 12:39:06 2014 +0200 +++ b/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp Tue Aug 19 10:50:27 2014 +0200 @@ -26,6 +26,7 @@ #define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_HPP #include "gc_implementation/g1/g1BiasedArray.hpp" +#include "gc_implementation/g1/heapRegionSet.hpp" class HeapRegion; class HeapRegionClosure; @@ -33,7 +34,7 @@ class G1HeapRegionTable : public G1BiasedMappedArray<HeapRegion*> { protected: - virtual HeapRegion* default_value() const { return NULL; } + virtual HeapRegion* default_value() const { return NULL; } }; // This class keeps track of the region metadata (i.e., HeapRegion @@ -64,43 +65,64 @@ G1HeapRegionTable _regions; - // The number of regions committed in the heap. - uint _committed_length; + ReservedSpace _reserved; + VirtualSpace _storage; + + FreeRegionList _free_list; - // A hint for which index to start searching from for humongous - // allocations. - uint _next_search_index; + // The number of regions committed in the heap. + uint _num_committed; + + // Internal only. The highest heap region +1 we allocated a HeapRegion instance for. + uint _allocated_heapregions_length; - // The number of regions for which we have allocated HeapRegions for. - uint _allocated_length; + HeapWord* heap_bottom() const { return _regions.bottom_address_mapped(); } + HeapWord* heap_top() const { return heap_bottom() + _num_committed * HeapRegion::GrainWords; } + HeapWord* heap_end() const {return _regions.end_address_mapped(); } + + void make_regions_available(uint index, uint num_regions = 1); - // Find a contiguous set of empty regions of length num, starting - // from the given index. - uint find_contiguous_from(uint from, uint num); + // Pass down commit calls to the VirtualSpace. + void commit_regions(uint index, size_t num_regions = 1); + void uncommit_regions(uint index, size_t num_regions = 1); - void increment_allocated_length() { - assert(_allocated_length < max_length(), "pre-condition"); - _allocated_length++; - } + // Notify other data structures about change in the heap layout. + void update_committed_space(HeapWord* old_end, HeapWord* new_end); + // Calculate the starting region for each worker during parallel iteration so + // that they do not all start from the same region. + uint start_region_for_worker(uint worker_i, uint num_workers, uint num_regions) const; - void increment_length() { - assert(length() < max_length(), "pre-condition"); - _committed_length++; - } + // Finds the next sequence of unavailable regions starting from start_idx. Returns the + // length of the sequence found. If this result is zero, no such sequence could be found, + // otherwise res_idx indicates the start index of these regions. + uint find_unavailable_from_idx(uint start_idx, uint* res_idx) const; + // Finds the next sequence of empty regions starting from start_idx, going backwards in + // the heap. Returns the length of the sequence found. If this value is zero, no + // sequence could be found, otherwise res_idx contains the start index of this range. + uint find_empty_from_idx_reverse(uint start_idx, uint* res_idx) const; +#ifdef ASSERT +public: + bool is_free(HeapRegion* hr) const; +#endif + // Returns whether the given region is available for allocation. + bool is_available(uint region) const; - void decrement_length() { - assert(length() > 0, "pre-condition"); - _committed_length--; - } + // Allocate a new HeapRegion for the given index. + HeapRegion* new_heap_region(uint hrs_index); + public: + // Empty constructor, we'll initialize it with the initialize() method. + HeapRegionSeq() : _regions(), _reserved(), _storage(), _num_committed(0), + _free_list("Master Free List", new MasterFreeRegionListMtSafeChecker()), + _allocated_heapregions_length(0) + { } - HeapWord* heap_bottom() const { return _regions.bottom_address_mapped(); } - HeapWord* heap_end() const {return _regions.end_address_mapped(); } + void initialize(ReservedSpace reserved); - public: - // Empty contructor, we'll initialize it with the initialize() method. - HeapRegionSeq() : _regions(), _committed_length(0), _next_search_index(0), _allocated_length(0) { } - - void initialize(HeapWord* bottom, HeapWord* end); + // Return the "dummy" region used for G1AllocRegion. This is currently a hardwired + // new HeapRegion that owns HeapRegion at index 0. Since at the moment we commit + // the heap from the lowest address, this region (and its associated data + // structures) are available and we do not need to check further. + HeapRegion* get_dummy_region() { return new_heap_region(0); } // Return the HeapRegion at the given index. Assume that the index // is valid. @@ -110,43 +132,84 @@ // HeapRegion, otherwise return NULL. inline HeapRegion* addr_to_region(HeapWord* addr) const; + // Insert the given region into the free region list. + inline void insert_into_free_list(HeapRegion* hr); + + // Insert the given region list into the global free region list. + void insert_list_into_free_list(FreeRegionList* list) { + _free_list.add_ordered(list); + } + + HeapRegion* allocate_free_region(bool is_old) { + HeapRegion* hr = _free_list.remove_region(is_old); + + if (hr != NULL) { + assert(hr->next() == NULL, "Single region should not have next"); + assert(is_available(hr->hrs_index()), "Must be committed"); + } + return hr; + } + + inline void allocate_free_regions_starting_at(uint first, uint num_regions); + + // Remove all regions from the free list. + void remove_all_free_regions() { + _free_list.remove_all(); + } + + // Return the number of committed free regions in the heap. + uint num_free_regions() const { + return _free_list.length(); + } + + size_t total_capacity_bytes() const { + return num_free_regions() * HeapRegion::GrainBytes; + } + + // Return the number of available (uncommitted) regions. + uint available() const { return max_length() - length(); } + // Return the number of regions that have been committed in the heap. - uint length() const { return _committed_length; } + uint length() const { return _num_committed; } // Return the maximum number of regions in the heap. uint max_length() const { return (uint)_regions.length(); } - // Expand the sequence to reflect that the heap has grown from - // old_end to new_end. Either create new HeapRegions, or re-use - // existing ones, and return them in the given list. Returns the - // memory region that covers the newly-created regions. If a - // HeapRegion allocation fails, the result memory region might be - // smaller than the desired one. - MemRegion expand_by(HeapWord* old_end, HeapWord* new_end, - FreeRegionList* list); + MemRegion committed() const { return MemRegion(heap_bottom(), heap_top()); } + + MemRegion reserved() const { return MemRegion(heap_bottom(), heap_end()); } + + // Expand the sequence to reflect that the heap has grown. Either create new + // HeapRegions, or re-use existing ones. Returns the number of regions the + // sequence was expanded by. If a HeapRegion allocation fails, the resulting + // number of regions might be smaller than what's desired. + uint expand_by(uint num_regions); - // Return the number of contiguous regions at the end of the sequence - // that are available for allocation. - uint free_suffix(); + // Makes sure that the regions from start to start+num_regions-1 are available + // for allocation. Returns the number of regions that were committed to achieve + // this. + uint expand_at(uint start, uint num_regions); - // Find a contiguous set of empty regions of length num and return - // the index of the first region or G1_NULL_HRS_INDEX if the - // search was unsuccessful. - uint find_contiguous(uint num); + // Find a contiguous set of empty or uncommitted regions of length num and return + // the index of the first region or G1_NO_HRS_INDEX if the search was unsuccessful. + // If only_empty is true, only empty regions are considered. + // Searches from bottom to top of the heap, doing a first-fit. + uint find_contiguous(size_t num, bool only_empty); + + HeapRegion* next_region_in_heap(const HeapRegion* r) const; // Apply blk->doHeapRegion() on all committed regions in address order, // terminating the iteration early if doHeapRegion() returns true. void iterate(HeapRegionClosure* blk) const; - // As above, but start the iteration from hr and loop around. If hr - // is NULL, we start from the first region in the heap. - void iterate_from(HeapRegion* hr, HeapRegionClosure* blk) const; + void par_iterate(HeapRegionClosure* blk, uint worker_id, uint no_of_par_workers, jint claim_value) const; - // Tag as uncommitted as many regions that are completely free as - // possible, up to num_regions_to_remove, from the suffix of the committed - // sequence. Return the actual number of removed regions. + // Uncommit up to num_regions_to_remove regions that are completely free. + // Return the actual number of uncommitted regions. uint shrink_by(uint num_regions_to_remove); + void verify(); + // Do some sanity checking. void verify_optional() PRODUCT_RETURN; };