ciProfileData* ciMethodData::bci_to_extra_data(int bci, ciMethod* m, bool& two_free_slots) { DataLayout* dp = extra_data_base(); DataLayout* end = args_data_limit(); two_free_slots = false; for (;dp < end; dp = MethodData::next_extra(dp)) { switch(dp->tag()) { case DataLayout::no_tag: _saw_free_extra_data = true; // observed an empty slot (common case) two_free_slots = (MethodData::next_extra(dp)->tag() == DataLayout::no_tag); return NULL; case DataLayout::arg_info_data_tag: return NULL; // ArgInfoData is at the end of extra data section. case DataLayout::bit_data_tag: if (m == NULL && dp->bci() == bci) { return new ciBitData(dp); } break; case DataLayout::speculative_trap_data_tag: { ciSpeculativeTrapData* data = new ciSpeculativeTrapData(dp); // data->method() might be null if the MDO is snapshotted // concurrently with a trap if (m != NULL && data->method() == m && dp->bci() == bci) { return data; } break; } default: fatal(err_msg("bad tag = %d", dp->tag())); } } return NULL; }
// Translate a bci to its corresponding extra data, or NULL. ProfileData* methodDataOopDesc::bci_to_extra_data(int bci, bool create_if_missing) { DataLayout* dp = extra_data_base(); DataLayout* end = extra_data_limit(); DataLayout* avail = NULL; for (; dp < end; dp = next_extra(dp)) { // No need for "OrderAccess::load_acquire" ops, // since the data structure is monotonic. if (dp->tag() == DataLayout::no_tag) break; if (dp->tag() == DataLayout::arg_info_data_tag) { dp = end; // ArgInfoData is at the end of extra data section. break; } if (dp->bci() == bci) { assert(dp->tag() == DataLayout::bit_data_tag, "sane"); return new BitData(dp); } } if (create_if_missing && dp < end) { // Allocate this one. There is no mutual exclusion, // so two threads could allocate different BCIs to the // same data layout. This means these extra data // records, like most other MDO contents, must not be // trusted too much. DataLayout temp; temp.initialize(DataLayout::bit_data_tag, bci, 0); dp->release_set_header(temp.header()); assert(dp->tag() == DataLayout::bit_data_tag, "sane"); //NO: assert(dp->bci() == bci, "no concurrent allocation"); return new BitData(dp); } return NULL; }
// Translate a bci to its corresponding data, or NULL. ciProfileData* ciMethodData::bci_to_data(int bci) { ciProfileData* data = data_before(bci); for ( ; is_valid(data); data = next_data(data)) { if (data->bci() == bci) { set_hint_di(dp_to_di(data->dp())); return data; } else if (data->bci() > bci) { break; } } // bci_to_extra_data(bci) ... DataLayout* dp = data_layout_at(data_size()); DataLayout* end = data_layout_at(data_size() + extra_data_size()); for (; dp < end; dp = methodDataOopDesc::next_extra(dp)) { if (dp->tag() == DataLayout::no_tag) { _saw_free_extra_data = true; // observed an empty slot (common case) return NULL; } if (dp->tag() == DataLayout::arg_info_data_tag) { break; // ArgInfoData is at the end of extra data section. } if (dp->bci() == bci) { assert(dp->tag() == DataLayout::bit_data_tag, "sane"); return new ciBitData(dp); } } return NULL; }