Mercurial > hg > graal-jvmci-8
comparison src/share/vm/ci/ciMethodData.cpp @ 45:48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
Summary: Use MDO to cache arguments escape state determined by the byte code escape analyzer.
Reviewed-by: never
author | kvn |
---|---|
date | Tue, 11 Mar 2008 19:00:38 -0700 |
parents | a61af66fc99e |
children | d1605aabd0a1 |
comparison
equal
deleted
inserted
replaced
44:52fed2ec0afb | 45:48a3fa21394b |
---|---|
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; |