< 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 >