src/share/vm/oops/methodData.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File
*** old/src/share/vm/oops/methodData.cpp	Fri Feb 21 09:27:53 2014
--- new/src/share/vm/oops/methodData.cpp	Fri Feb 21 09:27:53 2014

*** 1515,1535 **** --- 1515,1592 ---- 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); ! void MethodData::clean_extra_data_helper(DataLayout* dp, int shift, bool reset) { + if (shift == 0) { ! return; } ParametersTypeData* parameters = parameters_type_data(); if (parameters != NULL) { ! parameters->clean_weak_klass_links(is_alive); + 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