< prev index next >

src/share/vm/oops/methodData.cpp

Print this page
rev 9358 : 8057038: Speculative traps not robust when compilation and class unloading are concurrent
Summary: speculative traps can be removed from MDO while being copied by compiler
Reviewed-by: kvn, iveresov

*** 84,94 **** _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: --- 84,94 ---- _data = NULL; } char* ProfileData::print_data_on_helper(const MethodData* md) const { DataLayout* dp = md->extra_data_base(); ! DataLayout* end = md->args_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:
*** 1067,1084 **** for (data = first_data(); is_valid(data); data = next_data(data)) { stream->set_start(data->bci()); stream->next(); data->post_initialize(stream, this); } ! if (_parameters_type_data_di != -1) { parameters_type_data()->post_initialize(NULL, this); } } // Initialize the MethodData* corresponding to a given method. MethodData::MethodData(methodHandle method, int size, TRAPS) ! : _extra_data_lock(Monitor::leaf, "MDO extra data lock") { No_Safepoint_Verifier no_safepoint; // init function atomic wrt GC ResourceMark rm; // Set the method back-pointer. _method = method(); --- 1067,1085 ---- for (data = first_data(); is_valid(data); data = next_data(data)) { stream->set_start(data->bci()); stream->next(); data->post_initialize(stream, this); } ! if (_parameters_type_data_di != no_parameters) { parameters_type_data()->post_initialize(NULL, this); } } // Initialize the MethodData* corresponding to a given method. MethodData::MethodData(methodHandle method, int size, TRAPS) ! : _extra_data_lock(Monitor::leaf, "MDO extra data lock"), ! _parameters_type_data_di(parameters_uninitialized) { No_Safepoint_Verifier no_safepoint; // init function atomic wrt GC ResourceMark rm; // Set the method back-pointer. _method = method();
*** 1130,1140 **** 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 // first_di() may be out of bounds if data_size is 0. // In that situation, _hint_di is never used, but at --- 1131,1141 ---- 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 = no_parameters; } // Set an initial hint. Don't use set_hint_di() because // first_di() may be out of bounds if data_size is 0. // In that situation, _hint_di is never used, but at
*** 1252,1262 **** } return (DataLayout*)((address)dp + DataLayout::compute_size_in_bytes(nb_cells)); } ProfileData* MethodData::bci_to_extra_data_helper(int bci, Method* m, DataLayout*& dp, bool concurrent) { ! 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. --- 1253,1263 ---- } return (DataLayout*)((address)dp + DataLayout::compute_size_in_bytes(nb_cells)); } ProfileData* MethodData::bci_to_extra_data_helper(int bci, Method* m, DataLayout*& dp, bool concurrent) { ! DataLayout* end = args_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.
*** 1301,1311 **** 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. ProfileData* result = bci_to_extra_data_helper(bci, m, dp, true); --- 1302,1312 ---- 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 = args_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. ProfileData* result = bci_to_extra_data_helper(bci, m, dp, true);
*** 1346,1356 **** return NULL; } ArgInfoData *MethodData::arg_info() { DataLayout* dp = extra_data_base(); ! DataLayout* end = extra_data_limit(); for (; dp < end; dp = next_extra(dp)) { if (dp->tag() == DataLayout::arg_info_data_tag) return new ArgInfoData(dp); } return NULL; --- 1347,1357 ---- return NULL; } ArgInfoData *MethodData::arg_info() { DataLayout* dp = extra_data_base(); ! DataLayout* end = args_data_limit(); for (; dp < end; dp = next_extra(dp)) { if (dp->tag() == DataLayout::arg_info_data_tag) return new ArgInfoData(dp); } return NULL;
*** 1378,1398 **** #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, 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()) { --- 1379,1399 ---- #ifndef PRODUCT void MethodData::print_data_on(outputStream* st) const { ResourceMark rm; ProfileData* data = first_data(); ! if (_parameters_type_data_di != no_parameters) { 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, this); } st->print_cr("--- Extra data:"); DataLayout* dp = extra_data_base(); ! DataLayout* end = args_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()) {
*** 1587,1597 **** // Remove SpeculativeTrapData entries that reference an unloaded or // redefined method void MethodData::clean_extra_data(CleanExtraDataClosure* cl) { 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: { --- 1588,1598 ---- // Remove SpeculativeTrapData entries that reference an unloaded or // redefined method void MethodData::clean_extra_data(CleanExtraDataClosure* cl) { DataLayout* dp = extra_data_base(); ! DataLayout* end = args_data_limit(); int shift = 0; for (; dp < end; dp = next_extra(dp)) { switch(dp->tag()) { case DataLayout::speculative_trap_data_tag: {
*** 1632,1642 **** // Verify there's no unloaded or redefined method referenced by a // SpeculativeTrapData entry void MethodData::verify_extra_data_clean(CleanExtraDataClosure* cl) { #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); --- 1633,1643 ---- // Verify there's no unloaded or redefined method referenced by a // SpeculativeTrapData entry void MethodData::verify_extra_data_clean(CleanExtraDataClosure* cl) { #ifdef ASSERT DataLayout* dp = extra_data_base(); ! DataLayout* end = args_data_limit(); for (; dp < end; dp = next_extra(dp)) { switch(dp->tag()) { case DataLayout::speculative_trap_data_tag: { SpeculativeTrapData* data = new SpeculativeTrapData(dp);
< prev index next >