< prev index next > src/hotspot/share/oops/methodData.cpp
Print this page
if (extra != nullptr) {
st->print("%s", 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);
if (extra != nullptr) {
st->print("%s", extra);
}
int flags = data()->flags();
if (flags != 0) {
! st->print("flags(%d) %p/%d", flags, data(), in_bytes(DataLayout::flags_offset()));
}
}
void ProfileData::tab(outputStream* st, bool first) const {
st->fill_to(first ? tab_width_one : tab_width_two);
return args_count * per_arg_cell_count;
}
int TypeEntriesAtCall::compute_cell_count(BytecodeStream* stream) {
assert(Bytecodes::is_invoke(stream->code()), "should be invoke");
! assert(TypeStackSlotEntries::per_arg_count() > ReturnTypeEntry::static_cell_count(), "code to test for arguments/results broken");
const methodHandle m = stream->method();
int bci = stream->bci();
Bytecode_invoke inv(m, bci);
int args_cell = 0;
if (MethodData::profile_arguments_for_invoke(m, bci)) {
args_cell = TypeStackSlotEntries::compute_cell_count(inv.signature(), false, TypeProfileArgsLimit);
}
int ret_cell = 0;
if (MethodData::profile_return_for_invoke(m, bci) && is_reference_type(inv.result_type())) {
! ret_cell = ReturnTypeEntry::static_cell_count();
}
int header_cell = 0;
if (args_cell + ret_cell > 0) {
header_cell = header_cell_count();
}
return args_count * per_arg_cell_count;
}
int TypeEntriesAtCall::compute_cell_count(BytecodeStream* stream) {
assert(Bytecodes::is_invoke(stream->code()), "should be invoke");
! assert(TypeStackSlotEntries::per_arg_count() > SingleTypeEntry::static_cell_count(), "code to test for arguments/results broken");
const methodHandle m = stream->method();
int bci = stream->bci();
Bytecode_invoke inv(m, bci);
int args_cell = 0;
if (MethodData::profile_arguments_for_invoke(m, bci)) {
args_cell = TypeStackSlotEntries::compute_cell_count(inv.signature(), false, TypeProfileArgsLimit);
}
int ret_cell = 0;
if (MethodData::profile_return_for_invoke(m, bci) && is_reference_type(inv.result_type())) {
! ret_cell = SingleTypeEntry::static_cell_count();
}
int header_cell = 0;
if (args_cell + ret_cell > 0) {
header_cell = header_cell_count();
}
set_type(i, with_status((Klass*)nullptr, p));
}
}
}
! void ReturnTypeEntry::clean_weak_klass_links(bool always_clean) {
intptr_t p = type();
Klass* k = (Klass*)klass_part(p);
if (k != nullptr && (always_clean || !k->is_loader_alive())) {
set_type(with_status((Klass*)nullptr, p));
}
set_type(i, with_status((Klass*)nullptr, p));
}
}
}
! void SingleTypeEntry::clean_weak_klass_links(bool always_clean) {
intptr_t p = type();
Klass* k = (Klass*)klass_part(p);
if (k != nullptr && (always_clean || !k->is_loader_alive())) {
set_type(with_status((Klass*)nullptr, p));
}
print_klass(st, type(i));
st->cr();
}
}
! void ReturnTypeEntry::print_data_on(outputStream* st) const {
_pd->tab(st);
print_klass(st, type());
st->cr();
}
print_klass(st, type(i));
st->cr();
}
}
! void SingleTypeEntry::print_data_on(outputStream* st) const {
_pd->tab(st);
print_klass(st, type());
st->cr();
}
set_displacement(offset);
}
void BranchData::print_data_on(outputStream* st, const char* extra) const {
print_shared(st, "BranchData", extra);
+ if (data()->flags()) {
+ tty->cr();
+ tab(st);
+ }
st->print_cr("taken(%u) displacement(%d)",
taken(), displacement());
tab(st);
st->print_cr("not taken(%u)", not_taken());
}
tab(st);
method()->print_short_name(st);
st->cr();
}
+ void ArrayStoreData::print_data_on(outputStream* st, const char* extra) const {
+ print_shared(st, "ArrayStore", extra);
+ st->cr();
+ tab(st, true);
+ st->print("array");
+ _array.print_data_on(st);
+ tab(st, true);
+ st->print("element");
+ if (null_seen()) {
+ st->print(" (null seen)");
+ }
+ tab(st);
+ print_receiver_data_on(st);
+ }
+
+ void ArrayLoadData::print_data_on(outputStream* st, const char* extra) const {
+ print_shared(st, "ArrayLoad", extra);
+ st->cr();
+ tab(st, true);
+ st->print("array");
+ _array.print_data_on(st);
+ tab(st, true);
+ st->print("element");
+ _element.print_data_on(st);
+ }
+
+ void ACmpData::print_data_on(outputStream* st, const char* extra) const {
+ BranchData::print_data_on(st, extra);
+ tab(st, true);
+ st->print("left");
+ _left.print_data_on(st);
+ tab(st, true);
+ st->print("right");
+ _right.print_data_on(st);
+ }
+
// ==================================================================
// MethodData*
//
// A MethodData* holds information which has been collected about
// a method.
int MethodData::bytecode_cell_count(Bytecodes::Code code) {
switch (code) {
case Bytecodes::_checkcast:
case Bytecodes::_instanceof:
- case Bytecodes::_aastore:
if (TypeProfileCasts) {
return ReceiverTypeData::static_cell_count();
} else {
return BitData::static_cell_count();
}
case Bytecodes::_invokespecial:
case Bytecodes::_invokestatic:
if (MethodData::profile_arguments() || MethodData::profile_return()) {
return variable_cell_count;
} else {
int MethodData::bytecode_cell_count(Bytecodes::Code code) {
switch (code) {
case Bytecodes::_checkcast:
case Bytecodes::_instanceof:
if (TypeProfileCasts) {
return ReceiverTypeData::static_cell_count();
} else {
return BitData::static_cell_count();
}
+ case Bytecodes::_aaload:
+ return ArrayLoadData::static_cell_count();
+ case Bytecodes::_aastore:
+ return ArrayStoreData::static_cell_count();
case Bytecodes::_invokespecial:
case Bytecodes::_invokestatic:
if (MethodData::profile_arguments() || MethodData::profile_return()) {
return variable_cell_count;
} else {
case Bytecodes::_if_icmpne:
case Bytecodes::_if_icmplt:
case Bytecodes::_if_icmpge:
case Bytecodes::_if_icmpgt:
case Bytecodes::_if_icmple:
- case Bytecodes::_if_acmpeq:
- case Bytecodes::_if_acmpne:
case Bytecodes::_ifnull:
case Bytecodes::_ifnonnull:
return BranchData::static_cell_count();
case Bytecodes::_lookupswitch:
case Bytecodes::_tableswitch:
return variable_cell_count;
default:
return no_profile_data;
case Bytecodes::_if_icmpne:
case Bytecodes::_if_icmplt:
case Bytecodes::_if_icmpge:
case Bytecodes::_if_icmpgt:
case Bytecodes::_if_icmple:
case Bytecodes::_ifnull:
case Bytecodes::_ifnonnull:
return BranchData::static_cell_count();
+ case Bytecodes::_if_acmpne:
+ case Bytecodes::_if_acmpeq:
+ return ACmpData::static_cell_count();
case Bytecodes::_lookupswitch:
case Bytecodes::_tableswitch:
return variable_cell_count;
default:
return no_profile_data;
bool MethodData::is_speculative_trap_bytecode(Bytecodes::Code code) {
// Bytecodes for which we may use speculation
switch (code) {
case Bytecodes::_checkcast:
case Bytecodes::_instanceof:
+ case Bytecodes::_aaload:
case Bytecodes::_aastore:
case Bytecodes::_invokevirtual:
case Bytecodes::_invokeinterface:
case Bytecodes::_if_acmpeq:
case Bytecodes::_if_acmpne:
DataLayout* data_layout = data_layout_at(data_index);
Bytecodes::Code c = stream->code();
switch (c) {
case Bytecodes::_checkcast:
case Bytecodes::_instanceof:
- case Bytecodes::_aastore:
if (TypeProfileCasts) {
cell_count = ReceiverTypeData::static_cell_count();
tag = DataLayout::receiver_type_data_tag;
} else {
cell_count = BitData::static_cell_count();
tag = DataLayout::bit_data_tag;
}
break;
case Bytecodes::_invokespecial:
case Bytecodes::_invokestatic: {
int counter_data_cell_count = CounterData::static_cell_count();
if (profile_arguments_for_invoke(stream->method(), stream->bci()) ||
profile_return_for_invoke(stream->method(), stream->bci())) {
DataLayout* data_layout = data_layout_at(data_index);
Bytecodes::Code c = stream->code();
switch (c) {
case Bytecodes::_checkcast:
case Bytecodes::_instanceof:
if (TypeProfileCasts) {
cell_count = ReceiverTypeData::static_cell_count();
tag = DataLayout::receiver_type_data_tag;
} else {
cell_count = BitData::static_cell_count();
tag = DataLayout::bit_data_tag;
}
break;
+ case Bytecodes::_aaload:
+ cell_count = ArrayLoadData::static_cell_count();
+ tag = DataLayout::array_load_data_tag;
+ break;
+ case Bytecodes::_aastore:
+ cell_count = ArrayStoreData::static_cell_count();
+ tag = DataLayout::array_store_data_tag;
+ break;
case Bytecodes::_invokespecial:
case Bytecodes::_invokestatic: {
int counter_data_cell_count = CounterData::static_cell_count();
if (profile_arguments_for_invoke(stream->method(), stream->bci()) ||
profile_return_for_invoke(stream->method(), stream->bci())) {
case Bytecodes::_if_icmpne:
case Bytecodes::_if_icmplt:
case Bytecodes::_if_icmpge:
case Bytecodes::_if_icmpgt:
case Bytecodes::_if_icmple:
- case Bytecodes::_if_acmpeq:
- case Bytecodes::_if_acmpne:
case Bytecodes::_ifnull:
case Bytecodes::_ifnonnull:
cell_count = BranchData::static_cell_count();
tag = DataLayout::branch_data_tag;
break;
case Bytecodes::_lookupswitch:
case Bytecodes::_tableswitch:
cell_count = MultiBranchData::compute_cell_count(stream);
tag = DataLayout::multi_branch_data_tag;
break;
case Bytecodes::_if_icmpne:
case Bytecodes::_if_icmplt:
case Bytecodes::_if_icmpge:
case Bytecodes::_if_icmpgt:
case Bytecodes::_if_icmple:
case Bytecodes::_ifnull:
case Bytecodes::_ifnonnull:
cell_count = BranchData::static_cell_count();
tag = DataLayout::branch_data_tag;
break;
+ case Bytecodes::_if_acmpeq:
+ case Bytecodes::_if_acmpne:
+ cell_count = ACmpData::static_cell_count();
+ tag = DataLayout::acmp_data_tag;
+ break;
case Bytecodes::_lookupswitch:
case Bytecodes::_tableswitch:
cell_count = MultiBranchData::compute_cell_count(stream);
tag = DataLayout::multi_branch_data_tag;
break;
return ((new VirtualCallTypeData(this))->cell_count());
case DataLayout::parameters_type_data_tag:
return ((new ParametersTypeData(this))->cell_count());
case DataLayout::speculative_trap_data_tag:
return SpeculativeTrapData::static_cell_count();
+ case DataLayout::array_store_data_tag:
+ return ((new ArrayStoreData(this))->cell_count());
+ case DataLayout::array_load_data_tag:
+ return ((new ArrayLoadData(this))->cell_count());
+ case DataLayout::acmp_data_tag:
+ return ((new ACmpData(this))->cell_count());
}
}
ProfileData* DataLayout::data_in() {
switch (tag()) {
case DataLayout::no_tag:
return new VirtualCallTypeData(this);
case DataLayout::parameters_type_data_tag:
return new ParametersTypeData(this);
case DataLayout::speculative_trap_data_tag:
return new SpeculativeTrapData(this);
+ case DataLayout::array_store_data_tag:
+ return new ArrayStoreData(this);
+ case DataLayout::array_load_data_tag:
+ return new ArrayLoadData(this);
+ case DataLayout::acmp_data_tag:
+ return new ACmpData(this);
}
}
// Iteration over data.
ProfileData* MethodData::next_data(ProfileData* current) const {
< prev index next >