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