Mercurial > hg > truffle
comparison src/share/vm/oops/methodData.hpp @ 14521:29ccc4cbabca
Merge
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Wed, 12 Mar 2014 13:30:08 +0100 |
parents | d8041d695d19 |
children | 12eaf1a47a90 |
comparison
equal
deleted
inserted
replaced
14520:f84115370178 | 14521:29ccc4cbabca |
---|---|
118 branch_data_tag, | 118 branch_data_tag, |
119 multi_branch_data_tag, | 119 multi_branch_data_tag, |
120 arg_info_data_tag, | 120 arg_info_data_tag, |
121 call_type_data_tag, | 121 call_type_data_tag, |
122 virtual_call_type_data_tag, | 122 virtual_call_type_data_tag, |
123 parameters_type_data_tag | 123 parameters_type_data_tag, |
124 speculative_trap_data_tag | |
124 }; | 125 }; |
125 | 126 |
126 enum { | 127 enum { |
127 // The _struct._flags word is formatted as [trap_state:4 | flags:4]. | 128 // The _struct._flags word is formatted as [trap_state:4 | flags:4]. |
128 // The trap state breaks down further as [recompile:1 | reason:3]. | 129 // The trap state breaks down further as [recompile:1 | reason:3]. |
187 } | 188 } |
188 | 189 |
189 void set_header(intptr_t value) { | 190 void set_header(intptr_t value) { |
190 _header._bits = value; | 191 _header._bits = value; |
191 } | 192 } |
192 void release_set_header(intptr_t value) { | 193 bool atomic_set_header(intptr_t value) { |
193 OrderAccess::release_store_ptr(&_header._bits, value); | 194 if (Atomic::cmpxchg_ptr(value, (volatile intptr_t*)&_header._bits, 0) == 0) { |
195 return true; | |
196 } | |
197 return false; | |
194 } | 198 } |
195 intptr_t header() { | 199 intptr_t header() { |
196 return _header._bits; | 200 return _header._bits; |
197 } | 201 } |
198 void set_cell_at(int index, intptr_t value) { | 202 void set_cell_at(int index, intptr_t value) { |
228 return byte_offset_of(DataLayout, _header._struct._bci); | 232 return byte_offset_of(DataLayout, _header._struct._bci); |
229 } | 233 } |
230 static ByteSize cell_offset(int index) { | 234 static ByteSize cell_offset(int index) { |
231 return byte_offset_of(DataLayout, _cells) + in_ByteSize(index * cell_size); | 235 return byte_offset_of(DataLayout, _cells) + in_ByteSize(index * cell_size); |
232 } | 236 } |
237 #ifdef CC_INTERP | |
238 static int cell_offset_in_bytes(int index) { | |
239 return (int)offset_of(DataLayout, _cells[index]); | |
240 } | |
241 #endif // CC_INTERP | |
233 // Return a value which, when or-ed as a byte into _flags, sets the flag. | 242 // Return a value which, when or-ed as a byte into _flags, sets the flag. |
234 static int flag_number_to_byte_constant(int flag_number) { | 243 static int flag_number_to_byte_constant(int flag_number) { |
235 assert(0 <= flag_number && flag_number < flag_limit, "oob"); | 244 assert(0 <= flag_number && flag_number < flag_limit, "oob"); |
236 DataLayout temp; temp.set_header(0); | 245 DataLayout temp; temp.set_header(0); |
237 temp.set_flag_at(flag_number); | 246 temp.set_flag_at(flag_number); |
264 class BranchData; | 273 class BranchData; |
265 class ArrayData; | 274 class ArrayData; |
266 class MultiBranchData; | 275 class MultiBranchData; |
267 class ArgInfoData; | 276 class ArgInfoData; |
268 class ParametersTypeData; | 277 class ParametersTypeData; |
278 class SpeculativeTrapData; | |
269 | 279 |
270 // ProfileData | 280 // ProfileData |
271 // | 281 // |
272 // A ProfileData object is created to refer to a section of profiling | 282 // A ProfileData object is created to refer to a section of profiling |
273 // data in a structured way. | 283 // data in a structured way. |
284 #endif // !PRODUCT | 294 #endif // !PRODUCT |
285 | 295 |
286 // This is a pointer to a section of profiling data. | 296 // This is a pointer to a section of profiling data. |
287 DataLayout* _data; | 297 DataLayout* _data; |
288 | 298 |
299 char* print_data_on_helper(const MethodData* md) const; | |
300 | |
289 protected: | 301 protected: |
290 DataLayout* data() { return _data; } | 302 DataLayout* data() { return _data; } |
291 const DataLayout* data() const { return _data; } | 303 const DataLayout* data() const { return _data; } |
292 | 304 |
293 enum { | 305 enum { |
364 } | 376 } |
365 | 377 |
366 ProfileData(DataLayout* data) { | 378 ProfileData(DataLayout* data) { |
367 _data = data; | 379 _data = data; |
368 } | 380 } |
381 | |
382 #ifdef CC_INTERP | |
383 // Static low level accessors for DataLayout with ProfileData's semantics. | |
384 | |
385 static int cell_offset_in_bytes(int index) { | |
386 return DataLayout::cell_offset_in_bytes(index); | |
387 } | |
388 | |
389 static void increment_uint_at_no_overflow(DataLayout* layout, int index, | |
390 int inc = DataLayout::counter_increment) { | |
391 uint count = ((uint)layout->cell_at(index)) + inc; | |
392 if (count == 0) return; | |
393 layout->set_cell_at(index, (intptr_t) count); | |
394 } | |
395 | |
396 static int int_at(DataLayout* layout, int index) { | |
397 return (int)layout->cell_at(index); | |
398 } | |
399 | |
400 static int uint_at(DataLayout* layout, int index) { | |
401 return (uint)layout->cell_at(index); | |
402 } | |
403 | |
404 static oop oop_at(DataLayout* layout, int index) { | |
405 return cast_to_oop(layout->cell_at(index)); | |
406 } | |
407 | |
408 static void set_intptr_at(DataLayout* layout, int index, intptr_t value) { | |
409 layout->set_cell_at(index, (intptr_t) value); | |
410 } | |
411 | |
412 static void set_flag_at(DataLayout* layout, int flag_number) { | |
413 layout->set_flag_at(flag_number); | |
414 } | |
415 #endif // CC_INTERP | |
369 | 416 |
370 public: | 417 public: |
371 // Constructor for invalid ProfileData. | 418 // Constructor for invalid ProfileData. |
372 ProfileData(); | 419 ProfileData(); |
373 | 420 |
398 virtual bool is_MultiBranchData() const { return false; } | 445 virtual bool is_MultiBranchData() const { return false; } |
399 virtual bool is_ArgInfoData() const { return false; } | 446 virtual bool is_ArgInfoData() const { return false; } |
400 virtual bool is_CallTypeData() const { return false; } | 447 virtual bool is_CallTypeData() const { return false; } |
401 virtual bool is_VirtualCallTypeData()const { return false; } | 448 virtual bool is_VirtualCallTypeData()const { return false; } |
402 virtual bool is_ParametersTypeData() const { return false; } | 449 virtual bool is_ParametersTypeData() const { return false; } |
450 virtual bool is_SpeculativeTrapData()const { return false; } | |
403 | 451 |
404 | 452 |
405 BitData* as_BitData() const { | 453 BitData* as_BitData() const { |
406 assert(is_BitData(), "wrong type"); | 454 assert(is_BitData(), "wrong type"); |
407 return is_BitData() ? (BitData*) this : NULL; | 455 return is_BitData() ? (BitData*) this : NULL; |
451 return is_VirtualCallTypeData() ? (VirtualCallTypeData*)this : NULL; | 499 return is_VirtualCallTypeData() ? (VirtualCallTypeData*)this : NULL; |
452 } | 500 } |
453 ParametersTypeData* as_ParametersTypeData() const { | 501 ParametersTypeData* as_ParametersTypeData() const { |
454 assert(is_ParametersTypeData(), "wrong type"); | 502 assert(is_ParametersTypeData(), "wrong type"); |
455 return is_ParametersTypeData() ? (ParametersTypeData*)this : NULL; | 503 return is_ParametersTypeData() ? (ParametersTypeData*)this : NULL; |
504 } | |
505 SpeculativeTrapData* as_SpeculativeTrapData() const { | |
506 assert(is_SpeculativeTrapData(), "wrong type"); | |
507 return is_SpeculativeTrapData() ? (SpeculativeTrapData*)this : NULL; | |
456 } | 508 } |
457 | 509 |
458 | 510 |
459 // Subclass specific initialization | 511 // Subclass specific initialization |
460 virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) {} | 512 virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) {} |
467 // an oop in a ProfileData to the ci equivalent. Generally speaking, | 519 // an oop in a ProfileData to the ci equivalent. Generally speaking, |
468 // most ProfileData don't require any translation, so we provide the null | 520 // most ProfileData don't require any translation, so we provide the null |
469 // translation here, and the required translators are in the ci subclasses. | 521 // translation here, and the required translators are in the ci subclasses. |
470 virtual void translate_from(const ProfileData* data) {} | 522 virtual void translate_from(const ProfileData* data) {} |
471 | 523 |
472 virtual void print_data_on(outputStream* st) const { | 524 virtual void print_data_on(outputStream* st, const char* extra = NULL) const { |
473 ShouldNotReachHere(); | 525 ShouldNotReachHere(); |
474 } | 526 } |
475 | 527 |
528 void print_data_on(outputStream* st, const MethodData* md) const; | |
529 | |
476 #ifndef PRODUCT | 530 #ifndef PRODUCT |
477 void print_shared(outputStream* st, const char* name) const; | 531 void print_shared(outputStream* st, const char* name, const char* extra) const; |
478 void tab(outputStream* st, bool first = false) const; | 532 void tab(outputStream* st, bool first = false) const; |
479 #endif | 533 #endif |
480 }; | 534 }; |
481 | 535 |
482 // BitData | 536 // BitData |
527 | 581 |
528 static ByteSize bit_data_size() { | 582 static ByteSize bit_data_size() { |
529 return cell_offset(bit_cell_count); | 583 return cell_offset(bit_cell_count); |
530 } | 584 } |
531 | 585 |
586 #ifdef CC_INTERP | |
587 static int bit_data_size_in_bytes() { | |
588 return cell_offset_in_bytes(bit_cell_count); | |
589 } | |
590 | |
591 static void set_null_seen(DataLayout* layout) { | |
592 set_flag_at(layout, null_seen_flag); | |
593 } | |
594 | |
595 static DataLayout* advance(DataLayout* layout) { | |
596 return (DataLayout*) (((address)layout) + (ssize_t)BitData::bit_data_size_in_bytes()); | |
597 } | |
598 #endif // CC_INTERP | |
599 | |
532 #ifndef PRODUCT | 600 #ifndef PRODUCT |
533 void print_data_on(outputStream* st) const; | 601 void print_data_on(outputStream* st, const char* extra = NULL) const; |
534 #endif | 602 #endif |
535 }; | 603 }; |
536 | 604 |
537 // CounterData | 605 // CounterData |
538 // | 606 // |
571 | 639 |
572 void set_count(uint count) { | 640 void set_count(uint count) { |
573 set_uint_at(count_off, count); | 641 set_uint_at(count_off, count); |
574 } | 642 } |
575 | 643 |
644 #ifdef CC_INTERP | |
645 static int counter_data_size_in_bytes() { | |
646 return cell_offset_in_bytes(counter_cell_count); | |
647 } | |
648 | |
649 static void increment_count_no_overflow(DataLayout* layout) { | |
650 increment_uint_at_no_overflow(layout, count_off); | |
651 } | |
652 | |
653 // Support counter decrementation at checkcast / subtype check failed. | |
654 static void decrement_count(DataLayout* layout) { | |
655 increment_uint_at_no_overflow(layout, count_off, -1); | |
656 } | |
657 | |
658 static DataLayout* advance(DataLayout* layout) { | |
659 return (DataLayout*) (((address)layout) + (ssize_t)CounterData::counter_data_size_in_bytes()); | |
660 } | |
661 #endif // CC_INTERP | |
662 | |
576 #ifndef PRODUCT | 663 #ifndef PRODUCT |
577 void print_data_on(outputStream* st) const; | 664 void print_data_on(outputStream* st, const char* extra = NULL) const; |
578 #endif | 665 #endif |
579 }; | 666 }; |
580 | 667 |
581 // JumpData | 668 // JumpData |
582 // | 669 // |
641 | 728 |
642 static ByteSize displacement_offset() { | 729 static ByteSize displacement_offset() { |
643 return cell_offset(displacement_off_set); | 730 return cell_offset(displacement_off_set); |
644 } | 731 } |
645 | 732 |
733 #ifdef CC_INTERP | |
734 static void increment_taken_count_no_overflow(DataLayout* layout) { | |
735 increment_uint_at_no_overflow(layout, taken_off_set); | |
736 } | |
737 | |
738 static DataLayout* advance_taken(DataLayout* layout) { | |
739 return (DataLayout*) (((address)layout) + (ssize_t)int_at(layout, displacement_off_set)); | |
740 } | |
741 | |
742 static uint taken_count(DataLayout* layout) { | |
743 return (uint) uint_at(layout, taken_off_set); | |
744 } | |
745 #endif // CC_INTERP | |
746 | |
646 // Specific initialization. | 747 // Specific initialization. |
647 void post_initialize(BytecodeStream* stream, MethodData* mdo); | 748 void post_initialize(BytecodeStream* stream, MethodData* mdo); |
648 | 749 |
649 #ifndef PRODUCT | 750 #ifndef PRODUCT |
650 void print_data_on(outputStream* st) const; | 751 void print_data_on(outputStream* st, const char* extra = NULL) const; |
651 #endif | 752 #endif |
652 }; | 753 }; |
653 | 754 |
654 // Entries in a ProfileData object to record types: it can either be | 755 // Entries in a ProfileData object to record types: it can either be |
655 // none (no profile), unknown (conflicting profile data) or a klass if | 756 // none (no profile), unknown (conflicting profile data) or a klass if |
1056 _ret.clean_weak_klass_links(is_alive_closure); | 1157 _ret.clean_weak_klass_links(is_alive_closure); |
1057 } | 1158 } |
1058 } | 1159 } |
1059 | 1160 |
1060 #ifndef PRODUCT | 1161 #ifndef PRODUCT |
1061 virtual void print_data_on(outputStream* st) const; | 1162 virtual void print_data_on(outputStream* st, const char* extra = NULL) const; |
1062 #endif | 1163 #endif |
1063 }; | 1164 }; |
1064 | 1165 |
1065 // ReceiverTypeData | 1166 // ReceiverTypeData |
1066 // | 1167 // |
1195 } | 1296 } |
1196 | 1297 |
1197 // GC support | 1298 // GC support |
1198 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure); | 1299 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure); |
1199 | 1300 |
1301 #ifdef CC_INTERP | |
1302 static int receiver_type_data_size_in_bytes() { | |
1303 return cell_offset_in_bytes(static_cell_count()); | |
1304 } | |
1305 | |
1306 static Klass *receiver_unchecked(DataLayout* layout, uint row) { | |
1307 Klass* recv = (Klass*)layout->cell_at(receiver_cell_index(row)); | |
1308 return recv; | |
1309 } | |
1310 | |
1311 static void increment_receiver_count_no_overflow(DataLayout* layout, Klass *rcvr) { | |
1312 const int num_rows = row_limit(); | |
1313 // Receiver already exists? | |
1314 for (int row = 0; row < num_rows; row++) { | |
1315 if (receiver_unchecked(layout, row) == rcvr) { | |
1316 increment_uint_at_no_overflow(layout, receiver_count_cell_index(row)); | |
1317 return; | |
1318 } | |
1319 } | |
1320 // New receiver, find a free slot. | |
1321 for (int row = 0; row < num_rows; row++) { | |
1322 if (receiver_unchecked(layout, row) == NULL) { | |
1323 set_intptr_at(layout, receiver_cell_index(row), (intptr_t)rcvr); | |
1324 increment_uint_at_no_overflow(layout, receiver_count_cell_index(row)); | |
1325 return; | |
1326 } | |
1327 } | |
1328 // Receiver did not match any saved receiver and there is no empty row for it. | |
1329 // Increment total counter to indicate polymorphic case. | |
1330 increment_count_no_overflow(layout); | |
1331 } | |
1332 | |
1333 static DataLayout* advance(DataLayout* layout) { | |
1334 return (DataLayout*) (((address)layout) + (ssize_t)ReceiverTypeData::receiver_type_data_size_in_bytes()); | |
1335 } | |
1336 #endif // CC_INTERP | |
1337 | |
1200 #ifndef PRODUCT | 1338 #ifndef PRODUCT |
1201 void print_receiver_data_on(outputStream* st) const; | 1339 void print_receiver_data_on(outputStream* st) const; |
1202 void print_data_on(outputStream* st) const; | 1340 void print_data_on(outputStream* st, const char* extra = NULL) const; |
1203 #endif | 1341 #endif |
1204 }; | 1342 }; |
1205 | 1343 |
1206 // VirtualCallData | 1344 // VirtualCallData |
1207 // | 1345 // |
1229 // Direct accessors | 1367 // Direct accessors |
1230 static ByteSize virtual_call_data_size() { | 1368 static ByteSize virtual_call_data_size() { |
1231 return cell_offset(static_cell_count()); | 1369 return cell_offset(static_cell_count()); |
1232 } | 1370 } |
1233 | 1371 |
1372 #ifdef CC_INTERP | |
1373 static int virtual_call_data_size_in_bytes() { | |
1374 return cell_offset_in_bytes(static_cell_count()); | |
1375 } | |
1376 | |
1377 static DataLayout* advance(DataLayout* layout) { | |
1378 return (DataLayout*) (((address)layout) + (ssize_t)VirtualCallData::virtual_call_data_size_in_bytes()); | |
1379 } | |
1380 #endif // CC_INTERP | |
1381 | |
1234 #ifdef GRAAL | 1382 #ifdef GRAAL |
1235 static ByteSize method_offset(uint row) { | 1383 static ByteSize method_offset(uint row) { |
1236 return cell_offset(method_cell_index(row)); | 1384 return cell_offset(method_cell_index(row)); |
1237 } | 1385 } |
1238 static ByteSize method_count_offset(uint row) { | 1386 static ByteSize method_count_offset(uint row) { |
1285 | 1433 |
1286 #ifndef PRODUCT | 1434 #ifndef PRODUCT |
1287 #ifdef GRAAL | 1435 #ifdef GRAAL |
1288 void print_method_data_on(outputStream* st) const; | 1436 void print_method_data_on(outputStream* st) const; |
1289 #endif | 1437 #endif |
1290 void print_data_on(outputStream* st) const; | 1438 void print_data_on(outputStream* st, const char* extra = NULL) const; |
1291 #endif | 1439 #endif |
1292 }; | 1440 }; |
1293 | 1441 |
1294 // VirtualCallTypeData | 1442 // VirtualCallTypeData |
1295 // | 1443 // |
1411 _ret.clean_weak_klass_links(is_alive_closure); | 1559 _ret.clean_weak_klass_links(is_alive_closure); |
1412 } | 1560 } |
1413 } | 1561 } |
1414 | 1562 |
1415 #ifndef PRODUCT | 1563 #ifndef PRODUCT |
1416 virtual void print_data_on(outputStream* st) const; | 1564 virtual void print_data_on(outputStream* st, const char* extra = NULL) const; |
1417 #endif | 1565 #endif |
1418 }; | 1566 }; |
1419 | 1567 |
1420 // RetData | 1568 // RetData |
1421 // | 1569 // |
1506 } | 1654 } |
1507 static ByteSize bci_displacement_offset(uint row) { | 1655 static ByteSize bci_displacement_offset(uint row) { |
1508 return cell_offset(bci_displacement_cell_index(row)); | 1656 return cell_offset(bci_displacement_cell_index(row)); |
1509 } | 1657 } |
1510 | 1658 |
1659 #ifdef CC_INTERP | |
1660 static DataLayout* advance(MethodData *md, int bci); | |
1661 #endif // CC_INTERP | |
1662 | |
1511 // Specific initialization. | 1663 // Specific initialization. |
1512 void post_initialize(BytecodeStream* stream, MethodData* mdo); | 1664 void post_initialize(BytecodeStream* stream, MethodData* mdo); |
1513 | 1665 |
1514 #ifndef PRODUCT | 1666 #ifndef PRODUCT |
1515 void print_data_on(outputStream* st) const; | 1667 void print_data_on(outputStream* st, const char* extra = NULL) const; |
1516 #endif | 1668 #endif |
1517 }; | 1669 }; |
1518 | 1670 |
1519 // BranchData | 1671 // BranchData |
1520 // | 1672 // |
1570 } | 1722 } |
1571 static ByteSize branch_data_size() { | 1723 static ByteSize branch_data_size() { |
1572 return cell_offset(branch_cell_count); | 1724 return cell_offset(branch_cell_count); |
1573 } | 1725 } |
1574 | 1726 |
1727 #ifdef CC_INTERP | |
1728 static int branch_data_size_in_bytes() { | |
1729 return cell_offset_in_bytes(branch_cell_count); | |
1730 } | |
1731 | |
1732 static void increment_not_taken_count_no_overflow(DataLayout* layout) { | |
1733 increment_uint_at_no_overflow(layout, not_taken_off_set); | |
1734 } | |
1735 | |
1736 static DataLayout* advance_not_taken(DataLayout* layout) { | |
1737 return (DataLayout*) (((address)layout) + (ssize_t)BranchData::branch_data_size_in_bytes()); | |
1738 } | |
1739 #endif // CC_INTERP | |
1740 | |
1575 // Specific initialization. | 1741 // Specific initialization. |
1576 void post_initialize(BytecodeStream* stream, MethodData* mdo); | 1742 void post_initialize(BytecodeStream* stream, MethodData* mdo); |
1577 | 1743 |
1578 #ifndef PRODUCT | 1744 #ifndef PRODUCT |
1579 void print_data_on(outputStream* st) const; | 1745 void print_data_on(outputStream* st, const char* extra = NULL) const; |
1580 #endif | 1746 #endif |
1581 }; | 1747 }; |
1582 | 1748 |
1583 // ArrayData | 1749 // ArrayData |
1584 // | 1750 // |
1608 } | 1774 } |
1609 void array_set_int_at(int index, int value) { | 1775 void array_set_int_at(int index, int value) { |
1610 int aindex = index + array_start_off_set; | 1776 int aindex = index + array_start_off_set; |
1611 set_int_at(aindex, value); | 1777 set_int_at(aindex, value); |
1612 } | 1778 } |
1779 | |
1780 #ifdef CC_INTERP | |
1781 // Static low level accessors for DataLayout with ArrayData's semantics. | |
1782 | |
1783 static void increment_array_uint_at_no_overflow(DataLayout* layout, int index) { | |
1784 int aindex = index + array_start_off_set; | |
1785 increment_uint_at_no_overflow(layout, aindex); | |
1786 } | |
1787 | |
1788 static int array_int_at(DataLayout* layout, int index) { | |
1789 int aindex = index + array_start_off_set; | |
1790 return int_at(layout, aindex); | |
1791 } | |
1792 #endif // CC_INTERP | |
1613 | 1793 |
1614 // Code generation support for subclasses. | 1794 // Code generation support for subclasses. |
1615 static ByteSize array_element_offset(int index) { | 1795 static ByteSize array_element_offset(int index) { |
1616 return cell_offset(array_start_off_set + index); | 1796 return cell_offset(array_start_off_set + index); |
1617 } | 1797 } |
1727 } | 1907 } |
1728 static ByteSize relative_displacement_offset() { | 1908 static ByteSize relative_displacement_offset() { |
1729 return in_ByteSize(relative_displacement_off_set) * cell_size; | 1909 return in_ByteSize(relative_displacement_off_set) * cell_size; |
1730 } | 1910 } |
1731 | 1911 |
1912 #ifdef CC_INTERP | |
1913 static void increment_count_no_overflow(DataLayout* layout, int index) { | |
1914 if (index == -1) { | |
1915 increment_array_uint_at_no_overflow(layout, default_count_off_set); | |
1916 } else { | |
1917 increment_array_uint_at_no_overflow(layout, case_array_start + | |
1918 index * per_case_cell_count + | |
1919 relative_count_off_set); | |
1920 } | |
1921 } | |
1922 | |
1923 static DataLayout* advance(DataLayout* layout, int index) { | |
1924 if (index == -1) { | |
1925 return (DataLayout*) (((address)layout) + (ssize_t)array_int_at(layout, default_disaplacement_off_set)); | |
1926 } else { | |
1927 return (DataLayout*) (((address)layout) + (ssize_t)array_int_at(layout, case_array_start + | |
1928 index * per_case_cell_count + | |
1929 relative_displacement_off_set)); | |
1930 } | |
1931 } | |
1932 #endif // CC_INTERP | |
1933 | |
1732 // Specific initialization. | 1934 // Specific initialization. |
1733 void post_initialize(BytecodeStream* stream, MethodData* mdo); | 1935 void post_initialize(BytecodeStream* stream, MethodData* mdo); |
1734 | 1936 |
1735 #ifndef PRODUCT | 1937 #ifndef PRODUCT |
1736 void print_data_on(outputStream* st) const; | 1938 void print_data_on(outputStream* st, const char* extra = NULL) const; |
1737 #endif | 1939 #endif |
1738 }; | 1940 }; |
1739 | 1941 |
1740 class ArgInfoData : public ArrayData { | 1942 class ArgInfoData : public ArrayData { |
1741 | 1943 |
1758 void set_arg_modified(int arg, uint val) { | 1960 void set_arg_modified(int arg, uint val) { |
1759 array_set_int_at(arg, val); | 1961 array_set_int_at(arg, val); |
1760 } | 1962 } |
1761 | 1963 |
1762 #ifndef PRODUCT | 1964 #ifndef PRODUCT |
1763 void print_data_on(outputStream* st) const; | 1965 void print_data_on(outputStream* st, const char* extra = NULL) const; |
1764 #endif | 1966 #endif |
1765 }; | 1967 }; |
1766 | 1968 |
1767 // ParametersTypeData | 1969 // ParametersTypeData |
1768 // | 1970 // |
1819 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) { | 2021 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) { |
1820 _parameters.clean_weak_klass_links(is_alive_closure); | 2022 _parameters.clean_weak_klass_links(is_alive_closure); |
1821 } | 2023 } |
1822 | 2024 |
1823 #ifndef PRODUCT | 2025 #ifndef PRODUCT |
1824 virtual void print_data_on(outputStream* st) const; | 2026 virtual void print_data_on(outputStream* st, const char* extra = NULL) const; |
1825 #endif | 2027 #endif |
1826 | 2028 |
1827 static ByteSize stack_slot_offset(int i) { | 2029 static ByteSize stack_slot_offset(int i) { |
1828 return cell_offset(stack_slot_local_offset(i)); | 2030 return cell_offset(stack_slot_local_offset(i)); |
1829 } | 2031 } |
1830 | 2032 |
1831 static ByteSize type_offset(int i) { | 2033 static ByteSize type_offset(int i) { |
1832 return cell_offset(type_local_offset(i)); | 2034 return cell_offset(type_local_offset(i)); |
1833 } | 2035 } |
2036 }; | |
2037 | |
2038 // SpeculativeTrapData | |
2039 // | |
2040 // A SpeculativeTrapData is used to record traps due to type | |
2041 // speculation. It records the root of the compilation: that type | |
2042 // speculation is wrong in the context of one compilation (for | |
2043 // method1) doesn't mean it's wrong in the context of another one (for | |
2044 // method2). Type speculation could have more/different data in the | |
2045 // context of the compilation of method2 and it's worthwhile to try an | |
2046 // optimization that failed for compilation of method1 in the context | |
2047 // of compilation of method2. | |
2048 // Space for SpeculativeTrapData entries is allocated from the extra | |
2049 // data space in the MDO. If we run out of space, the trap data for | |
2050 // the ProfileData at that bci is updated. | |
2051 class SpeculativeTrapData : public ProfileData { | |
2052 protected: | |
2053 enum { | |
2054 method_offset, | |
2055 speculative_trap_cell_count | |
2056 }; | |
2057 public: | |
2058 SpeculativeTrapData(DataLayout* layout) : ProfileData(layout) { | |
2059 assert(layout->tag() == DataLayout::speculative_trap_data_tag, "wrong type"); | |
2060 } | |
2061 | |
2062 virtual bool is_SpeculativeTrapData() const { return true; } | |
2063 | |
2064 static int static_cell_count() { | |
2065 return speculative_trap_cell_count; | |
2066 } | |
2067 | |
2068 virtual int cell_count() const { | |
2069 return static_cell_count(); | |
2070 } | |
2071 | |
2072 // Direct accessor | |
2073 Method* method() const { | |
2074 return (Method*)intptr_at(method_offset); | |
2075 } | |
2076 | |
2077 void set_method(Method* m) { | |
2078 set_intptr_at(method_offset, (intptr_t)m); | |
2079 } | |
2080 | |
2081 #ifndef PRODUCT | |
2082 virtual void print_data_on(outputStream* st, const char* extra = NULL) const; | |
2083 #endif | |
1834 }; | 2084 }; |
1835 | 2085 |
1836 // MethodData* | 2086 // MethodData* |
1837 // | 2087 // |
1838 // A MethodData* holds information which has been collected about | 2088 // A MethodData* holds information which has been collected about |
1874 // from the base of the data entry array. A "displacement" is the byte offset | 2124 // from the base of the data entry array. A "displacement" is the byte offset |
1875 // in certain ProfileData objects that indicate the amount the mdp must be | 2125 // in certain ProfileData objects that indicate the amount the mdp must be |
1876 // adjusted in the event of a change in control flow. | 2126 // adjusted in the event of a change in control flow. |
1877 // | 2127 // |
1878 | 2128 |
2129 CC_INTERP_ONLY(class BytecodeInterpreter;) | |
2130 | |
1879 class MethodData : public Metadata { | 2131 class MethodData : public Metadata { |
1880 friend class VMStructs; | 2132 friend class VMStructs; |
2133 CC_INTERP_ONLY(friend class BytecodeInterpreter;) | |
1881 private: | 2134 private: |
1882 friend class ProfileData; | 2135 friend class ProfileData; |
1883 | 2136 |
1884 // Back pointer to the Method* | 2137 // Back pointer to the Method* |
1885 Method* _method; | 2138 Method* _method; |
1961 intptr_t _data[1]; | 2214 intptr_t _data[1]; |
1962 | 2215 |
1963 // Helper for size computation | 2216 // Helper for size computation |
1964 static int compute_data_size(BytecodeStream* stream); | 2217 static int compute_data_size(BytecodeStream* stream); |
1965 static int bytecode_cell_count(Bytecodes::Code code); | 2218 static int bytecode_cell_count(Bytecodes::Code code); |
2219 static bool is_speculative_trap_bytecode(Bytecodes::Code code); | |
1966 enum { no_profile_data = -1, variable_cell_count = -2 }; | 2220 enum { no_profile_data = -1, variable_cell_count = -2 }; |
1967 | 2221 |
1968 // Helper for initialization | 2222 // Helper for initialization |
1969 DataLayout* data_layout_at(int data_index) const { | 2223 DataLayout* data_layout_at(int data_index) const { |
1970 assert(data_index % sizeof(intptr_t) == 0, "unaligned"); | 2224 assert(data_index % sizeof(intptr_t) == 0, "unaligned"); |
2004 } | 2258 } |
2005 | 2259 |
2006 // What is the index of the first data entry? | 2260 // What is the index of the first data entry? |
2007 int first_di() const { return 0; } | 2261 int first_di() const { return 0; } |
2008 | 2262 |
2263 ProfileData* bci_to_extra_data_helper(int bci, Method* m, DataLayout*& dp); | |
2009 // Find or create an extra ProfileData: | 2264 // Find or create an extra ProfileData: |
2010 ProfileData* bci_to_extra_data(int bci, bool create_if_missing); | 2265 ProfileData* bci_to_extra_data(int bci, Method* m, bool create_if_missing); |
2011 | 2266 |
2012 // return the argument info cell | 2267 // return the argument info cell |
2013 ArgInfoData *arg_info(); | 2268 ArgInfoData *arg_info(); |
2014 | 2269 |
2015 enum { | 2270 enum { |
2028 static bool profile_return_for_invoke(methodHandle m, int bci); | 2283 static bool profile_return_for_invoke(methodHandle m, int bci); |
2029 static int profile_parameters_flag(); | 2284 static int profile_parameters_flag(); |
2030 static bool profile_parameters_jsr292_only(); | 2285 static bool profile_parameters_jsr292_only(); |
2031 static bool profile_all_parameters(); | 2286 static bool profile_all_parameters(); |
2032 | 2287 |
2288 void clean_extra_data(BoolObjectClosure* is_alive); | |
2289 void clean_extra_data_helper(DataLayout* dp, int shift, bool reset = false); | |
2290 void verify_extra_data_clean(BoolObjectClosure* is_alive); | |
2291 | |
2033 public: | 2292 public: |
2034 static int header_size() { | 2293 static int header_size() { |
2035 return sizeof(MethodData)/wordSize; | 2294 return sizeof(MethodData)/wordSize; |
2036 } | 2295 } |
2037 | 2296 |
2038 // Compute the size of a MethodData* before it is created. | 2297 // Compute the size of a MethodData* before it is created. |
2039 static int compute_allocation_size_in_bytes(methodHandle method); | 2298 static int compute_allocation_size_in_bytes(methodHandle method); |
2040 static int compute_allocation_size_in_words(methodHandle method); | 2299 static int compute_allocation_size_in_words(methodHandle method); |
2041 static int compute_extra_data_count(int data_size, int empty_bc_count); | 2300 static int compute_extra_data_count(int data_size, int empty_bc_count, bool needs_speculative_traps); |
2042 | 2301 |
2043 // Determine if a given bytecode can have profile information. | 2302 // Determine if a given bytecode can have profile information. |
2044 static bool bytecode_has_profile(Bytecodes::Code code) { | 2303 static bool bytecode_has_profile(Bytecodes::Code code) { |
2045 return bytecode_cell_count(code) != no_profile_data; | 2304 return bytecode_cell_count(code) != no_profile_data; |
2046 } | 2305 } |
2177 | 2436 |
2178 // Get the data at an arbitrary bci, or NULL if there is none. | 2437 // Get the data at an arbitrary bci, or NULL if there is none. |
2179 ProfileData* bci_to_data(int bci); | 2438 ProfileData* bci_to_data(int bci); |
2180 | 2439 |
2181 // Same, but try to create an extra_data record if one is needed: | 2440 // Same, but try to create an extra_data record if one is needed: |
2182 ProfileData* allocate_bci_to_data(int bci) { | 2441 ProfileData* allocate_bci_to_data(int bci, Method* m) { |
2183 ProfileData* data = bci_to_data(bci); | 2442 ProfileData* data = NULL; |
2184 return (data != NULL) ? data : bci_to_extra_data(bci, true); | 2443 // If m not NULL, try to allocate a SpeculativeTrapData entry |
2444 if (m == NULL) { | |
2445 data = bci_to_data(bci); | |
2446 } | |
2447 if (data != NULL) { | |
2448 return data; | |
2449 } | |
2450 data = bci_to_extra_data(bci, m, true); | |
2451 if (data != NULL) { | |
2452 return data; | |
2453 } | |
2454 // If SpeculativeTrapData allocation fails try to allocate a | |
2455 // regular entry | |
2456 data = bci_to_data(bci); | |
2457 if (data != NULL) { | |
2458 return data; | |
2459 } | |
2460 return bci_to_extra_data(bci, NULL, true); | |
2185 } | 2461 } |
2186 | 2462 |
2187 // Add a handful of extra data records, for trap tracking. | 2463 // Add a handful of extra data records, for trap tracking. |
2188 DataLayout* extra_data_base() const { return limit_data_position(); } | 2464 DataLayout* extra_data_base() const { return limit_data_position(); } |
2189 DataLayout* extra_data_limit() const { return (DataLayout*)((address)this + size_in_bytes()); } | 2465 DataLayout* extra_data_limit() const { return (DataLayout*)((address)this + size_in_bytes()); } |
2190 int extra_data_size() const { return (address)extra_data_limit() | 2466 int extra_data_size() const { return (address)extra_data_limit() |
2191 - (address)extra_data_base(); } | 2467 - (address)extra_data_base(); } |
2192 static DataLayout* next_extra(DataLayout* dp) { return (DataLayout*)((address)dp + in_bytes(DataLayout::cell_offset(0))); } | 2468 static DataLayout* next_extra(DataLayout* dp); |
2193 | 2469 |
2194 // Return (uint)-1 for overflow. | 2470 // Return (uint)-1 for overflow. |
2195 uint trap_count(int reason) const { | 2471 uint trap_count(int reason) const { |
2196 assert((uint)reason < GRAAL_ONLY(2*) _trap_hist_limit, "oob"); | 2472 assert((uint)reason < GRAAL_ONLY(2*) _trap_hist_limit, "oob"); |
2197 return (int)((_trap_hist._array[reason]+1) & _trap_hist_mask) - 1; | 2473 return (int)((_trap_hist._array[reason]+1) & _trap_hist_mask) - 1; |
2287 static bool profile_parameters_for_method(methodHandle m); | 2563 static bool profile_parameters_for_method(methodHandle m); |
2288 static bool profile_arguments(); | 2564 static bool profile_arguments(); |
2289 static bool profile_return(); | 2565 static bool profile_return(); |
2290 static bool profile_parameters(); | 2566 static bool profile_parameters(); |
2291 static bool profile_return_jsr292_only(); | 2567 static bool profile_return_jsr292_only(); |
2568 | |
2569 void clean_method_data(BoolObjectClosure* is_alive); | |
2292 }; | 2570 }; |
2293 | 2571 |
2294 #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP | 2572 #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP |