< prev index next >

src/share/vm/opto/callGenerator.cpp

Print this page

        

*** 115,132 **** // Internal class which handles all out-of-line calls w/o receiver type checks. class DirectCallGenerator : public CallGenerator { private: CallStaticJavaNode* _call_node; // Force separate memory and I/O projections for the exceptional ! // paths to facilitate late inlinig. bool _separate_io_proj; public: DirectCallGenerator(ciMethod* method, bool separate_io_proj) : CallGenerator(method), _separate_io_proj(separate_io_proj) { } virtual JVMState* generate(JVMState* jvms); CallStaticJavaNode* call_node() const { return _call_node; } }; --- 115,141 ---- // Internal class which handles all out-of-line calls w/o receiver type checks. class DirectCallGenerator : public CallGenerator { private: CallStaticJavaNode* _call_node; // Force separate memory and I/O projections for the exceptional ! // paths to facilitate late inlining. bool _separate_io_proj; public: DirectCallGenerator(ciMethod* method, bool separate_io_proj) : CallGenerator(method), _separate_io_proj(separate_io_proj) { + if (method->is_method_handle_intrinsic() && + method->signature()->return_type() == ciEnv::current()->___Value_klass()) { + // If that call has not been optimized by the time optimizations + // are over, we'll need to add a call to create a value type + // instance from the klass returned by the call. Separating + // memory and I/O projections for exceptions is required to + // perform that graph transformation. + _separate_io_proj = true; + } } virtual JVMState* generate(JVMState* jvms); CallStaticJavaNode* call_node() const { return _call_node; } };
*** 171,185 **** } kit.set_arguments_for_java_call(call); kit.set_edges_for_java_call(call, false, _separate_io_proj); Node* ret = kit.set_results_for_java_call(call, _separate_io_proj); // Check if return value is a value type pointer ! if (gvn.type(ret)->isa_valuetypeptr()) { // Create ValueTypeNode from the oop and replace the return value Node* vt = ValueTypeNode::make(gvn, kit.merged_memory(), ret); kit.push_node(T_VALUETYPE, vt); } else { kit.push_node(method()->return_type()->basic_type(), ret); } return kit.transfer_exceptions_into_jvms(); } --- 180,199 ---- } kit.set_arguments_for_java_call(call); kit.set_edges_for_java_call(call, false, _separate_io_proj); Node* ret = kit.set_results_for_java_call(call, _separate_io_proj); // Check if return value is a value type pointer ! const TypeValueTypePtr* vtptr = gvn.type(ret)->isa_valuetypeptr(); ! if (vtptr != NULL) { ! if (vtptr->klass() != kit.C->env()->___Value_klass()) { // Create ValueTypeNode from the oop and replace the return value Node* vt = ValueTypeNode::make(gvn, kit.merged_memory(), ret); kit.push_node(T_VALUETYPE, vt); } else { + kit.push_node(T_VALUETYPE, ret); + } + } else { kit.push_node(method()->return_type()->basic_type(), ret); } return kit.transfer_exceptions_into_jvms(); }
*** 427,437 **** } map->set_argument(jvms, i1, arg); } else { if (t->isa_valuetypeptr() && t->is_valuetypeptr()->klass() != C->env()->___Value_klass()) { ciValueKlass* vk = t->is_valuetypeptr()->value_type()->value_klass(); ! Node* vt = C->create_vt_node(call, vk, vk, 0, j); map->set_argument(jvms, i1, gvn.transform(vt)); j += vk->value_arg_slots(); } else { map->set_argument(jvms, i1, call->in(j)); j++; --- 441,451 ---- } map->set_argument(jvms, i1, arg); } else { if (t->isa_valuetypeptr() && t->is_valuetypeptr()->klass() != C->env()->___Value_klass()) { ciValueKlass* vk = t->is_valuetypeptr()->value_type()->value_klass(); ! Node* vt = C->create_vt_node(call, vk, vk, 0, j, true); map->set_argument(jvms, i1, gvn.transform(vt)); j += vk->value_arg_slots(); } else { map->set_argument(jvms, i1, call->in(j)); j++;
*** 468,488 **** // Capture any exceptional control flow GraphKit kit(new_jvms); // Find the result object Node* result = C->top(); ! int result_size = method()->return_type()->size(); if (result_size != 0 && !kit.stopped()) { result = (result_size == 1) ? kit.pop() : kit.pop_pair(); } C->set_has_loops(C->has_loops() || _inline_cg->method()->has_loops()); C->env()->notice_inlined_method(_inline_cg->method()); C->set_inlining_progress(true); if (result->is_ValueType()) { result = result->as_ValueType()->store_to_memory(&kit); } kit.replace_call(call, result, true); } --- 482,523 ---- // Capture any exceptional control flow GraphKit kit(new_jvms); // Find the result object Node* result = C->top(); ! ciType* return_type = _inline_cg->method()->return_type(); ! int result_size = return_type->size(); if (result_size != 0 && !kit.stopped()) { result = (result_size == 1) ? kit.pop() : kit.pop_pair(); } C->set_has_loops(C->has_loops() || _inline_cg->method()->has_loops()); C->env()->notice_inlined_method(_inline_cg->method()); C->set_inlining_progress(true); + if (return_type->is_valuetype() && return_type != C->env()->___Value_klass()) { if (result->is_ValueType()) { + if (!call->tf()->returns_value_type_as_fields()) { result = result->as_ValueType()->store_to_memory(&kit); + } else { + // Return of multiple values (the fields of a value type) + ValueTypeNode* vt = result->as_ValueType(); + vt->replace_call_results(call, C); + } + } else { + assert(result->is_top(), "what else?"); + for (DUIterator_Fast imax, i = call->fast_outs(imax); i < imax; i++) { + ProjNode *pn = call->fast_out(i)->as_Proj(); + uint con = pn->_con; + if (con >= TypeFunc::Parms) { + // C->gvn_replace_by(pn, C->top()); + C->initial_gvn()->hash_delete(pn); + pn->set_req(0, C->top()); + --i; --imax; + } + } + } } kit.replace_call(call, result, true); }
*** 519,537 **** } }; bool LateInlineMHCallGenerator::do_late_inline_check(JVMState* jvms) { ! CallGenerator* cg = for_method_handle_inline(jvms, _caller, method(), _input_not_const); Compile::current()->print_inlining_update_delayed(this); if (!_input_not_const) { _attempt++; } ! if (cg != NULL && cg->is_inline()) { assert(!cg->is_late_inline(), "we're doing late inlining"); _inline_cg = cg; Compile::current()->dec_number_of_mh_late_inlines(); return true; } --- 554,572 ---- } }; bool LateInlineMHCallGenerator::do_late_inline_check(JVMState* jvms) { ! CallGenerator* cg = for_method_handle_inline(jvms, _caller, method(), _input_not_const, AlwaysIncrementalInline); Compile::current()->print_inlining_update_delayed(this); if (!_input_not_const) { _attempt++; } ! if (cg != NULL && (cg->is_inline() || cg->is_inlined_method_handle_intrinsic(jvms, cg->method()))) { assert(!cg->is_late_inline(), "we're doing late inlining"); _inline_cg = cg; Compile::current()->dec_number_of_mh_late_inlines(); return true; }
*** 829,839 **** CallGenerator* CallGenerator::for_method_handle_call(JVMState* jvms, ciMethod* caller, ciMethod* callee, bool delayed_forbidden) { assert(callee->is_method_handle_intrinsic(), "for_method_handle_call mismatch"); bool input_not_const; ! CallGenerator* cg = CallGenerator::for_method_handle_inline(jvms, caller, callee, input_not_const); Compile* C = Compile::current(); if (cg != NULL) { if (!delayed_forbidden && AlwaysIncrementalInline) { return CallGenerator::for_late_inline(callee, cg); } else { --- 864,874 ---- CallGenerator* CallGenerator::for_method_handle_call(JVMState* jvms, ciMethod* caller, ciMethod* callee, bool delayed_forbidden) { assert(callee->is_method_handle_intrinsic(), "for_method_handle_call mismatch"); bool input_not_const; ! CallGenerator* cg = CallGenerator::for_method_handle_inline(jvms, caller, callee, input_not_const, false); Compile* C = Compile::current(); if (cg != NULL) { if (!delayed_forbidden && AlwaysIncrementalInline) { return CallGenerator::for_late_inline(callee, cg); } else {
*** 842,861 **** } int bci = jvms->bci(); ciCallProfile profile = caller->call_profile_at_bci(bci); int call_site_count = caller->scale_count(profile.count()); ! if (IncrementalInline && call_site_count > 0 && ! (input_not_const || !C->inlining_incrementally() || C->over_inlining_cutoff())) { return CallGenerator::for_mh_late_inline(caller, callee, input_not_const); } else { // Out-of-line call. return CallGenerator::for_direct_call(callee); } } ! CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* caller, ciMethod* callee, bool& input_not_const) { GraphKit kit(jvms); PhaseGVN& gvn = kit.gvn(); Compile* C = kit.C; vmIntrinsics::ID iid = callee->intrinsic_id(); input_not_const = true; --- 877,896 ---- } int bci = jvms->bci(); ciCallProfile profile = caller->call_profile_at_bci(bci); int call_site_count = caller->scale_count(profile.count()); ! if (IncrementalInline && (AlwaysIncrementalInline || ! (call_site_count > 0 && (input_not_const || !C->inlining_incrementally() || C->over_inlining_cutoff())))) { return CallGenerator::for_mh_late_inline(caller, callee, input_not_const); } else { // Out-of-line call. return CallGenerator::for_direct_call(callee); } } ! CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* caller, ciMethod* callee, bool& input_not_const, bool delayed_forbidden) { GraphKit kit(jvms); PhaseGVN& gvn = kit.gvn(); Compile* C = kit.C; vmIntrinsics::ID iid = callee->intrinsic_id(); input_not_const = true;
*** 878,888 **** CallGenerator* cg = C->call_generator(target, vtable_index, false /* call_does_dispatch */, jvms, true /* allow_inline */, ! PROB_ALWAYS); return cg; } else { print_inlining_failure(C, callee, jvms->depth() - 1, jvms->bci(), "receiver not constant"); } --- 913,926 ---- CallGenerator* cg = C->call_generator(target, vtable_index, false /* call_does_dispatch */, jvms, true /* allow_inline */, ! PROB_ALWAYS, ! NULL, ! true, ! delayed_forbidden); return cg; } else { print_inlining_failure(C, callee, jvms->depth() - 1, jvms->bci(), "receiver not constant"); }
*** 962,972 **** speculative_receiver_type = (receiver_type != NULL) ? receiver_type->speculative_type() : NULL; } CallGenerator* cg = C->call_generator(target, vtable_index, call_does_dispatch, jvms, true /* allow_inline */, PROB_ALWAYS, ! speculative_receiver_type); return cg; } else { print_inlining_failure(C, callee, jvms->depth() - 1, jvms->bci(), "member_name not constant"); } --- 1000,1012 ---- speculative_receiver_type = (receiver_type != NULL) ? receiver_type->speculative_type() : NULL; } CallGenerator* cg = C->call_generator(target, vtable_index, call_does_dispatch, jvms, true /* allow_inline */, PROB_ALWAYS, ! speculative_receiver_type, ! true, ! delayed_forbidden); return cg; } else { print_inlining_failure(C, callee, jvms->depth() - 1, jvms->bci(), "member_name not constant"); }
< prev index next >