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

src/share/vm/oops/methodData.cpp

Print this page
rev 5903 : 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 5904 : imported patch spectrap-chris
rev 5906 : [mq]: spectrapunloading

*** 1515,1535 **** assert(profile_parameters_jsr292_only(), "inconsistent"); return m->is_compiled_lambda_form(); } ! void MethodData::clean_method_data(BoolObjectClosure* is_alive) { ! for (ProfileData* data = first_data(); ! is_valid(data); ! data = next_data(data)) { ! data->clean_weak_klass_links(is_alive); } ! ParametersTypeData* parameters = parameters_type_data(); ! if (parameters != NULL) { ! parameters->clean_weak_klass_links(is_alive); } #ifdef ASSERT DataLayout* dp = extra_data_base(); DataLayout* end = extra_data_limit(); for (; dp < end; dp = next_extra(dp)) { --- 1515,1592 ---- assert(profile_parameters_jsr292_only(), "inconsistent"); return m->is_compiled_lambda_form(); } ! void MethodData::clean_extra_data_helper(DataLayout* dp, int shift, bool reset) { ! if (shift == 0) { ! return; } ! if (!reset) { ! // Move all cells of trap entry at dp left by "shift" cells ! intptr_t* start = (intptr_t*)dp; ! intptr_t* end = (intptr_t*)next_extra(dp); ! for (intptr_t* ptr = start; ptr < end; ptr++) { ! *(ptr-shift) = *ptr; } + } else { + // Reset "shift" cells stopping at dp + intptr_t* start = ((intptr_t*)dp) - shift; + intptr_t* end = (intptr_t*)dp; + for (intptr_t* ptr = start; ptr < end; ptr++) { + *ptr = 0; + } + } + } + // Remove SpeculativeTrapData entries that reference an unloaded + // method + void MethodData::clean_extra_data(BoolObjectClosure* is_alive) { + DataLayout* dp = extra_data_base(); + DataLayout* end = extra_data_limit(); + + int shift = 0; + for (; dp < end; dp = next_extra(dp)) { + switch(dp->tag()) { + case DataLayout::speculative_trap_data_tag: { + SpeculativeTrapData* data = new SpeculativeTrapData(dp); + Method* m = data->method(); + assert(m != NULL, "should have a method"); + if (!m->method_holder()->is_loader_alive(is_alive)) { + // "shift" accumulates the number of cells for dead + // SpeculativeTrapData entries that have been seen so + // far. Following entries must be shifted left by that many + // cells to remove the dead SpeculativeTrapData entries. + shift += (int)((intptr_t*)next_extra(dp) - (intptr_t*)dp); + } else { + // Shift this entry left if it follows dead + // SpeculativeTrapData entries + clean_extra_data_helper(dp, shift); + } + break; + } + case dp->DataLayout::bit_data_tag: + // Shift this entry left if it follows dead SpeculativeTrapData + // entries + clean_extra_data_helper(dp, shift); + continue; + case DataLayout::no_tag: + case DataLayout::arg_info_data_tag: + // We are at end of the live trap entries. The previous "shift" + // cells contain entries that are either dead or were shifted + // left. They need to be reset to no_tag + clean_extra_data_helper(dp, shift, true); + return; + default: + fatal(err_msg("unexpected tag %d", dp->tag())); + } + } + } + + // Verify there's no unloaded method referenced by a + // SpeculativeTrapData entry + void MethodData::verify_extra_data_clean(BoolObjectClosure* is_alive) { #ifdef ASSERT DataLayout* dp = extra_data_base(); DataLayout* end = extra_data_limit(); for (; dp < end; dp = next_extra(dp)) {
*** 1549,1553 **** --- 1606,1625 ---- fatal(err_msg("unexpected tag %d", dp->tag())); } } #endif } + + void MethodData::clean_method_data(BoolObjectClosure* is_alive) { + for (ProfileData* data = first_data(); + is_valid(data); + data = next_data(data)) { + data->clean_weak_klass_links(is_alive); + } + ParametersTypeData* parameters = parameters_type_data(); + if (parameters != NULL) { + parameters->clean_weak_klass_links(is_alive); + } + + clean_extra_data(is_alive); + verify_extra_data_clean(is_alive); + }
src/share/vm/oops/methodData.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File