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 5771 : 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 5772 : imported patch chris

*** 78,101 **** // Constructor for invalid ProfileData. ProfileData::ProfileData() { _data = NULL; } #ifndef PRODUCT ! void ProfileData::print_shared(outputStream* st, const char* name) const { st->print("bci: %d", bci()); st->fill_to(tab_width_one); st->print("%s", name); tab(st); int trap = trap_state(); if (trap != 0) { char buf[100]; st->print("trap(%s) ", Deoptimization::format_trap_state(buf, sizeof(buf), trap)); } int flags = data()->flags(); ! if (flags != 0) st->print("flags(%d) ", flags); } void ProfileData::tab(outputStream* st, bool first) const { st->fill_to(first ? tab_width_one : tab_width_two); } --- 78,139 ---- // Constructor for invalid ProfileData. ProfileData::ProfileData() { _data = NULL; } + char* ProfileData::print_data_on_helper(const MethodData* md) const { + DataLayout* dp = md->extra_data_base(); + DataLayout* end = md->extra_data_limit(); + stringStream ss; + for (;; dp = MethodData::next_extra(dp)) { + assert(dp < end, "moved past end of extra data"); + switch(dp->tag()) { + case DataLayout::speculative_trap_data_tag: + if (dp->bci() == bci()) { + SpeculativeTrapData* data = new SpeculativeTrapData(dp); + int trap = data->trap_state(); + char buf[100]; + ss.print("trap/"); + data->method()->print_short_name(&ss); + ss.print("(%s) ", Deoptimization::format_trap_state(buf, sizeof(buf), trap)); + } + break; + case DataLayout::bit_data_tag: + break; + case DataLayout::no_tag: + case DataLayout::arg_info_data_tag: + return ss.as_string(); + break; + default: + fatal(err_msg("unexpected tag %d", dp->tag())); + } + } + return NULL; + } + + void ProfileData::print_data_on(outputStream* st, const MethodData* md) const { + print_data_on(st, print_data_on_helper(md)); + } + #ifndef PRODUCT ! void ProfileData::print_shared(outputStream* st, const char* name, const char* extra) const { st->print("bci: %d", bci()); st->fill_to(tab_width_one); st->print("%s", name); tab(st); int trap = trap_state(); if (trap != 0) { char buf[100]; st->print("trap(%s) ", Deoptimization::format_trap_state(buf, sizeof(buf), trap)); } + if (extra != NULL) { + st->print(extra); + } int flags = data()->flags(); ! if (flags != 0) { st->print("flags(%d) ", flags); + } } void ProfileData::tab(outputStream* st, bool first) const { st->fill_to(first ? tab_width_one : tab_width_two); }
*** 107,129 **** // A BitData corresponds to a one-bit flag. This is used to indicate // whether a checkcast bytecode has seen a null value. #ifndef PRODUCT ! void BitData::print_data_on(outputStream* st) const { ! print_shared(st, "BitData"); } #endif // !PRODUCT // ================================================================== // CounterData // // A CounterData corresponds to a simple counter. #ifndef PRODUCT ! void CounterData::print_data_on(outputStream* st) const { ! print_shared(st, "CounterData"); st->print_cr("count(%u)", count()); } #endif // !PRODUCT // ================================================================== --- 145,167 ---- // A BitData corresponds to a one-bit flag. This is used to indicate // whether a checkcast bytecode has seen a null value. #ifndef PRODUCT ! void BitData::print_data_on(outputStream* st, const char* extra) const { ! print_shared(st, "BitData", extra); } #endif // !PRODUCT // ================================================================== // CounterData // // A CounterData corresponds to a simple counter. #ifndef PRODUCT ! void CounterData::print_data_on(outputStream* st, const char* extra) const { ! print_shared(st, "CounterData", extra); st->print_cr("count(%u)", count()); } #endif // !PRODUCT // ==================================================================
*** 148,159 **** int offset = target_di - my_di; set_displacement(offset); } #ifndef PRODUCT ! void JumpData::print_data_on(outputStream* st) const { ! print_shared(st, "JumpData"); st->print_cr("taken(%u) displacement(%d)", taken(), displacement()); } #endif // !PRODUCT int TypeStackSlotEntries::compute_cell_count(Symbol* signature, bool include_receiver, int max) { --- 186,197 ---- int offset = target_di - my_di; set_displacement(offset); } #ifndef PRODUCT ! void JumpData::print_data_on(outputStream* st, const char* extra) const { ! print_shared(st, "JumpData", extra); st->print_cr("taken(%u) displacement(%d)", taken(), displacement()); } #endif // !PRODUCT int TypeStackSlotEntries::compute_cell_count(Symbol* signature, bool include_receiver, int max) {
*** 330,341 **** _pd->tab(st); print_klass(st, type()); st->cr(); } ! void CallTypeData::print_data_on(outputStream* st) const { ! CounterData::print_data_on(st); if (has_arguments()) { tab(st, true); st->print("argument types"); _args.print_data_on(st); } --- 368,379 ---- _pd->tab(st); print_klass(st, type()); st->cr(); } ! void CallTypeData::print_data_on(outputStream* st, const char* extra) const { ! CounterData::print_data_on(st, extra); if (has_arguments()) { tab(st, true); st->print("argument types"); _args.print_data_on(st); }
*** 344,355 **** st->print("return type"); _ret.print_data_on(st); } } ! void VirtualCallTypeData::print_data_on(outputStream* st) const { ! VirtualCallData::print_data_on(st); if (has_arguments()) { tab(st, true); st->print("argument types"); _args.print_data_on(st); } --- 382,393 ---- st->print("return type"); _ret.print_data_on(st); } } ! void VirtualCallTypeData::print_data_on(outputStream* st, const char* extra) const { ! VirtualCallData::print_data_on(st, extra); if (has_arguments()) { tab(st, true); st->print("argument types"); _args.print_data_on(st); }
*** 398,413 **** receiver(row)->print_value_on(st); st->print_cr("(%u %4.2f)", receiver_count(row), (float) receiver_count(row) / (float) total); } } } ! void ReceiverTypeData::print_data_on(outputStream* st) const { ! print_shared(st, "ReceiverTypeData"); print_receiver_data_on(st); } ! void VirtualCallData::print_data_on(outputStream* st) const { ! print_shared(st, "VirtualCallData"); print_receiver_data_on(st); } #endif // !PRODUCT // ================================================================== --- 436,451 ---- receiver(row)->print_value_on(st); st->print_cr("(%u %4.2f)", receiver_count(row), (float) receiver_count(row) / (float) total); } } } ! void ReceiverTypeData::print_data_on(outputStream* st, const char* extra) const { ! print_shared(st, "ReceiverTypeData", extra); print_receiver_data_on(st); } ! void VirtualCallData::print_data_on(outputStream* st, const char* extra) const { ! print_shared(st, "VirtualCallData", extra); print_receiver_data_on(st); } #endif // !PRODUCT // ==================================================================
*** 454,465 **** return mdp; } #ifndef PRODUCT ! void RetData::print_data_on(outputStream* st) const { ! print_shared(st, "RetData"); uint row; int entries = 0; for (row = 0; row < row_limit(); row++) { if (bci(row) != no_bci) entries++; } --- 492,503 ---- return mdp; } #ifndef PRODUCT ! void RetData::print_data_on(outputStream* st, const char* extra) const { ! print_shared(st, "RetData", extra); uint row; int entries = 0; for (row = 0; row < row_limit(); row++) { if (bci(row) != no_bci) entries++; }
*** 489,500 **** int offset = target_di - my_di; set_displacement(offset); } #ifndef PRODUCT ! void BranchData::print_data_on(outputStream* st) const { ! print_shared(st, "BranchData"); st->print_cr("taken(%u) displacement(%d)", taken(), displacement()); tab(st); st->print_cr("not taken(%u)", not_taken()); } --- 527,538 ---- int offset = target_di - my_di; set_displacement(offset); } #ifndef PRODUCT ! void BranchData::print_data_on(outputStream* st, const char* extra) const { ! print_shared(st, "BranchData", extra); st->print_cr("taken(%u) displacement(%d)", taken(), displacement()); tab(st); st->print_cr("not taken(%u)", not_taken()); }
*** 563,574 **** set_default_displacement(offset); } } #ifndef PRODUCT ! void MultiBranchData::print_data_on(outputStream* st) const { ! print_shared(st, "MultiBranchData"); st->print_cr("default_count(%u) displacement(%d)", default_count(), default_displacement()); int cases = number_of_cases(); for (int i = 0; i < cases; i++) { tab(st); --- 601,612 ---- set_default_displacement(offset); } } #ifndef PRODUCT ! void MultiBranchData::print_data_on(outputStream* st, const char* extra) const { ! print_shared(st, "MultiBranchData", extra); st->print_cr("default_count(%u) displacement(%d)", default_count(), default_displacement()); int cases = number_of_cases(); for (int i = 0; i < cases; i++) { tab(st);
*** 577,588 **** } } #endif #ifndef PRODUCT ! void ArgInfoData::print_data_on(outputStream* st) const { ! print_shared(st, "ArgInfoData"); int nargs = number_of_args(); for (int i = 0; i < nargs; i++) { st->print(" 0x%x", arg_modified(i)); } st->cr(); --- 615,626 ---- } } #endif #ifndef PRODUCT ! void ArgInfoData::print_data_on(outputStream* st, const char* extra) const { ! print_shared(st, "ArgInfoData", extra); int nargs = number_of_args(); for (int i = 0; i < nargs; i++) { st->print(" 0x%x", arg_modified(i)); } st->cr();
*** 609,622 **** bool ParametersTypeData::profiling_enabled() { return MethodData::profile_parameters(); } #ifndef PRODUCT ! void ParametersTypeData::print_data_on(outputStream* st) const { ! st->print("parameter types"); _parameters.print_data_on(st); } #endif // ================================================================== // MethodData* // --- 647,667 ---- bool ParametersTypeData::profiling_enabled() { return MethodData::profile_parameters(); } #ifndef PRODUCT ! void ParametersTypeData::print_data_on(outputStream* st, const char* extra) const { ! st->print("parameter types", extra); _parameters.print_data_on(st); } + + void SpeculativeTrapData::print_data_on(outputStream* st, const char* extra) const { + print_shared(st, "SpeculativeTrapData", extra); + tab(st); + method()->print_short_name(st); + st->cr(); + } #endif // ================================================================== // MethodData* //
*** 738,759 **** // a DataLayout header, with no extra cells. assert(cell_count >= 0, "sanity"); return DataLayout::compute_size_in_bytes(cell_count); } ! int MethodData::compute_extra_data_count(int data_size, int empty_bc_count) { if (ProfileTraps) { // Assume that up to 3% of BCIs with no MDP will need to allocate one. int extra_data_count = (uint)(empty_bc_count * 3) / 128 + 1; // If the method is large, let the extra BCIs grow numerous (to ~1%). int one_percent_of_data = (uint)data_size / (DataLayout::header_size_in_bytes()*128); if (extra_data_count < one_percent_of_data) extra_data_count = one_percent_of_data; if (extra_data_count > empty_bc_count) extra_data_count = empty_bc_count; // no need for more ! return extra_data_count; } else { return 0; } } --- 783,833 ---- // a DataLayout header, with no extra cells. assert(cell_count >= 0, "sanity"); return DataLayout::compute_size_in_bytes(cell_count); } ! bool MethodData::speculative_trap_bytecode(Bytecodes::Code code) { ! // Bytecodes for which we may use speculation ! switch (code) { ! case Bytecodes::_checkcast: ! case Bytecodes::_instanceof: ! case Bytecodes::_aastore: ! case Bytecodes::_invokevirtual: ! case Bytecodes::_invokeinterface: ! case Bytecodes::_if_acmpeq: ! case Bytecodes::_if_acmpne: ! case Bytecodes::_invokestatic: ! return UseTypeSpeculation; ! default: ! return false; ! } ! return false; ! } ! ! int MethodData::compute_extra_data_count(int data_size, int empty_bc_count, bool needs_speculative_traps) { if (ProfileTraps) { // Assume that up to 3% of BCIs with no MDP will need to allocate one. int extra_data_count = (uint)(empty_bc_count * 3) / 128 + 1; // If the method is large, let the extra BCIs grow numerous (to ~1%). int one_percent_of_data = (uint)data_size / (DataLayout::header_size_in_bytes()*128); if (extra_data_count < one_percent_of_data) extra_data_count = one_percent_of_data; if (extra_data_count > empty_bc_count) extra_data_count = empty_bc_count; // no need for more ! ! // Make sure we have a minimum number of extra data slots to ! // allocate SpeculativeTrapData entries. We would want to have one ! // entry per compilation that inlines this method and for which ! // some type speculation assumption fails. So the room we need for ! // the SpeculativeTrapData entries doesn't directly depend on the ! // size of the method. Because it's hard to estimate, we reserve ! // space for an arbitrary number of entries. ! int spec_data_count = (needs_speculative_traps ? SpecTrapLimitExtraEntries : 0) * ! (SpeculativeTrapData::static_cell_count() + DataLayout::header_size_in_cells()); ! ! return MAX2(extra_data_count, spec_data_count); } else { return 0; } }
*** 762,780 **** int MethodData::compute_allocation_size_in_bytes(methodHandle method) { int data_size = 0; BytecodeStream stream(method); Bytecodes::Code c; int empty_bc_count = 0; // number of bytecodes lacking data while ((c = stream.next()) >= 0) { int size_in_bytes = compute_data_size(&stream); data_size += size_in_bytes; if (size_in_bytes == 0) empty_bc_count += 1; } int object_size = in_bytes(data_offset()) + data_size; // Add some extra DataLayout cells (at least one) to track stray traps. ! int extra_data_count = compute_extra_data_count(data_size, empty_bc_count); object_size += extra_data_count * DataLayout::compute_size_in_bytes(0); // Add a cell to record information about modified arguments. int arg_size = method->size_of_parameters(); object_size += DataLayout::compute_size_in_bytes(arg_size+1); --- 836,856 ---- int MethodData::compute_allocation_size_in_bytes(methodHandle method) { int data_size = 0; BytecodeStream stream(method); Bytecodes::Code c; int empty_bc_count = 0; // number of bytecodes lacking data + bool needs_speculative_traps = false; while ((c = stream.next()) >= 0) { int size_in_bytes = compute_data_size(&stream); data_size += size_in_bytes; if (size_in_bytes == 0) empty_bc_count += 1; + needs_speculative_traps = needs_speculative_traps || speculative_trap_bytecode(c); } int object_size = in_bytes(data_offset()) + data_size; // Add some extra DataLayout cells (at least one) to track stray traps. ! int extra_data_count = compute_extra_data_count(data_size, empty_bc_count, needs_speculative_traps); object_size += extra_data_count * DataLayout::compute_size_in_bytes(0); // Add a cell to record information about modified arguments. int arg_size = method->size_of_parameters(); object_size += DataLayout::compute_size_in_bytes(arg_size+1);
*** 1002,1023 **** int data_size = 0; int empty_bc_count = 0; // number of bytecodes lacking data _data[0] = 0; // apparently not set below. BytecodeStream stream(method); Bytecodes::Code c; while ((c = stream.next()) >= 0) { int size_in_bytes = initialize_data(&stream, data_size); data_size += size_in_bytes; if (size_in_bytes == 0) empty_bc_count += 1; } _data_size = data_size; int object_size = in_bytes(data_offset()) + data_size; // Add some extra DataLayout cells (at least one) to track stray traps. ! int extra_data_count = compute_extra_data_count(data_size, empty_bc_count); int extra_size = extra_data_count * DataLayout::compute_size_in_bytes(0); // Add a cell to record information about modified arguments. // Set up _args_modified array after traps cells so that // the code for traps cells works. DataLayout *dp = data_layout_at(data_size + extra_size); --- 1078,1104 ---- int data_size = 0; int empty_bc_count = 0; // number of bytecodes lacking data _data[0] = 0; // apparently not set below. BytecodeStream stream(method); Bytecodes::Code c; + bool needs_speculative_traps = false; while ((c = stream.next()) >= 0) { int size_in_bytes = initialize_data(&stream, data_size); data_size += size_in_bytes; if (size_in_bytes == 0) empty_bc_count += 1; + needs_speculative_traps = needs_speculative_traps || speculative_trap_bytecode(c); } _data_size = data_size; int object_size = in_bytes(data_offset()) + data_size; // Add some extra DataLayout cells (at least one) to track stray traps. ! int extra_data_count = compute_extra_data_count(data_size, empty_bc_count, needs_speculative_traps); int extra_size = extra_data_count * DataLayout::compute_size_in_bytes(0); + // Let's zero the space for the extra data + Copy::zero_to_bytes(((address)_data) + data_size, extra_size); + // Add a cell to record information about modified arguments. // Set up _args_modified array after traps cells so that // the code for traps cells works. DataLayout *dp = data_layout_at(data_size + extra_size);
*** 1025,1045 **** dp->initialize(DataLayout::arg_info_data_tag, 0, arg_size+1); int arg_data_size = DataLayout::compute_size_in_bytes(arg_size+1); object_size += extra_size + arg_data_size; ! int args_cell = ParametersTypeData::compute_cell_count(method()); // If we are profiling parameters, we reserver an area near the end // of the MDO after the slots for bytecodes (because there's no bci // for method entry so they don't fit with the framework for the // profiling of bytecodes). We store the offset within the MDO of // this area (or -1 if no parameter is profiled) ! if (args_cell > 0) { ! object_size += DataLayout::compute_size_in_bytes(args_cell); _parameters_type_data_di = data_size + extra_size + arg_data_size; DataLayout *dp = data_layout_at(data_size + extra_size + arg_data_size); ! dp->initialize(DataLayout::parameters_type_data_tag, 0, args_cell); } else { _parameters_type_data_di = -1; } // Set an initial hint. Don't use set_hint_di() because --- 1106,1126 ---- dp->initialize(DataLayout::arg_info_data_tag, 0, arg_size+1); int arg_data_size = DataLayout::compute_size_in_bytes(arg_size+1); object_size += extra_size + arg_data_size; ! int parms_cell = ParametersTypeData::compute_cell_count(method()); // If we are profiling parameters, we reserver an area near the end // of the MDO after the slots for bytecodes (because there's no bci // for method entry so they don't fit with the framework for the // profiling of bytecodes). We store the offset within the MDO of // this area (or -1 if no parameter is profiled) ! if (parms_cell > 0) { ! object_size += DataLayout::compute_size_in_bytes(parms_cell); _parameters_type_data_di = data_size + extra_size + arg_data_size; DataLayout *dp = data_layout_at(data_size + extra_size + arg_data_size); ! dp->initialize(DataLayout::parameters_type_data_tag, 0, parms_cell); } else { _parameters_type_data_di = -1; } // Set an initial hint. Don't use set_hint_di() because
*** 1126,1168 **** return data; } else if (data->bci() > bci) { break; } } ! return bci_to_extra_data(bci, false); } ! // Translate a bci to its corresponding extra data, or NULL. ! ProfileData* MethodData::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; } ArgInfoData *MethodData::arg_info() { --- 1207,1323 ---- return data; } else if (data->bci() > bci) { break; } } ! return bci_to_extra_data(bci, NULL, false); } ! DataLayout* MethodData::next_extra(DataLayout* dp) { ! int nb_cells = 0; ! switch(dp->tag()) { ! case DataLayout::bit_data_tag: ! case DataLayout::no_tag: ! nb_cells = BitData::static_cell_count(); ! break; ! case DataLayout::speculative_trap_data_tag: ! nb_cells = SpeculativeTrapData::static_cell_count(); ! break; ! default: ! fatal(err_msg("unexpected tag %d", dp->tag())); ! } ! return (DataLayout*)((address)dp + DataLayout::compute_size_in_bytes(nb_cells)); ! } ! ! ProfileData* MethodData::bci_to_extra_data_helper(int bci, Method* m, DataLayout*& dp) { DataLayout* end = extra_data_limit(); ! ! for (;; dp = next_extra(dp)) { ! assert(dp < end, "moved past end of extra data"); // No need for "OrderAccess::load_acquire" ops, // since the data structure is monotonic. ! switch(dp->tag()) { ! case DataLayout::no_tag: ! return NULL; ! case DataLayout::arg_info_data_tag: ! dp = end; ! return NULL; // ArgInfoData is at the end of extra data section. ! case DataLayout::bit_data_tag: ! if (m == NULL && dp->bci() == bci) { ! return new BitData(dp); } + break; + case DataLayout::speculative_trap_data_tag: + if (m != NULL) { + SpeculativeTrapData* data = new SpeculativeTrapData(dp); + // data->method() may be null in case of a concurrent + // allocation. Assume it's for the same method and use that + // entry in that case. if (dp->bci() == bci) { ! if (data->method() == NULL) { ! return NULL; ! } else if (data->method() == m) { ! return data; } } + } + break; + default: + fatal(err_msg("unexpected tag %d", dp->tag())); + } + } + return NULL; + } + + + // Translate a bci to its corresponding extra data, or NULL. + ProfileData* MethodData::bci_to_extra_data(int bci, Method* m, bool create_if_missing) { + // This code assumes an entry for a SpeculativeTrapData is 2 cells + assert(2*DataLayout::compute_size_in_bytes(BitData::static_cell_count()) == + DataLayout::compute_size_in_bytes(SpeculativeTrapData::static_cell_count()), + "code needs to be adjusted"); + + DataLayout* dp = extra_data_base(); + DataLayout* end = extra_data_limit(); + + // Allocation in the extra data space has to be atomic because not + // all entries have the same size and non atomic concurrent + // allocation would result in a corrupted extra data space. + while (true) { + ProfileData* result = bci_to_extra_data_helper(bci, m, dp); + if (result != NULL) { + return result; + } + if (create_if_missing && dp < end) { ! assert(dp->tag() == DataLayout::no_tag || (dp->tag() == DataLayout::speculative_trap_data_tag && m != NULL), "should be free"); ! assert(next_extra(dp)->tag() == DataLayout::no_tag || next_extra(dp)->tag() == DataLayout::arg_info_data_tag, "should be free or arg info"); ! u1 tag = m == NULL ? DataLayout::bit_data_tag : DataLayout::speculative_trap_data_tag; ! // SpeculativeTrapData is 2 slots. Make sure we have room. ! if (m != NULL && next_extra(dp)->tag() != DataLayout::no_tag) { ! return NULL; ! } DataLayout temp; ! temp.initialize(tag, bci, 0); ! // May have been set concurrently ! if (dp->header() != temp.header() && !dp->atomic_set_header(temp.header())) { ! // Allocation failure because of concurrent allocation. Try ! // again. ! continue; ! } ! assert(dp->tag() == tag, "sane"); ! assert(dp->bci() == bci, "no concurrent allocation"); ! if (tag == DataLayout::bit_data_tag) { return new BitData(dp); + } else { + // If being allocated concurrently, one trap may be lost + SpeculativeTrapData* data = new SpeculativeTrapData(dp); + data->set_method(m); + return data; + } + } + return NULL; } return NULL; } ArgInfoData *MethodData::arg_info() {
*** 1198,1231 **** #ifndef PRODUCT void MethodData::print_data_on(outputStream* st) const { ResourceMark rm; ProfileData* data = first_data(); if (_parameters_type_data_di != -1) { ! parameters_type_data()->print_data_on(st); } for ( ; is_valid(data); data = next_data(data)) { st->print("%d", dp_to_di(data->dp())); st->fill_to(6); ! data->print_data_on(st); } st->print_cr("--- Extra data:"); DataLayout* dp = extra_data_base(); DataLayout* end = extra_data_limit(); ! 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) 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 ArgInfoData(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); } } #endif #if INCLUDE_SERVICES --- 1353,1396 ---- #ifndef PRODUCT void MethodData::print_data_on(outputStream* st) const { ResourceMark rm; ProfileData* data = first_data(); if (_parameters_type_data_di != -1) { ! parameters_type_data()->print_data_on(st, (const char*)NULL); } for ( ; is_valid(data); data = next_data(data)) { st->print("%d", dp_to_di(data->dp())); st->fill_to(6); ! data->print_data_on(st, this); } st->print_cr("--- Extra data:"); DataLayout* dp = extra_data_base(); DataLayout* end = extra_data_limit(); ! for (;; dp = next_extra(dp)) { ! assert(dp < end, "moved past end of extra data"); // No need for "OrderAccess::load_acquire" ops, // since the data structure is monotonic. ! switch(dp->tag()) { ! case DataLayout::no_tag: ! continue; ! case DataLayout::bit_data_tag: data = new BitData(dp); ! break; ! case DataLayout::speculative_trap_data_tag: ! data = new SpeculativeTrapData(dp); ! break; ! case DataLayout::arg_info_data_tag: data = new ArgInfoData(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, (const char*)NULL); ! if (dp >= end) return; } } #endif #if INCLUDE_SERVICES
*** 1344,1348 **** --- 1509,1548 ---- } 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)) { + switch(dp->tag()) { + case DataLayout::speculative_trap_data_tag: { + SpeculativeTrapData* data = new SpeculativeTrapData(dp); + Method* m = data->method(); + assert(m != NULL && m->method_holder()->is_loader_alive(is_alive), "Method should exist"); + break; + } + case dp->DataLayout::bit_data_tag: + continue; + case DataLayout::no_tag: + case DataLayout::arg_info_data_tag: + return; + default: + fatal(err_msg("unexpected tag %d", dp->tag())); + } + } + #endif + }
src/share/vm/oops/methodData.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File