comparison src/share/vm/interpreter/linkResolver.cpp @ 6266:1d7922586cf6

7023639: JSR 292 method handle invocation needs a fast path for compiled code 6984705: JSR 292 method handle creation should not go through JNI Summary: remove assembly code for JDK 7 chained method handles Reviewed-by: jrose, twisti, kvn, mhaupt Contributed-by: John Rose <john.r.rose@oracle.com>, Christian Thalinger <christian.thalinger@oracle.com>, Michael Haupt <michael.haupt@oracle.com>
author twisti
date Tue, 24 Jul 2012 10:51:00 -0700
parents f08d439fab8c
children 93c71eb28866
comparison
equal deleted inserted replaced
6241:aba91a731143 6266:1d7922586cf6
94 } 94 }
95 95
96 void CallInfo::set_virtual(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) { 96 void CallInfo::set_virtual(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) {
97 assert(vtable_index >= 0 || vtable_index == methodOopDesc::nonvirtual_vtable_index, "valid index"); 97 assert(vtable_index >= 0 || vtable_index == methodOopDesc::nonvirtual_vtable_index, "valid index");
98 set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK); 98 set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK);
99 } 99 assert(!resolved_method->is_compiled_lambda_form(), "these must be handled via an invokehandle call");
100 100 }
101 void CallInfo::set_dynamic(methodHandle resolved_method, TRAPS) { 101
102 assert(resolved_method->is_method_handle_invoke(), ""); 102 void CallInfo::set_handle(methodHandle resolved_method, Handle resolved_appendix, TRAPS) {
103 if (resolved_method.is_null()) {
104 THROW_MSG(vmSymbols::java_lang_InternalError(), "resolved method is null");
105 }
103 KlassHandle resolved_klass = SystemDictionaryHandles::MethodHandle_klass(); 106 KlassHandle resolved_klass = SystemDictionaryHandles::MethodHandle_klass();
104 assert(resolved_klass == resolved_method->method_holder(), ""); 107 assert(resolved_method->intrinsic_id() == vmIntrinsics::_invokeBasic ||
108 resolved_method->is_compiled_lambda_form(),
109 "linkMethod must return one of these");
105 int vtable_index = methodOopDesc::nonvirtual_vtable_index; 110 int vtable_index = methodOopDesc::nonvirtual_vtable_index;
106 assert(resolved_method->vtable_index() == vtable_index, ""); 111 assert(resolved_method->vtable_index() == vtable_index, "");
107 set_common(resolved_klass, KlassHandle(), resolved_method, resolved_method, vtable_index, CHECK); 112 set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, vtable_index, CHECK);
113 _resolved_appendix = resolved_appendix;
108 } 114 }
109 115
110 void CallInfo::set_common(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) { 116 void CallInfo::set_common(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) {
111 assert(resolved_method->signature() == selected_method->signature(), "signatures must correspond"); 117 assert(resolved_method->signature() == selected_method->signature(), "signatures must correspond");
112 _resolved_klass = resolved_klass; 118 _resolved_klass = resolved_klass;
113 _selected_klass = selected_klass; 119 _selected_klass = selected_klass;
114 _resolved_method = resolved_method; 120 _resolved_method = resolved_method;
115 _selected_method = selected_method; 121 _selected_method = selected_method;
116 _vtable_index = vtable_index; 122 _vtable_index = vtable_index;
123 _resolved_appendix = Handle();
117 if (CompilationPolicy::must_be_compiled(selected_method)) { 124 if (CompilationPolicy::must_be_compiled(selected_method)) {
118 // This path is unusual, mostly used by the '-Xcomp' stress test mode. 125 // This path is unusual, mostly used by the '-Xcomp' stress test mode.
119 126
120 // Note: with several active threads, the must_be_compiled may be true 127 // Note: with several active threads, the must_be_compiled may be true
121 // while can_be_compiled is false; remove assert 128 // while can_be_compiled is false; remove assert
178 // According to JVM spec. $5.4.3c & $5.4.3d 185 // According to JVM spec. $5.4.3c & $5.4.3d
179 186
180 void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { 187 void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
181 methodOop result_oop = klass->uncached_lookup_method(name, signature); 188 methodOop result_oop = klass->uncached_lookup_method(name, signature);
182 if (EnableInvokeDynamic && result_oop != NULL) { 189 if (EnableInvokeDynamic && result_oop != NULL) {
183 switch (result_oop->intrinsic_id()) { 190 vmIntrinsics::ID iid = result_oop->intrinsic_id();
184 case vmIntrinsics::_invokeExact: 191 if (MethodHandles::is_signature_polymorphic(iid)) {
185 case vmIntrinsics::_invokeGeneric: 192 // Do not link directly to these. The VM must produce a synthetic one using lookup_polymorphic_method.
186 case vmIntrinsics::_invokeDynamic:
187 // Do not link directly to these. The VM must produce a synthetic one using lookup_implicit_method.
188 return; 193 return;
189 } 194 }
190 } 195 }
191 result = methodHandle(THREAD, result_oop); 196 result = methodHandle(THREAD, result_oop);
192 } 197 }
211 void LinkResolver::lookup_method_in_interfaces(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { 216 void LinkResolver::lookup_method_in_interfaces(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
212 instanceKlass *ik = instanceKlass::cast(klass()); 217 instanceKlass *ik = instanceKlass::cast(klass());
213 result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature)); 218 result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature));
214 } 219 }
215 220
216 void LinkResolver::lookup_implicit_method(methodHandle& result, 221 void LinkResolver::lookup_polymorphic_method(methodHandle& result,
217 KlassHandle klass, Symbol* name, Symbol* signature, 222 KlassHandle klass, Symbol* name, Symbol* full_signature,
218 KlassHandle current_klass, 223 KlassHandle current_klass,
219 TRAPS) { 224 Handle* appendix_result_or_null,
225 TRAPS) {
226 vmIntrinsics::ID iid = MethodHandles::signature_polymorphic_name_id(name);
227 if (TraceMethodHandles) {
228 tty->print_cr("lookup_polymorphic_method iid=%s %s.%s%s",
229 vmIntrinsics::name_at(iid), klass->external_name(),
230 name->as_C_string(), full_signature->as_C_string());
231 }
220 if (EnableInvokeDynamic && 232 if (EnableInvokeDynamic &&
221 klass() == SystemDictionary::MethodHandle_klass() && 233 klass() == SystemDictionary::MethodHandle_klass() &&
222 methodOopDesc::is_method_handle_invoke_name(name)) { 234 iid != vmIntrinsics::_none) {
223 if (!THREAD->is_Compiler_thread() && !MethodHandles::enabled()) { 235 if (MethodHandles::is_signature_polymorphic_intrinsic(iid)) {
224 // Make sure the Java part of the runtime has been booted up. 236 // Most of these do not need an up-call to Java to resolve, so can be done anywhere.
225 klassOop natives = SystemDictionary::MethodHandleNatives_klass(); 237 // Do not erase last argument type (MemberName) if it is a static linkTo method.
226 if (natives == NULL || instanceKlass::cast(natives)->is_not_initialized()) { 238 bool keep_last_arg = MethodHandles::is_signature_polymorphic_static(iid);
227 SystemDictionary::resolve_or_fail(vmSymbols::java_lang_invoke_MethodHandleNatives(), 239 TempNewSymbol basic_signature =
228 Handle(), 240 MethodHandles::lookup_basic_type_signature(full_signature, keep_last_arg, CHECK);
229 Handle(), 241 if (TraceMethodHandles) {
230 true, 242 tty->print_cr("lookup_polymorphic_method %s %s => basic %s",
231 CHECK); 243 name->as_C_string(),
244 full_signature->as_C_string(),
245 basic_signature->as_C_string());
232 } 246 }
233 } 247 result = SystemDictionary::find_method_handle_intrinsic(iid,
234 methodOop result_oop = SystemDictionary::find_method_handle_invoke(name, 248 basic_signature,
235 signature, 249 CHECK);
236 current_klass, 250 if (result.not_null()) {
237 CHECK); 251 assert(result->is_method_handle_intrinsic(), "MH.invokeBasic or MH.linkTo* intrinsic");
238 if (result_oop != NULL) { 252 assert(result->intrinsic_id() != vmIntrinsics::_invokeGeneric, "wrong place to find this");
239 assert(result_oop->is_method_handle_invoke() && result_oop->signature() == signature, "consistent"); 253 assert(basic_signature == result->signature(), "predict the result signature");
240 result = methodHandle(THREAD, result_oop); 254 if (TraceMethodHandles) {
255 tty->print("lookup_polymorphic_method => intrinsic ");
256 result->print_on(tty);
257 }
258 return;
259 }
260 } else if (iid == vmIntrinsics::_invokeGeneric
261 && !THREAD->is_Compiler_thread()
262 && appendix_result_or_null != NULL) {
263 // This is a method with type-checking semantics.
264 // We will ask Java code to spin an adapter method for it.
265 if (!MethodHandles::enabled()) {
266 // Make sure the Java part of the runtime has been booted up.
267 klassOop natives = SystemDictionary::MethodHandleNatives_klass();
268 if (natives == NULL || instanceKlass::cast(natives)->is_not_initialized()) {
269 SystemDictionary::resolve_or_fail(vmSymbols::java_lang_invoke_MethodHandleNatives(),
270 Handle(),
271 Handle(),
272 true,
273 CHECK);
274 }
275 }
276
277 Handle appendix;
278 result = SystemDictionary::find_method_handle_invoker(name,
279 full_signature,
280 current_klass,
281 &appendix,
282 CHECK);
283 if (TraceMethodHandles) {
284 tty->print("lookup_polymorphic_method => (via Java) ");
285 result->print_on(tty);
286 tty->print(" lookup_polymorphic_method => appendix = ");
287 if (appendix.is_null()) tty->print_cr("(none)");
288 else appendix->print_on(tty);
289 }
290 if (result.not_null()) {
291 #ifdef ASSERT
292 TempNewSymbol basic_signature =
293 MethodHandles::lookup_basic_type_signature(full_signature, CHECK);
294 int actual_size_of_params = result->size_of_parameters();
295 int expected_size_of_params = ArgumentSizeComputer(basic_signature).size();
296 // +1 for MethodHandle.this, +1 for trailing MethodType
297 if (!MethodHandles::is_signature_polymorphic_static(iid)) expected_size_of_params += 1;
298 if (appendix.not_null()) expected_size_of_params += 1;
299 if (actual_size_of_params != expected_size_of_params) {
300 tty->print_cr("*** basic_signature=%s", basic_signature->as_C_string());
301 tty->print_cr("*** result for %s: ", vmIntrinsics::name_at(iid));
302 result->print();
303 }
304 assert(actual_size_of_params == expected_size_of_params,
305 err_msg("%d != %d", actual_size_of_params, expected_size_of_params));
306 #endif //ASSERT
307
308 assert(appendix_result_or_null != NULL, "");
309 (*appendix_result_or_null) = appendix;
310 return;
311 }
241 } 312 }
242 } 313 }
243 } 314 }
244 315
245 void LinkResolver::check_method_accessability(KlassHandle ref_klass, 316 void LinkResolver::check_method_accessability(KlassHandle ref_klass,
265 jint new_flags = flags.as_int(); 336 jint new_flags = flags.as_int();
266 new_flags = new_flags & (~JVM_ACC_PROTECTED); 337 new_flags = new_flags & (~JVM_ACC_PROTECTED);
267 new_flags = new_flags | JVM_ACC_PUBLIC; 338 new_flags = new_flags | JVM_ACC_PUBLIC;
268 flags.set_flags(new_flags); 339 flags.set_flags(new_flags);
269 } 340 }
341 // assert(extra_arg_result_or_null != NULL, "must be able to return extra argument");
270 342
271 if (!Reflection::verify_field_access(ref_klass->as_klassOop(), 343 if (!Reflection::verify_field_access(ref_klass->as_klassOop(),
272 resolved_klass->as_klassOop(), 344 resolved_klass->as_klassOop(),
273 sel_klass->as_klassOop(), 345 sel_klass->as_klassOop(),
274 flags, 346 flags,
285 ); 357 );
286 return; 358 return;
287 } 359 }
288 } 360 }
289 361
290 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle& resolved_klass, 362 void LinkResolver::resolve_method_statically(methodHandle& resolved_method, KlassHandle& resolved_klass,
291 constantPoolHandle pool, int index, TRAPS) { 363 Bytecodes::Code code, constantPoolHandle pool, int index, TRAPS) {
292 364
293 // resolve klass 365 // resolve klass
366 if (code == Bytecodes::_invokedynamic) {
367 resolved_klass = SystemDictionaryHandles::MethodHandle_klass();
368 Symbol* method_name = vmSymbols::invoke_name();
369 Symbol* method_signature = pool->signature_ref_at(index);
370 KlassHandle current_klass(THREAD, pool->pool_holder());
371 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
372 return;
373 }
374
294 resolve_klass(resolved_klass, pool, index, CHECK); 375 resolve_klass(resolved_klass, pool, index, CHECK);
295 376
296 Symbol* method_name = pool->name_ref_at(index); 377 Symbol* method_name = pool->name_ref_at(index);
297 Symbol* method_signature = pool->signature_ref_at(index); 378 Symbol* method_signature = pool->signature_ref_at(index);
298 KlassHandle current_klass(THREAD, pool->pool_holder()); 379 KlassHandle current_klass(THREAD, pool->pool_holder());
299 380
300 if (pool->has_preresolution() 381 if (pool->has_preresolution()
301 || (resolved_klass() == SystemDictionary::MethodHandle_klass() && 382 || (resolved_klass() == SystemDictionary::MethodHandle_klass() &&
302 methodOopDesc::is_method_handle_invoke_name(method_name))) { 383 MethodHandles::is_signature_polymorphic_name(resolved_klass(), method_name))) {
303 methodOop result_oop = constantPoolOopDesc::method_at_if_loaded(pool, index); 384 methodOop result_oop = constantPoolOopDesc::method_at_if_loaded(pool, index);
304 if (result_oop != NULL) { 385 if (result_oop != NULL) {
305 resolved_method = methodHandle(THREAD, result_oop); 386 resolved_method = methodHandle(THREAD, result_oop);
306 return; 387 return;
307 } 388 }
308 } 389 }
309 390
310 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK); 391 if (code == Bytecodes::_invokeinterface) {
311 } 392 resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
312 393 } else {
313 void LinkResolver::resolve_dynamic_method(methodHandle& resolved_method, KlassHandle& resolved_klass, constantPoolHandle pool, int index, TRAPS) { 394 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
314 // The class is java.lang.invoke.MethodHandle 395 }
315 resolved_klass = SystemDictionaryHandles::MethodHandle_klass(); 396 }
316
317 Symbol* method_name = vmSymbols::invokeExact_name();
318
319 Symbol* method_signature = pool->signature_ref_at(index);
320 KlassHandle current_klass (THREAD, pool->pool_holder());
321
322 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
323 }
324
325 void LinkResolver::resolve_interface_method(methodHandle& resolved_method, KlassHandle& resolved_klass, constantPoolHandle pool, int index, TRAPS) {
326
327 // resolve klass
328 resolve_klass(resolved_klass, pool, index, CHECK);
329 Symbol* method_name = pool->name_ref_at(index);
330 Symbol* method_signature = pool->signature_ref_at(index);
331 KlassHandle current_klass(THREAD, pool->pool_holder());
332
333 resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
334 }
335
336 397
337 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass, 398 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass,
338 Symbol* method_name, Symbol* method_signature, 399 Symbol* method_name, Symbol* method_signature,
339 KlassHandle current_klass, bool check_access, TRAPS) { 400 KlassHandle current_klass, bool check_access, TRAPS) {
340 401
344 char buf[200]; 405 char buf[200];
345 jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected", Klass::cast(resolved_klass())->external_name()); 406 jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected", Klass::cast(resolved_klass())->external_name());
346 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 407 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
347 } 408 }
348 409
410 Handle nested_exception;
411
349 // 2. lookup method in resolved klass and its super klasses 412 // 2. lookup method in resolved klass and its super klasses
350 lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK); 413 lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK);
351 414
352 if (resolved_method.is_null()) { // not found in the class hierarchy 415 if (resolved_method.is_null()) { // not found in the class hierarchy
353 // 3. lookup method in all the interfaces implemented by the resolved klass 416 // 3. lookup method in all the interfaces implemented by the resolved klass
354 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK); 417 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
355 418
356 if (resolved_method.is_null()) { 419 if (resolved_method.is_null()) {
357 // JSR 292: see if this is an implicitly generated method MethodHandle.invoke(*...) 420 // JSR 292: see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
358 lookup_implicit_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, CHECK); 421 lookup_polymorphic_method(resolved_method, resolved_klass, method_name, method_signature,
422 current_klass, (Handle*)NULL, THREAD);
423 if (HAS_PENDING_EXCEPTION) {
424 nested_exception = Handle(THREAD, PENDING_EXCEPTION);
425 CLEAR_PENDING_EXCEPTION;
426 }
359 } 427 }
360 428
361 if (resolved_method.is_null()) { 429 if (resolved_method.is_null()) {
362 // 4. method lookup failed 430 // 4. method lookup failed
363 ResourceMark rm(THREAD); 431 ResourceMark rm(THREAD);
364 THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(), 432 THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(),
365 methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), 433 methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
366 method_name, 434 method_name,
367 method_signature)); 435 method_signature),
436 nested_exception);
368 } 437 }
369 } 438 }
370 439
371 // 5. check if method is concrete 440 // 5. check if method is concrete
372 if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) { 441 if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) {
1051 void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS) { 1120 void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS) {
1052 switch (byte) { 1121 switch (byte) {
1053 case Bytecodes::_invokestatic : resolve_invokestatic (result, pool, index, CHECK); break; 1122 case Bytecodes::_invokestatic : resolve_invokestatic (result, pool, index, CHECK); break;
1054 case Bytecodes::_invokespecial : resolve_invokespecial (result, pool, index, CHECK); break; 1123 case Bytecodes::_invokespecial : resolve_invokespecial (result, pool, index, CHECK); break;
1055 case Bytecodes::_invokevirtual : resolve_invokevirtual (result, recv, pool, index, CHECK); break; 1124 case Bytecodes::_invokevirtual : resolve_invokevirtual (result, recv, pool, index, CHECK); break;
1125 case Bytecodes::_invokehandle : resolve_invokehandle (result, pool, index, CHECK); break;
1056 case Bytecodes::_invokedynamic : resolve_invokedynamic (result, pool, index, CHECK); break; 1126 case Bytecodes::_invokedynamic : resolve_invokedynamic (result, pool, index, CHECK); break;
1057 case Bytecodes::_invokeinterface: resolve_invokeinterface(result, recv, pool, index, CHECK); break; 1127 case Bytecodes::_invokeinterface: resolve_invokeinterface(result, recv, pool, index, CHECK); break;
1058 } 1128 }
1059 return; 1129 return;
1060 } 1130 }
1114 KlassHandle recvrKlass (THREAD, recv.is_null() ? (klassOop)NULL : recv->klass()); 1184 KlassHandle recvrKlass (THREAD, recv.is_null() ? (klassOop)NULL : recv->klass());
1115 resolve_interface_call(result, recv, recvrKlass, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK); 1185 resolve_interface_call(result, recv, recvrKlass, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
1116 } 1186 }
1117 1187
1118 1188
1119 void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle pool, int raw_index, TRAPS) { 1189 void LinkResolver::resolve_invokehandle(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
1120 assert(EnableInvokeDynamic, ""); 1190 assert(EnableInvokeDynamic, "");
1121 1191 // This guy is reached from InterpreterRuntime::resolve_invokehandle.
1122 // This guy is reached from InterpreterRuntime::resolve_invokedynamic. 1192 KlassHandle resolved_klass;
1123 1193 Symbol* method_name = NULL;
1124 // At this point, we only need the signature, and can ignore the name. 1194 Symbol* method_signature = NULL;
1125 Symbol* method_signature = pool->signature_ref_at(raw_index); // raw_index works directly 1195 KlassHandle current_klass;
1126 Symbol* method_name = vmSymbols::invokeExact_name(); 1196 resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK);
1127 KlassHandle resolved_klass = SystemDictionaryHandles::MethodHandle_klass(); 1197 if (TraceMethodHandles)
1128 1198 tty->print_cr("resolve_invokehandle %s %s", method_name->as_C_string(), method_signature->as_C_string());
1129 // JSR 292: this must be an implicitly generated method MethodHandle.invokeExact(*...) 1199 resolve_handle_call(result, resolved_klass, method_name, method_signature, current_klass, CHECK);
1130 // The extra MH receiver will be inserted into the stack on every call. 1200 }
1201
1202 void LinkResolver::resolve_handle_call(CallInfo& result, KlassHandle resolved_klass,
1203 Symbol* method_name, Symbol* method_signature,
1204 KlassHandle current_klass,
1205 TRAPS) {
1206 // JSR 292: this must be an implicitly generated method MethodHandle.invokeExact(*...) or similar
1207 assert(resolved_klass() == SystemDictionary::MethodHandle_klass(), "");
1208 assert(MethodHandles::is_signature_polymorphic_name(method_name), "");
1131 methodHandle resolved_method; 1209 methodHandle resolved_method;
1132 KlassHandle current_klass(THREAD, pool->pool_holder()); 1210 Handle resolved_appendix;
1133 lookup_implicit_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, THREAD); 1211 lookup_polymorphic_method(resolved_method, resolved_klass,
1212 method_name, method_signature,
1213 current_klass, &resolved_appendix, CHECK);
1214 result.set_handle(resolved_method, resolved_appendix, CHECK);
1215 }
1216
1217
1218 void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
1219 assert(EnableInvokeDynamic, "");
1220 pool->set_invokedynamic(); // mark header to flag active call sites
1221
1222 //resolve_pool(<resolved_klass>, method_name, method_signature, current_klass, pool, index, CHECK);
1223 Symbol* method_name = pool->name_ref_at(index);
1224 Symbol* method_signature = pool->signature_ref_at(index);
1225 KlassHandle current_klass = KlassHandle(THREAD, pool->pool_holder());
1226
1227 // Resolve the bootstrap specifier (BSM + optional arguments).
1228 Handle bootstrap_specifier;
1229 // Check if CallSite has been bound already:
1230 ConstantPoolCacheEntry* cpce = pool->cache()->secondary_entry_at(index);
1231 if (cpce->is_f1_null()) {
1232 int pool_index = pool->cache()->main_entry_at(index)->constant_pool_index();
1233 oop bsm_info = pool->resolve_bootstrap_specifier_at(pool_index, CHECK);
1234 assert(bsm_info != NULL, "");
1235 // FIXME: Cache this once per BootstrapMethods entry, not once per CONSTANT_InvokeDynamic.
1236 bootstrap_specifier = Handle(THREAD, bsm_info);
1237 }
1238 if (!cpce->is_f1_null()) {
1239 methodHandle method(THREAD, cpce->f2_as_vfinal_method());
1240 Handle appendix(THREAD, cpce->has_appendix() ? cpce->f1_appendix() : (oop)NULL);
1241 result.set_handle(method, appendix, CHECK);
1242 return;
1243 }
1244
1245 if (TraceMethodHandles) {
1246 tty->print_cr("resolve_invokedynamic #%d %s %s",
1247 constantPoolCacheOopDesc::decode_secondary_index(index),
1248 method_name->as_C_string(), method_signature->as_C_string());
1249 tty->print(" BSM info: "); bootstrap_specifier->print();
1250 }
1251
1252 resolve_dynamic_call(result, bootstrap_specifier, method_name, method_signature, current_klass, CHECK);
1253 }
1254
1255 void LinkResolver::resolve_dynamic_call(CallInfo& result,
1256 Handle bootstrap_specifier,
1257 Symbol* method_name, Symbol* method_signature,
1258 KlassHandle current_klass,
1259 TRAPS) {
1260 // JSR 292: this must resolve to an implicitly generated method MH.linkToCallSite(*...)
1261 // The appendix argument is likely to be a freshly-created CallSite.
1262 Handle resolved_appendix;
1263 methodHandle resolved_method =
1264 SystemDictionary::find_dynamic_call_site_invoker(current_klass,
1265 bootstrap_specifier,
1266 method_name, method_signature,
1267 &resolved_appendix,
1268 CHECK);
1134 if (HAS_PENDING_EXCEPTION) { 1269 if (HAS_PENDING_EXCEPTION) {
1270 if (TraceMethodHandles) {
1271 tty->print_cr("invokedynamic throws BSME for "INTPTR_FORMAT, PENDING_EXCEPTION);
1272 PENDING_EXCEPTION->print();
1273 }
1135 if (PENDING_EXCEPTION->is_a(SystemDictionary::BootstrapMethodError_klass())) { 1274 if (PENDING_EXCEPTION->is_a(SystemDictionary::BootstrapMethodError_klass())) {
1136 // throw these guys, since they are already wrapped 1275 // throw these guys, since they are already wrapped
1137 return; 1276 return;
1138 } 1277 }
1139 if (!PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) { 1278 if (!PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) {
1140 // intercept only LinkageErrors which might have failed to wrap 1279 // intercept only LinkageErrors which might have failed to wrap
1141 return; 1280 return;
1142 } 1281 }
1143 // See the "Linking Exceptions" section for the invokedynamic instruction in the JVMS. 1282 // See the "Linking Exceptions" section for the invokedynamic instruction in the JVMS.
1144 Handle ex(THREAD, PENDING_EXCEPTION); 1283 Handle nested_exception(THREAD, PENDING_EXCEPTION);
1145 CLEAR_PENDING_EXCEPTION; 1284 CLEAR_PENDING_EXCEPTION;
1146 oop bsme = Klass::cast(SystemDictionary::BootstrapMethodError_klass())->java_mirror(); 1285 THROW_MSG_CAUSE(vmSymbols::java_lang_BootstrapMethodError(),
1147 MethodHandles::raise_exception(Bytecodes::_athrow, ex(), bsme, CHECK); 1286 "BootstrapMethodError", nested_exception)
1148 // java code should not return, but if it does throw out anyway 1287 }
1149 THROW(vmSymbols::java_lang_InternalError()); 1288 result.set_handle(resolved_method, resolved_appendix, CHECK);
1150 }
1151 if (resolved_method.is_null()) {
1152 THROW(vmSymbols::java_lang_InternalError());
1153 }
1154 result.set_dynamic(resolved_method, CHECK);
1155 } 1289 }
1156 1290
1157 //------------------------------------------------------------------------------------------------------------------------ 1291 //------------------------------------------------------------------------------------------------------------------------
1158 #ifndef PRODUCT 1292 #ifndef PRODUCT
1159 1293