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