161 // this DMH performs no dispatch; it is directly bound to a methodOop |
161 // this DMH performs no dispatch; it is directly bound to a methodOop |
162 // A MemberName may either be directly bound to a methodOop, |
162 // A MemberName may either be directly bound to a methodOop, |
163 // or it may use the klass/index form; both forms mean the same thing. |
163 // or it may use the klass/index form; both forms mean the same thing. |
164 methodOop m = decode_methodOop(methodOop(vmtarget), decode_flags_result); |
164 methodOop m = decode_methodOop(methodOop(vmtarget), decode_flags_result); |
165 if ((decode_flags_result & _dmf_has_receiver) != 0 |
165 if ((decode_flags_result & _dmf_has_receiver) != 0 |
166 && java_dyn_MethodType::is_instance(mtype)) { |
166 && java_lang_invoke_MethodType::is_instance(mtype)) { |
167 // Extract receiver type restriction from mtype.ptypes[0]. |
167 // Extract receiver type restriction from mtype.ptypes[0]. |
168 objArrayOop ptypes = java_dyn_MethodType::ptypes(mtype); |
168 objArrayOop ptypes = java_lang_invoke_MethodType::ptypes(mtype); |
169 oop ptype0 = (ptypes == NULL || ptypes->length() < 1) ? oop(NULL) : ptypes->obj_at(0); |
169 oop ptype0 = (ptypes == NULL || ptypes->length() < 1) ? oop(NULL) : ptypes->obj_at(0); |
170 if (java_lang_Class::is_instance(ptype0)) |
170 if (java_lang_Class::is_instance(ptype0)) |
171 receiver_limit_result = java_lang_Class::as_klassOop(ptype0); |
171 receiver_limit_result = java_lang_Class::as_klassOop(ptype0); |
172 } |
172 } |
173 if (vmindex == methodOopDesc::nonvirtual_vtable_index) { |
173 if (vmindex == methodOopDesc::nonvirtual_vtable_index) { |
197 |
197 |
198 // MemberName and DirectMethodHandle have the same linkage to the JVM internals. |
198 // MemberName and DirectMethodHandle have the same linkage to the JVM internals. |
199 // (MemberName is the non-operational name used for queries and setup.) |
199 // (MemberName is the non-operational name used for queries and setup.) |
200 |
200 |
201 methodOop MethodHandles::decode_DirectMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) { |
201 methodOop MethodHandles::decode_DirectMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) { |
202 oop vmtarget = sun_dyn_DirectMethodHandle::vmtarget(mh); |
202 oop vmtarget = java_lang_invoke_DirectMethodHandle::vmtarget(mh); |
203 int vmindex = sun_dyn_DirectMethodHandle::vmindex(mh); |
203 int vmindex = java_lang_invoke_DirectMethodHandle::vmindex(mh); |
204 oop mtype = sun_dyn_DirectMethodHandle::type(mh); |
204 oop mtype = java_lang_invoke_DirectMethodHandle::type(mh); |
205 return decode_vmtarget(vmtarget, vmindex, mtype, receiver_limit_result, decode_flags_result); |
205 return decode_vmtarget(vmtarget, vmindex, mtype, receiver_limit_result, decode_flags_result); |
206 } |
206 } |
207 |
207 |
208 methodOop MethodHandles::decode_BoundMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) { |
208 methodOop MethodHandles::decode_BoundMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) { |
209 assert(sun_dyn_BoundMethodHandle::is_instance(mh), ""); |
209 assert(java_lang_invoke_BoundMethodHandle::is_instance(mh), ""); |
210 assert(mh->klass() != SystemDictionary::AdapterMethodHandle_klass(), ""); |
210 assert(mh->klass() != SystemDictionary::AdapterMethodHandle_klass(), ""); |
211 for (oop bmh = mh;;) { |
211 for (oop bmh = mh;;) { |
212 // Bound MHs can be stacked to bind several arguments. |
212 // Bound MHs can be stacked to bind several arguments. |
213 oop target = java_dyn_MethodHandle::vmtarget(bmh); |
213 oop target = java_lang_invoke_MethodHandle::vmtarget(bmh); |
214 if (target == NULL) return NULL; |
214 if (target == NULL) return NULL; |
215 decode_flags_result |= MethodHandles::_dmf_binds_argument; |
215 decode_flags_result |= MethodHandles::_dmf_binds_argument; |
216 klassOop tk = target->klass(); |
216 klassOop tk = target->klass(); |
217 if (tk == SystemDictionary::BoundMethodHandle_klass()) { |
217 if (tk == SystemDictionary::BoundMethodHandle_klass()) { |
218 bmh = target; |
218 bmh = target; |
219 continue; |
219 continue; |
220 } else { |
220 } else { |
221 if (java_dyn_MethodHandle::is_subclass(tk)) { |
221 if (java_lang_invoke_MethodHandle::is_subclass(tk)) { |
222 //assert(tk == SystemDictionary::DirectMethodHandle_klass(), "end of BMH chain must be DMH"); |
222 //assert(tk == SystemDictionary::DirectMethodHandle_klass(), "end of BMH chain must be DMH"); |
223 return decode_MethodHandle(target, receiver_limit_result, decode_flags_result); |
223 return decode_MethodHandle(target, receiver_limit_result, decode_flags_result); |
224 } else { |
224 } else { |
225 // Optimized case: binding a receiver to a non-dispatched DMH |
225 // Optimized case: binding a receiver to a non-dispatched DMH |
226 // short-circuits directly to the methodOop. |
226 // short-circuits directly to the methodOop. |
238 |
238 |
239 methodOop MethodHandles::decode_AdapterMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) { |
239 methodOop MethodHandles::decode_AdapterMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) { |
240 assert(mh->klass() == SystemDictionary::AdapterMethodHandle_klass(), ""); |
240 assert(mh->klass() == SystemDictionary::AdapterMethodHandle_klass(), ""); |
241 for (oop amh = mh;;) { |
241 for (oop amh = mh;;) { |
242 // Adapter MHs can be stacked to convert several arguments. |
242 // Adapter MHs can be stacked to convert several arguments. |
243 int conv_op = adapter_conversion_op(sun_dyn_AdapterMethodHandle::conversion(amh)); |
243 int conv_op = adapter_conversion_op(java_lang_invoke_AdapterMethodHandle::conversion(amh)); |
244 decode_flags_result |= (_dmf_adapter_lsb << conv_op) & _DMF_ADAPTER_MASK; |
244 decode_flags_result |= (_dmf_adapter_lsb << conv_op) & _DMF_ADAPTER_MASK; |
245 oop target = java_dyn_MethodHandle::vmtarget(amh); |
245 oop target = java_lang_invoke_MethodHandle::vmtarget(amh); |
246 if (target == NULL) return NULL; |
246 if (target == NULL) return NULL; |
247 klassOop tk = target->klass(); |
247 klassOop tk = target->klass(); |
248 if (tk == SystemDictionary::AdapterMethodHandle_klass()) { |
248 if (tk == SystemDictionary::AdapterMethodHandle_klass()) { |
249 amh = target; |
249 amh = target; |
250 continue; |
250 continue; |
256 } |
256 } |
257 |
257 |
258 methodOop MethodHandles::decode_MethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) { |
258 methodOop MethodHandles::decode_MethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) { |
259 if (mh == NULL) return NULL; |
259 if (mh == NULL) return NULL; |
260 klassOop mhk = mh->klass(); |
260 klassOop mhk = mh->klass(); |
261 assert(java_dyn_MethodHandle::is_subclass(mhk), "must be a MethodHandle"); |
261 assert(java_lang_invoke_MethodHandle::is_subclass(mhk), "must be a MethodHandle"); |
262 if (mhk == SystemDictionary::DirectMethodHandle_klass()) { |
262 if (mhk == SystemDictionary::DirectMethodHandle_klass()) { |
263 return decode_DirectMethodHandle(mh, receiver_limit_result, decode_flags_result); |
263 return decode_DirectMethodHandle(mh, receiver_limit_result, decode_flags_result); |
264 } else if (mhk == SystemDictionary::BoundMethodHandle_klass()) { |
264 } else if (mhk == SystemDictionary::BoundMethodHandle_klass()) { |
265 return decode_BoundMethodHandle(mh, receiver_limit_result, decode_flags_result); |
265 return decode_BoundMethodHandle(mh, receiver_limit_result, decode_flags_result); |
266 } else if (mhk == SystemDictionary::AdapterMethodHandle_klass()) { |
266 } else if (mhk == SystemDictionary::AdapterMethodHandle_klass()) { |
267 return decode_AdapterMethodHandle(mh, receiver_limit_result, decode_flags_result); |
267 return decode_AdapterMethodHandle(mh, receiver_limit_result, decode_flags_result); |
268 } else if (sun_dyn_BoundMethodHandle::is_subclass(mhk)) { |
268 } else if (java_lang_invoke_BoundMethodHandle::is_subclass(mhk)) { |
269 // could be a JavaMethodHandle (but not an adapter MH) |
269 // could be a JavaMethodHandle (but not an adapter MH) |
270 return decode_BoundMethodHandle(mh, receiver_limit_result, decode_flags_result); |
270 return decode_BoundMethodHandle(mh, receiver_limit_result, decode_flags_result); |
271 } else { |
271 } else { |
272 assert(false, "cannot parse this MH"); |
272 assert(false, "cannot parse this MH"); |
273 return NULL; // random MH? |
273 return NULL; // random MH? |
306 if (xk == Universe::methodKlassObj()) { |
306 if (xk == Universe::methodKlassObj()) { |
307 return decode_methodOop((methodOop) x, decode_flags_result); |
307 return decode_methodOop((methodOop) x, decode_flags_result); |
308 } else if (xk == SystemDictionary::MemberName_klass()) { |
308 } else if (xk == SystemDictionary::MemberName_klass()) { |
309 // Note: This only works if the MemberName has already been resolved. |
309 // Note: This only works if the MemberName has already been resolved. |
310 return decode_MemberName(x, receiver_limit_result, decode_flags_result); |
310 return decode_MemberName(x, receiver_limit_result, decode_flags_result); |
311 } else if (java_dyn_MethodHandle::is_subclass(xk)) { |
311 } else if (java_lang_invoke_MethodHandle::is_subclass(xk)) { |
312 return decode_MethodHandle(x, receiver_limit_result, decode_flags_result); |
312 return decode_MethodHandle(x, receiver_limit_result, decode_flags_result); |
313 } else if (xk == SystemDictionary::reflect_Method_klass()) { |
313 } else if (xk == SystemDictionary::reflect_Method_klass()) { |
314 oop clazz = java_lang_reflect_Method::clazz(x); |
314 oop clazz = java_lang_reflect_Method::clazz(x); |
315 int slot = java_lang_reflect_Method::slot(x); |
315 int slot = java_lang_reflect_Method::slot(x); |
316 klassOop k = java_lang_Class::as_klassOop(clazz); |
316 klassOop k = java_lang_Class::as_klassOop(clazz); |
325 return decode_methodOop(instanceKlass::cast(k)->method_with_idnum(slot), |
325 return decode_methodOop(instanceKlass::cast(k)->method_with_idnum(slot), |
326 decode_flags_result); |
326 decode_flags_result); |
327 } else { |
327 } else { |
328 // unrecognized object |
328 // unrecognized object |
329 assert(!x->is_method(), "already checked"); |
329 assert(!x->is_method(), "already checked"); |
330 assert(!sun_dyn_MemberName::is_instance(x), "already checked"); |
330 assert(!java_lang_invoke_MemberName::is_instance(x), "already checked"); |
331 } |
331 } |
332 return NULL; |
332 return NULL; |
333 } |
333 } |
334 |
334 |
335 |
335 |
336 int MethodHandles::decode_MethodHandle_stack_pushes(oop mh) { |
336 int MethodHandles::decode_MethodHandle_stack_pushes(oop mh) { |
337 if (mh->klass() == SystemDictionary::DirectMethodHandle_klass()) |
337 if (mh->klass() == SystemDictionary::DirectMethodHandle_klass()) |
338 return 0; // no push/pop |
338 return 0; // no push/pop |
339 int this_vmslots = java_dyn_MethodHandle::vmslots(mh); |
339 int this_vmslots = java_lang_invoke_MethodHandle::vmslots(mh); |
340 int last_vmslots = 0; |
340 int last_vmslots = 0; |
341 oop last_mh = mh; |
341 oop last_mh = mh; |
342 for (;;) { |
342 for (;;) { |
343 oop target = java_dyn_MethodHandle::vmtarget(last_mh); |
343 oop target = java_lang_invoke_MethodHandle::vmtarget(last_mh); |
344 if (target->klass() == SystemDictionary::DirectMethodHandle_klass()) { |
344 if (target->klass() == SystemDictionary::DirectMethodHandle_klass()) { |
345 last_vmslots = java_dyn_MethodHandle::vmslots(target); |
345 last_vmslots = java_lang_invoke_MethodHandle::vmslots(target); |
346 break; |
346 break; |
347 } else if (!java_dyn_MethodHandle::is_instance(target)) { |
347 } else if (!java_lang_invoke_MethodHandle::is_instance(target)) { |
348 // might be klass or method |
348 // might be klass or method |
349 assert(target->is_method(), "must get here with a direct ref to method"); |
349 assert(target->is_method(), "must get here with a direct ref to method"); |
350 last_vmslots = methodOop(target)->size_of_parameters(); |
350 last_vmslots = methodOop(target)->size_of_parameters(); |
351 break; |
351 break; |
352 } |
352 } |
359 } |
359 } |
360 |
360 |
361 |
361 |
362 // MemberName support |
362 // MemberName support |
363 |
363 |
364 // import sun_dyn_MemberName.* |
364 // import java_lang_invoke_MemberName.* |
365 enum { |
365 enum { |
366 IS_METHOD = sun_dyn_MemberName::MN_IS_METHOD, |
366 IS_METHOD = java_lang_invoke_MemberName::MN_IS_METHOD, |
367 IS_CONSTRUCTOR = sun_dyn_MemberName::MN_IS_CONSTRUCTOR, |
367 IS_CONSTRUCTOR = java_lang_invoke_MemberName::MN_IS_CONSTRUCTOR, |
368 IS_FIELD = sun_dyn_MemberName::MN_IS_FIELD, |
368 IS_FIELD = java_lang_invoke_MemberName::MN_IS_FIELD, |
369 IS_TYPE = sun_dyn_MemberName::MN_IS_TYPE, |
369 IS_TYPE = java_lang_invoke_MemberName::MN_IS_TYPE, |
370 SEARCH_SUPERCLASSES = sun_dyn_MemberName::MN_SEARCH_SUPERCLASSES, |
370 SEARCH_SUPERCLASSES = java_lang_invoke_MemberName::MN_SEARCH_SUPERCLASSES, |
371 SEARCH_INTERFACES = sun_dyn_MemberName::MN_SEARCH_INTERFACES, |
371 SEARCH_INTERFACES = java_lang_invoke_MemberName::MN_SEARCH_INTERFACES, |
372 ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE, |
372 ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE, |
373 VM_INDEX_UNINITIALIZED = sun_dyn_MemberName::VM_INDEX_UNINITIALIZED |
373 VM_INDEX_UNINITIALIZED = java_lang_invoke_MemberName::VM_INDEX_UNINITIALIZED |
374 }; |
374 }; |
375 |
375 |
376 Handle MethodHandles::new_MemberName(TRAPS) { |
376 Handle MethodHandles::new_MemberName(TRAPS) { |
377 Handle empty; |
377 Handle empty; |
378 instanceKlassHandle k(THREAD, SystemDictionary::MemberName_klass()); |
378 instanceKlassHandle k(THREAD, SystemDictionary::MemberName_klass()); |
403 oop vmtarget = m; |
403 oop vmtarget = m; |
404 int vmindex = methodOopDesc::invalid_vtable_index; // implies no info yet |
404 int vmindex = methodOopDesc::invalid_vtable_index; // implies no info yet |
405 if (!do_dispatch || (flags & IS_CONSTRUCTOR) || m->can_be_statically_bound()) |
405 if (!do_dispatch || (flags & IS_CONSTRUCTOR) || m->can_be_statically_bound()) |
406 vmindex = methodOopDesc::nonvirtual_vtable_index; // implies never any dispatch |
406 vmindex = methodOopDesc::nonvirtual_vtable_index; // implies never any dispatch |
407 assert(vmindex != VM_INDEX_UNINITIALIZED, "Java sentinel value"); |
407 assert(vmindex != VM_INDEX_UNINITIALIZED, "Java sentinel value"); |
408 sun_dyn_MemberName::set_vmtarget(mname_oop, vmtarget); |
408 java_lang_invoke_MemberName::set_vmtarget(mname_oop, vmtarget); |
409 sun_dyn_MemberName::set_vmindex(mname_oop, vmindex); |
409 java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex); |
410 sun_dyn_MemberName::set_flags(mname_oop, flags); |
410 java_lang_invoke_MemberName::set_flags(mname_oop, flags); |
411 sun_dyn_MemberName::set_clazz(mname_oop, Klass::cast(m->method_holder())->java_mirror()); |
411 java_lang_invoke_MemberName::set_clazz(mname_oop, Klass::cast(m->method_holder())->java_mirror()); |
412 } |
412 } |
413 |
413 |
414 void MethodHandles::init_MemberName(oop mname_oop, klassOop field_holder, AccessFlags mods, int offset) { |
414 void MethodHandles::init_MemberName(oop mname_oop, klassOop field_holder, AccessFlags mods, int offset) { |
415 int flags = (IS_FIELD | (jushort)( mods.as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS )); |
415 int flags = (IS_FIELD | (jushort)( mods.as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS )); |
416 oop vmtarget = field_holder; |
416 oop vmtarget = field_holder; |
417 int vmindex = offset; // determines the field uniquely when combined with static bit |
417 int vmindex = offset; // determines the field uniquely when combined with static bit |
418 assert(vmindex != VM_INDEX_UNINITIALIZED, "bad alias on vmindex"); |
418 assert(vmindex != VM_INDEX_UNINITIALIZED, "bad alias on vmindex"); |
419 sun_dyn_MemberName::set_vmtarget(mname_oop, vmtarget); |
419 java_lang_invoke_MemberName::set_vmtarget(mname_oop, vmtarget); |
420 sun_dyn_MemberName::set_vmindex(mname_oop, vmindex); |
420 java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex); |
421 sun_dyn_MemberName::set_flags(mname_oop, flags); |
421 java_lang_invoke_MemberName::set_flags(mname_oop, flags); |
422 sun_dyn_MemberName::set_clazz(mname_oop, Klass::cast(field_holder)->java_mirror()); |
422 java_lang_invoke_MemberName::set_clazz(mname_oop, Klass::cast(field_holder)->java_mirror()); |
423 } |
423 } |
424 |
424 |
425 |
425 |
426 methodOop MethodHandles::decode_MemberName(oop mname, klassOop& receiver_limit_result, int& decode_flags_result) { |
426 methodOop MethodHandles::decode_MemberName(oop mname, klassOop& receiver_limit_result, int& decode_flags_result) { |
427 int flags = sun_dyn_MemberName::flags(mname); |
427 int flags = java_lang_invoke_MemberName::flags(mname); |
428 if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) == 0) return NULL; // not invocable |
428 if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) == 0) return NULL; // not invocable |
429 oop vmtarget = sun_dyn_MemberName::vmtarget(mname); |
429 oop vmtarget = java_lang_invoke_MemberName::vmtarget(mname); |
430 int vmindex = sun_dyn_MemberName::vmindex(mname); |
430 int vmindex = java_lang_invoke_MemberName::vmindex(mname); |
431 if (vmindex == VM_INDEX_UNINITIALIZED) return NULL; // not resolved |
431 if (vmindex == VM_INDEX_UNINITIALIZED) return NULL; // not resolved |
432 methodOop m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit_result, decode_flags_result); |
432 methodOop m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit_result, decode_flags_result); |
433 oop clazz = sun_dyn_MemberName::clazz(mname); |
433 oop clazz = java_lang_invoke_MemberName::clazz(mname); |
434 if (clazz != NULL && java_lang_Class::is_instance(clazz)) { |
434 if (clazz != NULL && java_lang_Class::is_instance(clazz)) { |
435 klassOop klass = java_lang_Class::as_klassOop(clazz); |
435 klassOop klass = java_lang_Class::as_klassOop(clazz); |
436 if (klass != NULL) receiver_limit_result = klass; |
436 if (klass != NULL) receiver_limit_result = klass; |
437 } |
437 } |
438 return m; |
438 return m; |
440 |
440 |
441 // convert the external string or reflective type to an internal signature |
441 // convert the external string or reflective type to an internal signature |
442 Symbol* MethodHandles::convert_to_signature(oop type_str, |
442 Symbol* MethodHandles::convert_to_signature(oop type_str, |
443 bool polymorphic, |
443 bool polymorphic, |
444 TRAPS) { |
444 TRAPS) { |
445 if (java_dyn_MethodType::is_instance(type_str)) { |
445 if (java_lang_invoke_MethodType::is_instance(type_str)) { |
446 return java_dyn_MethodType::as_signature(type_str, polymorphic, CHECK_NULL); |
446 return java_lang_invoke_MethodType::as_signature(type_str, polymorphic, CHECK_NULL); |
447 } else if (java_lang_Class::is_instance(type_str)) { |
447 } else if (java_lang_Class::is_instance(type_str)) { |
448 return java_lang_Class::as_signature(type_str, false, CHECK_NULL); |
448 return java_lang_Class::as_signature(type_str, false, CHECK_NULL); |
449 } else if (java_lang_String::is_instance(type_str)) { |
449 } else if (java_lang_String::is_instance(type_str)) { |
450 if (polymorphic) { |
450 if (polymorphic) { |
451 return java_lang_String::as_symbol(type_str, CHECK_NULL); |
451 return java_lang_String::as_symbol(type_str, CHECK_NULL); |
459 |
459 |
460 // An unresolved member name is a mere symbolic reference. |
460 // An unresolved member name is a mere symbolic reference. |
461 // Resolving it plants a vmtarget/vmindex in it, |
461 // Resolving it plants a vmtarget/vmindex in it, |
462 // which refers dirctly to JVM internals. |
462 // which refers dirctly to JVM internals. |
463 void MethodHandles::resolve_MemberName(Handle mname, TRAPS) { |
463 void MethodHandles::resolve_MemberName(Handle mname, TRAPS) { |
464 assert(sun_dyn_MemberName::is_instance(mname()), ""); |
464 assert(java_lang_invoke_MemberName::is_instance(mname()), ""); |
465 #ifdef ASSERT |
465 #ifdef ASSERT |
466 // If this assert throws, renegotiate the sentinel value used by the Java code, |
466 // If this assert throws, renegotiate the sentinel value used by the Java code, |
467 // so that it is distinct from any valid vtable index value, and any special |
467 // so that it is distinct from any valid vtable index value, and any special |
468 // values defined in methodOopDesc::VtableIndexFlag. |
468 // values defined in methodOopDesc::VtableIndexFlag. |
469 // The point of the slop is to give the Java code and the JVM some room |
469 // The point of the slop is to give the Java code and the JVM some room |
470 // to independently specify sentinel values. |
470 // to independently specify sentinel values. |
471 const int sentinel_slop = 10; |
471 const int sentinel_slop = 10; |
472 const int sentinel_limit = methodOopDesc::highest_unused_vtable_index_value - sentinel_slop; |
472 const int sentinel_limit = methodOopDesc::highest_unused_vtable_index_value - sentinel_slop; |
473 assert(VM_INDEX_UNINITIALIZED < sentinel_limit, "Java sentinel != JVM sentinels"); |
473 assert(VM_INDEX_UNINITIALIZED < sentinel_limit, "Java sentinel != JVM sentinels"); |
474 #endif |
474 #endif |
475 if (sun_dyn_MemberName::vmindex(mname()) != VM_INDEX_UNINITIALIZED) |
475 if (java_lang_invoke_MemberName::vmindex(mname()) != VM_INDEX_UNINITIALIZED) |
476 return; // already resolved |
476 return; // already resolved |
477 oop defc_oop = sun_dyn_MemberName::clazz(mname()); |
477 oop defc_oop = java_lang_invoke_MemberName::clazz(mname()); |
478 oop name_str = sun_dyn_MemberName::name(mname()); |
478 oop name_str = java_lang_invoke_MemberName::name(mname()); |
479 oop type_str = sun_dyn_MemberName::type(mname()); |
479 oop type_str = java_lang_invoke_MemberName::type(mname()); |
480 int flags = sun_dyn_MemberName::flags(mname()); |
480 int flags = java_lang_invoke_MemberName::flags(mname()); |
481 |
481 |
482 if (defc_oop == NULL || name_str == NULL || type_str == NULL) { |
482 if (defc_oop == NULL || name_str == NULL || type_str == NULL) { |
483 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to resolve"); |
483 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to resolve"); |
484 } |
484 } |
485 klassOop defc_klassOop = java_lang_Class::as_klassOop(defc_oop); |
485 klassOop defc_klassOop = java_lang_Class::as_klassOop(defc_oop); |
584 assert(result.is_statically_bound(), ""); |
584 assert(result.is_statically_bound(), ""); |
585 methodHandle m = result.resolved_method(); |
585 methodHandle m = result.resolved_method(); |
586 oop vmtarget = m(); |
586 oop vmtarget = m(); |
587 int vmindex = methodOopDesc::nonvirtual_vtable_index; |
587 int vmindex = methodOopDesc::nonvirtual_vtable_index; |
588 int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS); |
588 int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS); |
589 sun_dyn_MemberName::set_vmtarget(mname(), vmtarget); |
589 java_lang_invoke_MemberName::set_vmtarget(mname(), vmtarget); |
590 sun_dyn_MemberName::set_vmindex(mname(), vmindex); |
590 java_lang_invoke_MemberName::set_vmindex(mname(), vmindex); |
591 sun_dyn_MemberName::set_modifiers(mname(), mods); |
591 java_lang_invoke_MemberName::set_modifiers(mname(), mods); |
592 DEBUG_ONLY(int junk; klassOop junk2); |
592 DEBUG_ONLY(int junk; klassOop junk2); |
593 assert(decode_MemberName(mname(), junk2, junk) == result.resolved_method()(), |
593 assert(decode_MemberName(mname(), junk2, junk) == result.resolved_method()(), |
594 "properly stored for later decoding"); |
594 "properly stored for later decoding"); |
595 return; |
595 return; |
596 } |
596 } |
603 if (sel_klass.is_null()) return; |
603 if (sel_klass.is_null()) return; |
604 oop vmtarget = sel_klass->as_klassOop(); |
604 oop vmtarget = sel_klass->as_klassOop(); |
605 int vmindex = fd.offset(); |
605 int vmindex = fd.offset(); |
606 int mods = (fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS); |
606 int mods = (fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS); |
607 if (vmindex == VM_INDEX_UNINITIALIZED) break; // should not happen |
607 if (vmindex == VM_INDEX_UNINITIALIZED) break; // should not happen |
608 sun_dyn_MemberName::set_vmtarget(mname(), vmtarget); |
608 java_lang_invoke_MemberName::set_vmtarget(mname(), vmtarget); |
609 sun_dyn_MemberName::set_vmindex(mname(), vmindex); |
609 java_lang_invoke_MemberName::set_vmindex(mname(), vmindex); |
610 sun_dyn_MemberName::set_modifiers(mname(), mods); |
610 java_lang_invoke_MemberName::set_modifiers(mname(), mods); |
611 return; |
611 return; |
612 } |
612 } |
613 default: |
613 default: |
614 THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format"); |
614 THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format"); |
615 } |
615 } |
616 |
616 |
617 // Second chance. |
617 // Second chance. |
618 if (polymorphic_method_type.not_null()) { |
618 if (polymorphic_method_type.not_null()) { |
619 // Look on a non-null class loader. |
619 // Look on a non-null class loader. |
620 Handle cur_class_loader; |
620 Handle cur_class_loader; |
621 const int nptypes = java_dyn_MethodType::ptype_count(polymorphic_method_type()); |
621 const int nptypes = java_lang_invoke_MethodType::ptype_count(polymorphic_method_type()); |
622 for (int i = 0; i <= nptypes; i++) { |
622 for (int i = 0; i <= nptypes; i++) { |
623 oop type_mirror; |
623 oop type_mirror; |
624 if (i < nptypes) type_mirror = java_dyn_MethodType::ptype(polymorphic_method_type(), i); |
624 if (i < nptypes) type_mirror = java_lang_invoke_MethodType::ptype(polymorphic_method_type(), i); |
625 else type_mirror = java_dyn_MethodType::rtype(polymorphic_method_type()); |
625 else type_mirror = java_lang_invoke_MethodType::rtype(polymorphic_method_type()); |
626 klassOop example_type = java_lang_Class::as_klassOop(type_mirror); |
626 klassOop example_type = java_lang_Class::as_klassOop(type_mirror); |
627 if (example_type == NULL) continue; |
627 if (example_type == NULL) continue; |
628 oop class_loader = Klass::cast(example_type)->class_loader(); |
628 oop class_loader = Klass::cast(example_type)->class_loader(); |
629 if (class_loader == NULL || class_loader == cur_class_loader()) continue; |
629 if (class_loader == NULL || class_loader == cur_class_loader()) continue; |
630 cur_class_loader = Handle(THREAD, class_loader); |
630 cur_class_loader = Handle(THREAD, class_loader); |
651 // Conversely, a member name which is only initialized from JVM internals |
651 // Conversely, a member name which is only initialized from JVM internals |
652 // may have null defc, name, and type fields. |
652 // may have null defc, name, and type fields. |
653 // Resolving it plants a vmtarget/vmindex in it, |
653 // Resolving it plants a vmtarget/vmindex in it, |
654 // which refers directly to JVM internals. |
654 // which refers directly to JVM internals. |
655 void MethodHandles::expand_MemberName(Handle mname, int suppress, TRAPS) { |
655 void MethodHandles::expand_MemberName(Handle mname, int suppress, TRAPS) { |
656 assert(sun_dyn_MemberName::is_instance(mname()), ""); |
656 assert(java_lang_invoke_MemberName::is_instance(mname()), ""); |
657 oop vmtarget = sun_dyn_MemberName::vmtarget(mname()); |
657 oop vmtarget = java_lang_invoke_MemberName::vmtarget(mname()); |
658 int vmindex = sun_dyn_MemberName::vmindex(mname()); |
658 int vmindex = java_lang_invoke_MemberName::vmindex(mname()); |
659 if (vmtarget == NULL || vmindex == VM_INDEX_UNINITIALIZED) { |
659 if (vmtarget == NULL || vmindex == VM_INDEX_UNINITIALIZED) { |
660 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to expand"); |
660 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to expand"); |
661 } |
661 } |
662 |
662 |
663 bool have_defc = (sun_dyn_MemberName::clazz(mname()) != NULL); |
663 bool have_defc = (java_lang_invoke_MemberName::clazz(mname()) != NULL); |
664 bool have_name = (sun_dyn_MemberName::name(mname()) != NULL); |
664 bool have_name = (java_lang_invoke_MemberName::name(mname()) != NULL); |
665 bool have_type = (sun_dyn_MemberName::type(mname()) != NULL); |
665 bool have_type = (java_lang_invoke_MemberName::type(mname()) != NULL); |
666 int flags = sun_dyn_MemberName::flags(mname()); |
666 int flags = java_lang_invoke_MemberName::flags(mname()); |
667 |
667 |
668 if (suppress != 0) { |
668 if (suppress != 0) { |
669 if (suppress & _suppress_defc) have_defc = true; |
669 if (suppress & _suppress_defc) have_defc = true; |
670 if (suppress & _suppress_name) have_name = true; |
670 if (suppress & _suppress_name) have_name = true; |
671 if (suppress & _suppress_type) have_type = true; |
671 if (suppress & _suppress_type) have_type = true; |
685 if (!have_defc) { |
685 if (!have_defc) { |
686 klassOop defc = m->method_holder(); |
686 klassOop defc = m->method_holder(); |
687 if (receiver_limit != NULL && receiver_limit != defc |
687 if (receiver_limit != NULL && receiver_limit != defc |
688 && Klass::cast(receiver_limit)->is_subtype_of(defc)) |
688 && Klass::cast(receiver_limit)->is_subtype_of(defc)) |
689 defc = receiver_limit; |
689 defc = receiver_limit; |
690 sun_dyn_MemberName::set_clazz(mname(), Klass::cast(defc)->java_mirror()); |
690 java_lang_invoke_MemberName::set_clazz(mname(), Klass::cast(defc)->java_mirror()); |
691 } |
691 } |
692 if (!have_name) { |
692 if (!have_name) { |
693 //not java_lang_String::create_from_symbol; let's intern member names |
693 //not java_lang_String::create_from_symbol; let's intern member names |
694 Handle name = StringTable::intern(m->name(), CHECK); |
694 Handle name = StringTable::intern(m->name(), CHECK); |
695 sun_dyn_MemberName::set_name(mname(), name()); |
695 java_lang_invoke_MemberName::set_name(mname(), name()); |
696 } |
696 } |
697 if (!have_type) { |
697 if (!have_type) { |
698 Handle type = java_lang_String::create_from_symbol(m->signature(), CHECK); |
698 Handle type = java_lang_String::create_from_symbol(m->signature(), CHECK); |
699 sun_dyn_MemberName::set_type(mname(), type()); |
699 java_lang_invoke_MemberName::set_type(mname(), type()); |
700 } |
700 } |
701 return; |
701 return; |
702 } |
702 } |
703 case IS_FIELD: |
703 case IS_FIELD: |
704 { |
704 { |
709 bool is_static = ((flags & JVM_ACC_STATIC) != 0); |
709 bool is_static = ((flags & JVM_ACC_STATIC) != 0); |
710 fieldDescriptor fd; // find_field initializes fd if found |
710 fieldDescriptor fd; // find_field initializes fd if found |
711 if (!defc->find_field_from_offset(vmindex, is_static, &fd)) |
711 if (!defc->find_field_from_offset(vmindex, is_static, &fd)) |
712 break; // cannot expand |
712 break; // cannot expand |
713 if (!have_defc) { |
713 if (!have_defc) { |
714 sun_dyn_MemberName::set_clazz(mname(), defc->java_mirror()); |
714 java_lang_invoke_MemberName::set_clazz(mname(), defc->java_mirror()); |
715 } |
715 } |
716 if (!have_name) { |
716 if (!have_name) { |
717 //not java_lang_String::create_from_symbol; let's intern member names |
717 //not java_lang_String::create_from_symbol; let's intern member names |
718 Handle name = StringTable::intern(fd.name(), CHECK); |
718 Handle name = StringTable::intern(fd.name(), CHECK); |
719 sun_dyn_MemberName::set_name(mname(), name()); |
719 java_lang_invoke_MemberName::set_name(mname(), name()); |
720 } |
720 } |
721 if (!have_type) { |
721 if (!have_type) { |
722 Handle type = java_lang_String::create_from_symbol(fd.signature(), CHECK); |
722 Handle type = java_lang_String::create_from_symbol(fd.signature(), CHECK); |
723 sun_dyn_MemberName::set_type(mname(), type()); |
723 java_lang_invoke_MemberName::set_type(mname(), type()); |
724 } |
724 } |
725 return; |
725 return; |
726 } |
726 } |
727 } |
727 } |
728 THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format"); |
728 THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format"); |
855 |
855 |
856 // Decode the vmtarget field of a method handle. |
856 // Decode the vmtarget field of a method handle. |
857 // Sanitize out methodOops, klassOops, and any other non-Java data. |
857 // Sanitize out methodOops, klassOops, and any other non-Java data. |
858 // This is for debugging and reflection. |
858 // This is for debugging and reflection. |
859 oop MethodHandles::encode_target(Handle mh, int format, TRAPS) { |
859 oop MethodHandles::encode_target(Handle mh, int format, TRAPS) { |
860 assert(java_dyn_MethodHandle::is_instance(mh()), "must be a MH"); |
860 assert(java_lang_invoke_MethodHandle::is_instance(mh()), "must be a MH"); |
861 if (format == ETF_HANDLE_OR_METHOD_NAME) { |
861 if (format == ETF_HANDLE_OR_METHOD_NAME) { |
862 oop target = java_dyn_MethodHandle::vmtarget(mh()); |
862 oop target = java_lang_invoke_MethodHandle::vmtarget(mh()); |
863 if (target == NULL) { |
863 if (target == NULL) { |
864 return NULL; // unformed MH |
864 return NULL; // unformed MH |
865 } |
865 } |
866 klassOop tklass = target->klass(); |
866 klassOop tklass = target->klass(); |
867 if (Klass::cast(tklass)->is_subclass_of(SystemDictionary::Object_klass())) { |
867 if (Klass::cast(tklass)->is_subclass_of(SystemDictionary::Object_klass())) { |
1023 void MethodHandles::verify_method_signature(methodHandle m, |
1024 void MethodHandles::verify_method_signature(methodHandle m, |
1024 Handle mtype, |
1025 Handle mtype, |
1025 int first_ptype_pos, |
1026 int first_ptype_pos, |
1026 KlassHandle insert_ptype, |
1027 KlassHandle insert_ptype, |
1027 TRAPS) { |
1028 TRAPS) { |
1028 objArrayHandle ptypes(THREAD, java_dyn_MethodType::ptypes(mtype())); |
1029 objArrayHandle ptypes(THREAD, java_lang_invoke_MethodType::ptypes(mtype())); |
1029 int pnum = first_ptype_pos; |
1030 int pnum = first_ptype_pos; |
1030 int pmax = ptypes->length(); |
1031 int pmax = ptypes->length(); |
1031 int mnum = 0; // method argument |
1032 int mnum = 0; // method argument |
1032 const char* err = NULL; |
1033 const char* err = NULL; |
1033 ResourceMark rm(THREAD); |
1034 ResourceMark rm(THREAD); |
1034 for (SignatureStream ss(m->signature()); !ss.is_done(); ss.next()) { |
1035 for (SignatureStream ss(m->signature()); !ss.is_done(); ss.next()) { |
1035 oop ptype_oop = NULL; |
1036 oop ptype_oop = NULL; |
1036 if (ss.at_return_type()) { |
1037 if (ss.at_return_type()) { |
1037 if (pnum != pmax) |
1038 if (pnum != pmax) |
1038 { err = "too many arguments"; break; } |
1039 { err = "too many arguments"; break; } |
1039 ptype_oop = java_dyn_MethodType::rtype(mtype()); |
1040 ptype_oop = java_lang_invoke_MethodType::rtype(mtype()); |
1040 } else { |
1041 } else { |
1041 if (pnum >= pmax) |
1042 if (pnum >= pmax) |
1042 { err = "not enough arguments"; break; } |
1043 { err = "not enough arguments"; break; } |
1043 if (pnum >= 0) |
1044 if (pnum >= 0) |
1044 ptype_oop = ptypes->obj_at(pnum); |
1045 ptype_oop = ptypes->obj_at(pnum); |
1129 THROW_MSG(vmSymbols::java_lang_InternalError(), err); |
1130 THROW_MSG(vmSymbols::java_lang_InternalError(), err); |
1130 } |
1131 } |
1131 |
1132 |
1132 void MethodHandles::verify_vmslots(Handle mh, TRAPS) { |
1133 void MethodHandles::verify_vmslots(Handle mh, TRAPS) { |
1133 // Verify vmslots. |
1134 // Verify vmslots. |
1134 int check_slots = argument_slot_count(java_dyn_MethodHandle::type(mh())); |
1135 int check_slots = argument_slot_count(java_lang_invoke_MethodHandle::type(mh())); |
1135 if (java_dyn_MethodHandle::vmslots(mh()) != check_slots) { |
1136 if (java_lang_invoke_MethodHandle::vmslots(mh()) != check_slots) { |
1136 THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in BMH"); |
1137 THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in BMH"); |
1137 } |
1138 } |
1138 } |
1139 } |
1139 |
1140 |
1140 void MethodHandles::verify_vmargslot(Handle mh, int argnum, int argslot, TRAPS) { |
1141 void MethodHandles::verify_vmargslot(Handle mh, int argnum, int argslot, TRAPS) { |
1141 // Verify that argslot points at the given argnum. |
1142 // Verify that argslot points at the given argnum. |
1142 int check_slot = argument_slot(java_dyn_MethodHandle::type(mh()), argnum); |
1143 int check_slot = argument_slot(java_lang_invoke_MethodHandle::type(mh()), argnum); |
1143 if (argslot != check_slot || argslot < 0) { |
1144 if (argslot != check_slot || argslot < 0) { |
1144 const char* fmt = "for argnum of %d, vmargslot is %d, should be %d"; |
1145 const char* fmt = "for argnum of %d, vmargslot is %d, should be %d"; |
1145 size_t msglen = strlen(fmt) + 3*11 + 1; |
1146 size_t msglen = strlen(fmt) + 3*11 + 1; |
1146 char* msg = NEW_RESOURCE_ARRAY(char, msglen); |
1147 char* msg = NEW_RESOURCE_ARRAY(char, msglen); |
1147 jio_snprintf(msg, msglen, fmt, argnum, argslot, check_slot); |
1148 jio_snprintf(msg, msglen, fmt, argnum, argslot, check_slot); |
1312 // will be the size of all arguments, including the first. |
1313 // will be the size of all arguments, including the first. |
1313 // If the argument is neither -1 nor a valid argument index, |
1314 // If the argument is neither -1 nor a valid argument index, |
1314 // then return a negative number. Otherwise, the result |
1315 // then return a negative number. Otherwise, the result |
1315 // is in the range [0..vmslots] inclusive. |
1316 // is in the range [0..vmslots] inclusive. |
1316 int MethodHandles::argument_slot(oop method_type, int arg) { |
1317 int MethodHandles::argument_slot(oop method_type, int arg) { |
1317 objArrayOop ptypes = java_dyn_MethodType::ptypes(method_type); |
1318 objArrayOop ptypes = java_lang_invoke_MethodType::ptypes(method_type); |
1318 int argslot = 0; |
1319 int argslot = 0; |
1319 int len = ptypes->length(); |
1320 int len = ptypes->length(); |
1320 if (arg < -1 || arg >= len) return -99; |
1321 if (arg < -1 || arg >= len) return -99; |
1321 for (int i = len-1; i > arg; i--) { |
1322 for (int i = len-1; i > arg; i--) { |
1322 BasicType bt = java_lang_Class::as_BasicType(ptypes->obj_at(i)); |
1323 BasicType bt = java_lang_Class::as_BasicType(ptypes->obj_at(i)); |
1468 me = MethodHandles::entry(MethodHandles::_invokevirtual_mh); |
1469 me = MethodHandles::entry(MethodHandles::_invokevirtual_mh); |
1469 } |
1470 } |
1470 |
1471 |
1471 if (me == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
1472 if (me == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
1472 |
1473 |
1473 sun_dyn_DirectMethodHandle::set_vmtarget(mh(), vmtarget); |
1474 java_lang_invoke_DirectMethodHandle::set_vmtarget(mh(), vmtarget); |
1474 sun_dyn_DirectMethodHandle::set_vmindex(mh(), vmindex); |
1475 java_lang_invoke_DirectMethodHandle::set_vmindex(mh(), vmindex); |
1475 DEBUG_ONLY(int flags; klassOop rlimit); |
1476 DEBUG_ONLY(int flags; klassOop rlimit); |
1476 assert(MethodHandles::decode_method(mh(), rlimit, flags) == m(), |
1477 assert(MethodHandles::decode_method(mh(), rlimit, flags) == m(), |
1477 "properly stored for later decoding"); |
1478 "properly stored for later decoding"); |
1478 DEBUG_ONLY(bool actual_do_dispatch = ((flags & _dmf_does_dispatch) != 0)); |
1479 DEBUG_ONLY(bool actual_do_dispatch = ((flags & _dmf_does_dispatch) != 0)); |
1479 assert(!(actual_do_dispatch && !do_dispatch), |
1480 assert(!(actual_do_dispatch && !do_dispatch), |
1480 "do not perform dispatch if !do_dispatch specified"); |
1481 "do not perform dispatch if !do_dispatch specified"); |
1481 assert(actual_do_dispatch == (vmindex >= 0), "proper later decoding of do_dispatch"); |
1482 assert(actual_do_dispatch == (vmindex >= 0), "proper later decoding of do_dispatch"); |
1482 assert(decode_MethodHandle_stack_pushes(mh()) == 0, "DMH does not move stack"); |
1483 assert(decode_MethodHandle_stack_pushes(mh()) == 0, "DMH does not move stack"); |
1483 |
1484 |
1484 // Done! |
1485 // Done! |
1485 java_dyn_MethodHandle::set_vmentry(mh(), me); |
1486 java_lang_invoke_MethodHandle::set_vmentry(mh(), me); |
1486 } |
1487 } |
1487 |
1488 |
1488 void MethodHandles::verify_BoundMethodHandle_with_receiver(Handle mh, |
1489 void MethodHandles::verify_BoundMethodHandle_with_receiver(Handle mh, |
1489 methodHandle m, |
1490 methodHandle m, |
1490 TRAPS) { |
1491 TRAPS) { |
1491 // Verify type. |
1492 // Verify type. |
1492 oop receiver = sun_dyn_BoundMethodHandle::argument(mh()); |
1493 oop receiver = java_lang_invoke_BoundMethodHandle::argument(mh()); |
1493 Handle mtype(THREAD, java_dyn_MethodHandle::type(mh())); |
1494 Handle mtype(THREAD, java_lang_invoke_MethodHandle::type(mh())); |
1494 KlassHandle bound_recv_type; |
1495 KlassHandle bound_recv_type; |
1495 if (receiver != NULL) bound_recv_type = KlassHandle(THREAD, receiver->klass()); |
1496 if (receiver != NULL) bound_recv_type = KlassHandle(THREAD, receiver->klass()); |
1496 verify_method_type(m, mtype, true, bound_recv_type, CHECK); |
1497 verify_method_type(m, mtype, true, bound_recv_type, CHECK); |
1497 |
1498 |
1498 int receiver_pos = m->size_of_parameters() - 1; |
1499 int receiver_pos = m->size_of_parameters() - 1; |
1499 |
1500 |
1500 // Verify MH.vmargslot, which should point at the bound receiver. |
1501 // Verify MH.vmargslot, which should point at the bound receiver. |
1501 verify_vmargslot(mh, -1, sun_dyn_BoundMethodHandle::vmargslot(mh()), CHECK); |
1502 verify_vmargslot(mh, -1, java_lang_invoke_BoundMethodHandle::vmargslot(mh()), CHECK); |
1502 //verify_vmslots(mh, CHECK); |
1503 //verify_vmslots(mh, CHECK); |
1503 |
1504 |
1504 // Verify vmslots. |
1505 // Verify vmslots. |
1505 if (java_dyn_MethodHandle::vmslots(mh()) != receiver_pos) { |
1506 if (java_lang_invoke_MethodHandle::vmslots(mh()) != receiver_pos) { |
1506 THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in BMH (receiver)"); |
1507 THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in BMH (receiver)"); |
1507 } |
1508 } |
1508 } |
1509 } |
1509 |
1510 |
1510 // Initialize a BMH with a receiver bound directly to a methodOop. |
1511 // Initialize a BMH with a receiver bound directly to a methodOop. |
1518 THROW(vmSymbols::java_lang_InternalError()); |
1519 THROW(vmSymbols::java_lang_InternalError()); |
1519 } |
1520 } |
1520 |
1521 |
1521 KlassHandle receiver_klass; |
1522 KlassHandle receiver_klass; |
1522 { |
1523 { |
1523 oop receiver_oop = sun_dyn_BoundMethodHandle::argument(mh()); |
1524 oop receiver_oop = java_lang_invoke_BoundMethodHandle::argument(mh()); |
1524 if (receiver_oop != NULL) |
1525 if (receiver_oop != NULL) |
1525 receiver_klass = KlassHandle(THREAD, receiver_oop->klass()); |
1526 receiver_klass = KlassHandle(THREAD, receiver_oop->klass()); |
1526 } |
1527 } |
1527 methodHandle m = dispatch_decoded_method(original_m, |
1528 methodHandle m = dispatch_decoded_method(original_m, |
1528 receiver_limit, decode_flags, |
1529 receiver_limit, decode_flags, |
1529 receiver_klass, |
1530 receiver_klass, |
1530 CHECK); |
1531 CHECK); |
1531 if (m.is_null()) { THROW(vmSymbols::java_lang_InternalError()); } |
1532 if (m.is_null()) { THROW(vmSymbols::java_lang_InternalError()); } |
1532 if (m->is_abstract()) { THROW(vmSymbols::java_lang_AbstractMethodError()); } |
1533 if (m->is_abstract()) { THROW(vmSymbols::java_lang_AbstractMethodError()); } |
1533 |
1534 |
1534 java_dyn_MethodHandle::init_vmslots(mh()); |
1535 java_lang_invoke_MethodHandle::init_vmslots(mh()); |
1535 |
1536 |
1536 if (VerifyMethodHandles) { |
1537 if (VerifyMethodHandles) { |
1537 verify_BoundMethodHandle_with_receiver(mh, m, CHECK); |
1538 verify_BoundMethodHandle_with_receiver(mh, m, CHECK); |
1538 } |
1539 } |
1539 |
1540 |
1540 sun_dyn_BoundMethodHandle::set_vmtarget(mh(), m()); |
1541 java_lang_invoke_BoundMethodHandle::set_vmtarget(mh(), m()); |
1541 |
1542 |
1542 DEBUG_ONLY(int junk; klassOop junk2); |
1543 DEBUG_ONLY(int junk; klassOop junk2); |
1543 assert(MethodHandles::decode_method(mh(), junk2, junk) == m(), "properly stored for later decoding"); |
1544 assert(MethodHandles::decode_method(mh(), junk2, junk) == m(), "properly stored for later decoding"); |
1544 assert(decode_MethodHandle_stack_pushes(mh()) == 1, "BMH pushes one stack slot"); |
1545 assert(decode_MethodHandle_stack_pushes(mh()) == 1, "BMH pushes one stack slot"); |
1545 |
1546 |
1546 // Done! |
1547 // Done! |
1547 java_dyn_MethodHandle::set_vmentry(mh(), MethodHandles::entry(MethodHandles::_bound_ref_direct_mh)); |
1548 java_lang_invoke_MethodHandle::set_vmentry(mh(), MethodHandles::entry(MethodHandles::_bound_ref_direct_mh)); |
1548 } |
1549 } |
1549 |
1550 |
1550 void MethodHandles::verify_BoundMethodHandle(Handle mh, Handle target, int argnum, |
1551 void MethodHandles::verify_BoundMethodHandle(Handle mh, Handle target, int argnum, |
1551 bool direct_to_method, TRAPS) { |
1552 bool direct_to_method, TRAPS) { |
1552 Handle ptype_handle(THREAD, |
1553 Handle ptype_handle(THREAD, |
1553 java_dyn_MethodType::ptype(java_dyn_MethodHandle::type(target()), argnum)); |
1554 java_lang_invoke_MethodType::ptype(java_lang_invoke_MethodHandle::type(target()), argnum)); |
1554 KlassHandle ptype_klass; |
1555 KlassHandle ptype_klass; |
1555 BasicType ptype = java_lang_Class::as_BasicType(ptype_handle(), &ptype_klass); |
1556 BasicType ptype = java_lang_Class::as_BasicType(ptype_handle(), &ptype_klass); |
1556 int slots_pushed = type2size[ptype]; |
1557 int slots_pushed = type2size[ptype]; |
1557 |
1558 |
1558 oop argument = sun_dyn_BoundMethodHandle::argument(mh()); |
1559 oop argument = java_lang_invoke_BoundMethodHandle::argument(mh()); |
1559 |
1560 |
1560 const char* err = NULL; |
1561 const char* err = NULL; |
1561 |
1562 |
1562 switch (ptype) { |
1563 switch (ptype) { |
1563 case T_OBJECT: |
1564 case T_OBJECT: |
1621 } |
1622 } |
1622 } |
1623 } |
1623 |
1624 |
1624 if (err == NULL) { |
1625 if (err == NULL) { |
1625 // Verify the rest of the method type. |
1626 // Verify the rest of the method type. |
1626 err = check_method_type_insertion(java_dyn_MethodHandle::type(mh()), |
1627 err = check_method_type_insertion(java_lang_invoke_MethodHandle::type(mh()), |
1627 argnum, ptype_handle(), |
1628 argnum, ptype_handle(), |
1628 java_dyn_MethodHandle::type(target())); |
1629 java_lang_invoke_MethodHandle::type(target())); |
1629 } |
1630 } |
1630 |
1631 |
1631 if (err != NULL) { |
1632 if (err != NULL) { |
1632 THROW_MSG(vmSymbols::java_lang_InternalError(), err); |
1633 THROW_MSG(vmSymbols::java_lang_InternalError(), err); |
1633 } |
1634 } |
1634 } |
1635 } |
1635 |
1636 |
1636 void MethodHandles::init_BoundMethodHandle(Handle mh, Handle target, int argnum, TRAPS) { |
1637 void MethodHandles::init_BoundMethodHandle(Handle mh, Handle target, int argnum, TRAPS) { |
1637 // Check arguments. |
1638 // Check arguments. |
1638 if (mh.is_null() || target.is_null() || !java_dyn_MethodHandle::is_instance(target())) { |
1639 if (mh.is_null() || target.is_null() || !java_lang_invoke_MethodHandle::is_instance(target())) { |
1639 THROW(vmSymbols::java_lang_InternalError()); |
1640 THROW(vmSymbols::java_lang_InternalError()); |
1640 } |
1641 } |
1641 |
1642 |
1642 java_dyn_MethodHandle::init_vmslots(mh()); |
1643 java_lang_invoke_MethodHandle::init_vmslots(mh()); |
1643 |
1644 |
1644 if (VerifyMethodHandles) { |
1645 if (VerifyMethodHandles) { |
1645 int insert_after = argnum - 1; |
1646 int insert_after = argnum - 1; |
1646 verify_vmargslot(mh, insert_after, sun_dyn_BoundMethodHandle::vmargslot(mh()), CHECK); |
1647 verify_vmargslot(mh, insert_after, java_lang_invoke_BoundMethodHandle::vmargslot(mh()), CHECK); |
1647 verify_vmslots(mh, CHECK); |
1648 verify_vmslots(mh, CHECK); |
1648 } |
1649 } |
1649 |
1650 |
1650 // Get bound type and required slots. |
1651 // Get bound type and required slots. |
1651 oop ptype_oop = java_dyn_MethodType::ptype(java_dyn_MethodHandle::type(target()), argnum); |
1652 oop ptype_oop = java_lang_invoke_MethodType::ptype(java_lang_invoke_MethodHandle::type(target()), argnum); |
1652 BasicType ptype = java_lang_Class::as_BasicType(ptype_oop); |
1653 BasicType ptype = java_lang_Class::as_BasicType(ptype_oop); |
1653 int slots_pushed = type2size[ptype]; |
1654 int slots_pushed = type2size[ptype]; |
1654 |
1655 |
1655 // If (a) the target is a direct non-dispatched method handle, |
1656 // If (a) the target is a direct non-dispatched method handle, |
1656 // or (b) the target is a dispatched direct method handle and we |
1657 // or (b) the target is a dispatched direct method handle and we |
1657 // are binding the receiver, cut out the middle-man. |
1658 // are binding the receiver, cut out the middle-man. |
1658 // Do this by decoding the DMH and using its methodOop directly as vmtarget. |
1659 // Do this by decoding the DMH and using its methodOop directly as vmtarget. |
1659 bool direct_to_method = false; |
1660 bool direct_to_method = false; |
1660 if (OptimizeMethodHandles && |
1661 if (OptimizeMethodHandles && |
1661 target->klass() == SystemDictionary::DirectMethodHandle_klass() && |
1662 target->klass() == SystemDictionary::DirectMethodHandle_klass() && |
1662 (argnum == 0 || sun_dyn_DirectMethodHandle::vmindex(target()) < 0)) { |
1663 (argnum == 0 || java_lang_invoke_DirectMethodHandle::vmindex(target()) < 0)) { |
1663 int decode_flags = 0; klassOop receiver_limit_oop = NULL; |
1664 int decode_flags = 0; klassOop receiver_limit_oop = NULL; |
1664 methodHandle m(THREAD, decode_method(target(), receiver_limit_oop, decode_flags)); |
1665 methodHandle m(THREAD, decode_method(target(), receiver_limit_oop, decode_flags)); |
1665 if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "DMH failed to decode"); } |
1666 if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "DMH failed to decode"); } |
1666 DEBUG_ONLY(int m_vmslots = m->size_of_parameters() - slots_pushed); // pos. of 1st arg. |
1667 DEBUG_ONLY(int m_vmslots = m->size_of_parameters() - slots_pushed); // pos. of 1st arg. |
1667 assert(sun_dyn_BoundMethodHandle::vmslots(mh()) == m_vmslots, "type w/ m sig"); |
1668 assert(java_lang_invoke_BoundMethodHandle::vmslots(mh()) == m_vmslots, "type w/ m sig"); |
1668 if (argnum == 0 && (decode_flags & _dmf_has_receiver) != 0) { |
1669 if (argnum == 0 && (decode_flags & _dmf_has_receiver) != 0) { |
1669 KlassHandle receiver_limit(THREAD, receiver_limit_oop); |
1670 KlassHandle receiver_limit(THREAD, receiver_limit_oop); |
1670 init_BoundMethodHandle_with_receiver(mh, m, |
1671 init_BoundMethodHandle_with_receiver(mh, m, |
1671 receiver_limit, decode_flags, |
1672 receiver_limit, decode_flags, |
1672 CHECK); |
1673 CHECK); |
1675 |
1676 |
1676 // Even if it is not a bound receiver, we still might be able |
1677 // Even if it is not a bound receiver, we still might be able |
1677 // to bind another argument and still invoke the methodOop directly. |
1678 // to bind another argument and still invoke the methodOop directly. |
1678 if (!(decode_flags & _dmf_does_dispatch)) { |
1679 if (!(decode_flags & _dmf_does_dispatch)) { |
1679 direct_to_method = true; |
1680 direct_to_method = true; |
1680 sun_dyn_BoundMethodHandle::set_vmtarget(mh(), m()); |
1681 java_lang_invoke_BoundMethodHandle::set_vmtarget(mh(), m()); |
1681 } |
1682 } |
1682 } |
1683 } |
1683 if (!direct_to_method) |
1684 if (!direct_to_method) |
1684 sun_dyn_BoundMethodHandle::set_vmtarget(mh(), target()); |
1685 java_lang_invoke_BoundMethodHandle::set_vmtarget(mh(), target()); |
1685 |
1686 |
1686 if (VerifyMethodHandles) { |
1687 if (VerifyMethodHandles) { |
1687 verify_BoundMethodHandle(mh, target, argnum, direct_to_method, CHECK); |
1688 verify_BoundMethodHandle(mh, target, argnum, direct_to_method, CHECK); |
1688 } |
1689 } |
1689 |
1690 |
1701 } else { |
1702 } else { |
1702 assert(false, ""); |
1703 assert(false, ""); |
1703 } |
1704 } |
1704 |
1705 |
1705 // Done! |
1706 // Done! |
1706 java_dyn_MethodHandle::set_vmentry(mh(), me); |
1707 java_lang_invoke_MethodHandle::set_vmentry(mh(), me); |
1707 } |
1708 } |
1708 |
1709 |
1709 static void throw_InternalError_for_bad_conversion(int conversion, const char* err, TRAPS) { |
1710 static void throw_InternalError_for_bad_conversion(int conversion, const char* err, TRAPS) { |
1710 char msg[200]; |
1711 char msg[200]; |
1711 jio_snprintf(msg, sizeof(msg), "bad adapter (conversion=0x%08x): %s", conversion, err); |
1712 jio_snprintf(msg, sizeof(msg), "bad adapter (conversion=0x%08x): %s", conversion, err); |
1712 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), msg); |
1713 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), msg); |
1713 } |
1714 } |
1714 |
1715 |
1715 void MethodHandles::verify_AdapterMethodHandle(Handle mh, int argnum, TRAPS) { |
1716 void MethodHandles::verify_AdapterMethodHandle(Handle mh, int argnum, TRAPS) { |
1716 jint conversion = sun_dyn_AdapterMethodHandle::conversion(mh()); |
1717 jint conversion = java_lang_invoke_AdapterMethodHandle::conversion(mh()); |
1717 int argslot = sun_dyn_AdapterMethodHandle::vmargslot(mh()); |
1718 int argslot = java_lang_invoke_AdapterMethodHandle::vmargslot(mh()); |
1718 |
1719 |
1719 verify_vmargslot(mh, argnum, argslot, CHECK); |
1720 verify_vmargslot(mh, argnum, argslot, CHECK); |
1720 verify_vmslots(mh, CHECK); |
1721 verify_vmslots(mh, CHECK); |
1721 |
1722 |
1722 jint conv_op = adapter_conversion_op(conversion); |
1723 jint conv_op = adapter_conversion_op(conversion); |
1729 int stack_move = adapter_conversion_stack_move(conversion); |
1730 int stack_move = adapter_conversion_stack_move(conversion); |
1730 BasicType src = adapter_conversion_src_type(conversion); |
1731 BasicType src = adapter_conversion_src_type(conversion); |
1731 BasicType dest = adapter_conversion_dest_type(conversion); |
1732 BasicType dest = adapter_conversion_dest_type(conversion); |
1732 int vminfo = adapter_conversion_vminfo(conversion); // should be zero |
1733 int vminfo = adapter_conversion_vminfo(conversion); // should be zero |
1733 |
1734 |
1734 Handle argument(THREAD, sun_dyn_AdapterMethodHandle::argument(mh())); |
1735 Handle argument(THREAD, java_lang_invoke_AdapterMethodHandle::argument(mh())); |
1735 Handle target(THREAD, sun_dyn_AdapterMethodHandle::vmtarget(mh())); |
1736 Handle target(THREAD, java_lang_invoke_AdapterMethodHandle::vmtarget(mh())); |
1736 Handle src_mtype(THREAD, java_dyn_MethodHandle::type(mh())); |
1737 Handle src_mtype(THREAD, java_lang_invoke_MethodHandle::type(mh())); |
1737 Handle dst_mtype(THREAD, java_dyn_MethodHandle::type(target())); |
1738 Handle dst_mtype(THREAD, java_lang_invoke_MethodHandle::type(target())); |
1738 |
1739 |
1739 const char* err = NULL; |
1740 const char* err = NULL; |
1740 |
1741 |
1741 if (err == NULL) { |
1742 if (err == NULL) { |
1742 // Check that the correct argument is supplied, but only if it is required. |
1743 // Check that the correct argument is supplied, but only if it is required. |
1804 { |
1805 { |
1805 if (!src || src != dest) { |
1806 if (!src || src != dest) { |
1806 err = "adapter requires src/dest conversion subfields for swap"; break; |
1807 err = "adapter requires src/dest conversion subfields for swap"; break; |
1807 } |
1808 } |
1808 int swap_size = type2size[src]; |
1809 int swap_size = type2size[src]; |
1809 oop src_mtype = sun_dyn_AdapterMethodHandle::type(mh()); |
1810 oop src_mtype = java_lang_invoke_AdapterMethodHandle::type(mh()); |
1810 oop dest_mtype = sun_dyn_AdapterMethodHandle::type(target()); |
1811 oop dest_mtype = java_lang_invoke_AdapterMethodHandle::type(target()); |
1811 int slot_limit = sun_dyn_AdapterMethodHandle::vmslots(target()); |
1812 int slot_limit = java_lang_invoke_AdapterMethodHandle::vmslots(target()); |
1812 int src_slot = argslot; |
1813 int src_slot = argslot; |
1813 int dest_slot = vminfo; |
1814 int dest_slot = vminfo; |
1814 bool rotate_up = (src_slot > dest_slot); // upward rotation |
1815 bool rotate_up = (src_slot > dest_slot); // upward rotation |
1815 int src_arg = argnum; |
1816 int src_arg = argnum; |
1816 int dest_arg = argument_slot_to_argnum(dest_mtype, dest_slot); |
1817 int dest_arg = argument_slot_to_argnum(dest_mtype, dest_slot); |
1819 !(src_slot >= dest_slot + swap_size)) { |
1820 !(src_slot >= dest_slot + swap_size)) { |
1820 err = "source, destination slots must be distinct"; |
1821 err = "source, destination slots must be distinct"; |
1821 } else if (ek == _adapter_swap_args && !(src_slot > dest_slot)) { |
1822 } else if (ek == _adapter_swap_args && !(src_slot > dest_slot)) { |
1822 err = "source of swap must be deeper in stack"; |
1823 err = "source of swap must be deeper in stack"; |
1823 } else if (ek == _adapter_swap_args) { |
1824 } else if (ek == _adapter_swap_args) { |
1824 err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, dest_arg), |
1825 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype, dest_arg), |
1825 java_dyn_MethodType::ptype(dest_mtype, src_arg), |
1826 java_lang_invoke_MethodType::ptype(dest_mtype, src_arg), |
1826 dest_arg); |
1827 dest_arg); |
1827 } else if (ek == _adapter_rot_args) { |
1828 } else if (ek == _adapter_rot_args) { |
1828 if (rotate_up) { |
1829 if (rotate_up) { |
1829 assert((src_slot > dest_slot) && (src_arg < dest_arg), ""); |
1830 assert((src_slot > dest_slot) && (src_arg < dest_arg), ""); |
1830 // rotate up: [dest_slot..src_slot-ss] --> [dest_slot+ss..src_slot] |
1831 // rotate up: [dest_slot..src_slot-ss] --> [dest_slot+ss..src_slot] |
1831 // that is: [src_arg+1..dest_arg] --> [src_arg..dest_arg-1] |
1832 // that is: [src_arg+1..dest_arg] --> [src_arg..dest_arg-1] |
1832 for (int i = src_arg+1; i <= dest_arg && err == NULL; i++) { |
1833 for (int i = src_arg+1; i <= dest_arg && err == NULL; i++) { |
1833 err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, i), |
1834 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype, i), |
1834 java_dyn_MethodType::ptype(dest_mtype, i-1), |
1835 java_lang_invoke_MethodType::ptype(dest_mtype, i-1), |
1835 i); |
1836 i); |
1836 } |
1837 } |
1837 } else { // rotate down |
1838 } else { // rotate down |
1838 assert((src_slot < dest_slot) && (src_arg > dest_arg), ""); |
1839 assert((src_slot < dest_slot) && (src_arg > dest_arg), ""); |
1839 // rotate down: [src_slot+ss..dest_slot] --> [src_slot..dest_slot-ss] |
1840 // rotate down: [src_slot+ss..dest_slot] --> [src_slot..dest_slot-ss] |
1840 // that is: [dest_arg..src_arg-1] --> [dst_arg+1..src_arg] |
1841 // that is: [dest_arg..src_arg-1] --> [dst_arg+1..src_arg] |
1841 for (int i = dest_arg; i <= src_arg-1 && err == NULL; i++) { |
1842 for (int i = dest_arg; i <= src_arg-1 && err == NULL; i++) { |
1842 err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, i), |
1843 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype, i), |
1843 java_dyn_MethodType::ptype(dest_mtype, i+1), |
1844 java_lang_invoke_MethodType::ptype(dest_mtype, i+1), |
1844 i); |
1845 i); |
1845 } |
1846 } |
1846 } |
1847 } |
1847 } |
1848 } |
1848 if (err == NULL) |
1849 if (err == NULL) |
1849 err = check_argument_type_change(java_dyn_MethodType::ptype(src_mtype, src_arg), |
1850 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype, src_arg), |
1850 java_dyn_MethodType::ptype(dest_mtype, dest_arg), |
1851 java_lang_invoke_MethodType::ptype(dest_mtype, dest_arg), |
1851 src_arg); |
1852 src_arg); |
1852 } |
1853 } |
1853 break; |
1854 break; |
1854 case _adapter_collect_args: |
1855 case _adapter_collect_args: |
1855 case _adapter_spread_args: |
1856 case _adapter_spread_args: |
1983 } |
1984 } |
1984 |
1985 |
1985 } |
1986 } |
1986 |
1987 |
1987 void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnum, TRAPS) { |
1988 void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnum, TRAPS) { |
1988 oop argument = sun_dyn_AdapterMethodHandle::argument(mh()); |
1989 oop argument = java_lang_invoke_AdapterMethodHandle::argument(mh()); |
1989 int argslot = sun_dyn_AdapterMethodHandle::vmargslot(mh()); |
1990 int argslot = java_lang_invoke_AdapterMethodHandle::vmargslot(mh()); |
1990 jint conversion = sun_dyn_AdapterMethodHandle::conversion(mh()); |
1991 jint conversion = java_lang_invoke_AdapterMethodHandle::conversion(mh()); |
1991 jint conv_op = adapter_conversion_op(conversion); |
1992 jint conv_op = adapter_conversion_op(conversion); |
1992 |
1993 |
1993 // adjust the adapter code to the internal EntryKind enumeration: |
1994 // adjust the adapter code to the internal EntryKind enumeration: |
1994 EntryKind ek_orig = adapter_entry_kind(conv_op); |
1995 EntryKind ek_orig = adapter_entry_kind(conv_op); |
1995 EntryKind ek_opt = ek_orig; // may be optimized |
1996 EntryKind ek_opt = ek_orig; // may be optimized |
1996 |
1997 |
1997 // Finalize the vmtarget field (Java initialized it to null). |
1998 // Finalize the vmtarget field (Java initialized it to null). |
1998 if (!java_dyn_MethodHandle::is_instance(target())) { |
1999 if (!java_lang_invoke_MethodHandle::is_instance(target())) { |
1999 throw_InternalError_for_bad_conversion(conversion, "bad target", THREAD); |
2000 throw_InternalError_for_bad_conversion(conversion, "bad target", THREAD); |
2000 return; |
2001 return; |
2001 } |
2002 } |
2002 sun_dyn_AdapterMethodHandle::set_vmtarget(mh(), target()); |
2003 java_lang_invoke_AdapterMethodHandle::set_vmtarget(mh(), target()); |
2003 |
2004 |
2004 if (VerifyMethodHandles) { |
2005 if (VerifyMethodHandles) { |
2005 verify_AdapterMethodHandle(mh, argnum, CHECK); |
2006 verify_AdapterMethodHandle(mh, argnum, CHECK); |
2006 } |
2007 } |
2007 |
2008 |
2145 |
2146 |
2146 // Rebuild the conversion value; maybe parts of it were changed. |
2147 // Rebuild the conversion value; maybe parts of it were changed. |
2147 jint new_conversion = adapter_conversion(conv_op, src, dest, stack_move, vminfo); |
2148 jint new_conversion = adapter_conversion(conv_op, src, dest, stack_move, vminfo); |
2148 |
2149 |
2149 // Finalize the conversion field. (Note that it is final to Java code.) |
2150 // Finalize the conversion field. (Note that it is final to Java code.) |
2150 sun_dyn_AdapterMethodHandle::set_conversion(mh(), new_conversion); |
2151 java_lang_invoke_AdapterMethodHandle::set_conversion(mh(), new_conversion); |
2151 |
2152 |
2152 // Done! |
2153 // Done! |
2153 java_dyn_MethodHandle::set_vmentry(mh(), entry(ek_opt)); |
2154 java_lang_invoke_MethodHandle::set_vmentry(mh(), entry(ek_opt)); |
2154 |
2155 |
2155 // There should be enough memory barriers on exit from native methods |
2156 // There should be enough memory barriers on exit from native methods |
2156 // to ensure that the MH is fully initialized to all threads before |
2157 // to ensure that the MH is fully initialized to all threads before |
2157 // Java code can publish it in global data structures. |
2158 // Java code can publish it in global data structures. |
2158 } |
2159 } |
2159 |
2160 |
2160 // |
2161 // |
2161 // Here are the native methods on sun.dyn.MethodHandleImpl. |
2162 // Here are the native methods on sun.invoke.MethodHandleImpl. |
2162 // They are the private interface between this JVM and the HotSpot-specific |
2163 // They are the private interface between this JVM and the HotSpot-specific |
2163 // Java code that implements JSR 292 method handles. |
2164 // Java code that implements JSR 292 method handles. |
2164 // |
2165 // |
2165 // Note: We use a JVM_ENTRY macro to define each of these, for this is the way |
2166 // Note: We use a JVM_ENTRY macro to define each of these, for this is the way |
2166 // that intrinsic (non-JNI) native methods are defined in HotSpot. |
2167 // that intrinsic (non-JNI) native methods are defined in HotSpot. |
2167 // |
2168 // |
2168 |
2169 |
2169 // direct method handles for invokestatic or invokespecial |
2170 // direct method handles for invokestatic or invokespecial |
2170 // void init(DirectMethodHandle self, MemberName ref, boolean doDispatch, Class<?> caller); |
2171 // void init(DirectMethodHandle self, MemberName ref, boolean doDispatch, Class<?> caller); |
2171 JVM_ENTRY(void, MHI_init_DMH(JNIEnv *env, jobject igcls, jobject mh_jh, |
2172 JVM_ENTRY(void, MHN_init_DMH(JNIEnv *env, jobject igcls, jobject mh_jh, |
2172 jobject target_jh, jboolean do_dispatch, jobject caller_jh)) { |
2173 jobject target_jh, jboolean do_dispatch, jobject caller_jh)) { |
2173 ResourceMark rm; // for error messages |
2174 ResourceMark rm; // for error messages |
2174 |
2175 |
2175 // This is the guy we are initializing: |
2176 // This is the guy we are initializing: |
2176 if (mh_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
2177 if (mh_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
2177 Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh)); |
2178 Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh)); |
2178 |
2179 |
2179 // Early returns out of this method leave the DMH in an unfinished state. |
2180 // Early returns out of this method leave the DMH in an unfinished state. |
2180 assert(java_dyn_MethodHandle::vmentry(mh()) == NULL, "must be safely null"); |
2181 assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null"); |
2181 |
2182 |
2182 // which method are we really talking about? |
2183 // which method are we really talking about? |
2183 if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
2184 if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
2184 oop target_oop = JNIHandles::resolve_non_null(target_jh); |
2185 oop target_oop = JNIHandles::resolve_non_null(target_jh); |
2185 if (sun_dyn_MemberName::is_instance(target_oop) && |
2186 if (java_lang_invoke_MemberName::is_instance(target_oop) && |
2186 sun_dyn_MemberName::vmindex(target_oop) == VM_INDEX_UNINITIALIZED) { |
2187 java_lang_invoke_MemberName::vmindex(target_oop) == VM_INDEX_UNINITIALIZED) { |
2187 Handle mname(THREAD, target_oop); |
2188 Handle mname(THREAD, target_oop); |
2188 MethodHandles::resolve_MemberName(mname, CHECK); |
2189 MethodHandles::resolve_MemberName(mname, CHECK); |
2189 target_oop = mname(); // in case of GC |
2190 target_oop = mname(); // in case of GC |
2190 } |
2191 } |
2191 |
2192 |
2230 MethodHandles::init_DirectMethodHandle(mh, m, (do_dispatch != JNI_FALSE), CHECK); |
2231 MethodHandles::init_DirectMethodHandle(mh, m, (do_dispatch != JNI_FALSE), CHECK); |
2231 } |
2232 } |
2232 JVM_END |
2233 JVM_END |
2233 |
2234 |
2234 // bound method handles |
2235 // bound method handles |
2235 JVM_ENTRY(void, MHI_init_BMH(JNIEnv *env, jobject igcls, jobject mh_jh, |
2236 JVM_ENTRY(void, MHN_init_BMH(JNIEnv *env, jobject igcls, jobject mh_jh, |
2236 jobject target_jh, int argnum)) { |
2237 jobject target_jh, int argnum)) { |
2237 ResourceMark rm; // for error messages |
2238 ResourceMark rm; // for error messages |
2238 |
2239 |
2239 // This is the guy we are initializing: |
2240 // This is the guy we are initializing: |
2240 if (mh_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
2241 if (mh_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
2241 Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh)); |
2242 Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh)); |
2242 |
2243 |
2243 // Early returns out of this method leave the BMH in an unfinished state. |
2244 // Early returns out of this method leave the BMH in an unfinished state. |
2244 assert(java_dyn_MethodHandle::vmentry(mh()) == NULL, "must be safely null"); |
2245 assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null"); |
2245 |
2246 |
2246 if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
2247 if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
2247 Handle target(THREAD, JNIHandles::resolve_non_null(target_jh)); |
2248 Handle target(THREAD, JNIHandles::resolve_non_null(target_jh)); |
2248 |
2249 |
2249 if (!java_dyn_MethodHandle::is_instance(target())) { |
2250 if (!java_lang_invoke_MethodHandle::is_instance(target())) { |
2250 // Target object is a reflective method. (%%% Do we need this alternate path?) |
2251 // Target object is a reflective method. (%%% Do we need this alternate path?) |
2251 Untested("init_BMH of non-MH"); |
2252 Untested("init_BMH of non-MH"); |
2252 if (argnum != 0) { THROW(vmSymbols::java_lang_InternalError()); } |
2253 if (argnum != 0) { THROW(vmSymbols::java_lang_InternalError()); } |
2253 int decode_flags = 0; klassOop receiver_limit_oop = NULL; |
2254 int decode_flags = 0; klassOop receiver_limit_oop = NULL; |
2254 methodHandle m(THREAD, |
2255 methodHandle m(THREAD, |
2267 MethodHandles::init_BoundMethodHandle(mh, target, argnum, CHECK); |
2268 MethodHandles::init_BoundMethodHandle(mh, target, argnum, CHECK); |
2268 } |
2269 } |
2269 JVM_END |
2270 JVM_END |
2270 |
2271 |
2271 // adapter method handles |
2272 // adapter method handles |
2272 JVM_ENTRY(void, MHI_init_AMH(JNIEnv *env, jobject igcls, jobject mh_jh, |
2273 JVM_ENTRY(void, MHN_init_AMH(JNIEnv *env, jobject igcls, jobject mh_jh, |
2273 jobject target_jh, int argnum)) { |
2274 jobject target_jh, int argnum)) { |
2274 // This is the guy we are initializing: |
2275 // This is the guy we are initializing: |
2275 if (mh_jh == NULL || target_jh == NULL) { |
2276 if (mh_jh == NULL || target_jh == NULL) { |
2276 THROW(vmSymbols::java_lang_InternalError()); |
2277 THROW(vmSymbols::java_lang_InternalError()); |
2277 } |
2278 } |
2278 Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh)); |
2279 Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh)); |
2279 Handle target(THREAD, JNIHandles::resolve_non_null(target_jh)); |
2280 Handle target(THREAD, JNIHandles::resolve_non_null(target_jh)); |
2280 |
2281 |
2281 // Early returns out of this method leave the AMH in an unfinished state. |
2282 // Early returns out of this method leave the AMH in an unfinished state. |
2282 assert(java_dyn_MethodHandle::vmentry(mh()) == NULL, "must be safely null"); |
2283 assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null"); |
2283 |
2284 |
2284 MethodHandles::init_AdapterMethodHandle(mh, target, argnum, CHECK); |
2285 MethodHandles::init_AdapterMethodHandle(mh, target, argnum, CHECK); |
2285 } |
2286 } |
2286 JVM_END |
2287 JVM_END |
2287 |
2288 |
2288 // method type forms |
2289 // method type forms |
2289 JVM_ENTRY(void, MHI_init_MT(JNIEnv *env, jobject igcls, jobject erased_jh)) { |
2290 JVM_ENTRY(void, MHN_init_MT(JNIEnv *env, jobject igcls, jobject erased_jh)) { |
2290 if (erased_jh == NULL) return; |
2291 if (erased_jh == NULL) return; |
2291 if (TraceMethodHandles) { |
2292 if (TraceMethodHandles) { |
2292 tty->print("creating MethodType form "); |
2293 tty->print("creating MethodType form "); |
2293 if (WizardMode || Verbose) { // Warning: this calls Java code on the MH! |
2294 if (WizardMode || Verbose) { // Warning: this calls Java code on the MH! |
2294 // call Object.toString() |
2295 // call Object.toString() |
2305 } |
2306 } |
2306 } |
2307 } |
2307 JVM_END |
2308 JVM_END |
2308 |
2309 |
2309 // debugging and reflection |
2310 // debugging and reflection |
2310 JVM_ENTRY(jobject, MHI_getTarget(JNIEnv *env, jobject igcls, jobject mh_jh, jint format)) { |
2311 JVM_ENTRY(jobject, MHN_getTarget(JNIEnv *env, jobject igcls, jobject mh_jh, jint format)) { |
2311 Handle mh(THREAD, JNIHandles::resolve(mh_jh)); |
2312 Handle mh(THREAD, JNIHandles::resolve(mh_jh)); |
2312 if (!java_dyn_MethodHandle::is_instance(mh())) { |
2313 if (!java_lang_invoke_MethodHandle::is_instance(mh())) { |
2313 THROW_NULL(vmSymbols::java_lang_IllegalArgumentException()); |
2314 THROW_NULL(vmSymbols::java_lang_IllegalArgumentException()); |
2314 } |
2315 } |
2315 oop target = MethodHandles::encode_target(mh, format, CHECK_NULL); |
2316 oop target = MethodHandles::encode_target(mh, format, CHECK_NULL); |
2316 return JNIHandles::make_local(THREAD, target); |
2317 return JNIHandles::make_local(THREAD, target); |
2317 } |
2318 } |
2318 JVM_END |
2319 JVM_END |
2319 |
2320 |
2320 JVM_ENTRY(jint, MHI_getConstant(JNIEnv *env, jobject igcls, jint which)) { |
2321 JVM_ENTRY(jint, MHN_getConstant(JNIEnv *env, jobject igcls, jint which)) { |
2321 switch (which) { |
2322 switch (which) { |
2322 case MethodHandles::GC_JVM_PUSH_LIMIT: |
2323 case MethodHandles::GC_JVM_PUSH_LIMIT: |
2323 guarantee(MethodHandlePushLimit >= 2 && MethodHandlePushLimit <= 0xFF, |
2324 guarantee(MethodHandlePushLimit >= 2 && MethodHandlePushLimit <= 0xFF, |
2324 "MethodHandlePushLimit parameter must be in valid range"); |
2325 "MethodHandlePushLimit parameter must be in valid range"); |
2325 return MethodHandlePushLimit; |
2326 return MethodHandlePushLimit; |
2339 template(MethodHandles,GC_JVM_STACK_MOVE_UNIT) \ |
2340 template(MethodHandles,GC_JVM_STACK_MOVE_UNIT) \ |
2340 template(MethodHandles,ETF_HANDLE_OR_METHOD_NAME) \ |
2341 template(MethodHandles,ETF_HANDLE_OR_METHOD_NAME) \ |
2341 template(MethodHandles,ETF_DIRECT_HANDLE) \ |
2342 template(MethodHandles,ETF_DIRECT_HANDLE) \ |
2342 template(MethodHandles,ETF_METHOD_NAME) \ |
2343 template(MethodHandles,ETF_METHOD_NAME) \ |
2343 template(MethodHandles,ETF_REFLECT_METHOD) \ |
2344 template(MethodHandles,ETF_REFLECT_METHOD) \ |
2344 template(sun_dyn_MemberName,MN_IS_METHOD) \ |
2345 template(java_lang_invoke_MemberName,MN_IS_METHOD) \ |
2345 template(sun_dyn_MemberName,MN_IS_CONSTRUCTOR) \ |
2346 template(java_lang_invoke_MemberName,MN_IS_CONSTRUCTOR) \ |
2346 template(sun_dyn_MemberName,MN_IS_FIELD) \ |
2347 template(java_lang_invoke_MemberName,MN_IS_FIELD) \ |
2347 template(sun_dyn_MemberName,MN_IS_TYPE) \ |
2348 template(java_lang_invoke_MemberName,MN_IS_TYPE) \ |
2348 template(sun_dyn_MemberName,MN_SEARCH_SUPERCLASSES) \ |
2349 template(java_lang_invoke_MemberName,MN_SEARCH_SUPERCLASSES) \ |
2349 template(sun_dyn_MemberName,MN_SEARCH_INTERFACES) \ |
2350 template(java_lang_invoke_MemberName,MN_SEARCH_INTERFACES) \ |
2350 template(sun_dyn_MemberName,VM_INDEX_UNINITIALIZED) \ |
2351 template(java_lang_invoke_MemberName,VM_INDEX_UNINITIALIZED) \ |
2351 template(sun_dyn_AdapterMethodHandle,OP_RETYPE_ONLY) \ |
2352 template(java_lang_invoke_AdapterMethodHandle,OP_RETYPE_ONLY) \ |
2352 template(sun_dyn_AdapterMethodHandle,OP_RETYPE_RAW) \ |
2353 template(java_lang_invoke_AdapterMethodHandle,OP_RETYPE_RAW) \ |
2353 template(sun_dyn_AdapterMethodHandle,OP_CHECK_CAST) \ |
2354 template(java_lang_invoke_AdapterMethodHandle,OP_CHECK_CAST) \ |
2354 template(sun_dyn_AdapterMethodHandle,OP_PRIM_TO_PRIM) \ |
2355 template(java_lang_invoke_AdapterMethodHandle,OP_PRIM_TO_PRIM) \ |
2355 template(sun_dyn_AdapterMethodHandle,OP_REF_TO_PRIM) \ |
2356 template(java_lang_invoke_AdapterMethodHandle,OP_REF_TO_PRIM) \ |
2356 template(sun_dyn_AdapterMethodHandle,OP_PRIM_TO_REF) \ |
2357 template(java_lang_invoke_AdapterMethodHandle,OP_PRIM_TO_REF) \ |
2357 template(sun_dyn_AdapterMethodHandle,OP_SWAP_ARGS) \ |
2358 template(java_lang_invoke_AdapterMethodHandle,OP_SWAP_ARGS) \ |
2358 template(sun_dyn_AdapterMethodHandle,OP_ROT_ARGS) \ |
2359 template(java_lang_invoke_AdapterMethodHandle,OP_ROT_ARGS) \ |
2359 template(sun_dyn_AdapterMethodHandle,OP_DUP_ARGS) \ |
2360 template(java_lang_invoke_AdapterMethodHandle,OP_DUP_ARGS) \ |
2360 template(sun_dyn_AdapterMethodHandle,OP_DROP_ARGS) \ |
2361 template(java_lang_invoke_AdapterMethodHandle,OP_DROP_ARGS) \ |
2361 template(sun_dyn_AdapterMethodHandle,OP_COLLECT_ARGS) \ |
2362 template(java_lang_invoke_AdapterMethodHandle,OP_COLLECT_ARGS) \ |
2362 template(sun_dyn_AdapterMethodHandle,OP_SPREAD_ARGS) \ |
2363 template(java_lang_invoke_AdapterMethodHandle,OP_SPREAD_ARGS) \ |
2363 template(sun_dyn_AdapterMethodHandle,OP_FLYBY) \ |
2364 template(java_lang_invoke_AdapterMethodHandle,OP_FLYBY) \ |
2364 template(sun_dyn_AdapterMethodHandle,OP_RICOCHET) \ |
2365 template(java_lang_invoke_AdapterMethodHandle,OP_RICOCHET) \ |
2365 template(sun_dyn_AdapterMethodHandle,CONV_OP_LIMIT) \ |
2366 template(java_lang_invoke_AdapterMethodHandle,CONV_OP_LIMIT) \ |
2366 template(sun_dyn_AdapterMethodHandle,CONV_OP_MASK) \ |
2367 template(java_lang_invoke_AdapterMethodHandle,CONV_OP_MASK) \ |
2367 template(sun_dyn_AdapterMethodHandle,CONV_VMINFO_MASK) \ |
2368 template(java_lang_invoke_AdapterMethodHandle,CONV_VMINFO_MASK) \ |
2368 template(sun_dyn_AdapterMethodHandle,CONV_VMINFO_SHIFT) \ |
2369 template(java_lang_invoke_AdapterMethodHandle,CONV_VMINFO_SHIFT) \ |
2369 template(sun_dyn_AdapterMethodHandle,CONV_OP_SHIFT) \ |
2370 template(java_lang_invoke_AdapterMethodHandle,CONV_OP_SHIFT) \ |
2370 template(sun_dyn_AdapterMethodHandle,CONV_DEST_TYPE_SHIFT) \ |
2371 template(java_lang_invoke_AdapterMethodHandle,CONV_DEST_TYPE_SHIFT) \ |
2371 template(sun_dyn_AdapterMethodHandle,CONV_SRC_TYPE_SHIFT) \ |
2372 template(java_lang_invoke_AdapterMethodHandle,CONV_SRC_TYPE_SHIFT) \ |
2372 template(sun_dyn_AdapterMethodHandle,CONV_STACK_MOVE_SHIFT) \ |
2373 template(java_lang_invoke_AdapterMethodHandle,CONV_STACK_MOVE_SHIFT) \ |
2373 template(sun_dyn_AdapterMethodHandle,CONV_STACK_MOVE_MASK) \ |
2374 template(java_lang_invoke_AdapterMethodHandle,CONV_STACK_MOVE_MASK) \ |
2374 /*end*/ |
2375 /*end*/ |
2375 |
2376 |
2376 #define ONE_PLUS(scope,value) 1+ |
2377 #define ONE_PLUS(scope,value) 1+ |
2377 static const int con_value_count = EACH_NAMED_CON(ONE_PLUS) 0; |
2378 static const int con_value_count = EACH_NAMED_CON(ONE_PLUS) 0; |
2378 #define VALUE_COMMA(scope,value) scope::value, |
2379 #define VALUE_COMMA(scope,value) scope::value, |
2404 return 0; |
2405 return 0; |
2405 } |
2406 } |
2406 JVM_END |
2407 JVM_END |
2407 |
2408 |
2408 // void init(MemberName self, AccessibleObject ref) |
2409 // void init(MemberName self, AccessibleObject ref) |
2409 JVM_ENTRY(void, MHI_init_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jobject target_jh)) { |
2410 JVM_ENTRY(void, MHN_init_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jobject target_jh)) { |
2410 if (mname_jh == NULL || target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
2411 if (mname_jh == NULL || target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
2411 Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh)); |
2412 Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh)); |
2412 oop target_oop = JNIHandles::resolve_non_null(target_jh); |
2413 oop target_oop = JNIHandles::resolve_non_null(target_jh); |
2413 MethodHandles::init_MemberName(mname(), target_oop); |
2414 MethodHandles::init_MemberName(mname(), target_oop); |
2414 } |
2415 } |
2415 JVM_END |
2416 JVM_END |
2416 |
2417 |
2417 // void expand(MemberName self) |
2418 // void expand(MemberName self) |
2418 JVM_ENTRY(void, MHI_expand_Mem(JNIEnv *env, jobject igcls, jobject mname_jh)) { |
2419 JVM_ENTRY(void, MHN_expand_Mem(JNIEnv *env, jobject igcls, jobject mname_jh)) { |
2419 if (mname_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
2420 if (mname_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
2420 Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh)); |
2421 Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh)); |
2421 MethodHandles::expand_MemberName(mname, 0, CHECK); |
2422 MethodHandles::expand_MemberName(mname, 0, CHECK); |
2422 } |
2423 } |
2423 JVM_END |
2424 JVM_END |
2424 |
2425 |
2425 // void resolve(MemberName self, Class<?> caller) |
2426 // void resolve(MemberName self, Class<?> caller) |
2426 JVM_ENTRY(void, MHI_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh)) { |
2427 JVM_ENTRY(void, MHN_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh)) { |
2427 if (mname_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
2428 if (mname_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
2428 Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh)); |
2429 Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh)); |
2429 |
2430 |
2430 // The trusted Java code that calls this method should already have performed |
2431 // The trusted Java code that calls this method should already have performed |
2431 // access checks on behalf of the given caller. But, we can verify this. |
2432 // access checks on behalf of the given caller. But, we can verify this. |
2432 if (VerifyMethodHandles && caller_jh != NULL) { |
2433 if (VerifyMethodHandles && caller_jh != NULL) { |
2433 klassOop reference_klass = java_lang_Class::as_klassOop(sun_dyn_MemberName::clazz(mname())); |
2434 klassOop reference_klass = java_lang_Class::as_klassOop(java_lang_invoke_MemberName::clazz(mname())); |
2434 if (reference_klass != NULL) { |
2435 if (reference_klass != NULL) { |
2435 // Emulate LinkResolver::check_klass_accessability. |
2436 // Emulate LinkResolver::check_klass_accessability. |
2436 klassOop caller = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(caller_jh)); |
2437 klassOop caller = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(caller_jh)); |
2437 if (!Reflection::verify_class_access(caller, |
2438 if (!Reflection::verify_class_access(caller, |
2438 reference_klass, |
2439 reference_klass, |
2446 } |
2447 } |
2447 JVM_END |
2448 JVM_END |
2448 |
2449 |
2449 // static native int getMembers(Class<?> defc, String matchName, String matchSig, |
2450 // static native int getMembers(Class<?> defc, String matchName, String matchSig, |
2450 // int matchFlags, Class<?> caller, int skip, MemberName[] results); |
2451 // int matchFlags, Class<?> caller, int skip, MemberName[] results); |
2451 JVM_ENTRY(jint, MHI_getMembers(JNIEnv *env, jobject igcls, |
2452 JVM_ENTRY(jint, MHN_getMembers(JNIEnv *env, jobject igcls, |
2452 jclass clazz_jh, jstring name_jh, jstring sig_jh, |
2453 jclass clazz_jh, jstring name_jh, jstring sig_jh, |
2453 int mflags, jclass caller_jh, jint skip, jobjectArray results_jh)) { |
2454 int mflags, jclass caller_jh, jint skip, jobjectArray results_jh)) { |
2454 if (clazz_jh == NULL || results_jh == NULL) return -1; |
2455 if (clazz_jh == NULL || results_jh == NULL) return -1; |
2455 klassOop k_oop = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz_jh)); |
2456 klassOop k_oop = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz_jh)); |
2456 |
2457 |
2485 // TO DO: expand at least some of the MemberNames, to avoid massive callbacks |
2486 // TO DO: expand at least some of the MemberNames, to avoid massive callbacks |
2486 return res; |
2487 return res; |
2487 } |
2488 } |
2488 JVM_END |
2489 JVM_END |
2489 |
2490 |
2490 JVM_ENTRY(void, MHI_registerBootstrap(JNIEnv *env, jobject igcls, jclass caller_jh, jobject bsm_jh)) { |
2491 JVM_ENTRY(void, MHN_registerBootstrap(JNIEnv *env, jobject igcls, jclass caller_jh, jobject bsm_jh)) { |
2491 instanceKlassHandle ik = MethodHandles::resolve_instance_klass(caller_jh, THREAD); |
2492 instanceKlassHandle ik = MethodHandles::resolve_instance_klass(caller_jh, THREAD); |
2492 if (!AllowTransitionalJSR292) { |
2493 if (!AllowTransitionalJSR292) { |
2493 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), |
2494 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), |
2494 "registerBootstrapMethod is only supported in JSR 292 EDR"); |
2495 "registerBootstrapMethod is only supported in JSR 292 EDR"); |
2495 } |
2496 } |
2496 ik->link_class(CHECK); |
2497 ik->link_class(CHECK); |
2497 if (!java_dyn_MethodHandle::is_instance(JNIHandles::resolve(bsm_jh))) { |
2498 if (!java_lang_invoke_MethodHandle::is_instance(JNIHandles::resolve(bsm_jh))) { |
2498 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "method handle"); |
2499 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "method handle"); |
2499 } |
2500 } |
2500 const char* err = NULL; |
2501 const char* err = NULL; |
2501 if (ik->is_initialized() || ik->is_in_error_state()) { |
2502 if (ik->is_initialized() || ik->is_in_error_state()) { |
2502 err = "too late: class is already initialized"; |
2503 err = "too late: class is already initialized"; |
2520 THROW_MSG(vmSymbols::java_lang_IllegalStateException(), err); |
2521 THROW_MSG(vmSymbols::java_lang_IllegalStateException(), err); |
2521 } |
2522 } |
2522 } |
2523 } |
2523 JVM_END |
2524 JVM_END |
2524 |
2525 |
2525 JVM_ENTRY(jobject, MHI_getBootstrap(JNIEnv *env, jobject igcls, jclass caller_jh)) { |
2526 JVM_ENTRY(jobject, MHN_getBootstrap(JNIEnv *env, jobject igcls, jclass caller_jh)) { |
2526 if (!AllowTransitionalJSR292) |
2527 if (!AllowTransitionalJSR292) |
2527 THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "getBootstrap: transitional only"); |
2528 THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "getBootstrap: transitional only"); |
2528 instanceKlassHandle ik = MethodHandles::resolve_instance_klass(caller_jh, THREAD); |
2529 instanceKlassHandle ik = MethodHandles::resolve_instance_klass(caller_jh, THREAD); |
2529 return JNIHandles::make_local(THREAD, ik->bootstrap_method()); |
2530 return JNIHandles::make_local(THREAD, ik->bootstrap_method()); |
2530 } |
2531 } |
2531 JVM_END |
2532 JVM_END |
2532 |
2533 |
2533 JVM_ENTRY(void, MHI_setCallSiteTarget(JNIEnv *env, jobject igcls, jobject site_jh, jobject target_jh)) { |
2534 JVM_ENTRY(void, MHN_setCallSiteTarget(JNIEnv *env, jobject igcls, jobject site_jh, jobject target_jh)) { |
2534 if (!AllowTransitionalJSR292) |
2535 if (!AllowTransitionalJSR292) |
2535 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "setCallSite: transitional only"); |
2536 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "setCallSite: transitional only"); |
2536 } |
2537 } |
2537 JVM_END |
2538 JVM_END |
2538 |
2539 |
2539 |
2540 |
2540 /// JVM_RegisterMethodHandleMethods |
2541 /// JVM_RegisterMethodHandleMethods |
2541 |
|
2542 #define ADR "J" |
|
2543 |
2542 |
2544 #define LANG "Ljava/lang/" |
2543 #define LANG "Ljava/lang/" |
2545 #define JLINV "Ljava/lang/invoke/" /* standard package */ |
2544 #define JLINV "Ljava/lang/invoke/" /* standard package */ |
2546 #define JDYN "Ljava/dyn/" /* alternative package to JLINV if AllowTransitionalJSR292 */ |
2545 #define JDYN "Ljava/dyn/" /* alternative package to JLINV if AllowTransitionalJSR292 */ |
2547 #define IDYN "Lsun/dyn/" /* alternative package to JDYN if AllowTransitionalJSR292 */ |
2546 #define IDYN "Lsun/dyn/" /* alternative package to JDYN if AllowTransitionalJSR292 */ |
2559 #define DMH IDYN"DirectMethodHandle;" |
2558 #define DMH IDYN"DirectMethodHandle;" |
2560 |
2559 |
2561 #define CC (char*) /*cast a literal from (const char*)*/ |
2560 #define CC (char*) /*cast a literal from (const char*)*/ |
2562 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f) |
2561 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f) |
2563 |
2562 |
2564 // These are the native methods on sun.dyn.MethodHandleNatives. |
2563 // These are the native methods on sun.invoke.MethodHandleNatives. |
2565 static JNINativeMethod methods[] = { |
2564 static JNINativeMethod methods[] = { |
2566 // void init(MemberName self, AccessibleObject ref) |
2565 // void init(MemberName self, AccessibleObject ref) |
2567 {CC"init", CC"("AMH""MH"I)V", FN_PTR(MHI_init_AMH)}, |
2566 {CC"init", CC"("AMH""MH"I)V", FN_PTR(MHN_init_AMH)}, |
2568 {CC"init", CC"("BMH""OBJ"I)V", FN_PTR(MHI_init_BMH)}, |
2567 {CC"init", CC"("BMH""OBJ"I)V", FN_PTR(MHN_init_BMH)}, |
2569 {CC"init", CC"("DMH""OBJ"Z"CLS")V", FN_PTR(MHI_init_DMH)}, |
2568 {CC"init", CC"("DMH""OBJ"Z"CLS")V", FN_PTR(MHN_init_DMH)}, |
2570 {CC"init", CC"("MT")V", FN_PTR(MHI_init_MT)}, |
2569 {CC"init", CC"("MT")V", FN_PTR(MHN_init_MT)}, |
2571 {CC"init", CC"("MEM""OBJ")V", FN_PTR(MHI_init_Mem)}, |
2570 {CC"init", CC"("MEM""OBJ")V", FN_PTR(MHN_init_Mem)}, |
2572 {CC"expand", CC"("MEM")V", FN_PTR(MHI_expand_Mem)}, |
2571 {CC"expand", CC"("MEM")V", FN_PTR(MHN_expand_Mem)}, |
2573 {CC"resolve", CC"("MEM""CLS")V", FN_PTR(MHI_resolve_Mem)}, |
2572 {CC"resolve", CC"("MEM""CLS")V", FN_PTR(MHN_resolve_Mem)}, |
2574 {CC"getTarget", CC"("MH"I)"OBJ, FN_PTR(MHI_getTarget)}, |
2573 {CC"getTarget", CC"("MH"I)"OBJ, FN_PTR(MHN_getTarget)}, |
2575 {CC"getConstant", CC"(I)I", FN_PTR(MHI_getConstant)}, |
2574 {CC"getConstant", CC"(I)I", FN_PTR(MHN_getConstant)}, |
2576 // static native int getNamedCon(int which, Object[] name) |
2575 // static native int getNamedCon(int which, Object[] name) |
2577 {CC"getNamedCon", CC"(I["OBJ")I", FN_PTR(MHI_getNamedCon)}, |
2576 {CC"getNamedCon", CC"(I["OBJ")I", FN_PTR(MHN_getNamedCon)}, |
2578 // static native int getMembers(Class<?> defc, String matchName, String matchSig, |
2577 // static native int getMembers(Class<?> defc, String matchName, String matchSig, |
2579 // int matchFlags, Class<?> caller, int skip, MemberName[] results); |
2578 // int matchFlags, Class<?> caller, int skip, MemberName[] results); |
2580 {CC"getMembers", CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHI_getMembers)} |
2579 {CC"getMembers", CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHN_getMembers)} |
2581 }; |
2580 }; |
2582 |
2581 |
2583 // More entry points specifically for EnableInvokeDynamic. |
2582 // More entry points specifically for EnableInvokeDynamic. |
2584 // FIXME: Remove methods2 after AllowTransitionalJSR292 is removed. |
2583 // FIXME: Remove methods2 after AllowTransitionalJSR292 is removed. |
2585 static JNINativeMethod methods2[] = { |
2584 static JNINativeMethod methods2[] = { |
2586 {CC"registerBootstrap", CC"("CLS MH")V", FN_PTR(MHI_registerBootstrap)}, |
2585 {CC"registerBootstrap", CC"("CLS MH")V", FN_PTR(MHN_registerBootstrap)}, |
2587 {CC"getBootstrap", CC"("CLS")"MH, FN_PTR(MHI_getBootstrap)}, |
2586 {CC"getBootstrap", CC"("CLS")"MH, FN_PTR(MHN_getBootstrap)}, |
2588 {CC"setCallSiteTarget", CC"("CST MH")V", FN_PTR(MHI_setCallSiteTarget)} |
2587 {CC"setCallSiteTarget", CC"("CST MH")V", FN_PTR(MHN_setCallSiteTarget)} |
2589 }; |
2588 }; |
2590 |
2589 |
2591 static void hack_signatures(JNINativeMethod* methods, jint num_methods, const char* from_sig, const char* to_sig) { |
2590 static void hack_signatures(JNINativeMethod* methods, jint num_methods, const char* from_sig, const char* to_sig) { |
2592 for (int i = 0; i < num_methods; i++) { |
2591 for (int i = 0; i < num_methods; i++) { |
2593 const char* sig = methods[i].signature; |
2592 const char* sig = methods[i].signature; |