75 }
76 if (plen == 1 && fits_into_immediate(p[0])) {
77 (*this) = immediate_relocInfo(p[0]); // move data inside self
78 return this+1;
79 }
80 // cannot compact, so just update the count and return the limit pointer
81 (*this) = prefix_relocInfo(plen); // write new datalen
82 assert(data() + datalen() == prefix_limit, "pointers must line up");
83 return (relocInfo*)prefix_limit;
84 }
85
86 void relocInfo::set_type(relocType t) {
87 int old_offset = addr_offset();
88 int old_format = format();
89 (*this) = relocInfo(t, old_offset, old_format);
90 assert(type()==(int)t, "sanity check");
91 assert(addr_offset()==old_offset, "sanity check");
92 assert(format()==old_format, "sanity check");
93 }
94
95 nmethod* RelocIterator::code_as_nmethod() const {
96 return _code->as_nmethod();
97 }
98
99 void relocInfo::set_format(int f) {
100 int old_offset = addr_offset();
101 assert((f & format_mask) == f, "wrong format");
102 _value = (_value & ~(format_mask << offset_width)) | (f << offset_width);
103 assert(addr_offset()==old_offset, "sanity check");
104 }
105
106
107 void relocInfo::change_reloc_info_for_address(RelocIterator *itr, address pc, relocType old_type, relocType new_type) {
108 bool found = false;
109 while (itr->next() && !found) {
110 if (itr->addr() == pc) {
111 assert(itr->type()==old_type, "wrong relocInfo type found");
112 itr->current()->set_type(new_type);
113 found=true;
114 }
115 }
116 assert(found, "no relocInfo found for pc");
117 }
118
119
120 void relocInfo::remove_reloc_info_for_address(RelocIterator *itr, address pc, relocType old_type) {
121 change_reloc_info_for_address(itr, pc, old_type, none);
122 }
123
124
125 // ----------------------------------------------------------------------------------------------------
126 // Implementation of RelocIterator
127
128 void RelocIterator::initialize(CompiledMethod* nm, address begin, address limit) {
129 initialize_misc();
130
131 if (nm == NULL && begin != NULL) {
132 // allow nmethod to be deduced from beginning address
133 CodeBlob* cb = CodeCache::find_blob(begin);
134 nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
135 }
136 guarantee(nm != NULL, "must be able to deduce nmethod from other arguments");
137
138 _code = nm;
139 _current = nm->relocation_begin() - 1;
140 _end = nm->relocation_end();
141 _addr = nm->content_begin();
142
143 // Initialize code sections.
144 _section_start[CodeBuffer::SECT_CONSTS] = nm->consts_begin();
162 _current = cs->locs_start()-1;
163 _end = cs->locs_end();
164 _addr = cs->start();
165 _code = NULL; // Not cb->blob();
166
167 CodeBuffer* cb = cs->outer();
168 assert((int) SECT_LIMIT == CodeBuffer::SECT_LIMIT, "my copy must be equal");
169 for (int n = (int) CodeBuffer::SECT_FIRST; n < (int) CodeBuffer::SECT_LIMIT; n++) {
170 CodeSection* cs = cb->code_section(n);
171 _section_start[n] = cs->start();
172 _section_end [n] = cs->end();
173 }
174
175 assert(!has_current(), "just checking");
176
177 assert(begin == NULL || begin >= cs->start(), "in bounds");
178 assert(limit == NULL || limit <= cs->end(), "in bounds");
179 set_limits(begin, limit);
180 }
181
182
183 enum { indexCardSize = 128 };
184 struct RelocIndexEntry {
185 jint addr_offset; // offset from header_end of an addr()
186 jint reloc_offset; // offset from header_end of a relocInfo (prefix)
187 };
188
189
190 bool RelocIterator::addr_in_const() const {
191 const int n = CodeBuffer::SECT_CONSTS;
192 return section_start(n) <= addr() && addr() < section_end(n);
193 }
194
195
196 void RelocIterator::set_limits(address begin, address limit) {
197 _limit = limit;
198
199 // the limit affects this next stuff:
200 if (begin != NULL) {
201 relocInfo* backup;
202 address backup_addr;
203 while (true) {
204 backup = _current;
205 backup_addr = _addr;
206 if (!next() || addr() >= begin) break;
207 }
208 // At this point, either we are at the first matching record,
209 // or else there is no such record, and !has_current().
210 // In either case, revert to the immediatly preceding state.
211 _current = backup;
212 _addr = backup_addr;
213 set_has_current(false);
214 }
215 }
216
217
218 void RelocIterator::set_limit(address limit) {
219 address code_end = (address)code() + code()->size();
220 assert(limit == NULL || limit <= code_end, "in bounds");
221 _limit = limit;
222 }
223
224 // All the strange bit-encodings are in here.
225 // The idea is to encode relocation data which are small integers
226 // very efficiently (a single extra halfword). Larger chunks of
227 // relocation data need a halfword header to hold their size.
228 void RelocIterator::advance_over_prefix() {
229 if (_current->is_datalen()) {
230 _data = (short*) _current->data();
231 _datalen = _current->datalen();
232 _current += _datalen + 1; // skip the embedded data & header
233 } else {
234 _databuf = _current->immediate();
235 _data = &_databuf;
236 _datalen = 1;
237 _current++; // skip the header
238 }
239 // The client will see the following relocInfo, whatever that is.
240 // It is the reloc to which the preceding data applies.
241 }
242
243
602 return (Metadata**) pd_address_in_code();
603 } else {
604 // metadata is stored in table at nmethod::metadatas_begin
605 return code()->metadata_addr_at(n);
606 }
607 }
608
609
610 Metadata* metadata_Relocation::metadata_value() {
611 Metadata* v = *metadata_addr();
612 // clean inline caches store a special pseudo-null
613 if (v == (Metadata*)Universe::non_oop_word()) v = NULL;
614 return v;
615 }
616
617
618 void metadata_Relocation::fix_metadata_relocation() {
619 if (!metadata_is_immediate()) {
620 // get the metadata from the pool, and re-insert it into the instruction:
621 pd_fix_value(value());
622 }
623 }
624
625
626 void metadata_Relocation::verify_metadata_relocation() {
627 if (!metadata_is_immediate()) {
628 // get the metadata from the pool, and re-insert it into the instruction:
629 verify_value(value());
630 }
631 }
632
633 address virtual_call_Relocation::cached_value() {
634 assert(_cached_value != NULL && _cached_value < addr(), "must precede ic_call");
635 return _cached_value;
636 }
637
638 Method* virtual_call_Relocation::method_value() {
639 CompiledMethod* cm = code();
640 if (cm == NULL) return (Method*)NULL;
641 Metadata* m = cm->metadata_at(_method_index);
642 assert(m != NULL || _method_index == 0, "should be non-null for non-zero index");
643 assert(m == NULL || m->is_method(), "not a method");
644 return (Method*)m;
645 }
646
647 bool virtual_call_Relocation::clear_inline_cache() {
648 // No stubs for ICs
649 // Clean IC
|
75 }
76 if (plen == 1 && fits_into_immediate(p[0])) {
77 (*this) = immediate_relocInfo(p[0]); // move data inside self
78 return this+1;
79 }
80 // cannot compact, so just update the count and return the limit pointer
81 (*this) = prefix_relocInfo(plen); // write new datalen
82 assert(data() + datalen() == prefix_limit, "pointers must line up");
83 return (relocInfo*)prefix_limit;
84 }
85
86 void relocInfo::set_type(relocType t) {
87 int old_offset = addr_offset();
88 int old_format = format();
89 (*this) = relocInfo(t, old_offset, old_format);
90 assert(type()==(int)t, "sanity check");
91 assert(addr_offset()==old_offset, "sanity check");
92 assert(format()==old_format, "sanity check");
93 }
94
95 void relocInfo::change_reloc_info_for_address(RelocIterator *itr, address pc, relocType old_type, relocType new_type) {
96 bool found = false;
97 while (itr->next() && !found) {
98 if (itr->addr() == pc) {
99 assert(itr->type()==old_type, "wrong relocInfo type found");
100 itr->current()->set_type(new_type);
101 found=true;
102 }
103 }
104 assert(found, "no relocInfo found for pc");
105 }
106
107
108 // ----------------------------------------------------------------------------------------------------
109 // Implementation of RelocIterator
110
111 void RelocIterator::initialize(CompiledMethod* nm, address begin, address limit) {
112 initialize_misc();
113
114 if (nm == NULL && begin != NULL) {
115 // allow nmethod to be deduced from beginning address
116 CodeBlob* cb = CodeCache::find_blob(begin);
117 nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
118 }
119 guarantee(nm != NULL, "must be able to deduce nmethod from other arguments");
120
121 _code = nm;
122 _current = nm->relocation_begin() - 1;
123 _end = nm->relocation_end();
124 _addr = nm->content_begin();
125
126 // Initialize code sections.
127 _section_start[CodeBuffer::SECT_CONSTS] = nm->consts_begin();
145 _current = cs->locs_start()-1;
146 _end = cs->locs_end();
147 _addr = cs->start();
148 _code = NULL; // Not cb->blob();
149
150 CodeBuffer* cb = cs->outer();
151 assert((int) SECT_LIMIT == CodeBuffer::SECT_LIMIT, "my copy must be equal");
152 for (int n = (int) CodeBuffer::SECT_FIRST; n < (int) CodeBuffer::SECT_LIMIT; n++) {
153 CodeSection* cs = cb->code_section(n);
154 _section_start[n] = cs->start();
155 _section_end [n] = cs->end();
156 }
157
158 assert(!has_current(), "just checking");
159
160 assert(begin == NULL || begin >= cs->start(), "in bounds");
161 assert(limit == NULL || limit <= cs->end(), "in bounds");
162 set_limits(begin, limit);
163 }
164
165 bool RelocIterator::addr_in_const() const {
166 const int n = CodeBuffer::SECT_CONSTS;
167 return section_start(n) <= addr() && addr() < section_end(n);
168 }
169
170
171 void RelocIterator::set_limits(address begin, address limit) {
172 _limit = limit;
173
174 // the limit affects this next stuff:
175 if (begin != NULL) {
176 relocInfo* backup;
177 address backup_addr;
178 while (true) {
179 backup = _current;
180 backup_addr = _addr;
181 if (!next() || addr() >= begin) break;
182 }
183 // At this point, either we are at the first matching record,
184 // or else there is no such record, and !has_current().
185 // In either case, revert to the immediatly preceding state.
186 _current = backup;
187 _addr = backup_addr;
188 set_has_current(false);
189 }
190 }
191
192
193 // All the strange bit-encodings are in here.
194 // The idea is to encode relocation data which are small integers
195 // very efficiently (a single extra halfword). Larger chunks of
196 // relocation data need a halfword header to hold their size.
197 void RelocIterator::advance_over_prefix() {
198 if (_current->is_datalen()) {
199 _data = (short*) _current->data();
200 _datalen = _current->datalen();
201 _current += _datalen + 1; // skip the embedded data & header
202 } else {
203 _databuf = _current->immediate();
204 _data = &_databuf;
205 _datalen = 1;
206 _current++; // skip the header
207 }
208 // The client will see the following relocInfo, whatever that is.
209 // It is the reloc to which the preceding data applies.
210 }
211
212
571 return (Metadata**) pd_address_in_code();
572 } else {
573 // metadata is stored in table at nmethod::metadatas_begin
574 return code()->metadata_addr_at(n);
575 }
576 }
577
578
579 Metadata* metadata_Relocation::metadata_value() {
580 Metadata* v = *metadata_addr();
581 // clean inline caches store a special pseudo-null
582 if (v == (Metadata*)Universe::non_oop_word()) v = NULL;
583 return v;
584 }
585
586
587 void metadata_Relocation::fix_metadata_relocation() {
588 if (!metadata_is_immediate()) {
589 // get the metadata from the pool, and re-insert it into the instruction:
590 pd_fix_value(value());
591 }
592 }
593
594 address virtual_call_Relocation::cached_value() {
595 assert(_cached_value != NULL && _cached_value < addr(), "must precede ic_call");
596 return _cached_value;
597 }
598
599 Method* virtual_call_Relocation::method_value() {
600 CompiledMethod* cm = code();
601 if (cm == NULL) return (Method*)NULL;
602 Metadata* m = cm->metadata_at(_method_index);
603 assert(m != NULL || _method_index == 0, "should be non-null for non-zero index");
604 assert(m == NULL || m->is_method(), "not a method");
605 return (Method*)m;
606 }
607
608 bool virtual_call_Relocation::clear_inline_cache() {
609 // No stubs for ICs
610 // Clean IC
|