1.1 --- a/src/share/vm/opto/callGenerator.cpp Mon Jan 04 15:21:09 2010 -0800 1.2 +++ b/src/share/vm/opto/callGenerator.cpp Tue Jan 05 13:05:58 2010 +0100 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -136,6 +136,8 @@ 1.11 } 1.12 // Mark the call node as virtual, sort of: 1.13 call->set_optimized_virtual(true); 1.14 + if (method()->is_method_handle_invoke()) 1.15 + call->set_method_handle_invoke(true); 1.16 } 1.17 kit.set_arguments_for_java_call(call); 1.18 kit.set_edges_for_java_call(call, false, _separate_io_proj); 1.19 @@ -145,6 +147,71 @@ 1.20 return kit.transfer_exceptions_into_jvms(); 1.21 } 1.22 1.23 +//---------------------------DynamicCallGenerator----------------------------- 1.24 +// Internal class which handles all out-of-line dynamic calls. 1.25 +class DynamicCallGenerator : public CallGenerator { 1.26 +public: 1.27 + DynamicCallGenerator(ciMethod* method) 1.28 + : CallGenerator(method) 1.29 + { 1.30 + } 1.31 + virtual JVMState* generate(JVMState* jvms); 1.32 +}; 1.33 + 1.34 +JVMState* DynamicCallGenerator::generate(JVMState* jvms) { 1.35 + GraphKit kit(jvms); 1.36 + 1.37 + if (kit.C->log() != NULL) { 1.38 + kit.C->log()->elem("dynamic_call bci='%d'", jvms->bci()); 1.39 + } 1.40 + 1.41 + // Get the constant pool cache from the caller class. 1.42 + ciMethod* caller_method = jvms->method(); 1.43 + ciBytecodeStream str(caller_method); 1.44 + str.force_bci(jvms->bci()); // Set the stream to the invokedynamic bci. 1.45 + assert(str.cur_bc() == Bytecodes::_invokedynamic, "wrong place to issue a dynamic call!"); 1.46 + ciCPCache* cpcache = str.get_cpcache(); 1.47 + 1.48 + // Get the offset of the CallSite from the constant pool cache 1.49 + // pointer. 1.50 + int index = str.get_method_index(); 1.51 + size_t call_site_offset = cpcache->get_f1_offset(index); 1.52 + 1.53 + // Load the CallSite object from the constant pool cache. 1.54 + const TypeOopPtr* cpcache_ptr = TypeOopPtr::make_from_constant(cpcache); 1.55 + Node* cpc = kit.makecon(cpcache_ptr); 1.56 + Node* adr = kit.basic_plus_adr(cpc, cpc, call_site_offset); 1.57 + Node* call_site = kit.make_load(kit.control(), adr, TypeInstPtr::BOTTOM, T_OBJECT, Compile::AliasIdxRaw); 1.58 + 1.59 + // Load the MethodHandle (target) from the CallSite object. 1.60 + Node* mh_adr = kit.basic_plus_adr(call_site, call_site, java_dyn_CallSite::target_offset_in_bytes()); 1.61 + Node* mh = kit.make_load(kit.control(), mh_adr, TypeInstPtr::BOTTOM, T_OBJECT); 1.62 + 1.63 + address stub = SharedRuntime::get_resolve_opt_virtual_call_stub(); 1.64 + 1.65 + CallStaticJavaNode *call = new (kit.C, tf()->domain()->cnt()) CallStaticJavaNode(tf(), stub, method(), kit.bci()); 1.66 + // invokedynamic is treated as an optimized invokevirtual. 1.67 + call->set_optimized_virtual(true); 1.68 + // Take extra care (in the presence of argument motion) not to trash the SP: 1.69 + call->set_method_handle_invoke(true); 1.70 + 1.71 + // Pass the MethodHandle as first argument and shift the other 1.72 + // arguments. 1.73 + call->init_req(0 + TypeFunc::Parms, mh); 1.74 + uint nargs = call->method()->arg_size(); 1.75 + for (uint i = 1; i < nargs; i++) { 1.76 + Node* arg = kit.argument(i - 1); 1.77 + call->init_req(i + TypeFunc::Parms, arg); 1.78 + } 1.79 + 1.80 + kit.set_edges_for_java_call(call); 1.81 + Node* ret = kit.set_results_for_java_call(call); 1.82 + kit.push_node(method()->return_type()->basic_type(), ret); 1.83 + return kit.transfer_exceptions_into_jvms(); 1.84 +} 1.85 + 1.86 +//--------------------------VirtualCallGenerator------------------------------ 1.87 +// Internal class which handles all out-of-line calls checking receiver type. 1.88 class VirtualCallGenerator : public CallGenerator { 1.89 private: 1.90 int _vtable_index; 1.91 @@ -159,8 +226,6 @@ 1.92 virtual JVMState* generate(JVMState* jvms); 1.93 }; 1.94 1.95 -//--------------------------VirtualCallGenerator------------------------------ 1.96 -// Internal class which handles all out-of-line calls checking receiver type. 1.97 JVMState* VirtualCallGenerator::generate(JVMState* jvms) { 1.98 GraphKit kit(jvms); 1.99 Node* receiver = kit.argument(0); 1.100 @@ -253,8 +318,14 @@ 1.101 return new DirectCallGenerator(m, separate_io_proj); 1.102 } 1.103 1.104 +CallGenerator* CallGenerator::for_dynamic_call(ciMethod* m) { 1.105 + assert(m->is_method_handle_invoke(), "for_dynamic_call mismatch"); 1.106 + return new DynamicCallGenerator(m); 1.107 +} 1.108 + 1.109 CallGenerator* CallGenerator::for_virtual_call(ciMethod* m, int vtable_index) { 1.110 assert(!m->is_static(), "for_virtual_call mismatch"); 1.111 + assert(!m->is_method_handle_invoke(), "should be a direct call"); 1.112 return new VirtualCallGenerator(m, vtable_index); 1.113 } 1.114