189 const int n = CodeBuffer::SECT_CONSTS; |
189 const int n = CodeBuffer::SECT_CONSTS; |
190 return section_start(n) <= addr() && addr() < section_end(n); |
190 return section_start(n) <= addr() && addr() < section_end(n); |
191 } |
191 } |
192 |
192 |
193 |
193 |
194 static inline int num_cards(int code_size) { |
|
195 return (code_size-1) / indexCardSize; |
|
196 } |
|
197 |
|
198 |
|
199 int RelocIterator::locs_and_index_size(int code_size, int locs_size) { |
|
200 if (!UseRelocIndex) return locs_size; // no index |
|
201 code_size = round_to(code_size, oopSize); |
|
202 locs_size = round_to(locs_size, oopSize); |
|
203 int index_size = num_cards(code_size) * sizeof(RelocIndexEntry); |
|
204 // format of indexed relocs: |
|
205 // relocation_begin: relocInfo ... |
|
206 // index: (addr,reloc#) ... |
|
207 // indexSize :relocation_end |
|
208 return locs_size + index_size + BytesPerInt; |
|
209 } |
|
210 |
|
211 |
|
212 void RelocIterator::create_index(relocInfo* dest_begin, int dest_count, relocInfo* dest_end) { |
|
213 address relocation_begin = (address)dest_begin; |
|
214 address relocation_end = (address)dest_end; |
|
215 int total_size = relocation_end - relocation_begin; |
|
216 int locs_size = dest_count * sizeof(relocInfo); |
|
217 if (!UseRelocIndex) { |
|
218 Copy::fill_to_bytes(relocation_begin + locs_size, total_size-locs_size, 0); |
|
219 return; |
|
220 } |
|
221 int index_size = total_size - locs_size - BytesPerInt; // find out how much space is left |
|
222 int ncards = index_size / sizeof(RelocIndexEntry); |
|
223 assert(total_size == locs_size + index_size + BytesPerInt, "checkin'"); |
|
224 assert(index_size >= 0 && index_size % sizeof(RelocIndexEntry) == 0, "checkin'"); |
|
225 jint* index_size_addr = (jint*)relocation_end - 1; |
|
226 |
|
227 assert(sizeof(jint) == BytesPerInt, "change this code"); |
|
228 |
|
229 *index_size_addr = index_size; |
|
230 if (index_size != 0) { |
|
231 assert(index_size > 0, "checkin'"); |
|
232 |
|
233 RelocIndexEntry* index = (RelocIndexEntry *)(relocation_begin + locs_size); |
|
234 assert(index == (RelocIndexEntry*)index_size_addr - ncards, "checkin'"); |
|
235 |
|
236 // walk over the relocations, and fill in index entries as we go |
|
237 RelocIterator iter; |
|
238 const address initial_addr = NULL; |
|
239 relocInfo* const initial_current = dest_begin - 1; // biased by -1 like elsewhere |
|
240 |
|
241 iter._code = NULL; |
|
242 iter._addr = initial_addr; |
|
243 iter._limit = (address)(intptr_t)(ncards * indexCardSize); |
|
244 iter._current = initial_current; |
|
245 iter._end = dest_begin + dest_count; |
|
246 |
|
247 int i = 0; |
|
248 address next_card_addr = (address)indexCardSize; |
|
249 int addr_offset = 0; |
|
250 int reloc_offset = 0; |
|
251 while (true) { |
|
252 // Checkpoint the iterator before advancing it. |
|
253 addr_offset = iter._addr - initial_addr; |
|
254 reloc_offset = iter._current - initial_current; |
|
255 if (!iter.next()) break; |
|
256 while (iter.addr() >= next_card_addr) { |
|
257 index[i].addr_offset = addr_offset; |
|
258 index[i].reloc_offset = reloc_offset; |
|
259 i++; |
|
260 next_card_addr += indexCardSize; |
|
261 } |
|
262 } |
|
263 while (i < ncards) { |
|
264 index[i].addr_offset = addr_offset; |
|
265 index[i].reloc_offset = reloc_offset; |
|
266 i++; |
|
267 } |
|
268 } |
|
269 } |
|
270 |
|
271 |
|
272 void RelocIterator::set_limits(address begin, address limit) { |
194 void RelocIterator::set_limits(address begin, address limit) { |
273 int index_size = 0; |
|
274 if (UseRelocIndex && _code != NULL) { |
|
275 index_size = ((jint*)_end)[-1]; |
|
276 _end = (relocInfo*)( (address)_end - index_size - BytesPerInt ); |
|
277 } |
|
278 |
|
279 _limit = limit; |
195 _limit = limit; |
280 |
196 |
281 // the limit affects this next stuff: |
197 // the limit affects this next stuff: |
282 if (begin != NULL) { |
198 if (begin != NULL) { |
283 #ifdef ASSERT |
|
284 // In ASSERT mode we do not actually use the index, but simply |
|
285 // check that its contents would have led us to the right answer. |
|
286 address addrCheck = _addr; |
|
287 relocInfo* infoCheck = _current; |
|
288 #endif // ASSERT |
|
289 if (index_size > 0) { |
|
290 // skip ahead |
|
291 RelocIndexEntry* index = (RelocIndexEntry*)_end; |
|
292 RelocIndexEntry* index_limit = (RelocIndexEntry*)((address)index + index_size); |
|
293 assert(_addr == _code->code_begin(), "_addr must be unadjusted"); |
|
294 int card = (begin - _addr) / indexCardSize; |
|
295 if (card > 0) { |
|
296 if (index+card-1 < index_limit) index += card-1; |
|
297 else index = index_limit - 1; |
|
298 #ifdef ASSERT |
|
299 addrCheck = _addr + index->addr_offset; |
|
300 infoCheck = _current + index->reloc_offset; |
|
301 #else |
|
302 // Advance the iterator immediately to the last valid state |
|
303 // for the previous card. Calling "next" will then advance |
|
304 // it to the first item on the required card. |
|
305 _addr += index->addr_offset; |
|
306 _current += index->reloc_offset; |
|
307 #endif // ASSERT |
|
308 } |
|
309 } |
|
310 |
|
311 relocInfo* backup; |
199 relocInfo* backup; |
312 address backup_addr; |
200 address backup_addr; |
313 while (true) { |
201 while (true) { |
314 backup = _current; |
202 backup = _current; |
315 backup_addr = _addr; |
203 backup_addr = _addr; |
316 #ifdef ASSERT |
|
317 if (backup == infoCheck) { |
|
318 assert(backup_addr == addrCheck, "must match"); addrCheck = NULL; infoCheck = NULL; |
|
319 } else { |
|
320 assert(addrCheck == NULL || backup_addr <= addrCheck, "must not pass addrCheck"); |
|
321 } |
|
322 #endif // ASSERT |
|
323 if (!next() || addr() >= begin) break; |
204 if (!next() || addr() >= begin) break; |
324 } |
205 } |
325 assert(addrCheck == NULL || addrCheck == backup_addr, "must have matched addrCheck"); |
|
326 assert(infoCheck == NULL || infoCheck == backup, "must have matched infoCheck"); |
|
327 // At this point, either we are at the first matching record, |
206 // At this point, either we are at the first matching record, |
328 // or else there is no such record, and !has_current(). |
207 // or else there is no such record, and !has_current(). |
329 // In either case, revert to the immediatly preceding state. |
208 // In either case, revert to the immediatly preceding state. |
330 _current = backup; |
209 _current = backup; |
331 _addr = backup_addr; |
210 _addr = backup_addr; |