src/share/vm/opto/callGenerator.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File
*** old/src/share/vm/opto/callGenerator.cpp	Wed Dec  2 17:37:52 2009
--- new/src/share/vm/opto/callGenerator.cpp	Wed Dec  2 17:37:52 2009

*** 1,7 **** --- 1,7 ---- /* ! * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. ! * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 134,152 **** --- 134,219 ---- // And dump it back to the caller, decorated with any exceptions: return kit.transfer_exceptions_into_jvms(); } // Mark the call node as virtual, sort of: call->set_optimized_virtual(true); + if (method()->is_method_handle_invoke()) + 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); _call_node = call; // Save the call node in case we need it later return kit.transfer_exceptions_into_jvms(); } + //---------------------------DynamicCallGenerator----------------------------- + // Internal class which handles all out-of-line dynamic calls. + class DynamicCallGenerator : public CallGenerator { + public: + DynamicCallGenerator(ciMethod* method) + : CallGenerator(method) + { + } + virtual JVMState* generate(JVMState* jvms); + }; + + JVMState* DynamicCallGenerator::generate(JVMState* jvms) { + GraphKit kit(jvms); + + if (kit.C->log() != NULL) { + kit.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_ptr = TypeOopPtr::make_from_constant(cpcache); + Node* cpc = kit.makecon(cpcache_ptr); + Node* adr = kit.basic_plus_adr(cpc, cpc, call_site_offset); + Node* call_site = kit.make_load(kit.control(), adr, TypeInstPtr::BOTTOM, T_OBJECT, Compile::AliasIdxRaw); + + // Load the MethodHandle (target) from the CallSite object. + Node* mh_adr = kit.basic_plus_adr(call_site, call_site, java_dyn_CallSite::target_offset_in_bytes()); + Node* mh = kit.make_load(kit.control(), mh_adr, TypeInstPtr::BOTTOM, T_OBJECT); + + address stub = SharedRuntime::get_resolve_opt_virtual_call_stub(); + + CallStaticJavaNode *call = new (kit.C, tf()->domain()->cnt()) CallStaticJavaNode(tf(), 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 MethodHandle as first argument and shift the other + // arguments. + call->init_req(0 + TypeFunc::Parms, 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 { private: int _vtable_index; public: VirtualCallGenerator(ciMethod* method, int vtable_index)
*** 157,168 **** --- 224,233 ---- } virtual bool is_virtual() const { return true; } virtual JVMState* generate(JVMState* jvms); }; //--------------------------VirtualCallGenerator------------------------------ // Internal class which handles all out-of-line calls checking receiver type. JVMState* VirtualCallGenerator::generate(JVMState* jvms) { GraphKit kit(jvms); Node* receiver = kit.argument(0); if (kit.C->log() != NULL) {
*** 251,262 **** --- 316,333 ---- CallGenerator* CallGenerator::for_direct_call(ciMethod* m, bool separate_io_proj) { assert(!m->is_abstract(), "for_direct_call mismatch"); return new DirectCallGenerator(m, separate_io_proj); } + CallGenerator* CallGenerator::for_dynamic_call(ciMethod* m) { + assert(m->is_method_handle_invoke(), "for_dynamic_call mismatch"); + return new DynamicCallGenerator(m); + } + CallGenerator* CallGenerator::for_virtual_call(ciMethod* m, int vtable_index) { assert(!m->is_static(), "for_virtual_call mismatch"); + assert(!m->is_method_handle_invoke(), "should be a direct call"); return new VirtualCallGenerator(m, vtable_index); } // Allow inlining decisions to be delayed class LateInlineCallGenerator : public DirectCallGenerator {

src/share/vm/opto/callGenerator.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File