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;