# HG changeset patch # User twisti # Date 1345571330 25200 # Node ID 75aa4880b15f8dc54f082bb5c0b6cc533f0628a6 # Parent 4f0635e148c10b3a864ede9ce41d75f5dbb9347f 7192167: JSR 292: C1 has old broken code which needs to be removed Reviewed-by: kvn, roland, jrose diff -r 4f0635e148c1 -r 75aa4880b15f hotspot/src/share/vm/c1/c1_GraphBuilder.cpp --- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Mon Aug 20 09:58:58 2012 -0700 +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Tue Aug 21 10:48:50 2012 -0700 @@ -1646,10 +1646,6 @@ void GraphBuilder::invoke(Bytecodes::Code code) { - const bool has_receiver = - code == Bytecodes::_invokespecial || - code == Bytecodes::_invokevirtual || - code == Bytecodes::_invokeinterface; const bool is_invokedynamic = (code == Bytecodes::_invokedynamic); bool will_link; @@ -1690,8 +1686,12 @@ // convert them directly to an invokespecial or invokestatic. if (target->is_loaded() && !target->is_abstract() && target->can_be_statically_bound()) { switch (bc_raw) { - case Bytecodes::_invokevirtual: code = Bytecodes::_invokespecial; break; - case Bytecodes::_invokehandle: code = Bytecodes::_invokestatic; break; + case Bytecodes::_invokevirtual: + code = Bytecodes::_invokespecial; + break; + case Bytecodes::_invokehandle: + code = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokespecial; + break; } } @@ -1878,11 +1878,13 @@ // inlining not successful => standard invoke bool is_loaded = target->is_loaded(); ValueType* result_type = as_ValueType(target->return_type()); - - // We require the debug info to be the "state before" because - // invokedynamics may deoptimize. - ValueStack* state_before = is_invokedynamic ? copy_state_before() : copy_state_exhandling(); - + ValueStack* state_before = copy_state_exhandling(); + + // The bytecode (code) might change in this method so we are checking this very late. + const bool has_receiver = + code == Bytecodes::_invokespecial || + code == Bytecodes::_invokevirtual || + code == Bytecodes::_invokeinterface; Values* args = state()->pop_arguments(target->arg_size_no_receiver()); Value recv = has_receiver ? apop() : NULL; int vtable_index = methodOopDesc::invalid_vtable_index; diff -r 4f0635e148c1 -r 75aa4880b15f hotspot/src/share/vm/c1/c1_Instruction.cpp --- a/hotspot/src/share/vm/c1/c1_Instruction.cpp Mon Aug 20 09:58:58 2012 -0700 +++ b/hotspot/src/share/vm/c1/c1_Instruction.cpp Tue Aug 21 10:48:50 2012 -0700 @@ -369,9 +369,6 @@ _signature = new BasicTypeList(number_of_arguments() + (has_receiver() ? 1 : 0)); if (has_receiver()) { _signature->append(as_BasicType(receiver()->type())); - } else if (is_invokedynamic()) { - // Add the synthetic MethodHandle argument to the signature. - _signature->append(T_OBJECT); } for (int i = 0; i < number_of_arguments(); i++) { ValueType* t = argument_at(i)->type(); diff -r 4f0635e148c1 -r 75aa4880b15f hotspot/src/share/vm/c1/c1_LIRAssembler.cpp --- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp Mon Aug 20 09:58:58 2012 -0700 +++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp Tue Aug 21 10:48:50 2012 -0700 @@ -448,10 +448,10 @@ switch (op->code()) { case lir_static_call: + case lir_dynamic_call: call(op, relocInfo::static_call_type); break; case lir_optvirtual_call: - case lir_dynamic_call: call(op, relocInfo::opt_virtual_call_type); break; case lir_icvirtual_call: @@ -460,7 +460,9 @@ case lir_virtual_call: vtable_call(op); break; - default: ShouldNotReachHere(); + default: + fatal(err_msg_res("unexpected op code: %s", op->name())); + break; } // JSR 292 diff -r 4f0635e148c1 -r 75aa4880b15f hotspot/src/share/vm/c1/c1_LIRGenerator.cpp --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Mon Aug 20 09:58:58 2012 -0700 +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Tue Aug 21 10:48:50 2012 -0700 @@ -920,7 +920,8 @@ LIR_Opr LIRGenerator::force_to_spill(LIR_Opr value, BasicType t) { - assert(type2size[t] == type2size[value->type()], "size mismatch"); + assert(type2size[t] == type2size[value->type()], + err_msg_res("size mismatch: t=%s, value->type()=%s", type2name(t), type2name(value->type()))); if (!value->is_register()) { // force into a register LIR_Opr r = new_register(value->type()); @@ -2662,8 +2663,9 @@ void LIRGenerator::invoke_load_arguments(Invoke* x, LIRItemList* args, const LIR_OprList* arg_list) { - int i = (x->has_receiver() || x->is_invokedynamic()) ? 1 : 0; - for (; i < args->length(); i++) { + assert(args->length() == arg_list->length(), + err_msg_res("args=%d, arg_list=%d", args->length(), arg_list->length())); + for (int i = x->has_receiver() ? 1 : 0; i < args->length(); i++) { LIRItem* param = args->at(i); LIR_Opr loc = arg_list->at(i); if (loc->is_register()) { @@ -2703,15 +2705,9 @@ LIRItem* receiver = new LIRItem(x->receiver(), this); argument_items->append(receiver); } - if (x->is_invokedynamic()) { - // Insert a dummy for the synthetic MethodHandle argument. - argument_items->append(NULL); - } - int idx = x->has_receiver() ? 1 : 0; for (int i = 0; i < x->number_of_arguments(); i++) { LIRItem* param = new LIRItem(x->argument_at(i), this); argument_items->append(param); - idx += (param->type()->is_double_word() ? 2 : 1); } return argument_items; } @@ -2756,9 +2752,6 @@ CodeEmitInfo* info = state_for(x, x->state()); - // invokedynamics can deoptimize. - CodeEmitInfo* deopt_info = x->is_invokedynamic() ? state_for(x, x->state_before()) : NULL; - invoke_load_arguments(x, args, arg_list); if (x->has_receiver()) { @@ -2807,41 +2800,8 @@ } break; case Bytecodes::_invokedynamic: { - ciBytecodeStream bcs(x->scope()->method()); - bcs.force_bci(x->state()->bci()); - assert(bcs.cur_bc() == Bytecodes::_invokedynamic, "wrong stream"); - ciCPCache* cpcache = bcs.get_cpcache(); - - // Get CallSite offset from constant pool cache pointer. - int index = bcs.get_method_index(); - size_t call_site_offset = cpcache->get_f1_offset(index); - - // Load CallSite object from constant pool cache. - LIR_Opr call_site = new_register(objectType); - __ oop2reg(cpcache->constant_encoding(), call_site); - __ move_wide(new LIR_Address(call_site, call_site_offset, T_OBJECT), call_site); - - // If this invokedynamic call site hasn't been executed yet in - // the interpreter, the CallSite object in the constant pool - // cache is still null and we need to deoptimize. - if (cpcache->is_f1_null_at(index)) { - // Only deoptimize if the CallSite object is still null; we don't - // recompile methods in C1 after deoptimization so this call site - // might be resolved the next time we execute it after OSR. - DeoptimizeStub* deopt_stub = new DeoptimizeStub(deopt_info); - __ cmp(lir_cond_equal, call_site, LIR_OprFact::oopConst(NULL)); - __ branch(lir_cond_equal, T_OBJECT, deopt_stub); - } - - // Use the receiver register for the synthetic MethodHandle - // argument. - receiver = LIR_Assembler::receiverOpr(); - - // Load target MethodHandle from CallSite object. - __ load(new LIR_Address(call_site, java_lang_invoke_CallSite::target_offset_in_bytes(), T_OBJECT), receiver); - __ call_dynamic(target, receiver, result_register, - SharedRuntime::get_resolve_opt_virtual_call_stub(), + SharedRuntime::get_resolve_static_call_stub(), arg_list, info); break; } diff -r 4f0635e148c1 -r 75aa4880b15f hotspot/src/share/vm/opto/callGenerator.cpp --- a/hotspot/src/share/vm/opto/callGenerator.cpp Mon Aug 20 09:58:58 2012 -0700 +++ b/hotspot/src/share/vm/opto/callGenerator.cpp Tue Aug 21 10:48:50 2012 -0700 @@ -158,74 +158,6 @@ return kit.transfer_exceptions_into_jvms(); } -//---------------------------DynamicCallGenerator----------------------------- -// Internal class which handles all out-of-line invokedynamic calls. -class DynamicCallGenerator : public CallGenerator { -public: - DynamicCallGenerator(ciMethod* method) - : CallGenerator(method) - { - } - virtual JVMState* generate(JVMState* jvms); -}; - -JVMState* DynamicCallGenerator::generate(JVMState* jvms) { - GraphKit kit(jvms); - Compile* C = kit.C; - PhaseGVN& gvn = kit.gvn(); - - if (C->log() != NULL) { - C->log()->elem("dynamic_call bci='%d'", jvms->bci()); - } - - // Get the constant pool cache from the caller class. - ciMethod* caller_method = jvms->method(); - ciBytecodeStream str(caller_method); - str.force_bci(jvms->bci()); // Set the stream to the invokedynamic bci. - assert(str.cur_bc() == Bytecodes::_invokedynamic, "wrong place to issue a dynamic call!"); - ciCPCache* cpcache = str.get_cpcache(); - - // Get the offset of the CallSite from the constant pool cache - // pointer. - int index = str.get_method_index(); - size_t call_site_offset = cpcache->get_f1_offset(index); - - // Load the CallSite object from the constant pool cache. - const TypeOopPtr* cpcache_type = TypeOopPtr::make_from_constant(cpcache); // returns TypeAryPtr of type T_OBJECT - const TypeOopPtr* call_site_type = TypeOopPtr::make_from_klass(C->env()->CallSite_klass()); - Node* cpcache_adr = kit.makecon(cpcache_type); - Node* call_site_adr = kit.basic_plus_adr(cpcache_adr, call_site_offset); - // The oops in the constant pool cache are not compressed; load then as raw pointers. - Node* call_site = kit.make_load(kit.control(), call_site_adr, call_site_type, T_ADDRESS, Compile::AliasIdxRaw); - - // Load the target MethodHandle from the CallSite object. - const TypeOopPtr* target_type = TypeOopPtr::make_from_klass(C->env()->MethodHandle_klass()); - Node* target_mh_adr = kit.basic_plus_adr(call_site, java_lang_invoke_CallSite::target_offset_in_bytes()); - Node* target_mh = kit.make_load(kit.control(), target_mh_adr, target_type, T_OBJECT); - - address resolve_stub = SharedRuntime::get_resolve_opt_virtual_call_stub(); - - CallStaticJavaNode* call = new (C, tf()->domain()->cnt()) CallStaticJavaNode(tf(), resolve_stub, method(), kit.bci()); - // invokedynamic is treated as an optimized invokevirtual. - call->set_optimized_virtual(true); - // Take extra care (in the presence of argument motion) not to trash the SP: - call->set_method_handle_invoke(true); - - // Pass the target MethodHandle as first argument and shift the - // other arguments. - call->init_req(0 + TypeFunc::Parms, target_mh); - uint nargs = call->method()->arg_size(); - for (uint i = 1; i < nargs; i++) { - Node* arg = kit.argument(i - 1); - call->init_req(i + TypeFunc::Parms, arg); - } - - 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); - return kit.transfer_exceptions_into_jvms(); -} - //--------------------------VirtualCallGenerator------------------------------ // Internal class which handles all out-of-line calls checking receiver type. class VirtualCallGenerator : public CallGenerator { @@ -328,12 +260,6 @@ return new VirtualCallGenerator(m, vtable_index); } -CallGenerator* CallGenerator::for_dynamic_call(ciMethod* m) { - assert(m->is_compiled_lambda_form(), "for_dynamic_call mismatch"); - //@@ FIXME: this should be done via a direct call - return new DynamicCallGenerator(m); -} - // Allow inlining decisions to be delayed class LateInlineCallGenerator : public DirectCallGenerator { CallGenerator* _inline_cg; @@ -347,7 +273,7 @@ // Convert the CallStaticJava into an inline virtual void do_late_inline(); - JVMState* generate(JVMState* jvms) { + virtual JVMState* generate(JVMState* jvms) { // Record that this call site should be revisited once the main // parse is finished. Compile::current()->add_late_inline(this);