40 _state = empty_state; |
40 _state = empty_state; |
41 _saw_free_extra_data = false; |
41 _saw_free_extra_data = false; |
42 // Set an initial hint. Don't use set_hint_di() because |
42 // Set an initial hint. Don't use set_hint_di() because |
43 // first_di() may be out of bounds if data_size is 0. |
43 // first_di() may be out of bounds if data_size is 0. |
44 _hint_di = first_di(); |
44 _hint_di = first_di(); |
|
45 // Initialize the escape information (to "don't know."); |
|
46 _eflags = _arg_local = _arg_stack = _arg_returned = 0; |
45 } |
47 } |
46 |
48 |
47 // ------------------------------------------------------------------ |
49 // ------------------------------------------------------------------ |
48 // ciMethodData::ciMethodData |
50 // ciMethodData::ciMethodData |
49 // |
51 // |
57 _state = empty_state; |
59 _state = empty_state; |
58 _saw_free_extra_data = false; |
60 _saw_free_extra_data = false; |
59 // Set an initial hint. Don't use set_hint_di() because |
61 // Set an initial hint. Don't use set_hint_di() because |
60 // first_di() may be out of bounds if data_size is 0. |
62 // first_di() may be out of bounds if data_size is 0. |
61 _hint_di = first_di(); |
63 _hint_di = first_di(); |
|
64 // Initialize the escape information (to "don't know."); |
|
65 _eflags = _arg_local = _arg_stack = _arg_returned = 0; |
62 } |
66 } |
63 |
67 |
64 void ciMethodData::load_data() { |
68 void ciMethodData::load_data() { |
65 methodDataOop mdo = get_methodDataOop(); |
69 methodDataOop mdo = get_methodDataOop(); |
66 if (mdo == NULL) return; |
70 if (mdo == NULL) return; |
140 return new ciRetData(data_layout); |
144 return new ciRetData(data_layout); |
141 case DataLayout::branch_data_tag: |
145 case DataLayout::branch_data_tag: |
142 return new ciBranchData(data_layout); |
146 return new ciBranchData(data_layout); |
143 case DataLayout::multi_branch_data_tag: |
147 case DataLayout::multi_branch_data_tag: |
144 return new ciMultiBranchData(data_layout); |
148 return new ciMultiBranchData(data_layout); |
|
149 case DataLayout::arg_info_data_tag: |
|
150 return new ciArgInfoData(data_layout); |
145 }; |
151 }; |
146 } |
152 } |
147 |
153 |
148 // Iteration over data. |
154 // Iteration over data. |
149 ciProfileData* ciMethodData::next_data(ciProfileData* current) { |
155 ciProfileData* ciMethodData::next_data(ciProfileData* current) { |
169 DataLayout* end = data_layout_at(data_size() + extra_data_size()); |
175 DataLayout* end = data_layout_at(data_size() + extra_data_size()); |
170 for (; dp < end; dp = methodDataOopDesc::next_extra(dp)) { |
176 for (; dp < end; dp = methodDataOopDesc::next_extra(dp)) { |
171 if (dp->tag() == DataLayout::no_tag) { |
177 if (dp->tag() == DataLayout::no_tag) { |
172 _saw_free_extra_data = true; // observed an empty slot (common case) |
178 _saw_free_extra_data = true; // observed an empty slot (common case) |
173 return NULL; |
179 return NULL; |
|
180 } |
|
181 if (dp->tag() == DataLayout::arg_info_data_tag) { |
|
182 break; // ArgInfoData is at the end of extra data section. |
174 } |
183 } |
175 if (dp->bci() == bci) { |
184 if (dp->bci() == bci) { |
176 assert(dp->tag() == DataLayout::bit_data_tag, "sane"); |
185 assert(dp->tag() == DataLayout::bit_data_tag, "sane"); |
177 return new ciBitData(dp); |
186 return new ciBitData(dp); |
178 } |
187 } |
215 } |
224 } |
216 |
225 |
217 void ciMethodData::clear_escape_info() { |
226 void ciMethodData::clear_escape_info() { |
218 VM_ENTRY_MARK; |
227 VM_ENTRY_MARK; |
219 methodDataOop mdo = get_methodDataOop(); |
228 methodDataOop mdo = get_methodDataOop(); |
220 if (mdo != NULL) |
229 if (mdo != NULL) { |
221 mdo->clear_escape_info(); |
230 mdo->clear_escape_info(); |
|
231 ArgInfoData *aid = arg_info(); |
|
232 int arg_count = (aid == NULL) ? 0 : aid->number_of_args(); |
|
233 for (int i = 0; i < arg_count; i++) { |
|
234 set_arg_modified(i, 0); |
|
235 } |
|
236 } |
222 _eflags = _arg_local = _arg_stack = _arg_returned = 0; |
237 _eflags = _arg_local = _arg_stack = _arg_returned = 0; |
223 } |
238 } |
224 |
239 |
225 // copy our escape info to the methodDataOop if it exists |
240 // copy our escape info to the methodDataOop if it exists |
226 void ciMethodData::update_escape_info() { |
241 void ciMethodData::update_escape_info() { |
229 if ( mdo != NULL) { |
244 if ( mdo != NULL) { |
230 mdo->set_eflags(_eflags); |
245 mdo->set_eflags(_eflags); |
231 mdo->set_arg_local(_arg_local); |
246 mdo->set_arg_local(_arg_local); |
232 mdo->set_arg_stack(_arg_stack); |
247 mdo->set_arg_stack(_arg_stack); |
233 mdo->set_arg_returned(_arg_returned); |
248 mdo->set_arg_returned(_arg_returned); |
|
249 int arg_count = mdo->method()->size_of_parameters(); |
|
250 for (int i = 0; i < arg_count; i++) { |
|
251 mdo->set_arg_modified(i, arg_modified(i)); |
|
252 } |
234 } |
253 } |
235 } |
254 } |
236 |
255 |
237 bool ciMethodData::has_escape_info() { |
256 bool ciMethodData::has_escape_info() { |
238 return eflag_set(methodDataOopDesc::estimated); |
257 return eflag_set(methodDataOopDesc::estimated); |
260 |
279 |
261 void ciMethodData::set_arg_returned(int i) { |
280 void ciMethodData::set_arg_returned(int i) { |
262 set_nth_bit(_arg_returned, i); |
281 set_nth_bit(_arg_returned, i); |
263 } |
282 } |
264 |
283 |
|
284 void ciMethodData::set_arg_modified(int arg, uint val) { |
|
285 ArgInfoData *aid = arg_info(); |
|
286 if (aid == NULL) |
|
287 return; |
|
288 assert(arg >= 0 && arg < aid->number_of_args(), "valid argument number"); |
|
289 aid->set_arg_modified(arg, val); |
|
290 } |
|
291 |
265 bool ciMethodData::is_arg_local(int i) const { |
292 bool ciMethodData::is_arg_local(int i) const { |
266 return is_set_nth_bit(_arg_local, i); |
293 return is_set_nth_bit(_arg_local, i); |
267 } |
294 } |
268 |
295 |
269 bool ciMethodData::is_arg_stack(int i) const { |
296 bool ciMethodData::is_arg_stack(int i) const { |
270 return is_set_nth_bit(_arg_stack, i); |
297 return is_set_nth_bit(_arg_stack, i); |
271 } |
298 } |
272 |
299 |
273 bool ciMethodData::is_arg_returned(int i) const { |
300 bool ciMethodData::is_arg_returned(int i) const { |
274 return is_set_nth_bit(_arg_returned, i); |
301 return is_set_nth_bit(_arg_returned, i); |
|
302 } |
|
303 |
|
304 uint ciMethodData::arg_modified(int arg) const { |
|
305 ArgInfoData *aid = arg_info(); |
|
306 if (aid == NULL) |
|
307 return 0; |
|
308 assert(arg >= 0 && arg < aid->number_of_args(), "valid argument number"); |
|
309 return aid->arg_modified(arg); |
275 } |
310 } |
276 |
311 |
277 ByteSize ciMethodData::offset_of_slot(ciProfileData* data, ByteSize slot_offset_in_data) { |
312 ByteSize ciMethodData::offset_of_slot(ciProfileData* data, ByteSize slot_offset_in_data) { |
278 // Get offset within methodDataOop of the data array |
313 // Get offset within methodDataOop of the data array |
279 ByteSize data_offset = methodDataOopDesc::data_offset(); |
314 ByteSize data_offset = methodDataOopDesc::data_offset(); |
284 // Add in counter_offset, the # of bytes into the ProfileData of counter or flag |
319 // Add in counter_offset, the # of bytes into the ProfileData of counter or flag |
285 int offset = in_bytes(data_offset) + cell_offset + in_bytes(slot_offset_in_data); |
320 int offset = in_bytes(data_offset) + cell_offset + in_bytes(slot_offset_in_data); |
286 |
321 |
287 return in_ByteSize(offset); |
322 return in_ByteSize(offset); |
288 } |
323 } |
|
324 |
|
325 ciArgInfoData *ciMethodData::arg_info() const { |
|
326 // Should be last, have to skip all traps. |
|
327 DataLayout* dp = data_layout_at(data_size()); |
|
328 DataLayout* end = data_layout_at(data_size() + extra_data_size()); |
|
329 for (; dp < end; dp = methodDataOopDesc::next_extra(dp)) { |
|
330 if (dp->tag() == DataLayout::arg_info_data_tag) |
|
331 return new ciArgInfoData(dp); |
|
332 } |
|
333 return NULL; |
|
334 } |
|
335 |
289 |
336 |
290 // Implementation of the print method. |
337 // Implementation of the print method. |
291 void ciMethodData::print_impl(outputStream* st) { |
338 void ciMethodData::print_impl(outputStream* st) { |
292 ciObject::print_impl(st); |
339 ciObject::print_impl(st); |
293 } |
340 } |
303 for (data = first_data(); is_valid(data); data = next_data(data)) { |
350 for (data = first_data(); is_valid(data); data = next_data(data)) { |
304 st->print("%d", dp_to_di(data->dp())); |
351 st->print("%d", dp_to_di(data->dp())); |
305 st->fill_to(6); |
352 st->fill_to(6); |
306 data->print_data_on(st); |
353 data->print_data_on(st); |
307 } |
354 } |
|
355 st->print_cr("--- Extra data:"); |
|
356 DataLayout* dp = data_layout_at(data_size()); |
|
357 DataLayout* end = data_layout_at(data_size() + extra_data_size()); |
|
358 for (; dp < end; dp = methodDataOopDesc::next_extra(dp)) { |
|
359 if (dp->tag() == DataLayout::no_tag) continue; |
|
360 if (dp->tag() == DataLayout::bit_data_tag) { |
|
361 data = new BitData(dp); |
|
362 } else { |
|
363 assert(dp->tag() == DataLayout::arg_info_data_tag, "must be BitData or ArgInfo"); |
|
364 data = new ciArgInfoData(dp); |
|
365 dp = end; // ArgInfoData is at the end of extra data section. |
|
366 } |
|
367 st->print("%d", dp_to_di(data->dp())); |
|
368 st->fill_to(6); |
|
369 data->print_data_on(st); |
|
370 } |
308 } |
371 } |
309 |
372 |
310 void ciReceiverTypeData::print_receiver_data_on(outputStream* st) { |
373 void ciReceiverTypeData::print_receiver_data_on(outputStream* st) { |
311 uint row; |
374 uint row; |
312 int entries = 0; |
375 int entries = 0; |