src/share/vm/oops/methodData.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File
*** old/src/share/vm/oops/methodData.cpp	Tue Oct  8 18:00:00 2013
--- new/src/share/vm/oops/methodData.cpp	Tue Oct  8 17:59:59 2013

*** 154,173 **** --- 154,187 ---- print_shared(st, "JumpData"); st->print_cr("taken(%u) displacement(%d)", taken(), displacement()); } #endif // !PRODUCT ! int TypeStackSlotEntries::compute_cell_count(BytecodeStream* stream) { ! int max = TypeProfileArgsLimit; assert(Bytecodes::is_invoke(stream->code()), "should be invoke"); Bytecode_invoke inv(stream->method(), stream->bci()); ! int TypeStackSlotEntries::compute_cell_count(Symbol* signature, int max) { ! int args_count = 0; ResourceMark rm; ! SignatureStream ss(inv.signature()); ! int args_count = MIN2(ss.reference_parameter_count(), max); ! args_count += MIN2(ss.reference_parameter_count(), max); + return args_count * per_arg_cell_count; + } return args_count * per_arg_cell_count + (args_count > 0 ? header_cell_count() : 0); + int TypeEntriesAtCall::compute_cell_count(BytecodeStream* stream) { + assert(Bytecodes::is_invoke(stream->code()), "should be invoke"); + Bytecode_invoke inv(stream->method(), stream->bci()); + int args_cell = 0; + if (arguments_profiling_enabled()) { + args_cell = TypeStackSlotEntries::compute_cell_count(inv.signature(), TypeProfileArgsLimit); + } + int ret_cell = 0; + if (return_profiling_enabled() && (inv.result_type() == T_OBJECT || inv.result_type() == T_ARRAY)) { + ret_cell = ReturnTypeEntry::static_cell_count(); + } + int header_cell = 0; + if (args_cell + ret_cell > 0) { + header_cell = header_cell_count(); + } + return header_cell + args_cell + ret_cell; } class ArgumentOffsetComputer : public SignatureInfo { private: int _max;
*** 195,242 **** --- 209,285 ---- int total() { lazy_iterate_parameters(); return _size; } int off_at(int i) const { return _offsets.at(i); } }; ! void TypeStackSlotEntries::post_initialize(BytecodeStream* stream) { ! void TypeStackSlotEntries::post_initialize(Symbol* signature, bool has_receiver) { ResourceMark rm; + int start = 0; + ArgumentOffsetComputer aos(signature, _nb_entries-start); + aos.total(); + for (int i = start; i < _nb_entries; i++) { + set_stack_slot(i, aos.off_at(i-start) + (has_receiver ? 1 : 0)); + set_type(i, type_none()); + } + } + void TypeEntriesAtCall::post_initialize(BytecodeStream* stream) { assert(Bytecodes::is_invoke(stream->code()), "should be invoke"); Bytecode_invoke inv(stream->method(), stream->bci()); #ifdef ASSERT SignatureStream ss(inv.signature()); + if (arguments_profiling_enabled() && has_arguments()) { + #ifdef ASSERT + ResourceMark rm; int count = MIN2(ss.reference_parameter_count(), TypeProfileArgsLimit); assert(count > 0, "room for args type but none found?"); check_number_of_arguments(count); #endif + _args.post_initialize(inv.signature(), inv.has_receiver()); + } ! int start = 0; ! ArgumentOffsetComputer aos(inv.signature(), number_of_arguments()-start); ! aos.total(); bool has_receiver = inv.has_receiver(); for (int i = start; i < number_of_arguments(); i++) { set_stack_slot(i, aos.off_at(i-start) + (has_receiver ? 1 : 0)); set_type(i, type_none()); ! if (return_profiling_enabled() && has_return()) { ! assert(inv.result_type() == T_OBJECT || inv.result_type() == T_ARRAY, "room for a ret type but doesn't return obj?"); ! _ret.post_initialize(); } } bool TypeEntries::is_loader_alive(BoolObjectClosure* is_alive_cl, intptr_t p) { return !is_type_none(p) && !((Klass*)klass_part(p))->is_loader_alive(is_alive_cl); } void TypeStackSlotEntries::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) { ! for (int i = 0; i < number_of_arguments(); i++) { ! for (int i = 0; i < _nb_entries; i++) { intptr_t p = type(i); if (is_loader_alive(is_alive_cl, p)) { set_type(i, type_none()); } } } ! bool TypeStackSlotEntries::arguments_profiling_enabled() { ! void ReturnTypeEntry::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) { + intptr_t p = type(); + if (is_loader_alive(is_alive_cl, p)) { + set_type(type_none()); + } + } + + bool ReturnTypeEntry::profiling_enabled() { + return MethodData::profile_return(); + } + + void TypeEntriesAtCall::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) { + if (arguments_profiling_enabled()) { + _args.clean_weak_klass_links(is_alive_cl); + } + if (return_profiling_enabled()) { + _ret.clean_weak_klass_links(is_alive_cl); + } + } + + bool TypeEntriesAtCall::arguments_profiling_enabled() { return MethodData::profile_arguments(); } #ifndef PRODUCT void TypeEntries::print_klass(outputStream* st, intptr_t k) {
*** 251,278 **** --- 294,338 ---- st->print(" (null seen)"); } } void TypeStackSlotEntries::print_data_on(outputStream* st) const { _pd->tab(st, true); st->print("argument types"); for (int i = 0; i < number_of_arguments(); i++) { + for (int i = 0; i < _nb_entries; i++) { _pd->tab(st); st->print("%d: stack(%u) ", i, stack_slot(i)); print_klass(st, type(i)); st->cr(); } } + void ReturnTypeEntry::print_data_on(outputStream* st) const { + _pd->tab(st); + print_klass(st, type()); + st->cr(); + } + + void TypeEntriesAtCall::print_data_on(outputStream* st) const { + if (arguments_profiling_enabled() && has_arguments()) { + _pd->tab(st, true); + st->print("argument types"); + _args.print_data_on(st); + } + if (return_profiling_enabled() && has_return()) { + _pd->tab(st, true); + st->print("return type"); + _ret.print_data_on(st); + } + } + void CallTypeData::print_data_on(outputStream* st) const { CounterData::print_data_on(st); ! _args_and_ret.print_data_on(st); } void VirtualCallTypeData::print_data_on(outputStream* st) const { VirtualCallData::print_data_on(st); ! _args_and_ret.print_data_on(st); } #endif // ================================================================== // ReceiverTypeData
*** 528,538 **** --- 588,598 ---- } else { return BitData::static_cell_count(); } case Bytecodes::_invokespecial: case Bytecodes::_invokestatic: ! if (MethodData::profile_arguments() || MethodData::profile_return()) { return variable_cell_count; } else { return CounterData::static_cell_count(); } case Bytecodes::_goto:
*** 540,556 **** --- 600,616 ---- case Bytecodes::_jsr: case Bytecodes::_jsr_w: return JumpData::static_cell_count(); case Bytecodes::_invokevirtual: case Bytecodes::_invokeinterface: ! if (MethodData::profile_arguments() || MethodData::profile_return()) { return variable_cell_count; } else { return VirtualCallData::static_cell_count(); } case Bytecodes::_invokedynamic: ! if (MethodData::profile_arguments() || MethodData::profile_return()) { return variable_cell_count; } else { return CounterData::static_cell_count(); } case Bytecodes::_ret:
*** 594,614 **** --- 654,676 ---- cell_count = MultiBranchData::compute_cell_count(stream); break; case Bytecodes::_invokespecial: case Bytecodes::_invokestatic: case Bytecodes::_invokedynamic: ! assert(MethodData::profile_arguments() || MethodData::profile_return(), "should be collecting args profile"); ! if (profile_arguments_for_invoke(stream->method(), stream->bci())) { ! if (profile_arguments_for_invoke(stream->method(), stream->bci()) || + profile_return_for_invoke(stream->method(), stream->bci())) { cell_count = CallTypeData::compute_cell_count(stream); } else { cell_count = CounterData::static_cell_count(); } break; case Bytecodes::_invokevirtual: case Bytecodes::_invokeinterface: { ! assert(MethodData::profile_arguments() || MethodData::profile_return(), "should be collecting args profile"); ! if (profile_arguments_for_invoke(stream->method(), stream->bci())) { ! if (profile_arguments_for_invoke(stream->method(), stream->bci()) || + profile_return_for_invoke(stream->method(), stream->bci())) { cell_count = VirtualCallTypeData::compute_cell_count(stream); } else { cell_count = VirtualCallData::static_cell_count(); } break;
*** 697,707 **** --- 759,770 ---- } 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())) { ! if (profile_arguments_for_invoke(stream->method(), stream->bci()) || + profile_return_for_invoke(stream->method(), stream->bci())) { cell_count = CallTypeData::compute_cell_count(stream); } else { cell_count = counter_data_cell_count; } if (cell_count > counter_data_cell_count) {
*** 719,729 **** --- 782,793 ---- tag = DataLayout::jump_data_tag; break; case Bytecodes::_invokevirtual: case Bytecodes::_invokeinterface: { int virtual_call_data_cell_count = VirtualCallData::static_cell_count(); ! if (profile_arguments_for_invoke(stream->method(), stream->bci())) { ! if (profile_arguments_for_invoke(stream->method(), stream->bci()) || + profile_return_for_invoke(stream->method(), stream->bci())) { cell_count = VirtualCallTypeData::compute_cell_count(stream); } else { cell_count = virtual_call_data_cell_count; } if (cell_count > virtual_call_data_cell_count) {
*** 734,744 **** --- 798,809 ---- break; } case Bytecodes::_invokedynamic: { // %%% should make a type profile for any invokedynamic that takes a ref argument int counter_data_cell_count = CounterData::static_cell_count(); ! if (profile_arguments_for_invoke(stream->method(), stream->bci())) { ! if (profile_arguments_for_invoke(stream->method(), stream->bci()) || + profile_return_for_invoke(stream->method(), stream->bci())) { cell_count = CallTypeData::compute_cell_count(stream); } else { cell_count = counter_data_cell_count; } if (cell_count > counter_data_cell_count) {
*** 776,786 **** --- 841,851 ---- cell_count = MultiBranchData::compute_cell_count(stream); tag = DataLayout::multi_branch_data_tag; break; } assert(tag == DataLayout::multi_branch_data_tag || ! ((MethodData::profile_arguments() || MethodData::profile_return()) && (tag == DataLayout::call_type_data_tag || tag == DataLayout::counter_data_tag || tag == DataLayout::virtual_call_type_data_tag || tag == DataLayout::virtual_call_data_tag)) || cell_count == bytecode_cell_count(c), "cell counts must agree");
*** 1109,1119 **** --- 1174,1184 ---- Bytecode_invoke inv(m , bci); return inv.is_invokedynamic() || inv.is_invokehandle(); } int MethodData::profile_arguments_flag() { ! return TypeProfileLevel % 10; } bool MethodData::profile_arguments() { return profile_arguments_flag() > no_type_profile && profile_arguments_flag() <= type_profile_all; }
*** 1137,1141 **** --- 1202,1234 ---- assert(profile_arguments_jsr292_only(), "inconsistent"); return profile_jsr292(m, bci); } + int MethodData::profile_return_flag() { + return TypeProfileLevel / 10; + } + + bool MethodData::profile_return() { + return profile_return_flag() > no_type_profile && profile_return_flag() <= type_profile_all; + } + + bool MethodData::profile_return_jsr292_only() { + return profile_return_flag() == type_profile_jsr292; + } + + bool MethodData::profile_all_return() { + return profile_return_flag() == type_profile_all; + } + + bool MethodData::profile_return_for_invoke(methodHandle m, int bci) { + if (!profile_return()) { + return false; + } + + if (profile_all_return()) { + return true; + } + + assert(profile_return_jsr292_only(), "inconsistent"); + return profile_jsr292(m, bci); + }

src/share/vm/oops/methodData.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File