comparison src/share/vm/opto/callGenerator.cpp @ 6616:7a302948f5a4

7192167: JSR 292: C1 has old broken code which needs to be removed Reviewed-by: kvn, roland, jrose
author twisti
date Tue, 21 Aug 2012 10:48:50 -0700
parents 6c5b7a6becc8
children da91efe96a93
comparison
equal deleted inserted replaced
6615:09aad8452938 6616:7a302948f5a4
156 Node* ret = kit.set_results_for_java_call(call, _separate_io_proj); 156 Node* ret = kit.set_results_for_java_call(call, _separate_io_proj);
157 kit.push_node(method()->return_type()->basic_type(), ret); 157 kit.push_node(method()->return_type()->basic_type(), ret);
158 return kit.transfer_exceptions_into_jvms(); 158 return kit.transfer_exceptions_into_jvms();
159 } 159 }
160 160
161 //---------------------------DynamicCallGenerator-----------------------------
162 // Internal class which handles all out-of-line invokedynamic calls.
163 class DynamicCallGenerator : public CallGenerator {
164 public:
165 DynamicCallGenerator(ciMethod* method)
166 : CallGenerator(method)
167 {
168 }
169 virtual JVMState* generate(JVMState* jvms);
170 };
171
172 JVMState* DynamicCallGenerator::generate(JVMState* jvms) {
173 GraphKit kit(jvms);
174 Compile* C = kit.C;
175 PhaseGVN& gvn = kit.gvn();
176
177 if (C->log() != NULL) {
178 C->log()->elem("dynamic_call bci='%d'", jvms->bci());
179 }
180
181 // Get the constant pool cache from the caller class.
182 ciMethod* caller_method = jvms->method();
183 ciBytecodeStream str(caller_method);
184 str.force_bci(jvms->bci()); // Set the stream to the invokedynamic bci.
185 assert(str.cur_bc() == Bytecodes::_invokedynamic, "wrong place to issue a dynamic call!");
186 ciCPCache* cpcache = str.get_cpcache();
187
188 // Get the offset of the CallSite from the constant pool cache
189 // pointer.
190 int index = str.get_method_index();
191 size_t call_site_offset = cpcache->get_f1_offset(index);
192
193 // Load the CallSite object from the constant pool cache.
194 const TypeOopPtr* cpcache_type = TypeOopPtr::make_from_constant(cpcache); // returns TypeAryPtr of type T_OBJECT
195 const TypeOopPtr* call_site_type = TypeOopPtr::make_from_klass(C->env()->CallSite_klass());
196 Node* cpcache_adr = kit.makecon(cpcache_type);
197 Node* call_site_adr = kit.basic_plus_adr(cpcache_adr, call_site_offset);
198 // The oops in the constant pool cache are not compressed; load then as raw pointers.
199 Node* call_site = kit.make_load(kit.control(), call_site_adr, call_site_type, T_ADDRESS, Compile::AliasIdxRaw);
200
201 // Load the target MethodHandle from the CallSite object.
202 const TypeOopPtr* target_type = TypeOopPtr::make_from_klass(C->env()->MethodHandle_klass());
203 Node* target_mh_adr = kit.basic_plus_adr(call_site, java_lang_invoke_CallSite::target_offset_in_bytes());
204 Node* target_mh = kit.make_load(kit.control(), target_mh_adr, target_type, T_OBJECT);
205
206 address resolve_stub = SharedRuntime::get_resolve_opt_virtual_call_stub();
207
208 CallStaticJavaNode* call = new (C, tf()->domain()->cnt()) CallStaticJavaNode(tf(), resolve_stub, method(), kit.bci());
209 // invokedynamic is treated as an optimized invokevirtual.
210 call->set_optimized_virtual(true);
211 // Take extra care (in the presence of argument motion) not to trash the SP:
212 call->set_method_handle_invoke(true);
213
214 // Pass the target MethodHandle as first argument and shift the
215 // other arguments.
216 call->init_req(0 + TypeFunc::Parms, target_mh);
217 uint nargs = call->method()->arg_size();
218 for (uint i = 1; i < nargs; i++) {
219 Node* arg = kit.argument(i - 1);
220 call->init_req(i + TypeFunc::Parms, arg);
221 }
222
223 kit.set_edges_for_java_call(call);
224 Node* ret = kit.set_results_for_java_call(call);
225 kit.push_node(method()->return_type()->basic_type(), ret);
226 return kit.transfer_exceptions_into_jvms();
227 }
228
229 //--------------------------VirtualCallGenerator------------------------------ 161 //--------------------------VirtualCallGenerator------------------------------
230 // Internal class which handles all out-of-line calls checking receiver type. 162 // Internal class which handles all out-of-line calls checking receiver type.
231 class VirtualCallGenerator : public CallGenerator { 163 class VirtualCallGenerator : public CallGenerator {
232 private: 164 private:
233 int _vtable_index; 165 int _vtable_index;
326 assert(!m->is_static(), "for_virtual_call mismatch"); 258 assert(!m->is_static(), "for_virtual_call mismatch");
327 assert(!m->is_method_handle_intrinsic(), "should be a direct call"); 259 assert(!m->is_method_handle_intrinsic(), "should be a direct call");
328 return new VirtualCallGenerator(m, vtable_index); 260 return new VirtualCallGenerator(m, vtable_index);
329 } 261 }
330 262
331 CallGenerator* CallGenerator::for_dynamic_call(ciMethod* m) {
332 assert(m->is_compiled_lambda_form(), "for_dynamic_call mismatch");
333 //@@ FIXME: this should be done via a direct call
334 return new DynamicCallGenerator(m);
335 }
336
337 // Allow inlining decisions to be delayed 263 // Allow inlining decisions to be delayed
338 class LateInlineCallGenerator : public DirectCallGenerator { 264 class LateInlineCallGenerator : public DirectCallGenerator {
339 CallGenerator* _inline_cg; 265 CallGenerator* _inline_cg;
340 266
341 public: 267 public:
345 virtual bool is_late_inline() const { return true; } 271 virtual bool is_late_inline() const { return true; }
346 272
347 // Convert the CallStaticJava into an inline 273 // Convert the CallStaticJava into an inline
348 virtual void do_late_inline(); 274 virtual void do_late_inline();
349 275
350 JVMState* generate(JVMState* jvms) { 276 virtual JVMState* generate(JVMState* jvms) {
351 // Record that this call site should be revisited once the main 277 // Record that this call site should be revisited once the main
352 // parse is finished. 278 // parse is finished.
353 Compile::current()->add_late_inline(this); 279 Compile::current()->add_late_inline(this);
354 280
355 // Emit the CallStaticJava and request separate projections so 281 // Emit the CallStaticJava and request separate projections so