comparison src/share/vm/opto/callGenerator.cpp @ 1137:97125851f396

6829187: compiler optimizations required for JSR 292 Summary: C2 implementation for invokedynamic support. Reviewed-by: kvn, never
author twisti
date Tue, 05 Jan 2010 13:05:58 +0100
parents 7c57aead6d3e
children dd57230ba8fe
comparison
equal deleted inserted replaced
1136:4b84186a8248 1137:97125851f396
1 /* 1 /*
2 * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. 2 * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
134 // And dump it back to the caller, decorated with any exceptions: 134 // And dump it back to the caller, decorated with any exceptions:
135 return kit.transfer_exceptions_into_jvms(); 135 return kit.transfer_exceptions_into_jvms();
136 } 136 }
137 // Mark the call node as virtual, sort of: 137 // Mark the call node as virtual, sort of:
138 call->set_optimized_virtual(true); 138 call->set_optimized_virtual(true);
139 if (method()->is_method_handle_invoke())
140 call->set_method_handle_invoke(true);
139 } 141 }
140 kit.set_arguments_for_java_call(call); 142 kit.set_arguments_for_java_call(call);
141 kit.set_edges_for_java_call(call, false, _separate_io_proj); 143 kit.set_edges_for_java_call(call, false, _separate_io_proj);
142 Node* ret = kit.set_results_for_java_call(call, _separate_io_proj); 144 Node* ret = kit.set_results_for_java_call(call, _separate_io_proj);
143 kit.push_node(method()->return_type()->basic_type(), ret); 145 kit.push_node(method()->return_type()->basic_type(), ret);
144 _call_node = call; // Save the call node in case we need it later 146 _call_node = call; // Save the call node in case we need it later
145 return kit.transfer_exceptions_into_jvms(); 147 return kit.transfer_exceptions_into_jvms();
146 } 148 }
147 149
150 //---------------------------DynamicCallGenerator-----------------------------
151 // Internal class which handles all out-of-line dynamic calls.
152 class DynamicCallGenerator : public CallGenerator {
153 public:
154 DynamicCallGenerator(ciMethod* method)
155 : CallGenerator(method)
156 {
157 }
158 virtual JVMState* generate(JVMState* jvms);
159 };
160
161 JVMState* DynamicCallGenerator::generate(JVMState* jvms) {
162 GraphKit kit(jvms);
163
164 if (kit.C->log() != NULL) {
165 kit.C->log()->elem("dynamic_call bci='%d'", jvms->bci());
166 }
167
168 // Get the constant pool cache from the caller class.
169 ciMethod* caller_method = jvms->method();
170 ciBytecodeStream str(caller_method);
171 str.force_bci(jvms->bci()); // Set the stream to the invokedynamic bci.
172 assert(str.cur_bc() == Bytecodes::_invokedynamic, "wrong place to issue a dynamic call!");
173 ciCPCache* cpcache = str.get_cpcache();
174
175 // Get the offset of the CallSite from the constant pool cache
176 // pointer.
177 int index = str.get_method_index();
178 size_t call_site_offset = cpcache->get_f1_offset(index);
179
180 // Load the CallSite object from the constant pool cache.
181 const TypeOopPtr* cpcache_ptr = TypeOopPtr::make_from_constant(cpcache);
182 Node* cpc = kit.makecon(cpcache_ptr);
183 Node* adr = kit.basic_plus_adr(cpc, cpc, call_site_offset);
184 Node* call_site = kit.make_load(kit.control(), adr, TypeInstPtr::BOTTOM, T_OBJECT, Compile::AliasIdxRaw);
185
186 // Load the MethodHandle (target) from the CallSite object.
187 Node* mh_adr = kit.basic_plus_adr(call_site, call_site, java_dyn_CallSite::target_offset_in_bytes());
188 Node* mh = kit.make_load(kit.control(), mh_adr, TypeInstPtr::BOTTOM, T_OBJECT);
189
190 address stub = SharedRuntime::get_resolve_opt_virtual_call_stub();
191
192 CallStaticJavaNode *call = new (kit.C, tf()->domain()->cnt()) CallStaticJavaNode(tf(), stub, method(), kit.bci());
193 // invokedynamic is treated as an optimized invokevirtual.
194 call->set_optimized_virtual(true);
195 // Take extra care (in the presence of argument motion) not to trash the SP:
196 call->set_method_handle_invoke(true);
197
198 // Pass the MethodHandle as first argument and shift the other
199 // arguments.
200 call->init_req(0 + TypeFunc::Parms, mh);
201 uint nargs = call->method()->arg_size();
202 for (uint i = 1; i < nargs; i++) {
203 Node* arg = kit.argument(i - 1);
204 call->init_req(i + TypeFunc::Parms, arg);
205 }
206
207 kit.set_edges_for_java_call(call);
208 Node* ret = kit.set_results_for_java_call(call);
209 kit.push_node(method()->return_type()->basic_type(), ret);
210 return kit.transfer_exceptions_into_jvms();
211 }
212
213 //--------------------------VirtualCallGenerator------------------------------
214 // Internal class which handles all out-of-line calls checking receiver type.
148 class VirtualCallGenerator : public CallGenerator { 215 class VirtualCallGenerator : public CallGenerator {
149 private: 216 private:
150 int _vtable_index; 217 int _vtable_index;
151 public: 218 public:
152 VirtualCallGenerator(ciMethod* method, int vtable_index) 219 VirtualCallGenerator(ciMethod* method, int vtable_index)
157 } 224 }
158 virtual bool is_virtual() const { return true; } 225 virtual bool is_virtual() const { return true; }
159 virtual JVMState* generate(JVMState* jvms); 226 virtual JVMState* generate(JVMState* jvms);
160 }; 227 };
161 228
162 //--------------------------VirtualCallGenerator------------------------------
163 // Internal class which handles all out-of-line calls checking receiver type.
164 JVMState* VirtualCallGenerator::generate(JVMState* jvms) { 229 JVMState* VirtualCallGenerator::generate(JVMState* jvms) {
165 GraphKit kit(jvms); 230 GraphKit kit(jvms);
166 Node* receiver = kit.argument(0); 231 Node* receiver = kit.argument(0);
167 232
168 if (kit.C->log() != NULL) { 233 if (kit.C->log() != NULL) {
251 CallGenerator* CallGenerator::for_direct_call(ciMethod* m, bool separate_io_proj) { 316 CallGenerator* CallGenerator::for_direct_call(ciMethod* m, bool separate_io_proj) {
252 assert(!m->is_abstract(), "for_direct_call mismatch"); 317 assert(!m->is_abstract(), "for_direct_call mismatch");
253 return new DirectCallGenerator(m, separate_io_proj); 318 return new DirectCallGenerator(m, separate_io_proj);
254 } 319 }
255 320
321 CallGenerator* CallGenerator::for_dynamic_call(ciMethod* m) {
322 assert(m->is_method_handle_invoke(), "for_dynamic_call mismatch");
323 return new DynamicCallGenerator(m);
324 }
325
256 CallGenerator* CallGenerator::for_virtual_call(ciMethod* m, int vtable_index) { 326 CallGenerator* CallGenerator::for_virtual_call(ciMethod* m, int vtable_index) {
257 assert(!m->is_static(), "for_virtual_call mismatch"); 327 assert(!m->is_static(), "for_virtual_call mismatch");
328 assert(!m->is_method_handle_invoke(), "should be a direct call");
258 return new VirtualCallGenerator(m, vtable_index); 329 return new VirtualCallGenerator(m, vtable_index);
259 } 330 }
260 331
261 // Allow inlining decisions to be delayed 332 // Allow inlining decisions to be delayed
262 class LateInlineCallGenerator : public DirectCallGenerator { 333 class LateInlineCallGenerator : public DirectCallGenerator {