76 // Note that the committed size of the covered space may have changed, |
76 // Note that the committed size of the covered space may have changed, |
77 // so the table size might also wish to change. |
77 // so the table size might also wish to change. |
78 virtual void resize(size_t new_word_size) = 0; |
78 virtual void resize(size_t new_word_size) = 0; |
79 |
79 |
80 virtual void set_bottom(HeapWord* new_bottom) { |
80 virtual void set_bottom(HeapWord* new_bottom) { |
81 assert(new_bottom <= _end, "new_bottom > _end"); |
81 assert(new_bottom <= _end, |
|
82 err_msg("new_bottom (" PTR_FORMAT ") > _end (" PTR_FORMAT ")", |
|
83 new_bottom, _end)); |
82 _bottom = new_bottom; |
84 _bottom = new_bottom; |
83 resize(pointer_delta(_end, _bottom)); |
85 resize(pointer_delta(_end, _bottom)); |
84 } |
86 } |
85 |
87 |
86 // Requires "addr" to be contained by a block, and returns the address of |
88 // Requires "addr" to be contained by a block, and returns the address of |
132 // Array for keeping offsets for retrieving object start fast given an |
134 // Array for keeping offsets for retrieving object start fast given an |
133 // address. |
135 // address. |
134 VirtualSpace _vs; |
136 VirtualSpace _vs; |
135 u_char* _offset_array; // byte array keeping backwards offsets |
137 u_char* _offset_array; // byte array keeping backwards offsets |
136 |
138 |
|
139 void check_index(size_t index, const char* msg) const { |
|
140 assert(index < _vs.committed_size(), |
|
141 err_msg("%s - " |
|
142 "index: " SIZE_FORMAT ", _vs.committed_size: " SIZE_FORMAT, |
|
143 msg, index, _vs.committed_size())); |
|
144 } |
|
145 |
|
146 void check_offset(size_t offset, const char* msg) const { |
|
147 assert(offset <= N_words, |
|
148 err_msg("%s - " |
|
149 "offset: " UINT32_FORMAT", N_words: " UINT32_FORMAT, |
|
150 msg, offset, N_words)); |
|
151 } |
|
152 |
137 // Bounds checking accessors: |
153 // Bounds checking accessors: |
138 // For performance these have to devolve to array accesses in product builds. |
154 // For performance these have to devolve to array accesses in product builds. |
139 u_char offset_array(size_t index) const { |
155 u_char offset_array(size_t index) const { |
140 assert(index < _vs.committed_size(), "index out of range"); |
156 check_index(index, "index out of range"); |
141 return _offset_array[index]; |
157 return _offset_array[index]; |
142 } |
158 } |
143 |
159 |
144 void set_offset_array(size_t index, u_char offset) { |
160 void set_offset_array(size_t index, u_char offset) { |
145 assert(index < _vs.committed_size(), "index out of range"); |
161 check_index(index, "index out of range"); |
146 assert(offset <= N_words, "offset too large"); |
162 check_offset(offset, "offset too large"); |
147 _offset_array[index] = offset; |
163 _offset_array[index] = offset; |
148 } |
164 } |
149 |
165 |
150 void set_offset_array(size_t index, HeapWord* high, HeapWord* low) { |
166 void set_offset_array(size_t index, HeapWord* high, HeapWord* low) { |
151 assert(index < _vs.committed_size(), "index out of range"); |
167 check_index(index, "index out of range"); |
152 assert(high >= low, "addresses out of order"); |
168 assert(high >= low, "addresses out of order"); |
153 assert(pointer_delta(high, low) <= N_words, "offset too large"); |
169 check_offset(pointer_delta(high, low), "offset too large"); |
154 _offset_array[index] = (u_char) pointer_delta(high, low); |
170 _offset_array[index] = (u_char) pointer_delta(high, low); |
155 } |
171 } |
156 |
172 |
157 void set_offset_array(HeapWord* left, HeapWord* right, u_char offset) { |
173 void set_offset_array(HeapWord* left, HeapWord* right, u_char offset) { |
158 assert(index_for(right - 1) < _vs.committed_size(), |
174 check_index(index_for(right - 1), "right address out of range"); |
159 "right address out of range"); |
|
160 assert(left < right, "Heap addresses out of order"); |
175 assert(left < right, "Heap addresses out of order"); |
161 size_t num_cards = pointer_delta(right, left) >> LogN_words; |
176 size_t num_cards = pointer_delta(right, left) >> LogN_words; |
162 if (UseMemSetInBOT) { |
177 if (UseMemSetInBOT) { |
163 memset(&_offset_array[index_for(left)], offset, num_cards); |
178 memset(&_offset_array[index_for(left)], offset, num_cards); |
164 } else { |
179 } else { |
169 } |
184 } |
170 } |
185 } |
171 } |
186 } |
172 |
187 |
173 void set_offset_array(size_t left, size_t right, u_char offset) { |
188 void set_offset_array(size_t left, size_t right, u_char offset) { |
174 assert(right < _vs.committed_size(), "right address out of range"); |
189 check_index(right, "right index out of range"); |
175 assert(left <= right, "indexes out of order"); |
190 assert(left <= right, "indexes out of order"); |
176 size_t num_cards = right - left + 1; |
191 size_t num_cards = right - left + 1; |
177 if (UseMemSetInBOT) { |
192 if (UseMemSetInBOT) { |
178 memset(&_offset_array[left], offset, num_cards); |
193 memset(&_offset_array[left], offset, num_cards); |
179 } else { |
194 } else { |
184 } |
199 } |
185 } |
200 } |
186 } |
201 } |
187 |
202 |
188 void check_offset_array(size_t index, HeapWord* high, HeapWord* low) const { |
203 void check_offset_array(size_t index, HeapWord* high, HeapWord* low) const { |
189 assert(index < _vs.committed_size(), "index out of range"); |
204 check_index(index, "index out of range"); |
190 assert(high >= low, "addresses out of order"); |
205 assert(high >= low, "addresses out of order"); |
191 assert(pointer_delta(high, low) <= N_words, "offset too large"); |
206 check_offset(pointer_delta(high, low), "offset too large"); |
192 assert(_offset_array[index] == pointer_delta(high, low), |
207 assert(_offset_array[index] == pointer_delta(high, low), "Wrong offset"); |
193 "Wrong offset"); |
|
194 } |
208 } |
195 |
209 |
196 bool is_card_boundary(HeapWord* p) const; |
210 bool is_card_boundary(HeapWord* p) const; |
197 |
211 |
198 // Return the number of slots needed for an offset array |
212 // Return the number of slots needed for an offset array |