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

src/share/vm/ci/ciMethodData.cpp

Print this page
rev 5774 : 8031752: Failed speculative optimizations should be reattempted when root of compilation is different
Summary: support for speculative traps that keep track of the root of the compilation in which a trap occurs.
Reviewed-by:
rev 5775 : imported patch spectrap-chris
rev 5776 : imported patch spectrapfix

*** 76,85 **** --- 76,114 ---- // Initialize the escape information (to "don't know."); _eflags = _arg_local = _arg_stack = _arg_returned = 0; _parameters = NULL; } + void ciMethodData::load_extra_data() { + MethodData* mdo = get_MethodData(); + + // speculative trap entries also hold a pointer to a Method so need to be translated + DataLayout* dp_src = mdo->extra_data_base(); + DataLayout* end_src = mdo->extra_data_limit(); + DataLayout* dp_dst = extra_data_base(); + for (;; dp_src = MethodData::next_extra(dp_src), dp_dst = MethodData::next_extra(dp_dst)) { + assert(dp_src < end_src, "moved past end of extra data"); + assert(dp_src->tag() == dp_dst->tag(), err_msg("should be same tags %d != %d", dp_src->tag(), dp_dst->tag())); + switch(dp_src->tag()) { + case DataLayout::speculative_trap_data_tag: { + ciSpeculativeTrapData* data_dst = new ciSpeculativeTrapData(dp_dst); + SpeculativeTrapData* data_src = new SpeculativeTrapData(dp_src); + data_dst->translate_from(data_src); + break; + } + case DataLayout::bit_data_tag: + break; + case DataLayout::no_tag: + case DataLayout::arg_info_data_tag: + // An empty slot or ArgInfoData entry marks the end of the trap data + return; + default: + fatal(err_msg("bad tag = %d", dp_src->tag())); + } + } + } + void ciMethodData::load_data() { MethodData* mdo = get_MethodData(); if (mdo == NULL) { return; }
*** 114,123 **** --- 143,154 ---- _parameters = data_layout_at(mdo->parameters_type_data_di()); ciParametersTypeData* parameters = new ciParametersTypeData(_parameters); parameters->translate_from(mdo->parameters_type_data()); } + load_extra_data(); + // Note: Extra data are all BitData, and do not need translation. _current_mileage = MethodData::mileage_of(mdo->method()); _invocation_counter = mdo->invocation_count(); _backedge_counter = mdo->backedge_count(); _state = mdo->is_mature()? mature_state: immature_state;
*** 154,163 **** --- 185,200 ---- void ciReturnTypeEntry::translate_type_data_from(const ReturnTypeEntry* ret) { intptr_t k = ret->type(); set_type(translate_klass(k)); } + void ciSpeculativeTrapData::translate_from(const ProfileData* data) { + Method* m = data->as_SpeculativeTrapData()->method(); + ciMethod* ci_m = CURRENT_ENV->get_method(m); + set_method(ci_m); + } + // Get the data at an arbitrary (sort of) data index. ciProfileData* ciMethodData::data_at(int data_index) { if (out_of_bounds(data_index)) { return NULL; }
*** 201,236 **** int next_index = current_index + current->size_in_bytes(); ciProfileData* next = data_at(next_index); return next; } // 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 = MethodData::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; } // Conservatively decode the trap_state of a ciProfileData. --- 238,305 ---- int next_index = current_index + current->size_in_bytes(); ciProfileData* next = data_at(next_index); return next; } + ciProfileData* ciMethodData::bci_to_extra_data(int bci, ciMethod* m, bool& two_free_slots) { + // bci_to_extra_data(bci) ... + DataLayout* dp = data_layout_at(data_size()); + DataLayout* end = data_layout_at(data_size() + extra_data_size()); + 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 data, or NULL. ! ciProfileData* ciMethodData::bci_to_data(int bci, ciMethod* m) { ! // If m is not NULL we look for a SpeculativeTrapData entry ! if (m == NULL) { 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; } } } + bool two_free_slots = false; + ciProfileData* result = bci_to_extra_data(bci, m, two_free_slots); + if (result != NULL) { + return result; + } + if (m != NULL && !two_free_slots) { + // We were looking for a SpeculativeTrapData entry we didn't + // find. Room is not available for more SpeculativeTrapData + // entries, look in the non SpeculativeTrapData entries. + return bci_to_data(bci, NULL); } return NULL; } // Conservatively decode the trap_state of a ciProfileData.
*** 523,544 **** data->print_data_on(st); } st->print_cr("--- Extra data:"); DataLayout* dp = data_layout_at(data_size()); DataLayout* end = data_layout_at(data_size() + extra_data_size()); ! for (; dp < end; dp = MethodData::next_extra(dp)) { ! if (dp->tag() == DataLayout::no_tag) continue; ! if (dp->tag() == DataLayout::bit_data_tag) { data = new BitData(dp); ! } else { ! assert(dp->tag() == DataLayout::arg_info_data_tag, "must be BitData or ArgInfo"); data = new ciArgInfoData(dp); dp = end; // ArgInfoData is at the end of extra data section. } st->print("%d", dp_to_di(data->dp())); st->fill_to(6); data->print_data_on(st); } } void ciTypeEntries::print_ciklass(outputStream* st, intptr_t k) { if (TypeEntries::is_type_none(k)) { --- 592,620 ---- data->print_data_on(st); } st->print_cr("--- Extra data:"); DataLayout* dp = data_layout_at(data_size()); DataLayout* end = data_layout_at(data_size() + extra_data_size()); ! for (;; dp = MethodData::next_extra(dp)) { ! assert(dp < end, "moved past end of extra data"); ! switch (dp->tag()) { ! case DataLayout::no_tag: ! continue; ! case DataLayout::bit_data_tag: data = new BitData(dp); ! break; ! case DataLayout::arg_info_data_tag: data = new ciArgInfoData(dp); dp = end; // ArgInfoData is at the end of extra data section. + break; + default: + fatal(err_msg("unexpected tag %d", dp->tag())); } st->print("%d", dp_to_di(data->dp())); st->fill_to(6); data->print_data_on(st); + if (dp >= end) return; } } void ciTypeEntries::print_ciklass(outputStream* st, intptr_t k) { if (TypeEntries::is_type_none(k)) {
*** 567,578 **** st->print("ret "); print_ciklass(st, type()); st->cr(); } ! void ciCallTypeData::print_data_on(outputStream* st) const { ! print_shared(st, "ciCallTypeData"); if (has_arguments()) { tab(st, true); st->print("argument types"); args()->print_data_on(st); } --- 643,654 ---- st->print("ret "); print_ciklass(st, type()); st->cr(); } ! void ciCallTypeData::print_data_on(outputStream* st, const char* extra) const { ! print_shared(st, "ciCallTypeData", extra); if (has_arguments()) { tab(st, true); st->print("argument types"); args()->print_data_on(st); }
*** 597,618 **** st->print_cr("(%u)", receiver_count(row)); } } } ! void ciReceiverTypeData::print_data_on(outputStream* st) const { ! print_shared(st, "ciReceiverTypeData"); print_receiver_data_on(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); if (has_arguments()) { tab(st, true); st->print("argument types"); args()->print_data_on(st); --- 673,694 ---- st->print_cr("(%u)", receiver_count(row)); } } } ! void ciReceiverTypeData::print_data_on(outputStream* st, const char* extra) const { ! print_shared(st, "ciReceiverTypeData", extra); print_receiver_data_on(st); } ! void ciVirtualCallData::print_data_on(outputStream* st, const char* extra) const { ! print_shared(st, "ciVirtualCallData", extra); rtd_super()->print_receiver_data_on(st); } ! void ciVirtualCallTypeData::print_data_on(outputStream* st, const char* extra) const { ! print_shared(st, "ciVirtualCallTypeData", extra); rtd_super()->print_receiver_data_on(st); if (has_arguments()) { tab(st, true); st->print("argument types"); args()->print_data_on(st);
*** 622,631 **** st->print("return type"); ret()->print_data_on(st); } } ! void ciParametersTypeData::print_data_on(outputStream* st) const { ! st->print_cr("Parametertypes"); parameters()->print_data_on(st); } #endif --- 698,714 ---- st->print("return type"); ret()->print_data_on(st); } } ! void ciParametersTypeData::print_data_on(outputStream* st, const char* extra) const { ! st->print_cr("ciParametersTypeData"); parameters()->print_data_on(st); } + + void ciSpeculativeTrapData::print_data_on(outputStream* st, const char* extra) const { + st->print_cr("ciSpeculativeTrapData"); + tab(st); + method()->print_short_name(st); + st->cr(); + } #endif
src/share/vm/ci/ciMethodData.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File