< prev index next >

src/hotspot/share/opto/callGenerator.cpp

Print this page

        

*** 37,46 **** --- 37,47 ---- #include "opto/cfgnode.hpp" #include "opto/parse.hpp" #include "opto/rootnode.hpp" #include "opto/runtime.hpp" #include "opto/subnode.hpp" + #include "opto/valuetypenode.hpp" #include "runtime/sharedRuntime.hpp" // Utility function. const TypeFunc* CallGenerator::tf() const { return TypeFunc::make(method());
*** 121,147 **** // 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; } }; JVMState* DirectCallGenerator::generate(JVMState* jvms) { GraphKit kit(jvms); kit.C->print_inlining_update(this); bool is_static = method()->is_static(); address target = is_static ? SharedRuntime::get_resolve_static_call_stub() : SharedRuntime::get_resolve_opt_virtual_call_stub(); if (kit.C->log() != NULL) { --- 122,158 ---- // 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), + _call_node(NULL), _separate_io_proj(separate_io_proj) { + if (ValueTypeReturnedAsFields && method->is_method_handle_intrinsic()) { + // 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 (see PhaseMacroExpand::expand_mh_intrinsic_return). + // 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; } }; JVMState* DirectCallGenerator::generate(JVMState* jvms) { GraphKit kit(jvms); kit.C->print_inlining_update(this); + PhaseGVN& gvn = kit.gvn(); bool is_static = method()->is_static(); address target = is_static ? SharedRuntime::get_resolve_static_call_stub() : SharedRuntime::get_resolve_opt_virtual_call_stub(); if (kit.C->log() != NULL) {
*** 170,180 **** if (method()->is_method_handle_intrinsic() || method()->is_compiled_lambda_form()) { call->set_method_handle_invoke(true); } } ! 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); kit.push_node(method()->return_type()->basic_type(), ret); return kit.transfer_exceptions_into_jvms(); } --- 181,194 ---- if (method()->is_method_handle_intrinsic() || method()->is_compiled_lambda_form()) { call->set_method_handle_invoke(true); } } ! kit.set_arguments_for_java_call(call, is_late_inline()); ! if (kit.stopped()) { ! return kit.transfer_exceptions_into_jvms(); ! } kit.set_edges_for_java_call(call, false, _separate_io_proj); Node* ret = kit.set_results_for_java_call(call, _separate_io_proj); kit.push_node(method()->return_type()->basic_type(), ret); return kit.transfer_exceptions_into_jvms(); }
*** 196,206 **** }; JVMState* VirtualCallGenerator::generate(JVMState* jvms) { GraphKit kit(jvms); Node* receiver = kit.argument(0); - kit.C->print_inlining_update(this); if (kit.C->log() != NULL) { kit.C->log()->elem("virtual_call bci='%d'", jvms->bci()); } --- 210,219 ----
*** 208,218 **** // If the receiver is a constant null, do not torture the system // by attempting to call through it. The compile will proceed // correctly, but may bail out in final_graph_reshaping, because // the call instruction will have a seemingly deficient out-count. // (The bailout says something misleading about an "infinite loop".) ! if (kit.gvn().type(receiver)->higher_equal(TypePtr::NULL_PTR)) { assert(Bytecodes::is_invoke(kit.java_bc()), "%d: %s", kit.java_bc(), Bytecodes::name(kit.java_bc())); ciMethod* declared_method = kit.method()->get_method_at_bci(kit.bci()); int arg_size = declared_method->signature()->arg_size_for_bc(kit.java_bc()); kit.inc_sp(arg_size); // restore arguments kit.uncommon_trap(Deoptimization::Reason_null_check, --- 221,231 ---- // If the receiver is a constant null, do not torture the system // by attempting to call through it. The compile will proceed // correctly, but may bail out in final_graph_reshaping, because // the call instruction will have a seemingly deficient out-count. // (The bailout says something misleading about an "infinite loop".) ! if (!receiver->is_ValueType() && kit.gvn().type(receiver)->higher_equal(TypePtr::NULL_PTR)) { assert(Bytecodes::is_invoke(kit.java_bc()), "%d: %s", kit.java_bc(), Bytecodes::name(kit.java_bc())); ciMethod* declared_method = kit.method()->get_method_at_bci(kit.bci()); int arg_size = declared_method->signature()->arg_size_for_bc(kit.java_bc()); kit.inc_sp(arg_size); // restore arguments kit.uncommon_trap(Deoptimization::Reason_null_check,
*** 254,263 **** --- 267,279 ---- // about the method being invoked should be attached to the call site to // make resolution logic work (see SharedRuntime::resolve_{virtual,opt_virtual}_call_C). call->set_override_symbolic_info(true); } kit.set_arguments_for_java_call(call); + if (kit.stopped()) { + return kit.transfer_exceptions_into_jvms(); + } kit.set_edges_for_java_call(call); Node* ret = kit.set_results_for_java_call(call); kit.push_node(method()->return_type()->basic_type(), ret); // Represent the effect of an implicit receiver null_check
*** 354,366 **** if (call == NULL || call->outcnt() == 0 || call->in(0) == NULL || call->in(0)->is_top()) { return; } ! const TypeTuple *r = call->tf()->domain(); ! for (int i1 = 0; i1 < method()->arg_size(); i1++) { ! if (call->in(TypeFunc::Parms + i1)->is_top() && r->field_at(TypeFunc::Parms + i1) != Type::HALF) { assert(Compile::current()->inlining_incrementally(), "shouldn't happen during parsing"); return; } } --- 370,393 ---- if (call == NULL || call->outcnt() == 0 || call->in(0) == NULL || call->in(0)->is_top()) { return; } ! const GrowableArray<SigEntry>* sig_cc = method()->get_sig_cc(); ! const TypeTuple* r = call->tf()->domain_cc(); ! for (uint i1 = TypeFunc::Parms, i2 = 0; i1 < r->cnt(); i1++) { ! if (sig_cc != NULL) { ! // Skip reserved entries ! while (!SigEntry::skip_value_delimiters(sig_cc, i2)) { ! i2++; ! } ! if (SigEntry::is_reserved_entry(sig_cc, i2++)) { ! assert(call->in(i1)->is_top(), "should be top"); ! continue; ! } ! } ! if (call->in(i1)->is_top() && r->field_at(i1) != Type::HALF) { assert(Compile::current()->inlining_incrementally(), "shouldn't happen during parsing"); return; } }
*** 368,397 **** assert(Compile::current()->inlining_incrementally(), "shouldn't happen during parsing"); return; } // check for unreachable loop ! CallProjections callprojs; ! call->extract_projections(&callprojs, true); ! if (callprojs.fallthrough_catchproj == call->in(0) || ! callprojs.catchall_catchproj == call->in(0) || ! callprojs.fallthrough_memproj == call->in(TypeFunc::Memory) || ! callprojs.catchall_memproj == call->in(TypeFunc::Memory) || ! callprojs.fallthrough_ioproj == call->in(TypeFunc::I_O) || ! callprojs.catchall_ioproj == call->in(TypeFunc::I_O) || ! (callprojs.resproj != NULL && call->find_edge(callprojs.resproj) != -1) || ! (callprojs.exobj != NULL && call->find_edge(callprojs.exobj) != -1)) { return; } Compile* C = Compile::current(); // Remove inlined methods from Compiler's lists. if (call->is_macro()) { C->remove_macro_node(call); } - bool result_not_used = (callprojs.resproj == NULL || callprojs.resproj->outcnt() == 0); if (_is_pure_call && result_not_used) { // The call is marked as pure (no important side effects), but result isn't used. // It's safe to remove the call. GraphKit kit(call->jvms()); kit.replace_call(call, C->top(), true); --- 395,432 ---- assert(Compile::current()->inlining_incrementally(), "shouldn't happen during parsing"); return; } // check for unreachable loop ! CallProjections* callprojs = call->extract_projections(true); ! if (callprojs->fallthrough_catchproj == call->in(0) || ! callprojs->catchall_catchproj == call->in(0) || ! callprojs->fallthrough_memproj == call->in(TypeFunc::Memory) || ! callprojs->catchall_memproj == call->in(TypeFunc::Memory) || ! callprojs->fallthrough_ioproj == call->in(TypeFunc::I_O) || ! callprojs->catchall_ioproj == call->in(TypeFunc::I_O) || ! (callprojs->exobj != NULL && call->find_edge(callprojs->exobj) != -1)) { return; } + bool result_not_used = true; + for (uint i = 0; i < callprojs->nb_resproj; i++) { + if (callprojs->resproj[i] != NULL) { + if (callprojs->resproj[i]->outcnt() != 0) { + result_not_used = false; + } + if (call->find_edge(callprojs->resproj[i]) != -1) { + return; + } + } + } Compile* C = Compile::current(); // Remove inlined methods from Compiler's lists. if (call->is_macro()) { C->remove_macro_node(call); } if (_is_pure_call && result_not_used) { // The call is marked as pure (no important side effects), but result isn't used. // It's safe to remove the call. GraphKit kit(call->jvms()); kit.replace_call(call, C->top(), true);
*** 403,432 **** SafePointNode* map = new SafePointNode(size, jvms); for (uint i1 = 0; i1 < size; i1++) { map->init_req(i1, call->in(i1)); } // Make sure the state is a MergeMem for parsing. if (!map->in(TypeFunc::Memory)->is_MergeMem()) { Node* mem = MergeMemNode::make(map->in(TypeFunc::Memory)); ! C->initial_gvn()->set_type_bottom(mem); map->set_req(TypeFunc::Memory, mem); } - uint nargs = method()->arg_size(); // blow away old call arguments ! Node* top = C->top(); ! for (uint i1 = 0; i1 < nargs; i1++) { ! map->set_req(TypeFunc::Parms + i1, top); } jvms->set_map(map); // Make enough space in the expression stack to transfer // the incoming arguments and return value. map->ensure_stack(jvms, jvms->method()->max_stack()); for (uint i1 = 0; i1 < nargs; i1++) { ! map->set_argument(jvms, i1, call->in(TypeFunc::Parms + i1)); } C->print_inlining_assert_ready(); C->print_inlining_move_to(this); --- 438,487 ---- SafePointNode* map = new SafePointNode(size, jvms); for (uint i1 = 0; i1 < size; i1++) { map->init_req(i1, call->in(i1)); } + PhaseGVN& gvn = *C->initial_gvn(); // Make sure the state is a MergeMem for parsing. if (!map->in(TypeFunc::Memory)->is_MergeMem()) { Node* mem = MergeMemNode::make(map->in(TypeFunc::Memory)); ! gvn.set_type_bottom(mem); map->set_req(TypeFunc::Memory, mem); } // blow away old call arguments ! for (uint i1 = TypeFunc::Parms; i1 < r->cnt(); i1++) { ! map->set_req(i1, C->top()); } jvms->set_map(map); // Make enough space in the expression stack to transfer // the incoming arguments and return value. map->ensure_stack(jvms, jvms->method()->max_stack()); + const TypeTuple *domain_sig = call->_tf->domain_sig(); + ExtendedSignature sig_cc = ExtendedSignature(method()->get_sig_cc(), SigEntryFilter()); + uint nargs = method()->arg_size(); + assert(domain_sig->cnt() - TypeFunc::Parms == nargs, "inconsistent signature"); + + uint j = TypeFunc::Parms; for (uint i1 = 0; i1 < nargs; i1++) { ! const Type* t = domain_sig->field_at(TypeFunc::Parms + i1); ! if (method()->has_scalarized_args() && t->is_valuetypeptr() && !t->maybe_null()) { ! // Value type arguments are not passed by reference: we get an argument per ! // field of the value type. Build ValueTypeNodes from the value type arguments. ! GraphKit arg_kit(jvms, &gvn); ! arg_kit.set_control(map->control()); ! ValueTypeNode* vt = ValueTypeNode::make_from_multi(&arg_kit, call, sig_cc, t->value_klass(), j, true); ! map->set_control(arg_kit.control()); ! map->set_argument(jvms, i1, vt); ! } else { ! map->set_argument(jvms, i1, call->in(j++)); ! BasicType bt = t->basic_type(); ! while (SigEntry::next_is_reserved(sig_cc, bt, true)) { ! j += type2size[bt]; // Skip reserved arguments ! } ! } } C->print_inlining_assert_ready(); C->print_inlining_move_to(this);
*** 465,474 **** --- 520,554 ---- 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); C->set_do_cleanup(kit.stopped()); // path is dead; needs cleanup + + // Handle value type returns + bool returned_as_fields = call->tf()->returns_value_type_as_fields(); + if (result->is_ValueType()) { + ValueTypeNode* vt = result->as_ValueType(); + if (returned_as_fields) { + // Return of multiple values (the fields of a value type) + vt->replace_call_results(&kit, call, C); + if (vt->is_allocated(&gvn) && !StressValueTypeReturnedAsFields) { + result = vt->get_oop(); + } else { + result = vt->tagged_klass(gvn); + } + } else { + result = ValueTypePtrNode::make_from_value_type(&kit, vt); + } + } else if (gvn.type(result)->is_valuetypeptr() && returned_as_fields) { + const Type* vt_t = call->_tf->range_sig()->field_at(TypeFunc::Parms); + Node* cast = new CheckCastPPNode(NULL, result, vt_t); + gvn.record_for_igvn(cast); + ValueTypePtrNode* vtptr = ValueTypePtrNode::make_from_oop(&kit, gvn.transform(cast)); + vtptr->replace_call_results(&kit, call, C); + result = cast; + } + kit.replace_call(call, result, true); } }
*** 504,522 **** } }; 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; } --- 584,602 ---- } }; 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; }
*** 782,791 **** --- 862,893 ---- // Inlined method threw an exception, so it's just the slow path after all. kit.set_jvms(slow_jvms); return kit.transfer_exceptions_into_jvms(); } + // Allocate value types if they are merged with objects (similar to Parse::merge_common()) + uint tos = kit.jvms()->stkoff() + kit.sp(); + uint limit = slow_map->req(); + for (uint i = TypeFunc::Parms; i < limit; i++) { + Node* m = kit.map()->in(i); + Node* n = slow_map->in(i); + const Type* t = gvn.type(m)->meet_speculative(gvn.type(n)); + if (m->is_ValueType() && !t->isa_valuetype()) { + // Allocate value type in fast path + m = ValueTypePtrNode::make_from_value_type(&kit, m->as_ValueType()); + kit.map()->set_req(i, m); + } + if (n->is_ValueType() && !t->isa_valuetype()) { + // Allocate value type in slow path + PreserveJVMState pjvms(&kit); + kit.set_map(slow_map); + n = ValueTypePtrNode::make_from_value_type(&kit, n->as_ValueType()); + kit.map()->set_req(i, n); + slow_map = kit.stop(); + } + } + // There are 2 branches and the replaced nodes are only valid on // one: restore the replaced nodes to what they were before the // branch. kit.map()->set_replaced_nodes(replaced_nodes);
*** 805,816 **** Node* phi = mms.memory(); if (phi->is_Phi() && phi->in(0) == region) { mms.set_memory(gvn.transform(phi)); } } - uint tos = kit.jvms()->stkoff() + kit.sp(); - uint limit = slow_map->req(); for (uint i = TypeFunc::Parms; i < limit; i++) { // Skip unused stack slots; fast forward to monoff(); if (i == tos) { i = kit.jvms()->monoff(); if( i >= limit ) break; --- 907,916 ----
*** 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 { --- 929,939 ---- 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; --- 942,978 ---- } 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); } } ! static void cast_argument(int nargs, int arg_nb, ciType* t, GraphKit& kit) { ! PhaseGVN& gvn = kit.gvn(); ! Node* arg = kit.argument(arg_nb); ! const Type* arg_type = arg->bottom_type(); ! const Type* sig_type = TypeOopPtr::make_from_klass(t->as_klass()); ! if (arg_type->isa_oopptr() && !arg_type->higher_equal(sig_type)) { ! const Type* narrowed_arg_type = arg_type->join_speculative(sig_type); // keep speculative part ! arg = gvn.transform(new CheckCastPPNode(kit.control(), arg, narrowed_arg_type)); ! kit.set_argument(arg_nb, arg); ! } ! if (sig_type->is_valuetypeptr() && !arg->is_ValueType() && ! !kit.gvn().type(arg)->maybe_null() && t->as_value_klass()->is_scalarizable()) { ! arg = ValueTypeNode::make_from_oop(&kit, arg, t->as_value_klass()); ! kit.set_argument(arg_nb, arg); ! } ! } ! ! 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"); } --- 995,1008 ---- 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"); }
*** 892,903 **** case vmIntrinsics::_linkToVirtual: case vmIntrinsics::_linkToStatic: case vmIntrinsics::_linkToSpecial: case vmIntrinsics::_linkToInterface: { // Get MemberName argument: ! Node* member_name = kit.argument(callee->arg_size() - 1); if (member_name->Opcode() == Op_ConP) { input_not_const = false; const TypeOopPtr* oop_ptr = member_name->bottom_type()->is_oopptr(); ciMethod* target = oop_ptr->const_oop()->as_member_name()->get_vmtarget(); --- 1012,1024 ---- case vmIntrinsics::_linkToVirtual: case vmIntrinsics::_linkToStatic: case vmIntrinsics::_linkToSpecial: case vmIntrinsics::_linkToInterface: { + int nargs = callee->arg_size(); // Get MemberName argument: ! Node* member_name = kit.argument(nargs - 1); if (member_name->Opcode() == Op_ConP) { input_not_const = false; const TypeOopPtr* oop_ptr = member_name->bottom_type()->is_oopptr(); ciMethod* target = oop_ptr->const_oop()->as_member_name()->get_vmtarget();
*** 913,943 **** // actual types. ciSignature* signature = target->signature(); const int receiver_skip = target->is_static() ? 0 : 1; // Cast receiver to its type. if (!target->is_static()) { ! Node* arg = kit.argument(0); ! const TypeOopPtr* arg_type = arg->bottom_type()->isa_oopptr(); ! const Type* sig_type = TypeOopPtr::make_from_klass(signature->accessing_klass()); ! if (arg_type != NULL && !arg_type->higher_equal(sig_type)) { ! const Type* recv_type = arg_type->join_speculative(sig_type); // keep speculative part ! Node* cast_obj = gvn.transform(new CheckCastPPNode(kit.control(), arg, recv_type)); ! kit.set_argument(0, cast_obj); ! } } // Cast reference arguments to its type. for (int i = 0, j = 0; i < signature->count(); i++) { ciType* t = signature->type_at(i); if (t->is_klass()) { ! Node* arg = kit.argument(receiver_skip + j); ! const TypeOopPtr* arg_type = arg->bottom_type()->isa_oopptr(); ! const Type* sig_type = TypeOopPtr::make_from_klass(t->as_klass()); ! if (arg_type != NULL && !arg_type->higher_equal(sig_type)) { ! const Type* narrowed_arg_type = arg_type->join_speculative(sig_type); // keep speculative part ! Node* cast_obj = gvn.transform(new CheckCastPPNode(kit.control(), arg, narrowed_arg_type)); ! kit.set_argument(receiver_skip + j, cast_obj); ! } } j += t->size(); // long and double take two slots } // Try to get the most accurate receiver type --- 1034,1050 ---- // actual types. ciSignature* signature = target->signature(); const int receiver_skip = target->is_static() ? 0 : 1; // Cast receiver to its type. if (!target->is_static()) { ! cast_argument(nargs, 0, signature->accessing_klass(), kit); } // Cast reference arguments to its type. for (int i = 0, j = 0; i < signature->count(); i++) { ciType* t = signature->type_at(i); if (t->is_klass()) { ! cast_argument(nargs, receiver_skip + j, t, kit); } j += t->size(); // long and double take two slots } // Try to get the most accurate receiver type
*** 964,974 **** speculative_receiver_type = (receiver_type != NULL) ? receiver_type->speculative_type() : NULL; } CallGenerator* cg = C->call_generator(target, vtable_index, call_does_dispatch, jvms, !StressMethodHandleLinkerInlining /* allow_inline */, PROB_ALWAYS, ! speculative_receiver_type); return cg; } else { print_inlining_failure(C, callee, jvms->depth() - 1, jvms->bci(), "member_name not constant"); } --- 1071,1083 ---- speculative_receiver_type = (receiver_type != NULL) ? receiver_type->speculative_type() : NULL; } CallGenerator* cg = C->call_generator(target, vtable_index, call_does_dispatch, jvms, !StressMethodHandleLinkerInlining /* 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"); }
*** 1035,1045 **** } if (!method()->is_static()) { // We need an explicit receiver null_check before checking its type in predicate. // We share a map with the caller, so his JVMS gets adjusted. ! Node* receiver = kit.null_check_receiver_before_call(method()); if (kit.stopped()) { return kit.transfer_exceptions_into_jvms(); } } --- 1144,1154 ---- } if (!method()->is_static()) { // We need an explicit receiver null_check before checking its type in predicate. // We share a map with the caller, so his JVMS gets adjusted. ! kit.null_check_receiver_before_call(method()); if (kit.stopped()) { return kit.transfer_exceptions_into_jvms(); } }
< prev index next >