126 assert(nm != NULL, "must be able to deduce nmethod from other arguments"); |
126 assert(nm != NULL, "must be able to deduce nmethod from other arguments"); |
127 |
127 |
128 _code = nm; |
128 _code = nm; |
129 _current = nm->relocation_begin() - 1; |
129 _current = nm->relocation_begin() - 1; |
130 _end = nm->relocation_end(); |
130 _end = nm->relocation_end(); |
131 _addr = (address) nm->code_begin(); |
131 _addr = nm->content_begin(); |
|
132 |
|
133 // Initialize code sections. |
|
134 _section_start[CodeBuffer::SECT_CONSTS] = nm->consts_begin(); |
|
135 _section_start[CodeBuffer::SECT_INSTS ] = nm->insts_begin() ; |
|
136 _section_start[CodeBuffer::SECT_STUBS ] = nm->stub_begin() ; |
|
137 |
|
138 _section_end [CodeBuffer::SECT_CONSTS] = nm->consts_end() ; |
|
139 _section_end [CodeBuffer::SECT_INSTS ] = nm->insts_end() ; |
|
140 _section_end [CodeBuffer::SECT_STUBS ] = nm->stub_end() ; |
132 |
141 |
133 assert(!has_current(), "just checking"); |
142 assert(!has_current(), "just checking"); |
134 assert(begin == NULL || begin >= nm->code_begin(), "in bounds"); |
143 assert(begin == NULL || begin >= nm->code_begin(), "in bounds"); |
135 assert(limit == NULL || limit <= nm->code_end(), "in bounds"); |
144 assert(limit == NULL || limit <= nm->code_end(), "in bounds"); |
136 set_limits(begin, limit); |
145 set_limits(begin, limit); |
144 _end = cs->locs_end(); |
153 _end = cs->locs_end(); |
145 _addr = cs->start(); |
154 _addr = cs->start(); |
146 _code = NULL; // Not cb->blob(); |
155 _code = NULL; // Not cb->blob(); |
147 |
156 |
148 CodeBuffer* cb = cs->outer(); |
157 CodeBuffer* cb = cs->outer(); |
149 assert((int)SECT_LIMIT == CodeBuffer::SECT_LIMIT, "my copy must be equal"); |
158 assert((int) SECT_LIMIT == CodeBuffer::SECT_LIMIT, "my copy must be equal"); |
150 for (int n = 0; n < (int)SECT_LIMIT; n++) { |
159 for (int n = (int) CodeBuffer::SECT_FIRST; n < (int) CodeBuffer::SECT_LIMIT; n++) { |
151 _section_start[n] = cb->code_section(n)->start(); |
160 CodeSection* cs = cb->code_section(n); |
|
161 _section_start[n] = cs->start(); |
|
162 _section_end [n] = cs->end(); |
152 } |
163 } |
153 |
164 |
154 assert(!has_current(), "just checking"); |
165 assert(!has_current(), "just checking"); |
155 |
166 |
156 assert(begin == NULL || begin >= cs->start(), "in bounds"); |
167 assert(begin == NULL || begin >= cs->start(), "in bounds"); |
162 enum { indexCardSize = 128 }; |
173 enum { indexCardSize = 128 }; |
163 struct RelocIndexEntry { |
174 struct RelocIndexEntry { |
164 jint addr_offset; // offset from header_end of an addr() |
175 jint addr_offset; // offset from header_end of an addr() |
165 jint reloc_offset; // offset from header_end of a relocInfo (prefix) |
176 jint reloc_offset; // offset from header_end of a relocInfo (prefix) |
166 }; |
177 }; |
|
178 |
|
179 |
|
180 bool RelocIterator::addr_in_const() const { |
|
181 const int n = CodeBuffer::SECT_CONSTS; |
|
182 return section_start(n) <= addr() && addr() < section_end(n); |
|
183 } |
167 |
184 |
168 |
185 |
169 static inline int num_cards(int code_size) { |
186 static inline int num_cards(int code_size) { |
170 return (code_size-1) / indexCardSize; |
187 return (code_size-1) / indexCardSize; |
171 } |
188 } |
358 // The client will see the following relocInfo, whatever that is. |
375 // The client will see the following relocInfo, whatever that is. |
359 // It is the reloc to which the preceding data applies. |
376 // It is the reloc to which the preceding data applies. |
360 } |
377 } |
361 |
378 |
362 |
379 |
363 address RelocIterator::compute_section_start(int n) const { |
380 void RelocIterator::initialize_misc() { |
364 // This routine not only computes a section start, but also |
381 set_has_current(false); |
365 // memoizes it for later. |
382 for (int i = (int) CodeBuffer::SECT_FIRST; i < (int) CodeBuffer::SECT_LIMIT; i++) { |
366 #define CACHE ((RelocIterator*)this)->_section_start[n] |
383 _section_start[i] = NULL; // these will be lazily computed, if needed |
367 CodeBlob* cb = code(); |
384 _section_end [i] = NULL; |
368 guarantee(cb != NULL, "must have a code blob"); |
385 } |
369 if (n == CodeBuffer::SECT_INSTS) |
|
370 return CACHE = cb->code_begin(); |
|
371 assert(cb->is_nmethod(), "only nmethods have these sections"); |
|
372 nmethod* nm = (nmethod*) cb; |
|
373 address res = NULL; |
|
374 switch (n) { |
|
375 case CodeBuffer::SECT_STUBS: |
|
376 res = nm->stub_begin(); |
|
377 break; |
|
378 case CodeBuffer::SECT_CONSTS: |
|
379 res = nm->consts_begin(); |
|
380 break; |
|
381 default: |
|
382 ShouldNotReachHere(); |
|
383 } |
|
384 assert(nm->contains(res) || res == nm->code_end(), "tame pointer"); |
|
385 CACHE = res; |
|
386 return res; |
|
387 #undef CACHE |
|
388 } |
386 } |
389 |
387 |
390 |
388 |
391 Relocation* RelocIterator::reloc() { |
389 Relocation* RelocIterator::reloc() { |
392 // (take the "switch" out-of-line) |
390 // (take the "switch" out-of-line) |