1.1 --- a/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp Tue Aug 19 10:50:27 2014 +0200 1.2 +++ b/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp Thu Aug 21 11:47:10 2014 +0200 1.3 @@ -25,6 +25,7 @@ 1.4 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1BLOCKOFFSETTABLE_HPP 1.5 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1BLOCKOFFSETTABLE_HPP 1.6 1.7 +#include "gc_implementation/g1/g1RegionToSpaceMapper.hpp" 1.8 #include "memory/memRegion.hpp" 1.9 #include "runtime/virtualspace.hpp" 1.10 #include "utilities/globalDefinitions.hpp" 1.11 @@ -106,6 +107,11 @@ 1.12 inline HeapWord* block_start_const(const void* addr) const; 1.13 }; 1.14 1.15 +class G1BlockOffsetSharedArrayMappingChangedListener : public G1MappingChangedListener { 1.16 + public: 1.17 + virtual void on_commit(uint start_idx, size_t num_regions); 1.18 +}; 1.19 + 1.20 // This implementation of "G1BlockOffsetTable" divides the covered region 1.21 // into "N"-word subregions (where "N" = 2^"LogN". An array with an entry 1.22 // for each such subregion indicates how far back one must go to find the 1.23 @@ -125,6 +131,7 @@ 1.24 friend class VMStructs; 1.25 1.26 private: 1.27 + G1BlockOffsetSharedArrayMappingChangedListener _listener; 1.28 // The reserved region covered by the shared array. 1.29 MemRegion _reserved; 1.30 1.31 @@ -133,16 +140,8 @@ 1.32 1.33 // Array for keeping offsets for retrieving object start fast given an 1.34 // address. 1.35 - VirtualSpace _vs; 1.36 u_char* _offset_array; // byte array keeping backwards offsets 1.37 1.38 - void check_index(size_t index, const char* msg) const { 1.39 - assert(index < _vs.committed_size(), 1.40 - err_msg("%s - " 1.41 - "index: " SIZE_FORMAT ", _vs.committed_size: " SIZE_FORMAT, 1.42 - msg, index, _vs.committed_size())); 1.43 - } 1.44 - 1.45 void check_offset(size_t offset, const char* msg) const { 1.46 assert(offset <= N_words, 1.47 err_msg("%s - " 1.48 @@ -152,63 +151,33 @@ 1.49 1.50 // Bounds checking accessors: 1.51 // For performance these have to devolve to array accesses in product builds. 1.52 - u_char offset_array(size_t index) const { 1.53 - check_index(index, "index out of range"); 1.54 - return _offset_array[index]; 1.55 - } 1.56 + inline u_char offset_array(size_t index) const; 1.57 1.58 void set_offset_array(HeapWord* left, HeapWord* right, u_char offset); 1.59 1.60 - void set_offset_array(size_t index, u_char offset) { 1.61 - check_index(index, "index out of range"); 1.62 - check_offset(offset, "offset too large"); 1.63 + void set_offset_array_raw(size_t index, u_char offset) { 1.64 _offset_array[index] = offset; 1.65 } 1.66 1.67 - void set_offset_array(size_t index, HeapWord* high, HeapWord* low) { 1.68 - check_index(index, "index out of range"); 1.69 - assert(high >= low, "addresses out of order"); 1.70 - check_offset(pointer_delta(high, low), "offset too large"); 1.71 - _offset_array[index] = (u_char) pointer_delta(high, low); 1.72 - } 1.73 + inline void set_offset_array(size_t index, u_char offset); 1.74 1.75 - void set_offset_array(size_t left, size_t right, u_char offset) { 1.76 - check_index(right, "right index out of range"); 1.77 - assert(left <= right, "indexes out of order"); 1.78 - size_t num_cards = right - left + 1; 1.79 - if (UseMemSetInBOT) { 1.80 - memset(&_offset_array[left], offset, num_cards); 1.81 - } else { 1.82 - size_t i = left; 1.83 - const size_t end = i + num_cards; 1.84 - for (; i < end; i++) { 1.85 - _offset_array[i] = offset; 1.86 - } 1.87 - } 1.88 - } 1.89 + inline void set_offset_array(size_t index, HeapWord* high, HeapWord* low); 1.90 1.91 - void check_offset_array(size_t index, HeapWord* high, HeapWord* low) const { 1.92 - check_index(index, "index out of range"); 1.93 - assert(high >= low, "addresses out of order"); 1.94 - check_offset(pointer_delta(high, low), "offset too large"); 1.95 - assert(_offset_array[index] == pointer_delta(high, low), "Wrong offset"); 1.96 - } 1.97 + inline void set_offset_array(size_t left, size_t right, u_char offset); 1.98 + 1.99 + inline void check_offset_array(size_t index, HeapWord* high, HeapWord* low) const; 1.100 1.101 bool is_card_boundary(HeapWord* p) const; 1.102 1.103 +public: 1.104 + 1.105 // Return the number of slots needed for an offset array 1.106 // that covers mem_region_words words. 1.107 - // We always add an extra slot because if an object 1.108 - // ends on a card boundary we put a 0 in the next 1.109 - // offset array slot, so we want that slot always 1.110 - // to be reserved. 1.111 - 1.112 - size_t compute_size(size_t mem_region_words) { 1.113 - size_t number_of_slots = (mem_region_words / N_words) + 1; 1.114 - return ReservedSpace::page_align_size_up(number_of_slots); 1.115 + static size_t compute_size(size_t mem_region_words) { 1.116 + size_t number_of_slots = (mem_region_words / N_words); 1.117 + return ReservedSpace::allocation_align_size_up(number_of_slots); 1.118 } 1.119 1.120 -public: 1.121 enum SomePublicConstants { 1.122 LogN = 9, 1.123 LogN_words = LogN - LogHeapWordSize, 1.124 @@ -222,21 +191,21 @@ 1.125 // least "init_word_size".) The contents of the initial table are 1.126 // undefined; it is the responsibility of the constituent 1.127 // G1BlockOffsetTable(s) to initialize cards. 1.128 - G1BlockOffsetSharedArray(MemRegion reserved, size_t init_word_size); 1.129 - 1.130 - // Notes a change in the committed size of the region covered by the 1.131 - // table. The "new_word_size" may not be larger than the size of the 1.132 - // reserved region this table covers. 1.133 - void resize(size_t new_word_size); 1.134 + G1BlockOffsetSharedArray(MemRegion heap, G1RegionToSpaceMapper* storage); 1.135 1.136 void set_bottom(HeapWord* new_bottom); 1.137 1.138 // Return the appropriate index into "_offset_array" for "p". 1.139 inline size_t index_for(const void* p) const; 1.140 + inline size_t index_for_raw(const void* p) const; 1.141 1.142 // Return the address indicating the start of the region corresponding to 1.143 // "index" in "_offset_array". 1.144 inline HeapWord* address_for_index(size_t index) const; 1.145 + // Variant of address_for_index that does not check the index for validity. 1.146 + inline HeapWord* address_for_index_raw(size_t index) const { 1.147 + return _reserved.start() + (index << LogN_words); 1.148 + } 1.149 }; 1.150 1.151 // And here is the G1BlockOffsetTable subtype that uses the array. 1.152 @@ -476,6 +445,12 @@ 1.153 blk_start, blk_end); 1.154 } 1.155 1.156 + // Variant of zero_bottom_entry that does not check for availability of the 1.157 + // memory first. 1.158 + void zero_bottom_entry_raw(); 1.159 + // Variant of initialize_threshold that does not check for availability of the 1.160 + // memory first. 1.161 + HeapWord* initialize_threshold_raw(); 1.162 // Zero out the entry for _bottom (offset will be zero). 1.163 void zero_bottom_entry(); 1.164 public: 1.165 @@ -486,8 +461,8 @@ 1.166 HeapWord* initialize_threshold(); 1.167 1.168 void reset_bot() { 1.169 - zero_bottom_entry(); 1.170 - initialize_threshold(); 1.171 + zero_bottom_entry_raw(); 1.172 + initialize_threshold_raw(); 1.173 } 1.174 1.175 // Return the next threshold, the point at which the table should be