src/share/vm/c1/c1_GraphBuilder.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Cdiff src/share/vm/c1/c1_GraphBuilder.cpp

src/share/vm/c1/c1_GraphBuilder.cpp

Print this page
rev 5240 : 8023657: New type profiling points: arguments to call
Summary: x86 interpreter and c1 type profiling for arguments at calls
Reviewed-by:

*** 1656,1665 **** --- 1656,1701 ---- Dependencies* GraphBuilder::dependency_recorder() const { assert(DeoptC1, "need debug information"); return compilation()->dependency_recorder(); } + // How many arguments do we want to profile? + Values* GraphBuilder::args_list_for_profiling(ciMethod* target, int& start, bool may_have_receiver) { + int n = 0; + assert(start == 0, "should be initialized"); + if (MethodData::profile_arguments()) { + ciProfileData* data = method()->method_data()->bci_to_data(bci()); + if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) { + n = data->is_CallTypeData() ? data->as_CallTypeData()->number_of_arguments() : data->as_VirtualCallTypeData()->number_of_arguments(); + bool has_receiver = may_have_receiver && Bytecodes::has_receiver(method()->java_code_at_bci(bci())); + start = has_receiver ? 1 : 0; + } + } + if (n > 0) { + return new Values(n); + } + return NULL; + } + + // Collect arguments that we want to profile in a list + Values* GraphBuilder::collect_args_for_profiling(Values* args, ciMethod* target, bool may_have_receiver) { + int start = 0; + Values* obj_args = args_list_for_profiling(target, start, may_have_receiver); + if (obj_args == NULL) { + return NULL; + } + int s = obj_args->size(); + for (int i = start, j = 0; j < s; i++) { + if (args->at(i)->type()->is_object_kind()) { + obj_args->push(args->at(i)); + j++; + } + } + assert(s == obj_args->length(), "missed on arg?"); + return obj_args; + } + void GraphBuilder::invoke(Bytecodes::Code code) { bool will_link; ciSignature* declared_signature = NULL; ciMethod* target = stream()->get_method(will_link, &declared_signature);
*** 1955,1965 **** if (cha_monomorphic_target != NULL) { target_klass = cha_monomorphic_target->holder(); } else if (exact_target != NULL) { target_klass = exact_target->holder(); } ! profile_call(target, recv, target_klass); } } Invoke* result = new Invoke(code, result_type, recv, args, vtable_index, target, state_before); // push result --- 1991,2001 ---- if (cha_monomorphic_target != NULL) { target_klass = cha_monomorphic_target->holder(); } else if (exact_target != NULL) { target_klass = exact_target->holder(); } ! profile_call(target, recv, target_klass, collect_args_for_profiling(args, NULL, false), false); } } Invoke* result = new Invoke(code, result_type, recv, args, vtable_index, target, state_before); // push result
*** 3507,3517 **** Value recv = NULL; if (has_receiver) { recv = args->at(0); null_check(recv); } ! profile_call(callee, recv, NULL); } } } Intrinsic* result = new Intrinsic(result_type, id, args, has_receiver, state_before, --- 3543,3553 ---- Value recv = NULL; if (has_receiver) { recv = args->at(0); null_check(recv); } ! profile_call(callee, recv, NULL, collect_args_for_profiling(args, NULL, true), true); } } } Intrinsic* result = new Intrinsic(result_type, id, args, has_receiver, state_before,
*** 3761,3771 **** // Note that we'd collect profile data in this method if we wanted it. // this may be redundant here... compilation()->set_would_profile(true); if (profile_calls()) { ! profile_call(callee, recv, holder_known ? callee->holder() : NULL); } } // Introduce a new callee continuation point - if the callee has // more than one return instruction or the return does not allow --- 3797,3828 ---- // Note that we'd collect profile data in this method if we wanted it. // this may be redundant here... compilation()->set_would_profile(true); if (profile_calls()) { ! int start = 0; ! Values* obj_args = args_list_for_profiling(callee, start, has_receiver); ! if (obj_args != NULL) { ! int s = obj_args->size(); ! // if called through method handle invoke, some arguments may have been popped ! for (int i = args_base+start, j = 0; j < obj_args->size() && i < state()->stack_size(); ) { ! Value v = state()->stack_at_inc(i); ! if (v->type()->is_object_kind()) { ! obj_args->push(v); ! j++; ! } ! } ! #ifdef ASSERT ! { ! bool ignored_will_link; ! ciSignature* declared_signature = NULL; ! ciMethod* real_target = method()->get_method_at_bci(bci(), ignored_will_link, &declared_signature); ! assert(s == obj_args->length() || real_target->is_method_handle_intrinsic(), "missed on arg?"); ! } ! #endif ! } ! profile_call(callee, recv, holder_known ? callee->holder() : NULL, obj_args, true); } } // Introduce a new callee continuation point - if the callee has // more than one return instruction or the return does not allow
*** 4247,4258 **** void GraphBuilder::print_stats() { vmap()->print(); } #endif // PRODUCT ! void GraphBuilder::profile_call(ciMethod* callee, Value recv, ciKlass* known_holder) { ! append(new ProfileCall(method(), bci(), callee, recv, known_holder)); } void GraphBuilder::profile_invocation(ciMethod* callee, ValueStack* state) { append(new ProfileInvoke(callee, state)); } --- 4304,4315 ---- void GraphBuilder::print_stats() { vmap()->print(); } #endif // PRODUCT ! void GraphBuilder::profile_call(ciMethod* callee, Value recv, ciKlass* known_holder, Values* obj_args, bool inlined) { ! append(new ProfileCall(method(), bci(), callee, recv, known_holder, obj_args, inlined)); } void GraphBuilder::profile_invocation(ciMethod* callee, ValueStack* state) { append(new ProfileInvoke(callee, state)); }
src/share/vm/c1/c1_GraphBuilder.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File