208 assert(flag_number < flag_limit, "oob");
209 return (_header._struct._flags & (0x1 << flag_number)) != 0;
210 }
211
212 // Low-level support for code generation.
213 static ByteSize header_offset() {
214 return byte_offset_of(DataLayout, _header);
215 }
216 static ByteSize tag_offset() {
217 return byte_offset_of(DataLayout, _header._struct._tag);
218 }
219 static ByteSize flags_offset() {
220 return byte_offset_of(DataLayout, _header._struct._flags);
221 }
222 static ByteSize bci_offset() {
223 return byte_offset_of(DataLayout, _header._struct._bci);
224 }
225 static ByteSize cell_offset(int index) {
226 return byte_offset_of(DataLayout, _cells) + in_ByteSize(index * cell_size);
227 }
228 // Return a value which, when or-ed as a byte into _flags, sets the flag.
229 static int flag_number_to_byte_constant(int flag_number) {
230 assert(0 <= flag_number && flag_number < flag_limit, "oob");
231 DataLayout temp; temp.set_header(0);
232 temp.set_flag_at(flag_number);
233 return temp._header._struct._flags;
234 }
235 // Return a value which, when or-ed as a word into _header, sets the flag.
236 static intptr_t flag_mask_to_header_mask(int byte_constant) {
237 DataLayout temp; temp.set_header(0);
238 temp._header._struct._flags = byte_constant;
239 return temp._header._bits;
240 }
241
242 ProfileData* data_in();
243
244 // GC support
245 void clean_weak_klass_links(BoolObjectClosure* cl);
246 };
247
339
340 void set_flag_at(int flag_number) {
341 data()->set_flag_at(flag_number);
342 }
343 bool flag_at(int flag_number) {
344 return data()->flag_at(flag_number);
345 }
346
347 // two convenient imports for use by subclasses:
348 static ByteSize cell_offset(int index) {
349 return DataLayout::cell_offset(index);
350 }
351 static int flag_number_to_byte_constant(int flag_number) {
352 return DataLayout::flag_number_to_byte_constant(flag_number);
353 }
354
355 ProfileData(DataLayout* data) {
356 _data = data;
357 }
358
359 public:
360 // Constructor for invalid ProfileData.
361 ProfileData();
362
363 u2 bci() {
364 return data()->bci();
365 }
366
367 address dp() {
368 return (address)_data;
369 }
370
371 int trap_state() {
372 return data()->trap_state();
373 }
374 void set_trap_state(int new_state) {
375 data()->set_trap_state(new_state);
376 }
377
378 // Type checking
478 return static_cell_count();
479 }
480
481 // Accessor
482
483 // The null_seen flag bit is specially known to the interpreter.
484 // Consulting it allows the compiler to avoid setting up null_check traps.
485 bool null_seen() { return flag_at(null_seen_flag); }
486 void set_null_seen() { set_flag_at(null_seen_flag); }
487
488
489 // Code generation support
490 static int null_seen_byte_constant() {
491 return flag_number_to_byte_constant(null_seen_flag);
492 }
493
494 static ByteSize bit_data_size() {
495 return cell_offset(bit_cell_count);
496 }
497
498 #ifndef PRODUCT
499 void print_data_on(outputStream* st);
500 #endif
501 };
502
503 // CounterData
504 //
505 // A CounterData corresponds to a simple counter.
506 class CounterData : public BitData {
507 protected:
508 enum {
509 count_off,
510 counter_cell_count
511 };
512 public:
513 CounterData(DataLayout* layout) : BitData(layout) {}
514
515 virtual bool is_CounterData() { return true; }
516
517 static int static_cell_count() {
522 return static_cell_count();
523 }
524
525 // Direct accessor
526 uint count() {
527 return uint_at(count_off);
528 }
529
530 // Code generation support
531 static ByteSize count_offset() {
532 return cell_offset(count_off);
533 }
534 static ByteSize counter_data_size() {
535 return cell_offset(counter_cell_count);
536 }
537
538 void set_count(uint count) {
539 set_uint_at(count_off, count);
540 }
541
542 #ifndef PRODUCT
543 void print_data_on(outputStream* st);
544 #endif
545 };
546
547 // JumpData
548 //
549 // A JumpData is used to access profiling information for a direct
550 // branch. It is a counter, used for counting the number of branches,
551 // plus a data displacement, used for realigning the data pointer to
552 // the corresponding target bci.
553 class JumpData : public ProfileData {
554 protected:
555 enum {
556 taken_off_set,
557 displacement_off_set,
558 jump_cell_count
559 };
560
561 void set_displacement(int displacement) {
592 uint cnt = taken() + 1;
593 // Did we wrap? Will compiler screw us??
594 if (cnt == 0) cnt--;
595 set_uint_at(taken_off_set, cnt);
596 return cnt;
597 }
598
599 int displacement() {
600 return int_at(displacement_off_set);
601 }
602
603 // Code generation support
604 static ByteSize taken_offset() {
605 return cell_offset(taken_off_set);
606 }
607
608 static ByteSize displacement_offset() {
609 return cell_offset(displacement_off_set);
610 }
611
612 // Specific initialization.
613 void post_initialize(BytecodeStream* stream, MethodData* mdo);
614
615 #ifndef PRODUCT
616 void print_data_on(outputStream* st);
617 #endif
618 };
619
620 // ReceiverTypeData
621 //
622 // A ReceiverTypeData is used to access profiling information about a
623 // dynamic type check. It consists of a counter which counts the total times
624 // that the check is reached, and a series of (Klass*, count) pairs
625 // which are used to store a type profile for the receiver of the check.
626 class ReceiverTypeData : public CounterData {
627 protected:
628 enum {
629 receiver0_offset = counter_cell_count,
630 count0_offset,
631 receiver_type_row_cell_count = (count0_offset + 1) - receiver0_offset
701 //
702 set_count(0);
703 set_receiver(row, NULL);
704 set_receiver_count(row, 0);
705 }
706
707 // Code generation support
708 static ByteSize receiver_offset(uint row) {
709 return cell_offset(receiver_cell_index(row));
710 }
711 static ByteSize receiver_count_offset(uint row) {
712 return cell_offset(receiver_count_cell_index(row));
713 }
714 static ByteSize receiver_type_data_size() {
715 return cell_offset(static_cell_count());
716 }
717
718 // GC support
719 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);
720
721 #ifndef PRODUCT
722 void print_receiver_data_on(outputStream* st);
723 void print_data_on(outputStream* st);
724 #endif
725 };
726
727 // VirtualCallData
728 //
729 // A VirtualCallData is used to access profiling information about a
730 // virtual call. For now, it has nothing more than a ReceiverTypeData.
731 class VirtualCallData : public ReceiverTypeData {
732 public:
733 VirtualCallData(DataLayout* layout) : ReceiverTypeData(layout) {
734 assert(layout->tag() == DataLayout::virtual_call_data_tag, "wrong type");
735 }
736
737 virtual bool is_VirtualCallData() { return true; }
738
739 static int static_cell_count() {
740 // At this point we could add more profile state, e.g., for arguments.
741 // But for now it's the same size as the base record type.
742 return ReceiverTypeData::static_cell_count();
743 }
744
745 virtual int cell_count() {
746 return static_cell_count();
747 }
748
749 // Direct accessors
750 static ByteSize virtual_call_data_size() {
751 return cell_offset(static_cell_count());
752 }
753
754 #ifndef PRODUCT
755 void print_data_on(outputStream* st);
756 #endif
757 };
758
759 // RetData
760 //
761 // A RetData is used to access profiling information for a ret bytecode.
762 // It is composed of a count of the number of times that the ret has
763 // been executed, followed by a series of triples of the form
764 // (bci, count, di) which count the number of times that some bci was the
765 // target of the ret and cache a corresponding data displacement.
766 class RetData : public CounterData {
767 protected:
768 enum {
769 bci0_offset = counter_cell_count,
770 count0_offset,
771 displacement0_offset,
772 ret_row_cell_count = (displacement0_offset + 1) - bci0_offset
773 };
830 return uint_at(bci_count_cell_index(row));
831 }
832 int bci_displacement(uint row) {
833 return int_at(bci_displacement_cell_index(row));
834 }
835
836 // Interpreter Runtime support
837 address fixup_ret(int return_bci, MethodData* mdo);
838
839 // Code generation support
840 static ByteSize bci_offset(uint row) {
841 return cell_offset(bci_cell_index(row));
842 }
843 static ByteSize bci_count_offset(uint row) {
844 return cell_offset(bci_count_cell_index(row));
845 }
846 static ByteSize bci_displacement_offset(uint row) {
847 return cell_offset(bci_displacement_cell_index(row));
848 }
849
850 // Specific initialization.
851 void post_initialize(BytecodeStream* stream, MethodData* mdo);
852
853 #ifndef PRODUCT
854 void print_data_on(outputStream* st);
855 #endif
856 };
857
858 // BranchData
859 //
860 // A BranchData is used to access profiling data for a two-way branch.
861 // It consists of taken and not_taken counts as well as a data displacement
862 // for the taken case.
863 class BranchData : public JumpData {
864 protected:
865 enum {
866 not_taken_off_set = jump_cell_count,
867 branch_cell_count
868 };
869
894 void set_not_taken(uint cnt) {
895 set_uint_at(not_taken_off_set, cnt);
896 }
897
898 uint inc_not_taken() {
899 uint cnt = not_taken() + 1;
900 // Did we wrap? Will compiler screw us??
901 if (cnt == 0) cnt--;
902 set_uint_at(not_taken_off_set, cnt);
903 return cnt;
904 }
905
906 // Code generation support
907 static ByteSize not_taken_offset() {
908 return cell_offset(not_taken_off_set);
909 }
910 static ByteSize branch_data_size() {
911 return cell_offset(branch_cell_count);
912 }
913
914 // Specific initialization.
915 void post_initialize(BytecodeStream* stream, MethodData* mdo);
916
917 #ifndef PRODUCT
918 void print_data_on(outputStream* st);
919 #endif
920 };
921
922 // ArrayData
923 //
924 // A ArrayData is a base class for accessing profiling data which does
925 // not have a statically known size. It consists of an array length
926 // and an array start.
927 class ArrayData : public ProfileData {
928 protected:
929 friend class DataLayout;
930
931 enum {
932 array_len_off_set,
933 array_start_off_set
934 };
935
936 uint array_uint_at(int index) {
937 int aindex = index + array_start_off_set;
938 return uint_at(aindex);
939 }
940 int array_int_at(int index) {
941 int aindex = index + array_start_off_set;
942 return int_at(aindex);
943 }
944 oop array_oop_at(int index) {
945 int aindex = index + array_start_off_set;
946 return oop_at(aindex);
947 }
948 void array_set_int_at(int index, int value) {
949 int aindex = index + array_start_off_set;
950 set_int_at(aindex, value);
951 }
952
953 // Code generation support for subclasses.
954 static ByteSize array_element_offset(int index) {
955 return cell_offset(array_start_off_set + index);
956 }
957
958 public:
959 ArrayData(DataLayout* layout) : ProfileData(layout) {}
960
961 virtual bool is_ArrayData() { return true; }
962
963 static int static_cell_count() {
964 return -1;
965 }
966
967 int array_len() {
968 return int_at_unchecked(array_len_off_set);
969 }
970
971 virtual int cell_count() {
972 return array_len() + 1;
1051 return array_element_offset(default_disaplacement_off_set);
1052 }
1053 static ByteSize case_count_offset(int index) {
1054 return case_array_offset() +
1055 (per_case_size() * index) +
1056 relative_count_offset();
1057 }
1058 static ByteSize case_array_offset() {
1059 return array_element_offset(case_array_start);
1060 }
1061 static ByteSize per_case_size() {
1062 return in_ByteSize(per_case_cell_count) * cell_size;
1063 }
1064 static ByteSize relative_count_offset() {
1065 return in_ByteSize(relative_count_off_set) * cell_size;
1066 }
1067 static ByteSize relative_displacement_offset() {
1068 return in_ByteSize(relative_displacement_off_set) * cell_size;
1069 }
1070
1071 // Specific initialization.
1072 void post_initialize(BytecodeStream* stream, MethodData* mdo);
1073
1074 #ifndef PRODUCT
1075 void print_data_on(outputStream* st);
1076 #endif
1077 };
1078
1079 class ArgInfoData : public ArrayData {
1080
1081 public:
1082 ArgInfoData(DataLayout* layout) : ArrayData(layout) {
1083 assert(layout->tag() == DataLayout::arg_info_data_tag, "wrong type");
1084 }
1085
1086 virtual bool is_ArgInfoData() { return true; }
1087
1088
1089 int number_of_args() {
1090 return array_len();
1129 // method. The entries in the array are sorted by the corresponding
1130 // bytecode. Access to the data is via resource-allocated ProfileData,
1131 // which point to the underlying blocks of DataLayout structures.
1132 //
1133 // During interpretation, if profiling in enabled, the interpreter
1134 // maintains a method data pointer (mdp), which points at the entry
1135 // in the array corresponding to the current bci. In the course of
1136 // intepretation, when a bytecode is encountered that has profile data
1137 // associated with it, the entry pointed to by mdp is updated, then the
1138 // mdp is adjusted to point to the next appropriate DataLayout. If mdp
1139 // is NULL to begin with, the interpreter assumes that the current method
1140 // is not (yet) being profiled.
1141 //
1142 // In MethodData* parlance, "dp" is a "data pointer", the actual address
1143 // of a DataLayout element. A "di" is a "data index", the offset in bytes
1144 // from the base of the data entry array. A "displacement" is the byte offset
1145 // in certain ProfileData objects that indicate the amount the mdp must be
1146 // adjusted in the event of a change in control flow.
1147 //
1148
1149 class MethodData : public Metadata {
1150 friend class VMStructs;
1151 private:
1152 friend class ProfileData;
1153
1154 // Back pointer to the Method*
1155 Method* _method;
1156
1157 // Size of this oop in bytes
1158 int _size;
1159
1160 // Cached hint for bci_to_dp and bci_to_data
1161 int _hint_di;
1162
1163 MethodData(methodHandle method, int size, TRAPS);
1164 public:
1165 static MethodData* allocate(ClassLoaderData* loader_data, methodHandle method, TRAPS);
1166 MethodData() {}; // For ciMethodData
1167
1168 bool is_methodData() const volatile { return true; }
1169
1170 // Whole-method sticky bits and flags
|
208 assert(flag_number < flag_limit, "oob");
209 return (_header._struct._flags & (0x1 << flag_number)) != 0;
210 }
211
212 // Low-level support for code generation.
213 static ByteSize header_offset() {
214 return byte_offset_of(DataLayout, _header);
215 }
216 static ByteSize tag_offset() {
217 return byte_offset_of(DataLayout, _header._struct._tag);
218 }
219 static ByteSize flags_offset() {
220 return byte_offset_of(DataLayout, _header._struct._flags);
221 }
222 static ByteSize bci_offset() {
223 return byte_offset_of(DataLayout, _header._struct._bci);
224 }
225 static ByteSize cell_offset(int index) {
226 return byte_offset_of(DataLayout, _cells) + in_ByteSize(index * cell_size);
227 }
228 #ifdef CC_INTERP
229 static int cell_offset_in_bytes(int index) {
230 return (int)offset_of(DataLayout, _cells[index]);
231 }
232 #endif // CC_INTERP
233 // 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) {
235 assert(0 <= flag_number && flag_number < flag_limit, "oob");
236 DataLayout temp; temp.set_header(0);
237 temp.set_flag_at(flag_number);
238 return temp._header._struct._flags;
239 }
240 // Return a value which, when or-ed as a word into _header, sets the flag.
241 static intptr_t flag_mask_to_header_mask(int byte_constant) {
242 DataLayout temp; temp.set_header(0);
243 temp._header._struct._flags = byte_constant;
244 return temp._header._bits;
245 }
246
247 ProfileData* data_in();
248
249 // GC support
250 void clean_weak_klass_links(BoolObjectClosure* cl);
251 };
252
344
345 void set_flag_at(int flag_number) {
346 data()->set_flag_at(flag_number);
347 }
348 bool flag_at(int flag_number) {
349 return data()->flag_at(flag_number);
350 }
351
352 // two convenient imports for use by subclasses:
353 static ByteSize cell_offset(int index) {
354 return DataLayout::cell_offset(index);
355 }
356 static int flag_number_to_byte_constant(int flag_number) {
357 return DataLayout::flag_number_to_byte_constant(flag_number);
358 }
359
360 ProfileData(DataLayout* data) {
361 _data = data;
362 }
363
364 #ifdef CC_INTERP
365 // Static low level accessors for DataLayout with ProfileData's semantics.
366
367 static int cell_offset_in_bytes(int index) {
368 return DataLayout::cell_offset_in_bytes(index);
369 }
370
371 static void increment_uint_at_no_overflow(DataLayout* layout, int index,
372 int inc = DataLayout::counter_increment) {
373 uint count = ((uint)layout->cell_at(index)) + inc;
374 if (count == 0) return;
375 layout->set_cell_at(index, (intptr_t) count);
376 }
377
378 static int int_at(DataLayout* layout, int index) {
379 return (int)layout->cell_at(index);
380 }
381
382 static int uint_at(DataLayout* layout, int index) {
383 return (uint)layout->cell_at(index);
384 }
385
386 static oop oop_at(DataLayout* layout, int index) {
387 return (oop)layout->cell_at(index);
388 }
389
390 static void set_intptr_at(DataLayout* layout, int index, intptr_t value) {
391 layout->set_cell_at(index, (intptr_t) value);
392 }
393
394 static void set_flag_at(DataLayout* layout, int flag_number) {
395 layout->set_flag_at(flag_number);
396 }
397 #endif // CC_INTERP
398
399 public:
400 // Constructor for invalid ProfileData.
401 ProfileData();
402
403 u2 bci() {
404 return data()->bci();
405 }
406
407 address dp() {
408 return (address)_data;
409 }
410
411 int trap_state() {
412 return data()->trap_state();
413 }
414 void set_trap_state(int new_state) {
415 data()->set_trap_state(new_state);
416 }
417
418 // Type checking
518 return static_cell_count();
519 }
520
521 // Accessor
522
523 // The null_seen flag bit is specially known to the interpreter.
524 // Consulting it allows the compiler to avoid setting up null_check traps.
525 bool null_seen() { return flag_at(null_seen_flag); }
526 void set_null_seen() { set_flag_at(null_seen_flag); }
527
528
529 // Code generation support
530 static int null_seen_byte_constant() {
531 return flag_number_to_byte_constant(null_seen_flag);
532 }
533
534 static ByteSize bit_data_size() {
535 return cell_offset(bit_cell_count);
536 }
537
538 #ifdef CC_INTERP
539 static int bit_data_size_in_bytes() {
540 return cell_offset_in_bytes(bit_cell_count);
541 }
542
543 static void set_null_seen(DataLayout* layout) {
544 set_flag_at(layout, null_seen_flag);
545 }
546
547 static DataLayout* advance(DataLayout* layout) {
548 return (DataLayout*) (((address)layout) + (ssize_t)BitData::bit_data_size_in_bytes());
549 }
550 #endif // CC_INTERP
551
552 #ifndef PRODUCT
553 void print_data_on(outputStream* st);
554 #endif
555 };
556
557 // CounterData
558 //
559 // A CounterData corresponds to a simple counter.
560 class CounterData : public BitData {
561 protected:
562 enum {
563 count_off,
564 counter_cell_count
565 };
566 public:
567 CounterData(DataLayout* layout) : BitData(layout) {}
568
569 virtual bool is_CounterData() { return true; }
570
571 static int static_cell_count() {
576 return static_cell_count();
577 }
578
579 // Direct accessor
580 uint count() {
581 return uint_at(count_off);
582 }
583
584 // Code generation support
585 static ByteSize count_offset() {
586 return cell_offset(count_off);
587 }
588 static ByteSize counter_data_size() {
589 return cell_offset(counter_cell_count);
590 }
591
592 void set_count(uint count) {
593 set_uint_at(count_off, count);
594 }
595
596 #ifdef CC_INTERP
597 static int counter_data_size_in_bytes() {
598 return cell_offset_in_bytes(counter_cell_count);
599 }
600
601 static void increment_count_no_overflow(DataLayout* layout) {
602 increment_uint_at_no_overflow(layout, count_off);
603 }
604
605 // Support counter decrementation at checkcast / subtype check failed.
606 static void decrement_count(DataLayout* layout) {
607 increment_uint_at_no_overflow(layout, count_off, -1);
608 }
609
610 static DataLayout* advance(DataLayout* layout) {
611 return (DataLayout*) (((address)layout) + (ssize_t)CounterData::counter_data_size_in_bytes());
612 }
613 #endif // CC_INTERP
614
615 #ifndef PRODUCT
616 void print_data_on(outputStream* st);
617 #endif
618 };
619
620 // JumpData
621 //
622 // A JumpData is used to access profiling information for a direct
623 // branch. It is a counter, used for counting the number of branches,
624 // plus a data displacement, used for realigning the data pointer to
625 // the corresponding target bci.
626 class JumpData : public ProfileData {
627 protected:
628 enum {
629 taken_off_set,
630 displacement_off_set,
631 jump_cell_count
632 };
633
634 void set_displacement(int displacement) {
665 uint cnt = taken() + 1;
666 // Did we wrap? Will compiler screw us??
667 if (cnt == 0) cnt--;
668 set_uint_at(taken_off_set, cnt);
669 return cnt;
670 }
671
672 int displacement() {
673 return int_at(displacement_off_set);
674 }
675
676 // Code generation support
677 static ByteSize taken_offset() {
678 return cell_offset(taken_off_set);
679 }
680
681 static ByteSize displacement_offset() {
682 return cell_offset(displacement_off_set);
683 }
684
685 #ifdef CC_INTERP
686 static void increment_taken_count_no_overflow(DataLayout* layout) {
687 increment_uint_at_no_overflow(layout, taken_off_set);
688 }
689
690 static DataLayout* advance_taken(DataLayout* layout) {
691 return (DataLayout*) (((address)layout) + (ssize_t)int_at(layout, displacement_off_set));
692 }
693
694 static uint taken_count(DataLayout* layout) {
695 return (uint) uint_at(layout, taken_off_set);
696 }
697 #endif // CC_INTERP
698
699 // Specific initialization.
700 void post_initialize(BytecodeStream* stream, MethodData* mdo);
701
702 #ifndef PRODUCT
703 void print_data_on(outputStream* st);
704 #endif
705 };
706
707 // ReceiverTypeData
708 //
709 // A ReceiverTypeData is used to access profiling information about a
710 // dynamic type check. It consists of a counter which counts the total times
711 // that the check is reached, and a series of (Klass*, count) pairs
712 // which are used to store a type profile for the receiver of the check.
713 class ReceiverTypeData : public CounterData {
714 protected:
715 enum {
716 receiver0_offset = counter_cell_count,
717 count0_offset,
718 receiver_type_row_cell_count = (count0_offset + 1) - receiver0_offset
788 //
789 set_count(0);
790 set_receiver(row, NULL);
791 set_receiver_count(row, 0);
792 }
793
794 // Code generation support
795 static ByteSize receiver_offset(uint row) {
796 return cell_offset(receiver_cell_index(row));
797 }
798 static ByteSize receiver_count_offset(uint row) {
799 return cell_offset(receiver_count_cell_index(row));
800 }
801 static ByteSize receiver_type_data_size() {
802 return cell_offset(static_cell_count());
803 }
804
805 // GC support
806 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);
807
808 #ifdef CC_INTERP
809 static int receiver_type_data_size_in_bytes() {
810 return cell_offset_in_bytes(static_cell_count());
811 }
812
813 static Klass *receiver_unchecked(DataLayout* layout, uint row) {
814 oop recv = oop_at(layout, receiver_cell_index(row));
815 return (Klass *)recv;
816 }
817
818 static void increment_receiver_count_no_overflow(DataLayout* layout, Klass *rcvr) {
819 const int num_rows = row_limit();
820 // Receiver already exists?
821 for (int row = 0; row < num_rows; row++) {
822 if (receiver_unchecked(layout, row) == rcvr) {
823 increment_uint_at_no_overflow(layout, receiver_count_cell_index(row));
824 return;
825 }
826 }
827 // New receiver, find a free slot.
828 for (int row = 0; row < num_rows; row++) {
829 if (receiver_unchecked(layout, row) == NULL) {
830 set_intptr_at(layout, receiver_cell_index(row), (intptr_t)rcvr);
831 increment_uint_at_no_overflow(layout, receiver_count_cell_index(row));
832 return;
833 }
834 }
835 // Receiver did not match any saved receiver and there is no empty row for it.
836 // Increment total counter to indicate polymorphic case.
837 increment_count_no_overflow(layout);
838 }
839
840 static DataLayout* advance(DataLayout* layout) {
841 return (DataLayout*) (((address)layout) + (ssize_t)ReceiverTypeData::receiver_type_data_size_in_bytes());
842 }
843 #endif // CC_INTERP
844
845 #ifndef PRODUCT
846 void print_receiver_data_on(outputStream* st);
847 void print_data_on(outputStream* st);
848 #endif
849 };
850
851 // VirtualCallData
852 //
853 // A VirtualCallData is used to access profiling information about a
854 // virtual call. For now, it has nothing more than a ReceiverTypeData.
855 class VirtualCallData : public ReceiverTypeData {
856 public:
857 VirtualCallData(DataLayout* layout) : ReceiverTypeData(layout) {
858 assert(layout->tag() == DataLayout::virtual_call_data_tag, "wrong type");
859 }
860
861 virtual bool is_VirtualCallData() { return true; }
862
863 static int static_cell_count() {
864 // At this point we could add more profile state, e.g., for arguments.
865 // But for now it's the same size as the base record type.
866 return ReceiverTypeData::static_cell_count();
867 }
868
869 virtual int cell_count() {
870 return static_cell_count();
871 }
872
873 // Direct accessors
874 static ByteSize virtual_call_data_size() {
875 return cell_offset(static_cell_count());
876 }
877
878 #ifdef CC_INTERP
879 static int virtual_call_data_size_in_bytes() {
880 return cell_offset_in_bytes(static_cell_count());
881 }
882
883 static DataLayout* advance(DataLayout* layout) {
884 return (DataLayout*) (((address)layout) + (ssize_t)VirtualCallData::virtual_call_data_size_in_bytes());
885 }
886 #endif // CC_INTERP
887
888 #ifndef PRODUCT
889 void print_data_on(outputStream* st);
890 #endif
891 };
892
893 // RetData
894 //
895 // A RetData is used to access profiling information for a ret bytecode.
896 // It is composed of a count of the number of times that the ret has
897 // been executed, followed by a series of triples of the form
898 // (bci, count, di) which count the number of times that some bci was the
899 // target of the ret and cache a corresponding data displacement.
900 class RetData : public CounterData {
901 protected:
902 enum {
903 bci0_offset = counter_cell_count,
904 count0_offset,
905 displacement0_offset,
906 ret_row_cell_count = (displacement0_offset + 1) - bci0_offset
907 };
964 return uint_at(bci_count_cell_index(row));
965 }
966 int bci_displacement(uint row) {
967 return int_at(bci_displacement_cell_index(row));
968 }
969
970 // Interpreter Runtime support
971 address fixup_ret(int return_bci, MethodData* mdo);
972
973 // Code generation support
974 static ByteSize bci_offset(uint row) {
975 return cell_offset(bci_cell_index(row));
976 }
977 static ByteSize bci_count_offset(uint row) {
978 return cell_offset(bci_count_cell_index(row));
979 }
980 static ByteSize bci_displacement_offset(uint row) {
981 return cell_offset(bci_displacement_cell_index(row));
982 }
983
984 #ifdef CC_INTERP
985 static DataLayout* advance(MethodData *md, int bci);
986 #endif // CC_INTERP
987
988 // Specific initialization.
989 void post_initialize(BytecodeStream* stream, MethodData* mdo);
990
991 #ifndef PRODUCT
992 void print_data_on(outputStream* st);
993 #endif
994 };
995
996 // BranchData
997 //
998 // A BranchData is used to access profiling data for a two-way branch.
999 // It consists of taken and not_taken counts as well as a data displacement
1000 // for the taken case.
1001 class BranchData : public JumpData {
1002 protected:
1003 enum {
1004 not_taken_off_set = jump_cell_count,
1005 branch_cell_count
1006 };
1007
1032 void set_not_taken(uint cnt) {
1033 set_uint_at(not_taken_off_set, cnt);
1034 }
1035
1036 uint inc_not_taken() {
1037 uint cnt = not_taken() + 1;
1038 // Did we wrap? Will compiler screw us??
1039 if (cnt == 0) cnt--;
1040 set_uint_at(not_taken_off_set, cnt);
1041 return cnt;
1042 }
1043
1044 // Code generation support
1045 static ByteSize not_taken_offset() {
1046 return cell_offset(not_taken_off_set);
1047 }
1048 static ByteSize branch_data_size() {
1049 return cell_offset(branch_cell_count);
1050 }
1051
1052 #ifdef CC_INTERP
1053 static int branch_data_size_in_bytes() {
1054 return cell_offset_in_bytes(branch_cell_count);
1055 }
1056
1057 static void increment_not_taken_count_no_overflow(DataLayout* layout) {
1058 increment_uint_at_no_overflow(layout, not_taken_off_set);
1059 }
1060
1061 static DataLayout* advance_not_taken(DataLayout* layout) {
1062 return (DataLayout*) (((address)layout) + (ssize_t)BranchData::branch_data_size_in_bytes());
1063 }
1064 #endif // CC_INTERP
1065
1066 // Specific initialization.
1067 void post_initialize(BytecodeStream* stream, MethodData* mdo);
1068
1069 #ifndef PRODUCT
1070 void print_data_on(outputStream* st);
1071 #endif
1072 };
1073
1074 // ArrayData
1075 //
1076 // A ArrayData is a base class for accessing profiling data which does
1077 // not have a statically known size. It consists of an array length
1078 // and an array start.
1079 class ArrayData : public ProfileData {
1080 protected:
1081 friend class DataLayout;
1082
1083 enum {
1084 array_len_off_set,
1085 array_start_off_set
1086 };
1087
1088 uint array_uint_at(int index) {
1089 int aindex = index + array_start_off_set;
1090 return uint_at(aindex);
1091 }
1092 int array_int_at(int index) {
1093 int aindex = index + array_start_off_set;
1094 return int_at(aindex);
1095 }
1096 oop array_oop_at(int index) {
1097 int aindex = index + array_start_off_set;
1098 return oop_at(aindex);
1099 }
1100 void array_set_int_at(int index, int value) {
1101 int aindex = index + array_start_off_set;
1102 set_int_at(aindex, value);
1103 }
1104
1105 #ifdef CC_INTERP
1106 // Static low level accessors for DataLayout with ArrayData's semantics.
1107
1108 static void increment_array_uint_at_no_overflow(DataLayout* layout, int index) {
1109 int aindex = index + array_start_off_set;
1110 increment_uint_at_no_overflow(layout, aindex);
1111 }
1112
1113 static int array_int_at(DataLayout* layout, int index) {
1114 int aindex = index + array_start_off_set;
1115 return int_at(layout, aindex);
1116 }
1117 #endif // CC_INTERP
1118
1119 // Code generation support for subclasses.
1120 static ByteSize array_element_offset(int index) {
1121 return cell_offset(array_start_off_set + index);
1122 }
1123
1124 public:
1125 ArrayData(DataLayout* layout) : ProfileData(layout) {}
1126
1127 virtual bool is_ArrayData() { return true; }
1128
1129 static int static_cell_count() {
1130 return -1;
1131 }
1132
1133 int array_len() {
1134 return int_at_unchecked(array_len_off_set);
1135 }
1136
1137 virtual int cell_count() {
1138 return array_len() + 1;
1217 return array_element_offset(default_disaplacement_off_set);
1218 }
1219 static ByteSize case_count_offset(int index) {
1220 return case_array_offset() +
1221 (per_case_size() * index) +
1222 relative_count_offset();
1223 }
1224 static ByteSize case_array_offset() {
1225 return array_element_offset(case_array_start);
1226 }
1227 static ByteSize per_case_size() {
1228 return in_ByteSize(per_case_cell_count) * cell_size;
1229 }
1230 static ByteSize relative_count_offset() {
1231 return in_ByteSize(relative_count_off_set) * cell_size;
1232 }
1233 static ByteSize relative_displacement_offset() {
1234 return in_ByteSize(relative_displacement_off_set) * cell_size;
1235 }
1236
1237 #ifdef CC_INTERP
1238 static void increment_count_no_overflow(DataLayout* layout, int index) {
1239 if (index == -1) {
1240 increment_array_uint_at_no_overflow(layout, default_count_off_set);
1241 } else {
1242 increment_array_uint_at_no_overflow(layout, case_array_start +
1243 index * per_case_cell_count +
1244 relative_count_off_set);
1245 }
1246 }
1247
1248 static DataLayout* advance(DataLayout* layout, int index) {
1249 if (index == -1) {
1250 return (DataLayout*) (((address)layout) + (ssize_t)array_int_at(layout, default_disaplacement_off_set));
1251 } else {
1252 return (DataLayout*) (((address)layout) + (ssize_t)array_int_at(layout, case_array_start +
1253 index * per_case_cell_count +
1254 relative_displacement_off_set));
1255 }
1256 }
1257 #endif // CC_INTERP
1258
1259 // Specific initialization.
1260 void post_initialize(BytecodeStream* stream, MethodData* mdo);
1261
1262 #ifndef PRODUCT
1263 void print_data_on(outputStream* st);
1264 #endif
1265 };
1266
1267 class ArgInfoData : public ArrayData {
1268
1269 public:
1270 ArgInfoData(DataLayout* layout) : ArrayData(layout) {
1271 assert(layout->tag() == DataLayout::arg_info_data_tag, "wrong type");
1272 }
1273
1274 virtual bool is_ArgInfoData() { return true; }
1275
1276
1277 int number_of_args() {
1278 return array_len();
1317 // method. The entries in the array are sorted by the corresponding
1318 // bytecode. Access to the data is via resource-allocated ProfileData,
1319 // which point to the underlying blocks of DataLayout structures.
1320 //
1321 // During interpretation, if profiling in enabled, the interpreter
1322 // maintains a method data pointer (mdp), which points at the entry
1323 // in the array corresponding to the current bci. In the course of
1324 // intepretation, when a bytecode is encountered that has profile data
1325 // associated with it, the entry pointed to by mdp is updated, then the
1326 // mdp is adjusted to point to the next appropriate DataLayout. If mdp
1327 // is NULL to begin with, the interpreter assumes that the current method
1328 // is not (yet) being profiled.
1329 //
1330 // In MethodData* parlance, "dp" is a "data pointer", the actual address
1331 // of a DataLayout element. A "di" is a "data index", the offset in bytes
1332 // from the base of the data entry array. A "displacement" is the byte offset
1333 // in certain ProfileData objects that indicate the amount the mdp must be
1334 // adjusted in the event of a change in control flow.
1335 //
1336
1337 CC_INTERP_ONLY(class BytecodeInterpreter;)
1338
1339 class MethodData : public Metadata {
1340 friend class VMStructs;
1341 CC_INTERP_ONLY(friend class BytecodeInterpreter;)
1342 private:
1343 friend class ProfileData;
1344
1345 // Back pointer to the Method*
1346 Method* _method;
1347
1348 // Size of this oop in bytes
1349 int _size;
1350
1351 // Cached hint for bci_to_dp and bci_to_data
1352 int _hint_di;
1353
1354 MethodData(methodHandle method, int size, TRAPS);
1355 public:
1356 static MethodData* allocate(ClassLoaderData* loader_data, methodHandle method, TRAPS);
1357 MethodData() {}; // For ciMethodData
1358
1359 bool is_methodData() const volatile { return true; }
1360
1361 // Whole-method sticky bits and flags
|