Mercurial > hg > graal-jvmci-8
diff src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp @ 20337:1f1d373cd044
8038423: G1: Decommit memory within heap
Summary: Allow G1 to decommit memory of arbitrary regions within the heap and their associated auxiliary data structures card table, BOT, hot card cache, and mark bitmaps.
Reviewed-by: mgerdin, brutisso, jwilhelm
author | tschatzl |
---|---|
date | Thu, 21 Aug 2014 11:47:10 +0200 |
parents | 6701abbc4441 |
children | 0fcaab91d485 |
line wrap: on
line diff
--- a/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp Tue Aug 19 10:50:27 2014 +0200 +++ b/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp Thu Aug 21 11:47:10 2014 +0200 @@ -25,6 +25,7 @@ #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1BLOCKOFFSETTABLE_HPP #define SHARE_VM_GC_IMPLEMENTATION_G1_G1BLOCKOFFSETTABLE_HPP +#include "gc_implementation/g1/g1RegionToSpaceMapper.hpp" #include "memory/memRegion.hpp" #include "runtime/virtualspace.hpp" #include "utilities/globalDefinitions.hpp" @@ -106,6 +107,11 @@ inline HeapWord* block_start_const(const void* addr) const; }; +class G1BlockOffsetSharedArrayMappingChangedListener : public G1MappingChangedListener { + public: + virtual void on_commit(uint start_idx, size_t num_regions); +}; + // This implementation of "G1BlockOffsetTable" divides the covered region // into "N"-word subregions (where "N" = 2^"LogN". An array with an entry // for each such subregion indicates how far back one must go to find the @@ -125,6 +131,7 @@ friend class VMStructs; private: + G1BlockOffsetSharedArrayMappingChangedListener _listener; // The reserved region covered by the shared array. MemRegion _reserved; @@ -133,16 +140,8 @@ // Array for keeping offsets for retrieving object start fast given an // address. - VirtualSpace _vs; u_char* _offset_array; // byte array keeping backwards offsets - void check_index(size_t index, const char* msg) const { - assert(index < _vs.committed_size(), - err_msg("%s - " - "index: " SIZE_FORMAT ", _vs.committed_size: " SIZE_FORMAT, - msg, index, _vs.committed_size())); - } - void check_offset(size_t offset, const char* msg) const { assert(offset <= N_words, err_msg("%s - " @@ -152,63 +151,33 @@ // Bounds checking accessors: // For performance these have to devolve to array accesses in product builds. - u_char offset_array(size_t index) const { - check_index(index, "index out of range"); - return _offset_array[index]; - } + inline u_char offset_array(size_t index) const; void set_offset_array(HeapWord* left, HeapWord* right, u_char offset); - void set_offset_array(size_t index, u_char offset) { - check_index(index, "index out of range"); - check_offset(offset, "offset too large"); + void set_offset_array_raw(size_t index, u_char offset) { _offset_array[index] = offset; } - void set_offset_array(size_t index, HeapWord* high, HeapWord* low) { - check_index(index, "index out of range"); - assert(high >= low, "addresses out of order"); - check_offset(pointer_delta(high, low), "offset too large"); - _offset_array[index] = (u_char) pointer_delta(high, low); - } + inline void set_offset_array(size_t index, u_char offset); + + inline void set_offset_array(size_t index, HeapWord* high, HeapWord* low); - void set_offset_array(size_t left, size_t right, u_char offset) { - check_index(right, "right index out of range"); - assert(left <= right, "indexes out of order"); - size_t num_cards = right - left + 1; - if (UseMemSetInBOT) { - memset(&_offset_array[left], offset, num_cards); - } else { - size_t i = left; - const size_t end = i + num_cards; - for (; i < end; i++) { - _offset_array[i] = offset; - } - } - } + inline void set_offset_array(size_t left, size_t right, u_char offset); - void check_offset_array(size_t index, HeapWord* high, HeapWord* low) const { - check_index(index, "index out of range"); - assert(high >= low, "addresses out of order"); - check_offset(pointer_delta(high, low), "offset too large"); - assert(_offset_array[index] == pointer_delta(high, low), "Wrong offset"); - } + inline void check_offset_array(size_t index, HeapWord* high, HeapWord* low) const; bool is_card_boundary(HeapWord* p) const; +public: + // Return the number of slots needed for an offset array // that covers mem_region_words words. - // We always add an extra slot because if an object - // ends on a card boundary we put a 0 in the next - // offset array slot, so we want that slot always - // to be reserved. - - size_t compute_size(size_t mem_region_words) { - size_t number_of_slots = (mem_region_words / N_words) + 1; - return ReservedSpace::page_align_size_up(number_of_slots); + static size_t compute_size(size_t mem_region_words) { + size_t number_of_slots = (mem_region_words / N_words); + return ReservedSpace::allocation_align_size_up(number_of_slots); } -public: enum SomePublicConstants { LogN = 9, LogN_words = LogN - LogHeapWordSize, @@ -222,21 +191,21 @@ // least "init_word_size".) The contents of the initial table are // undefined; it is the responsibility of the constituent // G1BlockOffsetTable(s) to initialize cards. - G1BlockOffsetSharedArray(MemRegion reserved, size_t init_word_size); - - // Notes a change in the committed size of the region covered by the - // table. The "new_word_size" may not be larger than the size of the - // reserved region this table covers. - void resize(size_t new_word_size); + G1BlockOffsetSharedArray(MemRegion heap, G1RegionToSpaceMapper* storage); void set_bottom(HeapWord* new_bottom); // Return the appropriate index into "_offset_array" for "p". inline size_t index_for(const void* p) const; + inline size_t index_for_raw(const void* p) const; // Return the address indicating the start of the region corresponding to // "index" in "_offset_array". inline HeapWord* address_for_index(size_t index) const; + // Variant of address_for_index that does not check the index for validity. + inline HeapWord* address_for_index_raw(size_t index) const { + return _reserved.start() + (index << LogN_words); + } }; // And here is the G1BlockOffsetTable subtype that uses the array. @@ -476,6 +445,12 @@ blk_start, blk_end); } + // Variant of zero_bottom_entry that does not check for availability of the + // memory first. + void zero_bottom_entry_raw(); + // Variant of initialize_threshold that does not check for availability of the + // memory first. + HeapWord* initialize_threshold_raw(); // Zero out the entry for _bottom (offset will be zero). void zero_bottom_entry(); public: @@ -486,8 +461,8 @@ HeapWord* initialize_threshold(); void reset_bot() { - zero_bottom_entry(); - initialize_threshold(); + zero_bottom_entry_raw(); + initialize_threshold_raw(); } // Return the next threshold, the point at which the table should be