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	Wed Oct  9 18:09:23 2013
--- new/src/share/vm/oops/methodData.cpp	Wed Oct  9 18:09:23 2013

*** 154,173 **** --- 154,188 ---- 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) { ResourceMark rm; ! SignatureStream ss(inv.signature()); int 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"); + assert(TypeStackSlotEntries::per_arg_count() > ReturnTypeEntry::static_cell_count(), "code to test for arguments/results broken"); + 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 **** --- 210,297 ---- 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; + ArgumentOffsetComputer aos(signature, _number_of_entries); + aos.total(); + for (int i = 0; i < _number_of_entries; i++) { + set_stack_slot(i, aos.off_at(i) + (has_receiver ? 1 : 0)); + set_type(i, type_none()); + } + } + + void CallTypeData::post_initialize(BytecodeStream* stream, MethodData* mdo) { + assert(Bytecodes::is_invoke(stream->code()), "should be invoke"); + Bytecode_invoke inv(stream->method(), stream->bci()); + + SignatureStream ss(inv.signature()); + if (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()); + } + + if (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(); + } + } + void VirtualCallTypeData::post_initialize(BytecodeStream* stream, MethodData* mdo) { assert(Bytecodes::is_invoke(stream->code()), "should be invoke"); Bytecode_invoke inv(stream->method(), stream->bci()); + if (has_arguments()) { #ifdef ASSERT + ResourceMark rm; SignatureStream ss(inv.signature()); 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 (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 < _number_of_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 TypeEntriesAtCall::return_profiling_enabled() { + return MethodData::profile_return(); + } + + bool TypeEntriesAtCall::arguments_profiling_enabled() { return MethodData::profile_arguments(); } #ifndef PRODUCT void TypeEntries::print_klass(outputStream* st, intptr_t k) {
*** 251,278 **** --- 306,355 ---- 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 < _number_of_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 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); + } + if (has_return()) { + tab(st, true); + 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); + } + if (has_return()) { + tab(st, true); + st->print("return type"); + _ret.print_data_on(st); + } } #endif // ================================================================== // ReceiverTypeData
*** 528,538 **** --- 605,615 ---- } 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 **** --- 617,633 ---- 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 **** --- 671,693 ---- 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 **** --- 776,787 ---- } 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 **** --- 799,810 ---- 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 **** --- 815,826 ---- 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 **** --- 858,868 ---- 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 **** --- 1191,1201 ---- 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 **** --- 1219,1251 ---- 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