7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "ci/ciMetadata.hpp"
26 #include "ci/ciMethodData.hpp"
27 #include "ci/ciReplay.hpp"
28 #include "ci/ciUtilities.inline.hpp"
29 #include "compiler/compiler_globals.hpp"
30 #include "memory/allocation.inline.hpp"
31 #include "memory/resourceArea.hpp"
32 #include "oops/klass.inline.hpp"
33 #include "oops/methodData.inline.hpp"
34 #include "oops/trainingData.hpp"
35 #include "runtime/deoptimization.hpp"
36 #include "utilities/copy.hpp"
37
38 // ciMethodData
39
40 // ------------------------------------------------------------------
41 // ciMethodData::ciMethodData
42 //
43 ciMethodData::ciMethodData(MethodData* md)
44 : ciMetadata(md),
45 _data_size(0), _extra_data_size(0), _data(nullptr),
46 _parameters_data_offset(0),
320 }
321 } else {
322 set_receiver(row, nullptr);
323 }
324 }
325 }
326
327 void ciTypeStackSlotEntries::translate_type_data_from(const TypeStackSlotEntries* entries) {
328 for (int i = 0; i < number_of_entries(); i++) {
329 intptr_t k = entries->type(i);
330 Klass* klass = (Klass*)klass_part(k);
331 if (klass == nullptr || !klass->is_loader_present_and_alive() || !is_klass_loaded(klass)) {
332 // With concurrent class unloading, the MDO could have stale metadata; override it
333 TypeStackSlotEntries::set_type(i, TypeStackSlotEntries::with_status((Klass*)nullptr, k));
334 } else {
335 TypeStackSlotEntries::set_type(i, translate_klass(k));
336 }
337 }
338 }
339
340 void ciReturnTypeEntry::translate_type_data_from(const ReturnTypeEntry* ret) {
341 intptr_t k = ret->type();
342 Klass* klass = (Klass*)klass_part(k);
343 if (klass == nullptr || !klass->is_loader_present_and_alive() || !is_klass_loaded(klass)) {
344 // With concurrent class unloading, the MDO could have stale metadata; override it
345 set_type(ReturnTypeEntry::with_status((Klass*)nullptr, k));
346 } else {
347 set_type(translate_klass(k));
348 }
349 }
350
351 void ciSpeculativeTrapData::translate_from(const ProfileData* data) {
352 Method* m = data->as_SpeculativeTrapData()->method();
353 ciMethod* ci_m = CURRENT_ENV->get_method(m);
354 set_method(ci_m);
355 }
356
357 // Get the data at an arbitrary (sort of) data index.
358 ciProfileData* ciMethodData::data_at(int data_index) {
359 if (out_of_bounds(data_index)) {
360 return nullptr;
361 }
362 DataLayout* data_layout = data_layout_at(data_index);
363 return data_from(data_layout);
364 }
365
376 case DataLayout::jump_data_tag:
377 return new ciJumpData(data_layout);
378 case DataLayout::receiver_type_data_tag:
379 return new ciReceiverTypeData(data_layout);
380 case DataLayout::virtual_call_data_tag:
381 return new ciVirtualCallData(data_layout);
382 case DataLayout::ret_data_tag:
383 return new ciRetData(data_layout);
384 case DataLayout::branch_data_tag:
385 return new ciBranchData(data_layout);
386 case DataLayout::multi_branch_data_tag:
387 return new ciMultiBranchData(data_layout);
388 case DataLayout::arg_info_data_tag:
389 return new ciArgInfoData(data_layout);
390 case DataLayout::call_type_data_tag:
391 return new ciCallTypeData(data_layout);
392 case DataLayout::virtual_call_type_data_tag:
393 return new ciVirtualCallTypeData(data_layout);
394 case DataLayout::parameters_type_data_tag:
395 return new ciParametersTypeData(data_layout);
396 };
397 }
398
399 // Iteration over data.
400 ciProfileData* ciMethodData::next_data(ciProfileData* current) {
401 int current_index = dp_to_di(current->dp());
402 int next_index = current_index + current->size_in_bytes();
403 ciProfileData* next = data_at(next_index);
404 return next;
405 }
406
407 DataLayout* ciMethodData::next_data_layout_helper(DataLayout* current, bool extra) {
408 int current_index = dp_to_di((address)current);
409 int next_index = current_index + current->size_in_bytes();
410 if (extra ? out_of_bounds_extra(next_index) : out_of_bounds(next_index)) {
411 return nullptr;
412 }
413 DataLayout* next = data_layout_at(next_index);
414 return next;
415 }
698 DataLayout* dp = extra_data_base();
699 DataLayout* end = args_data_limit();
700 for (; dp < end; dp = MethodData::next_extra(dp)) {
701 if (dp->tag() == DataLayout::arg_info_data_tag)
702 return new ciArgInfoData(dp);
703 }
704 return nullptr;
705 }
706
707
708 // Implementation of the print method.
709 void ciMethodData::print_impl(outputStream* st) {
710 ciMetadata::print_impl(st);
711 }
712
713 void ciMethodData::dump_replay_data_type_helper(outputStream* out, int round, int& count, ProfileData* pdata, ByteSize offset, ciKlass* k) {
714 if (k != nullptr) {
715 if (round == 0) {
716 count++;
717 } else {
718 out->print(" %d %s", (int)(dp_to_di(pdata->dp() + in_bytes(offset)) / sizeof(intptr_t)),
719 CURRENT_ENV->replay_name(k));
720 }
721 }
722 }
723
724 template<class T> void ciMethodData::dump_replay_data_receiver_type_helper(outputStream* out, int round, int& count, T* vdata) {
725 for (uint i = 0; i < vdata->row_limit(); i++) {
726 dump_replay_data_type_helper(out, round, count, vdata, vdata->receiver_offset(i), vdata->receiver(i));
727 }
728 }
729
730 template<class T> void ciMethodData::dump_replay_data_call_type_helper(outputStream* out, int round, int& count, T* call_type_data) {
731 if (call_type_data->has_arguments()) {
732 for (int i = 0; i < call_type_data->number_of_arguments(); i++) {
733 dump_replay_data_type_helper(out, round, count, call_type_data, call_type_data->argument_type_offset(i), call_type_data->valid_argument_type(i));
734 }
735 }
736 if (call_type_data->has_return()) {
737 dump_replay_data_type_helper(out, round, count, call_type_data, call_type_data->return_type_offset(), call_type_data->valid_return_type());
738 }
739 }
793 // harder. data()'s element type is intptr_t.
794 out->print(" 0x%zx", data()[i]);
795 }
796
797 // The MDO contained oop references as ciObjects, so scan for those
798 // and emit pairs of offset and klass name so that they can be
799 // reconstructed at runtime. The first round counts the number of
800 // oop references and the second actually emits them.
801 ciParametersTypeData* parameters = parameters_type_data();
802 for (int count = 0, round = 0; round < 2; round++) {
803 if (round == 1) out->print(" oops %d", count);
804 ProfileData* pdata = first_data();
805 for ( ; is_valid(pdata); pdata = next_data(pdata)) {
806 if (pdata->is_VirtualCallData()) {
807 ciVirtualCallData* vdata = (ciVirtualCallData*)pdata;
808 dump_replay_data_receiver_type_helper<ciVirtualCallData>(out, round, count, vdata);
809 if (pdata->is_VirtualCallTypeData()) {
810 ciVirtualCallTypeData* call_type_data = (ciVirtualCallTypeData*)pdata;
811 dump_replay_data_call_type_helper<ciVirtualCallTypeData>(out, round, count, call_type_data);
812 }
813 } else if (pdata->is_ReceiverTypeData()) {
814 ciReceiverTypeData* vdata = (ciReceiverTypeData*)pdata;
815 dump_replay_data_receiver_type_helper<ciReceiverTypeData>(out, round, count, vdata);
816 } else if (pdata->is_CallTypeData()) {
817 ciCallTypeData* call_type_data = (ciCallTypeData*)pdata;
818 dump_replay_data_call_type_helper<ciCallTypeData>(out, round, count, call_type_data);
819 }
820 }
821 if (parameters != nullptr) {
822 for (int i = 0; i < parameters->number_of_parameters(); i++) {
823 dump_replay_data_type_helper(out, round, count, parameters, ParametersTypeData::type_offset(i), parameters->valid_parameter_type(i));
824 }
825 }
826 }
827 for (int count = 0, round = 0; round < 2; round++) {
828 if (round == 1) out->print(" methods %d", count);
829 dump_replay_data_extra_data_helper(out, round, count);
830 }
831 out->cr();
832 }
833
834 #ifndef PRODUCT
835 void ciMethodData::print() {
836 print_data_on(tty);
837 }
838
881 st->print("none");
882 } else if (TypeEntries::is_type_unknown(k)) {
883 st->print("unknown");
884 } else {
885 valid_ciklass(k)->print_name_on(st);
886 }
887 if (TypeEntries::was_null_seen(k)) {
888 st->print(" (null seen)");
889 }
890 }
891
892 void ciTypeStackSlotEntries::print_data_on(outputStream* st) const {
893 for (int i = 0; i < number_of_entries(); i++) {
894 _pd->tab(st);
895 st->print("%d: stack (%u) ", i, stack_slot(i));
896 print_ciklass(st, type(i));
897 st->cr();
898 }
899 }
900
901 void ciReturnTypeEntry::print_data_on(outputStream* st) const {
902 _pd->tab(st);
903 st->print("ret ");
904 print_ciklass(st, type());
905 st->cr();
906 }
907
908 void ciCallTypeData::print_data_on(outputStream* st, const char* extra) const {
909 print_shared(st, "ciCallTypeData", extra);
910 if (has_arguments()) {
911 tab(st, true);
912 st->print_cr("argument types");
913 args()->print_data_on(st);
914 }
915 if (has_return()) {
916 tab(st, true);
917 st->print_cr("return type");
918 ret()->print_data_on(st);
919 }
920 }
921
954 args()->print_data_on(st);
955 }
956 if (has_return()) {
957 tab(st, true);
958 st->print("return type");
959 ret()->print_data_on(st);
960 }
961 }
962
963 void ciParametersTypeData::print_data_on(outputStream* st, const char* extra) const {
964 st->print_cr("ciParametersTypeData");
965 parameters()->print_data_on(st);
966 }
967
968 void ciSpeculativeTrapData::print_data_on(outputStream* st, const char* extra) const {
969 st->print_cr("ciSpeculativeTrapData");
970 tab(st);
971 method()->print_short_name(st);
972 st->cr();
973 }
974 #endif
|
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "ci/ciMetadata.hpp"
26 #include "ci/ciMethodData.hpp"
27 #include "ci/ciObjArrayKlass.hpp"
28 #include "ci/ciReplay.hpp"
29 #include "ci/ciUtilities.inline.hpp"
30 #include "compiler/compiler_globals.hpp"
31 #include "memory/allocation.inline.hpp"
32 #include "memory/resourceArea.hpp"
33 #include "oops/klass.inline.hpp"
34 #include "oops/methodData.inline.hpp"
35 #include "oops/trainingData.hpp"
36 #include "runtime/deoptimization.hpp"
37 #include "utilities/copy.hpp"
38
39 // ciMethodData
40
41 // ------------------------------------------------------------------
42 // ciMethodData::ciMethodData
43 //
44 ciMethodData::ciMethodData(MethodData* md)
45 : ciMetadata(md),
46 _data_size(0), _extra_data_size(0), _data(nullptr),
47 _parameters_data_offset(0),
321 }
322 } else {
323 set_receiver(row, nullptr);
324 }
325 }
326 }
327
328 void ciTypeStackSlotEntries::translate_type_data_from(const TypeStackSlotEntries* entries) {
329 for (int i = 0; i < number_of_entries(); i++) {
330 intptr_t k = entries->type(i);
331 Klass* klass = (Klass*)klass_part(k);
332 if (klass == nullptr || !klass->is_loader_present_and_alive() || !is_klass_loaded(klass)) {
333 // With concurrent class unloading, the MDO could have stale metadata; override it
334 TypeStackSlotEntries::set_type(i, TypeStackSlotEntries::with_status((Klass*)nullptr, k));
335 } else {
336 TypeStackSlotEntries::set_type(i, translate_klass(k));
337 }
338 }
339 }
340
341 void ciSingleTypeEntry::translate_type_data_from(const SingleTypeEntry* ret) {
342 intptr_t k = ret->type();
343 Klass* klass = (Klass*)klass_part(k);
344 if (klass == nullptr || !klass->is_loader_present_and_alive() || !is_klass_loaded(klass)) {
345 // With concurrent class unloading, the MDO could have stale metadata; override it
346 set_type(SingleTypeEntry::with_status((Klass*)nullptr, k));
347 } else {
348 set_type(translate_klass(k));
349 }
350 }
351
352 void ciSpeculativeTrapData::translate_from(const ProfileData* data) {
353 Method* m = data->as_SpeculativeTrapData()->method();
354 ciMethod* ci_m = CURRENT_ENV->get_method(m);
355 set_method(ci_m);
356 }
357
358 // Get the data at an arbitrary (sort of) data index.
359 ciProfileData* ciMethodData::data_at(int data_index) {
360 if (out_of_bounds(data_index)) {
361 return nullptr;
362 }
363 DataLayout* data_layout = data_layout_at(data_index);
364 return data_from(data_layout);
365 }
366
377 case DataLayout::jump_data_tag:
378 return new ciJumpData(data_layout);
379 case DataLayout::receiver_type_data_tag:
380 return new ciReceiverTypeData(data_layout);
381 case DataLayout::virtual_call_data_tag:
382 return new ciVirtualCallData(data_layout);
383 case DataLayout::ret_data_tag:
384 return new ciRetData(data_layout);
385 case DataLayout::branch_data_tag:
386 return new ciBranchData(data_layout);
387 case DataLayout::multi_branch_data_tag:
388 return new ciMultiBranchData(data_layout);
389 case DataLayout::arg_info_data_tag:
390 return new ciArgInfoData(data_layout);
391 case DataLayout::call_type_data_tag:
392 return new ciCallTypeData(data_layout);
393 case DataLayout::virtual_call_type_data_tag:
394 return new ciVirtualCallTypeData(data_layout);
395 case DataLayout::parameters_type_data_tag:
396 return new ciParametersTypeData(data_layout);
397 case DataLayout::array_store_data_tag:
398 return new ciArrayStoreData(data_layout);
399 case DataLayout::array_load_data_tag:
400 return new ciArrayLoadData(data_layout);
401 case DataLayout::acmp_data_tag:
402 return new ciACmpData(data_layout);
403 };
404 }
405
406 // Iteration over data.
407 ciProfileData* ciMethodData::next_data(ciProfileData* current) {
408 int current_index = dp_to_di(current->dp());
409 int next_index = current_index + current->size_in_bytes();
410 ciProfileData* next = data_at(next_index);
411 return next;
412 }
413
414 DataLayout* ciMethodData::next_data_layout_helper(DataLayout* current, bool extra) {
415 int current_index = dp_to_di((address)current);
416 int next_index = current_index + current->size_in_bytes();
417 if (extra ? out_of_bounds_extra(next_index) : out_of_bounds(next_index)) {
418 return nullptr;
419 }
420 DataLayout* next = data_layout_at(next_index);
421 return next;
422 }
705 DataLayout* dp = extra_data_base();
706 DataLayout* end = args_data_limit();
707 for (; dp < end; dp = MethodData::next_extra(dp)) {
708 if (dp->tag() == DataLayout::arg_info_data_tag)
709 return new ciArgInfoData(dp);
710 }
711 return nullptr;
712 }
713
714
715 // Implementation of the print method.
716 void ciMethodData::print_impl(outputStream* st) {
717 ciMetadata::print_impl(st);
718 }
719
720 void ciMethodData::dump_replay_data_type_helper(outputStream* out, int round, int& count, ProfileData* pdata, ByteSize offset, ciKlass* k) {
721 if (k != nullptr) {
722 if (round == 0) {
723 count++;
724 } else {
725 if (Arguments::is_valhalla_enabled() && k->is_obj_array_klass()) {
726 // For value class arrays, we also record the array property to load the correct array class during replay.
727 ArrayKlass::ArrayProperties array_properties = k->as_obj_array_klass()->properties();
728 out->print(" %d %s %d", static_cast<int>(dp_to_di(pdata->dp() + in_bytes(offset)) / sizeof(intptr_t)),
729 CURRENT_ENV->replay_name(k), static_cast<int>(array_properties));
730 } else {
731 out->print(" %d %s", static_cast<int>(dp_to_di(pdata->dp() + in_bytes(offset)) / sizeof(intptr_t)),
732 CURRENT_ENV->replay_name(k));
733 }
734 }
735 }
736 }
737
738 template<class T> void ciMethodData::dump_replay_data_receiver_type_helper(outputStream* out, int round, int& count, T* vdata) {
739 for (uint i = 0; i < vdata->row_limit(); i++) {
740 dump_replay_data_type_helper(out, round, count, vdata, vdata->receiver_offset(i), vdata->receiver(i));
741 }
742 }
743
744 template<class T> void ciMethodData::dump_replay_data_call_type_helper(outputStream* out, int round, int& count, T* call_type_data) {
745 if (call_type_data->has_arguments()) {
746 for (int i = 0; i < call_type_data->number_of_arguments(); i++) {
747 dump_replay_data_type_helper(out, round, count, call_type_data, call_type_data->argument_type_offset(i), call_type_data->valid_argument_type(i));
748 }
749 }
750 if (call_type_data->has_return()) {
751 dump_replay_data_type_helper(out, round, count, call_type_data, call_type_data->return_type_offset(), call_type_data->valid_return_type());
752 }
753 }
807 // harder. data()'s element type is intptr_t.
808 out->print(" 0x%zx", data()[i]);
809 }
810
811 // The MDO contained oop references as ciObjects, so scan for those
812 // and emit pairs of offset and klass name so that they can be
813 // reconstructed at runtime. The first round counts the number of
814 // oop references and the second actually emits them.
815 ciParametersTypeData* parameters = parameters_type_data();
816 for (int count = 0, round = 0; round < 2; round++) {
817 if (round == 1) out->print(" oops %d", count);
818 ProfileData* pdata = first_data();
819 for ( ; is_valid(pdata); pdata = next_data(pdata)) {
820 if (pdata->is_VirtualCallData()) {
821 ciVirtualCallData* vdata = (ciVirtualCallData*)pdata;
822 dump_replay_data_receiver_type_helper<ciVirtualCallData>(out, round, count, vdata);
823 if (pdata->is_VirtualCallTypeData()) {
824 ciVirtualCallTypeData* call_type_data = (ciVirtualCallTypeData*)pdata;
825 dump_replay_data_call_type_helper<ciVirtualCallTypeData>(out, round, count, call_type_data);
826 }
827 } else if (pdata->is_CallTypeData()) {
828 ciCallTypeData* call_type_data = (ciCallTypeData*)pdata;
829 dump_replay_data_call_type_helper<ciCallTypeData>(out, round, count, call_type_data);
830 } else if (pdata->is_ArrayStoreData()) {
831 ciArrayStoreData* array_store_data = (ciArrayStoreData*)pdata;
832 dump_replay_data_type_helper(out, round, count, array_store_data, ciArrayStoreData::array_offset(),
833 array_store_data->array()->valid_type());
834 dump_replay_data_receiver_type_helper<ciArrayStoreData>(out, round, count, array_store_data);
835 } else if (pdata->is_ArrayLoadData()) {
836 ciArrayLoadData* array_load_data = (ciArrayLoadData*)pdata;
837 dump_replay_data_type_helper(out, round, count, array_load_data, ciArrayLoadData::array_offset(),
838 array_load_data->array()->valid_type());
839 dump_replay_data_type_helper(out, round, count, array_load_data, ciArrayLoadData::element_offset(),
840 array_load_data->element()->valid_type());
841 } else if (pdata->is_ACmpData()) {
842 ciACmpData* acmp_data = (ciACmpData*)pdata;
843 dump_replay_data_type_helper(out, round, count, acmp_data, ciACmpData::left_offset(),
844 acmp_data->left()->valid_type());
845 dump_replay_data_type_helper(out, round, count, acmp_data, ciACmpData::right_offset(),
846 acmp_data->right()->valid_type());
847 } else if (pdata->is_ReceiverTypeData()) {
848 ciReceiverTypeData* vdata = (ciReceiverTypeData*)pdata;
849 dump_replay_data_receiver_type_helper<ciReceiverTypeData>(out, round, count, vdata);
850 }
851 }
852 if (parameters != nullptr) {
853 for (int i = 0; i < parameters->number_of_parameters(); i++) {
854 dump_replay_data_type_helper(out, round, count, parameters, ParametersTypeData::type_offset(i), parameters->valid_parameter_type(i));
855 }
856 }
857 }
858 for (int count = 0, round = 0; round < 2; round++) {
859 if (round == 1) out->print(" methods %d", count);
860 dump_replay_data_extra_data_helper(out, round, count);
861 }
862 out->cr();
863 }
864
865 #ifndef PRODUCT
866 void ciMethodData::print() {
867 print_data_on(tty);
868 }
869
912 st->print("none");
913 } else if (TypeEntries::is_type_unknown(k)) {
914 st->print("unknown");
915 } else {
916 valid_ciklass(k)->print_name_on(st);
917 }
918 if (TypeEntries::was_null_seen(k)) {
919 st->print(" (null seen)");
920 }
921 }
922
923 void ciTypeStackSlotEntries::print_data_on(outputStream* st) const {
924 for (int i = 0; i < number_of_entries(); i++) {
925 _pd->tab(st);
926 st->print("%d: stack (%u) ", i, stack_slot(i));
927 print_ciklass(st, type(i));
928 st->cr();
929 }
930 }
931
932 void ciSingleTypeEntry::print_data_on(outputStream* st) const {
933 _pd->tab(st);
934 st->print("ret ");
935 print_ciklass(st, type());
936 st->cr();
937 }
938
939 void ciCallTypeData::print_data_on(outputStream* st, const char* extra) const {
940 print_shared(st, "ciCallTypeData", extra);
941 if (has_arguments()) {
942 tab(st, true);
943 st->print_cr("argument types");
944 args()->print_data_on(st);
945 }
946 if (has_return()) {
947 tab(st, true);
948 st->print_cr("return type");
949 ret()->print_data_on(st);
950 }
951 }
952
985 args()->print_data_on(st);
986 }
987 if (has_return()) {
988 tab(st, true);
989 st->print("return type");
990 ret()->print_data_on(st);
991 }
992 }
993
994 void ciParametersTypeData::print_data_on(outputStream* st, const char* extra) const {
995 st->print_cr("ciParametersTypeData");
996 parameters()->print_data_on(st);
997 }
998
999 void ciSpeculativeTrapData::print_data_on(outputStream* st, const char* extra) const {
1000 st->print_cr("ciSpeculativeTrapData");
1001 tab(st);
1002 method()->print_short_name(st);
1003 st->cr();
1004 }
1005
1006 void ciArrayStoreData::print_data_on(outputStream* st, const char* extra) const {
1007 print_shared(st, "ciArrayStoreData", extra);
1008 st->cr();
1009 tab(st, true);
1010 st->print("array");
1011 array()->print_data_on(st);
1012 tab(st, true);
1013 st->print("element");
1014 rtd_super()->print_receiver_data_on(st);
1015 }
1016
1017 void ciArrayLoadData::print_data_on(outputStream* st, const char* extra) const {
1018 print_shared(st, "ciArrayLoadData", extra);
1019 st->cr();
1020 tab(st, true);
1021 st->print("array");
1022 array()->print_data_on(st);
1023 tab(st, true);
1024 st->print("element");
1025 element()->print_data_on(st);
1026 }
1027
1028 void ciACmpData::print_data_on(outputStream* st, const char* extra) const {
1029 BranchData::print_data_on(st, extra);
1030 st->cr();
1031 tab(st, true);
1032 st->print("left");
1033 left()->print_data_on(st);
1034 tab(st, true);
1035 st->print("right");
1036 right()->print_data_on(st);
1037 }
1038 #endif
|