diff src/share/vm/ci/ciMethodData.cpp @ 12875:d13d7aba8c12

8023657: New type profiling points: arguments to call Summary: x86 interpreter and c1 type profiling for arguments at calls Reviewed-by: kvn, twisti
author roland
date Wed, 09 Oct 2013 16:32:21 +0200
parents c775af091fe9
children ce0cc25bc5e2
line wrap: on
line diff
--- a/src/share/vm/ci/ciMethodData.cpp	Wed Oct 09 11:05:17 2013 -0700
+++ b/src/share/vm/ci/ciMethodData.cpp	Wed Oct 09 16:32:21 2013 +0200
@@ -125,7 +125,7 @@
 #endif
 }
 
-void ciReceiverTypeData::translate_receiver_data_from(ProfileData* data) {
+void ciReceiverTypeData::translate_receiver_data_from(const ProfileData* data) {
   for (uint row = 0; row < row_limit(); row++) {
     Klass* k = data->as_ReceiverTypeData()->receiver(row);
     if (k != NULL) {
@@ -136,6 +136,13 @@
 }
 
 
+void ciTypeStackSlotEntries::translate_type_data_from(const TypeStackSlotEntries* entries) {
+  for (int i = 0; i < number_of_arguments(); i++) {
+    intptr_t k = entries->type(i);
+    TypeStackSlotEntries::set_type(i, translate_klass(k));
+  }
+}
+
 // Get the data at an arbitrary (sort of) data index.
 ciProfileData* ciMethodData::data_at(int data_index) {
   if (out_of_bounds(data_index)) {
@@ -166,6 +173,10 @@
     return new ciMultiBranchData(data_layout);
   case DataLayout::arg_info_data_tag:
     return new ciArgInfoData(data_layout);
+  case DataLayout::call_type_data_tag:
+    return new ciCallTypeData(data_layout);
+  case DataLayout::virtual_call_type_data_tag:
+    return new ciVirtualCallTypeData(data_layout);
   };
 }
 
@@ -288,6 +299,20 @@
   }
 }
 
+void ciMethodData::set_argument_type(int bci, int i, ciKlass* k) {
+  VM_ENTRY_MARK;
+  MethodData* mdo = get_MethodData();
+  if (mdo != NULL) {
+    ProfileData* data = mdo->bci_to_data(bci);
+    if (data->is_CallTypeData()) {
+      data->as_CallTypeData()->set_argument_type(i, k->get_Klass());
+    } else {
+      assert(data->is_VirtualCallTypeData(), "no arguments!");
+      data->as_VirtualCallTypeData()->set_argument_type(i, k->get_Klass());
+    }
+  }
+}
+
 bool ciMethodData::has_escape_info() {
   return eflag_set(MethodData::estimated);
 }
@@ -478,7 +503,36 @@
   }
 }
 
-void ciReceiverTypeData::print_receiver_data_on(outputStream* st) {
+void ciTypeEntries::print_ciklass(outputStream* st, intptr_t k) {
+  if (TypeEntries::is_type_none(k)) {
+    st->print("none");
+  } else if (TypeEntries::is_type_unknown(k)) {
+    st->print("unknown");
+  } else {
+    valid_ciklass(k)->print_name_on(st);
+  }
+  if (TypeEntries::was_null_seen(k)) {
+    st->print(" (null seen)");
+  }
+}
+
+void ciTypeStackSlotEntries::print_data_on(outputStream* st) const {
+  _pd->tab(st, true);
+  st->print("argument types");
+  for (int i = 0; i < number_of_arguments(); i++) {
+    _pd->tab(st);
+    st->print("%d: stack (%u) ", i, stack_slot(i));
+    print_ciklass(st, type(i));
+    st->cr();
+  }
+}
+
+void ciCallTypeData::print_data_on(outputStream* st) const {
+  print_shared(st, "ciCallTypeData");
+  args()->print_data_on(st);
+}
+
+void ciReceiverTypeData::print_receiver_data_on(outputStream* st) const {
   uint row;
   int entries = 0;
   for (row = 0; row < row_limit(); row++) {
@@ -494,13 +548,19 @@
   }
 }
 
-void ciReceiverTypeData::print_data_on(outputStream* st) {
+void ciReceiverTypeData::print_data_on(outputStream* st) const {
   print_shared(st, "ciReceiverTypeData");
   print_receiver_data_on(st);
 }
 
-void ciVirtualCallData::print_data_on(outputStream* st) {
+void ciVirtualCallData::print_data_on(outputStream* st) const {
   print_shared(st, "ciVirtualCallData");
   rtd_super()->print_receiver_data_on(st);
 }
+
+void ciVirtualCallTypeData::print_data_on(outputStream* st) const {
+  print_shared(st, "ciVirtualCallTypeData");
+  rtd_super()->print_receiver_data_on(st);
+  args()->print_data_on(st);
+}
 #endif