src/share/vm/ci/ciMethodData.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/ci

src/share/vm/ci/ciMethodData.cpp

Print this page
rev 5411 : 8026251: New type profiling points: parameters to methods
Summary: x86 interpreter and c1 type profiling for parameters on method entries
Reviewed-by:


  36 
  37 // ------------------------------------------------------------------
  38 // ciMethodData::ciMethodData
  39 //
  40 ciMethodData::ciMethodData(MethodData* md) : ciMetadata(md) {
  41   assert(md != NULL, "no null method data");
  42   Copy::zero_to_words((HeapWord*) &_orig, sizeof(_orig) / sizeof(HeapWord));
  43   _data = NULL;
  44   _data_size = 0;
  45   _extra_data_size = 0;
  46   _current_mileage = 0;
  47   _invocation_counter = 0;
  48   _backedge_counter = 0;
  49   _state = empty_state;
  50   _saw_free_extra_data = false;
  51   // Set an initial hint. Don't use set_hint_di() because
  52   // first_di() may be out of bounds if data_size is 0.
  53   _hint_di = first_di();
  54   // Initialize the escape information (to "don't know.");
  55   _eflags = _arg_local = _arg_stack = _arg_returned = 0;

  56 }
  57 
  58 // ------------------------------------------------------------------
  59 // ciMethodData::ciMethodData
  60 //
  61 // No MethodData*.
  62 ciMethodData::ciMethodData() : ciMetadata(NULL) {
  63   Copy::zero_to_words((HeapWord*) &_orig, sizeof(_orig) / sizeof(HeapWord));
  64   _data = NULL;
  65   _data_size = 0;
  66   _extra_data_size = 0;
  67   _current_mileage = 0;
  68   _invocation_counter = 0;
  69   _backedge_counter = 0;
  70   _state = empty_state;
  71   _saw_free_extra_data = false;
  72   // Set an initial hint. Don't use set_hint_di() because
  73   // first_di() may be out of bounds if data_size is 0.
  74   _hint_di = first_di();
  75   // Initialize the escape information (to "don't know.");
  76   _eflags = _arg_local = _arg_stack = _arg_returned = 0;

  77 }
  78 
  79 void ciMethodData::load_data() {
  80   MethodData* mdo = get_MethodData();
  81   if (mdo == NULL) {
  82     return;
  83   }
  84 
  85   // To do: don't copy the data if it is not "ripe" -- require a minimum #
  86   // of invocations.
  87 
  88   // Snapshot the data -- actually, take an approximate snapshot of
  89   // the data.  Any concurrently executing threads may be changing the
  90   // data as we copy it.
  91   Copy::disjoint_words((HeapWord*) mdo,
  92                        (HeapWord*) &_orig,
  93                        sizeof(_orig) / HeapWordSize);
  94   Arena* arena = CURRENT_ENV->arena();
  95   _data_size = mdo->data_size();
  96   _extra_data_size = mdo->extra_data_size();
  97   int total_size = _data_size + _extra_data_size;
  98   _data = (intptr_t *) arena->Amalloc(total_size);
  99   Copy::disjoint_words((HeapWord*) mdo->data_base(), (HeapWord*) _data, total_size / HeapWordSize);
 100 
 101   // Traverse the profile data, translating any oops into their
 102   // ci equivalents.
 103   ResourceMark rm;
 104   ciProfileData* ci_data = first_data();
 105   ProfileData* data = mdo->first_data();
 106   while (is_valid(ci_data)) {
 107     ci_data->translate_from(data);
 108     ci_data = next_data(ci_data);
 109     data = mdo->next_data(data);
 110   }






 111   // Note:  Extra data are all BitData, and do not need translation.
 112   _current_mileage = MethodData::mileage_of(mdo->method());
 113   _invocation_counter = mdo->invocation_count();
 114   _backedge_counter = mdo->backedge_count();
 115   _state = mdo->is_mature()? mature_state: immature_state;
 116 
 117   _eflags = mdo->eflags();
 118   _arg_local = mdo->arg_local();
 119   _arg_stack = mdo->arg_stack();
 120   _arg_returned  = mdo->arg_returned();
 121 #ifndef PRODUCT
 122   if (ReplayCompiles) {
 123     ciReplay::initialize(this);
 124   }
 125 #endif
 126 }
 127 
 128 void ciReceiverTypeData::translate_receiver_data_from(const ProfileData* data) {
 129   for (uint row = 0; row < row_limit(); row++) {
 130     Klass* k = data->as_ReceiverTypeData()->receiver(row);


 165   case DataLayout::counter_data_tag:
 166     return new ciCounterData(data_layout);
 167   case DataLayout::jump_data_tag:
 168     return new ciJumpData(data_layout);
 169   case DataLayout::receiver_type_data_tag:
 170     return new ciReceiverTypeData(data_layout);
 171   case DataLayout::virtual_call_data_tag:
 172     return new ciVirtualCallData(data_layout);
 173   case DataLayout::ret_data_tag:
 174     return new ciRetData(data_layout);
 175   case DataLayout::branch_data_tag:
 176     return new ciBranchData(data_layout);
 177   case DataLayout::multi_branch_data_tag:
 178     return new ciMultiBranchData(data_layout);
 179   case DataLayout::arg_info_data_tag:
 180     return new ciArgInfoData(data_layout);
 181   case DataLayout::call_type_data_tag:
 182     return new ciCallTypeData(data_layout);
 183   case DataLayout::virtual_call_type_data_tag:
 184     return new ciVirtualCallTypeData(data_layout);


 185   };
 186 }
 187 
 188 // Iteration over data.
 189 ciProfileData* ciMethodData::next_data(ciProfileData* current) {
 190   int current_index = dp_to_di(current->dp());
 191   int next_index = current_index + current->size_in_bytes();
 192   ciProfileData* next = data_at(next_index);
 193   return next;
 194 }
 195 
 196 // Translate a bci to its corresponding data, or NULL.
 197 ciProfileData* ciMethodData::bci_to_data(int bci) {
 198   ciProfileData* data = data_before(bci);
 199   for ( ; is_valid(data); data = next_data(data)) {
 200     if (data->bci() == bci) {
 201       set_hint_di(dp_to_di(data->dp()));
 202       return data;
 203     } else if (data->bci() > bci) {
 204       break;


 301   MethodData* mdo = get_MethodData();
 302   if (mdo != NULL) {
 303     mdo->set_would_profile(p);
 304   }
 305 }
 306 
 307 void ciMethodData::set_argument_type(int bci, int i, ciKlass* k) {
 308   VM_ENTRY_MARK;
 309   MethodData* mdo = get_MethodData();
 310   if (mdo != NULL) {
 311     ProfileData* data = mdo->bci_to_data(bci);
 312     if (data->is_CallTypeData()) {
 313       data->as_CallTypeData()->set_argument_type(i, k->get_Klass());
 314     } else {
 315       assert(data->is_VirtualCallTypeData(), "no arguments!");
 316       data->as_VirtualCallTypeData()->set_argument_type(i, k->get_Klass());
 317     }
 318   }
 319 }
 320 








 321 void ciMethodData::set_return_type(int bci, ciKlass* k) {
 322   VM_ENTRY_MARK;
 323   MethodData* mdo = get_MethodData();
 324   if (mdo != NULL) {
 325     ProfileData* data = mdo->bci_to_data(bci);
 326     if (data->is_CallTypeData()) {
 327       data->as_CallTypeData()->set_return_type(k->get_Klass());
 328     } else {
 329       assert(data->is_VirtualCallTypeData(), "no arguments!");
 330       data->as_VirtualCallTypeData()->set_return_type(k->get_Klass());
 331     }
 332   }
 333 }
 334 
 335 bool ciMethodData::has_escape_info() {
 336   return eflag_set(MethodData::estimated);
 337 }
 338 
 339 void ciMethodData::set_eflag(MethodData::EscapeFlag f) {
 340   set_bits(_eflags, f);


 587 }
 588 
 589 void ciVirtualCallData::print_data_on(outputStream* st) const {
 590   print_shared(st, "ciVirtualCallData");
 591   rtd_super()->print_receiver_data_on(st);
 592 }
 593 
 594 void ciVirtualCallTypeData::print_data_on(outputStream* st) const {
 595   print_shared(st, "ciVirtualCallTypeData");
 596   rtd_super()->print_receiver_data_on(st);
 597   if (has_arguments()) {
 598     tab(st, true);
 599     st->print("argument types");
 600     args()->print_data_on(st);
 601   }
 602   if (has_return()) {
 603     tab(st, true);
 604     st->print("return type");
 605     ret()->print_data_on(st);
 606   }





 607 }
 608 #endif


  36 
  37 // ------------------------------------------------------------------
  38 // ciMethodData::ciMethodData
  39 //
  40 ciMethodData::ciMethodData(MethodData* md) : ciMetadata(md) {
  41   assert(md != NULL, "no null method data");
  42   Copy::zero_to_words((HeapWord*) &_orig, sizeof(_orig) / sizeof(HeapWord));
  43   _data = NULL;
  44   _data_size = 0;
  45   _extra_data_size = 0;
  46   _current_mileage = 0;
  47   _invocation_counter = 0;
  48   _backedge_counter = 0;
  49   _state = empty_state;
  50   _saw_free_extra_data = false;
  51   // Set an initial hint. Don't use set_hint_di() because
  52   // first_di() may be out of bounds if data_size is 0.
  53   _hint_di = first_di();
  54   // Initialize the escape information (to "don't know.");
  55   _eflags = _arg_local = _arg_stack = _arg_returned = 0;
  56   _parameters = NULL;
  57 }
  58 
  59 // ------------------------------------------------------------------
  60 // ciMethodData::ciMethodData
  61 //
  62 // No MethodData*.
  63 ciMethodData::ciMethodData() : ciMetadata(NULL) {
  64   Copy::zero_to_words((HeapWord*) &_orig, sizeof(_orig) / sizeof(HeapWord));
  65   _data = NULL;
  66   _data_size = 0;
  67   _extra_data_size = 0;
  68   _current_mileage = 0;
  69   _invocation_counter = 0;
  70   _backedge_counter = 0;
  71   _state = empty_state;
  72   _saw_free_extra_data = false;
  73   // Set an initial hint. Don't use set_hint_di() because
  74   // first_di() may be out of bounds if data_size is 0.
  75   _hint_di = first_di();
  76   // Initialize the escape information (to "don't know.");
  77   _eflags = _arg_local = _arg_stack = _arg_returned = 0;
  78   _parameters = NULL;
  79 }
  80 
  81 void ciMethodData::load_data() {
  82   MethodData* mdo = get_MethodData();
  83   if (mdo == NULL) {
  84     return;
  85   }
  86 
  87   // To do: don't copy the data if it is not "ripe" -- require a minimum #
  88   // of invocations.
  89 
  90   // Snapshot the data -- actually, take an approximate snapshot of
  91   // the data.  Any concurrently executing threads may be changing the
  92   // data as we copy it.
  93   Copy::disjoint_words((HeapWord*) mdo,
  94                        (HeapWord*) &_orig,
  95                        sizeof(_orig) / HeapWordSize);
  96   Arena* arena = CURRENT_ENV->arena();
  97   _data_size = mdo->data_size();
  98   _extra_data_size = mdo->extra_data_size();
  99   int total_size = _data_size + _extra_data_size;
 100   _data = (intptr_t *) arena->Amalloc(total_size);
 101   Copy::disjoint_words((HeapWord*) mdo->data_base(), (HeapWord*) _data, total_size / HeapWordSize);
 102 
 103   // Traverse the profile data, translating any oops into their
 104   // ci equivalents.
 105   ResourceMark rm;
 106   ciProfileData* ci_data = first_data();
 107   ProfileData* data = mdo->first_data();
 108   while (is_valid(ci_data)) {
 109     ci_data->translate_from(data);
 110     ci_data = next_data(ci_data);
 111     data = mdo->next_data(data);
 112   }
 113   if (mdo->parameters_type_data() != NULL) {
 114     _parameters = data_layout_at(mdo->parameters_type_data_di());
 115     ciParametersTypeData* parameters = new ciParametersTypeData(_parameters);
 116     parameters->translate_from(mdo->parameters_type_data());
 117   }
 118 
 119   // Note:  Extra data are all BitData, and do not need translation.
 120   _current_mileage = MethodData::mileage_of(mdo->method());
 121   _invocation_counter = mdo->invocation_count();
 122   _backedge_counter = mdo->backedge_count();
 123   _state = mdo->is_mature()? mature_state: immature_state;
 124 
 125   _eflags = mdo->eflags();
 126   _arg_local = mdo->arg_local();
 127   _arg_stack = mdo->arg_stack();
 128   _arg_returned  = mdo->arg_returned();
 129 #ifndef PRODUCT
 130   if (ReplayCompiles) {
 131     ciReplay::initialize(this);
 132   }
 133 #endif
 134 }
 135 
 136 void ciReceiverTypeData::translate_receiver_data_from(const ProfileData* data) {
 137   for (uint row = 0; row < row_limit(); row++) {
 138     Klass* k = data->as_ReceiverTypeData()->receiver(row);


 173   case DataLayout::counter_data_tag:
 174     return new ciCounterData(data_layout);
 175   case DataLayout::jump_data_tag:
 176     return new ciJumpData(data_layout);
 177   case DataLayout::receiver_type_data_tag:
 178     return new ciReceiverTypeData(data_layout);
 179   case DataLayout::virtual_call_data_tag:
 180     return new ciVirtualCallData(data_layout);
 181   case DataLayout::ret_data_tag:
 182     return new ciRetData(data_layout);
 183   case DataLayout::branch_data_tag:
 184     return new ciBranchData(data_layout);
 185   case DataLayout::multi_branch_data_tag:
 186     return new ciMultiBranchData(data_layout);
 187   case DataLayout::arg_info_data_tag:
 188     return new ciArgInfoData(data_layout);
 189   case DataLayout::call_type_data_tag:
 190     return new ciCallTypeData(data_layout);
 191   case DataLayout::virtual_call_type_data_tag:
 192     return new ciVirtualCallTypeData(data_layout);
 193   case DataLayout::parameters_type_data_tag:
 194     return new ciParametersTypeData(data_layout);
 195   };
 196 }
 197 
 198 // Iteration over data.
 199 ciProfileData* ciMethodData::next_data(ciProfileData* current) {
 200   int current_index = dp_to_di(current->dp());
 201   int next_index = current_index + current->size_in_bytes();
 202   ciProfileData* next = data_at(next_index);
 203   return next;
 204 }
 205 
 206 // Translate a bci to its corresponding data, or NULL.
 207 ciProfileData* ciMethodData::bci_to_data(int bci) {
 208   ciProfileData* data = data_before(bci);
 209   for ( ; is_valid(data); data = next_data(data)) {
 210     if (data->bci() == bci) {
 211       set_hint_di(dp_to_di(data->dp()));
 212       return data;
 213     } else if (data->bci() > bci) {
 214       break;


 311   MethodData* mdo = get_MethodData();
 312   if (mdo != NULL) {
 313     mdo->set_would_profile(p);
 314   }
 315 }
 316 
 317 void ciMethodData::set_argument_type(int bci, int i, ciKlass* k) {
 318   VM_ENTRY_MARK;
 319   MethodData* mdo = get_MethodData();
 320   if (mdo != NULL) {
 321     ProfileData* data = mdo->bci_to_data(bci);
 322     if (data->is_CallTypeData()) {
 323       data->as_CallTypeData()->set_argument_type(i, k->get_Klass());
 324     } else {
 325       assert(data->is_VirtualCallTypeData(), "no arguments!");
 326       data->as_VirtualCallTypeData()->set_argument_type(i, k->get_Klass());
 327     }
 328   }
 329 }
 330 
 331 void ciMethodData::set_parameter_type(int i, ciKlass* k) {
 332   VM_ENTRY_MARK;
 333   MethodData* mdo = get_MethodData();
 334   if (mdo != NULL) {
 335     mdo->parameters_type_data()->set_type(i, k->get_Klass());
 336   }
 337 }
 338 
 339 void ciMethodData::set_return_type(int bci, ciKlass* k) {
 340   VM_ENTRY_MARK;
 341   MethodData* mdo = get_MethodData();
 342   if (mdo != NULL) {
 343     ProfileData* data = mdo->bci_to_data(bci);
 344     if (data->is_CallTypeData()) {
 345       data->as_CallTypeData()->set_return_type(k->get_Klass());
 346     } else {
 347       assert(data->is_VirtualCallTypeData(), "no arguments!");
 348       data->as_VirtualCallTypeData()->set_return_type(k->get_Klass());
 349     }
 350   }
 351 }
 352 
 353 bool ciMethodData::has_escape_info() {
 354   return eflag_set(MethodData::estimated);
 355 }
 356 
 357 void ciMethodData::set_eflag(MethodData::EscapeFlag f) {
 358   set_bits(_eflags, f);


 605 }
 606 
 607 void ciVirtualCallData::print_data_on(outputStream* st) const {
 608   print_shared(st, "ciVirtualCallData");
 609   rtd_super()->print_receiver_data_on(st);
 610 }
 611 
 612 void ciVirtualCallTypeData::print_data_on(outputStream* st) const {
 613   print_shared(st, "ciVirtualCallTypeData");
 614   rtd_super()->print_receiver_data_on(st);
 615   if (has_arguments()) {
 616     tab(st, true);
 617     st->print("argument types");
 618     args()->print_data_on(st);
 619   }
 620   if (has_return()) {
 621     tab(st, true);
 622     st->print("return type");
 623     ret()->print_data_on(st);
 624   }
 625 }
 626 
 627 void ciParametersTypeData::print_data_on(outputStream* st) const {
 628   st->print_cr("Parametertypes");
 629   parameters()->print_data_on(st);
 630 }
 631 #endif
src/share/vm/ci/ciMethodData.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File