151 // Note: A method which does not have a TRAPS argument cannot block in the GC |
151 // Note: A method which does not have a TRAPS argument cannot block in the GC |
152 // or throw exceptions. Such methods are used in this file to do something quick |
152 // or throw exceptions. Such methods are used in this file to do something quick |
153 // and local, like parse a data structure. For speed, such methods work on plain |
153 // and local, like parse a data structure. For speed, such methods work on plain |
154 // oops, not handles. Trapping methods uniformly operate on handles. |
154 // oops, not handles. Trapping methods uniformly operate on handles. |
155 |
155 |
156 methodOop MethodHandles::decode_vmtarget(oop vmtarget, int vmindex, oop mtype, |
156 methodHandle MethodHandles::decode_vmtarget(oop vmtarget, int vmindex, oop mtype, |
157 klassOop& receiver_limit_result, int& decode_flags_result) { |
157 KlassHandle& receiver_limit_result, int& decode_flags_result) { |
158 if (vmtarget == NULL) return NULL; |
158 if (vmtarget == NULL) return methodHandle(); |
159 assert(methodOopDesc::nonvirtual_vtable_index < 0, "encoding"); |
159 assert(methodOopDesc::nonvirtual_vtable_index < 0, "encoding"); |
160 if (vmindex < 0) { |
160 if (vmindex < 0) { |
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. |
196 } |
196 } |
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 methodHandle MethodHandles::decode_DirectMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result) { |
202 oop vmtarget = java_lang_invoke_DirectMethodHandle::vmtarget(mh); |
202 oop vmtarget = java_lang_invoke_DirectMethodHandle::vmtarget(mh); |
203 int vmindex = java_lang_invoke_DirectMethodHandle::vmindex(mh); |
203 int vmindex = java_lang_invoke_DirectMethodHandle::vmindex(mh); |
204 oop mtype = java_lang_invoke_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 methodHandle MethodHandles::decode_BoundMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result) { |
209 assert(java_lang_invoke_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_lang_invoke_MethodHandle::vmtarget(bmh); |
213 oop target = java_lang_invoke_MethodHandle::vmtarget(bmh); |
214 if (target == NULL) return NULL; |
214 if (target == NULL) return methodHandle(); |
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; |
234 } |
234 } |
235 } |
235 } |
236 } |
236 } |
237 } |
237 } |
238 |
238 |
239 methodOop MethodHandles::decode_AdapterMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) { |
239 methodHandle MethodHandles::decode_AdapterMethodHandle(oop mh, KlassHandle& 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(java_lang_invoke_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_lang_invoke_MethodHandle::vmtarget(amh); |
245 oop target = java_lang_invoke_MethodHandle::vmtarget(amh); |
246 if (target == NULL) return NULL; |
246 if (target == NULL) return methodHandle(); |
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; |
251 } else { |
251 } else { |
253 return MethodHandles::decode_MethodHandle(target, receiver_limit_result, decode_flags_result); |
253 return MethodHandles::decode_MethodHandle(target, receiver_limit_result, decode_flags_result); |
254 } |
254 } |
255 } |
255 } |
256 } |
256 } |
257 |
257 |
258 methodOop MethodHandles::decode_MethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) { |
258 methodHandle MethodHandles::decode_MethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result) { |
259 if (mh == NULL) return NULL; |
259 if (mh == NULL) return methodHandle(); |
260 klassOop mhk = mh->klass(); |
260 klassOop mhk = mh->klass(); |
261 assert(java_lang_invoke_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()) { |
268 } else if (java_lang_invoke_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 methodHandle(); // random MH? |
274 } |
274 } |
275 } |
275 } |
276 |
276 |
277 methodOop MethodHandles::decode_methodOop(methodOop m, int& decode_flags_result) { |
277 methodOop MethodHandles::decode_methodOop(methodOop m, int& decode_flags_result) { |
278 assert(m->is_method(), ""); |
278 assert(m->is_method(), ""); |
297 } |
297 } |
298 |
298 |
299 |
299 |
300 // A trusted party is handing us a cookie to determine a method. |
300 // A trusted party is handing us a cookie to determine a method. |
301 // Let's boil it down to the method oop they really want. |
301 // Let's boil it down to the method oop they really want. |
302 methodOop MethodHandles::decode_method(oop x, klassOop& receiver_limit_result, int& decode_flags_result) { |
302 methodHandle MethodHandles::decode_method(oop x, KlassHandle& receiver_limit_result, int& decode_flags_result) { |
303 decode_flags_result = 0; |
303 decode_flags_result = 0; |
304 receiver_limit_result = NULL; |
304 receiver_limit_result = KlassHandle(); |
305 klassOop xk = x->klass(); |
305 klassOop xk = x->klass(); |
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. |
387 int mods = java_lang_reflect_Field::modifiers(target_oop); |
387 int mods = java_lang_reflect_Field::modifiers(target_oop); |
388 klassOop k = java_lang_Class::as_klassOop(clazz); |
388 klassOop k = java_lang_Class::as_klassOop(clazz); |
389 int offset = instanceKlass::cast(k)->offset_from_fields(slot); |
389 int offset = instanceKlass::cast(k)->offset_from_fields(slot); |
390 init_MemberName(mname_oop, k, accessFlags_from(mods), offset); |
390 init_MemberName(mname_oop, k, accessFlags_from(mods), offset); |
391 } else { |
391 } else { |
392 int decode_flags = 0; klassOop receiver_limit = NULL; |
392 KlassHandle receiver_limit; int decode_flags = 0; |
393 methodOop m = MethodHandles::decode_method(target_oop, |
393 methodHandle m = MethodHandles::decode_method(target_oop, receiver_limit, decode_flags); |
394 receiver_limit, decode_flags); |
|
395 bool do_dispatch = ((decode_flags & MethodHandles::_dmf_does_dispatch) != 0); |
394 bool do_dispatch = ((decode_flags & MethodHandles::_dmf_does_dispatch) != 0); |
396 init_MemberName(mname_oop, m, do_dispatch); |
395 init_MemberName(mname_oop, m(), do_dispatch); |
397 } |
396 } |
398 } |
397 } |
399 |
398 |
400 void MethodHandles::init_MemberName(oop mname_oop, methodOop m, bool do_dispatch) { |
399 void MethodHandles::init_MemberName(oop mname_oop, methodOop m, bool do_dispatch) { |
401 int flags = ((m->is_initializer() ? IS_CONSTRUCTOR : IS_METHOD) |
400 int flags = ((m->is_initializer() ? IS_CONSTRUCTOR : IS_METHOD) |
421 java_lang_invoke_MemberName::set_flags(mname_oop, flags); |
420 java_lang_invoke_MemberName::set_flags(mname_oop, flags); |
422 java_lang_invoke_MemberName::set_clazz(mname_oop, Klass::cast(field_holder)->java_mirror()); |
421 java_lang_invoke_MemberName::set_clazz(mname_oop, Klass::cast(field_holder)->java_mirror()); |
423 } |
422 } |
424 |
423 |
425 |
424 |
426 methodOop MethodHandles::decode_MemberName(oop mname, klassOop& receiver_limit_result, int& decode_flags_result) { |
425 methodHandle MethodHandles::decode_MemberName(oop mname, KlassHandle& receiver_limit_result, int& decode_flags_result) { |
|
426 methodHandle empty; |
427 int flags = java_lang_invoke_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 empty; // not invocable |
429 oop vmtarget = java_lang_invoke_MemberName::vmtarget(mname); |
429 oop vmtarget = java_lang_invoke_MemberName::vmtarget(mname); |
430 int vmindex = java_lang_invoke_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 empty; // not resolved |
432 methodOop m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit_result, decode_flags_result); |
432 methodHandle m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit_result, decode_flags_result); |
433 oop clazz = java_lang_invoke_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; |
439 } |
439 } |
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, bool polymorphic, TRAPS) { |
443 bool polymorphic, |
|
444 TRAPS) { |
|
445 if (java_lang_invoke_MethodType::is_instance(type_str)) { |
443 if (java_lang_invoke_MethodType::is_instance(type_str)) { |
446 return java_lang_invoke_MethodType::as_signature(type_str, polymorphic, CHECK_NULL); |
444 return java_lang_invoke_MethodType::as_signature(type_str, polymorphic, CHECK_NULL); |
447 } else if (java_lang_Class::is_instance(type_str)) { |
445 } else if (java_lang_Class::is_instance(type_str)) { |
448 return java_lang_Class::as_signature(type_str, false, CHECK_NULL); |
446 return java_lang_Class::as_signature(type_str, false, CHECK_NULL); |
449 } else if (java_lang_String::is_instance(type_str)) { |
447 } else if (java_lang_String::is_instance(type_str)) { |
472 const int sentinel_limit = methodOopDesc::highest_unused_vtable_index_value - sentinel_slop; |
470 const int sentinel_limit = methodOopDesc::highest_unused_vtable_index_value - sentinel_slop; |
473 assert(VM_INDEX_UNINITIALIZED < sentinel_limit, "Java sentinel != JVM sentinels"); |
471 assert(VM_INDEX_UNINITIALIZED < sentinel_limit, "Java sentinel != JVM sentinels"); |
474 #endif |
472 #endif |
475 if (java_lang_invoke_MemberName::vmindex(mname()) != VM_INDEX_UNINITIALIZED) |
473 if (java_lang_invoke_MemberName::vmindex(mname()) != VM_INDEX_UNINITIALIZED) |
476 return; // already resolved |
474 return; // already resolved |
477 oop defc_oop = java_lang_invoke_MemberName::clazz(mname()); |
475 Handle defc_oop(THREAD, java_lang_invoke_MemberName::clazz(mname())); |
478 oop name_str = java_lang_invoke_MemberName::name(mname()); |
476 Handle name_str(THREAD, java_lang_invoke_MemberName::name( mname())); |
479 oop type_str = java_lang_invoke_MemberName::type(mname()); |
477 Handle type_str(THREAD, java_lang_invoke_MemberName::type( mname())); |
480 int flags = java_lang_invoke_MemberName::flags(mname()); |
478 int flags = java_lang_invoke_MemberName::flags(mname()); |
481 |
479 |
482 if (defc_oop == NULL || name_str == NULL || type_str == NULL) { |
480 if (defc_oop.is_null() || name_str.is_null() || type_str.is_null()) { |
483 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to resolve"); |
481 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to resolve"); |
484 } |
482 } |
485 klassOop defc_klassOop = java_lang_Class::as_klassOop(defc_oop); |
483 |
486 defc_oop = NULL; // safety |
484 instanceKlassHandle defc; |
487 if (defc_klassOop == NULL) return; // a primitive; no resolution possible |
485 { |
488 if (!Klass::cast(defc_klassOop)->oop_is_instance()) { |
486 klassOop defc_klassOop = java_lang_Class::as_klassOop(defc_oop()); |
489 if (!Klass::cast(defc_klassOop)->oop_is_array()) return; |
487 if (defc_klassOop == NULL) return; // a primitive; no resolution possible |
490 defc_klassOop = SystemDictionary::Object_klass(); |
488 if (!Klass::cast(defc_klassOop)->oop_is_instance()) { |
491 } |
489 if (!Klass::cast(defc_klassOop)->oop_is_array()) return; |
492 instanceKlassHandle defc(THREAD, defc_klassOop); |
490 defc_klassOop = SystemDictionary::Object_klass(); |
493 defc_klassOop = NULL; // safety |
491 } |
|
492 defc = instanceKlassHandle(THREAD, defc_klassOop); |
|
493 } |
494 if (defc.is_null()) { |
494 if (defc.is_null()) { |
495 THROW_MSG(vmSymbols::java_lang_InternalError(), "primitive class"); |
495 THROW_MSG(vmSymbols::java_lang_InternalError(), "primitive class"); |
496 } |
496 } |
497 defc->link_class(CHECK); |
497 defc->link_class(CHECK); // possible safepoint |
498 |
498 |
499 // convert the external string name to an internal symbol |
499 // convert the external string name to an internal symbol |
500 TempNewSymbol name = java_lang_String::as_symbol_or_null(name_str); |
500 TempNewSymbol name = java_lang_String::as_symbol_or_null(name_str()); |
501 if (name == NULL) return; // no such name |
501 if (name == NULL) return; // no such name |
502 name_str = NULL; // safety |
|
503 |
502 |
504 Handle polymorphic_method_type; |
503 Handle polymorphic_method_type; |
505 bool polymorphic_signature = false; |
504 bool polymorphic_signature = false; |
506 if ((flags & ALL_KINDS) == IS_METHOD && |
505 if ((flags & ALL_KINDS) == IS_METHOD && |
507 (defc() == SystemDictionary::MethodHandle_klass() && |
506 (defc() == SystemDictionary::MethodHandle_klass() && |
508 methodOopDesc::is_method_handle_invoke_name(name))) |
507 methodOopDesc::is_method_handle_invoke_name(name))) { |
509 polymorphic_signature = true; |
508 polymorphic_signature = true; |
|
509 } |
510 |
510 |
511 // convert the external string or reflective type to an internal signature |
511 // convert the external string or reflective type to an internal signature |
512 TempNewSymbol type = convert_to_signature(type_str, polymorphic_signature, CHECK); |
512 TempNewSymbol type = convert_to_signature(type_str(), polymorphic_signature, CHECK); |
513 if (java_lang_invoke_MethodType::is_instance(type_str) && polymorphic_signature) { |
513 if (java_lang_invoke_MethodType::is_instance(type_str()) && polymorphic_signature) { |
514 polymorphic_method_type = Handle(THREAD, type_str); //preserve exactly |
514 polymorphic_method_type = type_str; // preserve exactly |
515 } |
515 } |
516 |
|
517 if (type == NULL) return; // no such signature exists in the VM |
516 if (type == NULL) return; // no such signature exists in the VM |
518 type_str = NULL; // safety |
|
519 |
517 |
520 // Time to do the lookup. |
518 // Time to do the lookup. |
521 switch (flags & ALL_KINDS) { |
519 switch (flags & ALL_KINDS) { |
522 case IS_METHOD: |
520 case IS_METHOD: |
523 { |
521 { |
558 } |
556 } |
559 int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS); |
557 int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS); |
560 java_lang_invoke_MemberName::set_vmtarget(mname(), vmtarget); |
558 java_lang_invoke_MemberName::set_vmtarget(mname(), vmtarget); |
561 java_lang_invoke_MemberName::set_vmindex(mname(), vmindex); |
559 java_lang_invoke_MemberName::set_vmindex(mname(), vmindex); |
562 java_lang_invoke_MemberName::set_modifiers(mname(), mods); |
560 java_lang_invoke_MemberName::set_modifiers(mname(), mods); |
563 DEBUG_ONLY(int junk; klassOop junk2); |
561 DEBUG_ONLY(KlassHandle junk1; int junk2); |
564 assert(decode_MemberName(mname(), junk2, junk) == result.resolved_method()(), |
562 assert(decode_MemberName(mname(), junk1, junk2) == result.resolved_method(), |
565 "properly stored for later decoding"); |
563 "properly stored for later decoding"); |
566 return; |
564 return; |
567 } |
565 } |
568 case IS_CONSTRUCTOR: |
566 case IS_CONSTRUCTOR: |
569 { |
567 { |
587 int vmindex = methodOopDesc::nonvirtual_vtable_index; |
585 int vmindex = methodOopDesc::nonvirtual_vtable_index; |
588 int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS); |
586 int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS); |
589 java_lang_invoke_MemberName::set_vmtarget(mname(), vmtarget); |
587 java_lang_invoke_MemberName::set_vmtarget(mname(), vmtarget); |
590 java_lang_invoke_MemberName::set_vmindex(mname(), vmindex); |
588 java_lang_invoke_MemberName::set_vmindex(mname(), vmindex); |
591 java_lang_invoke_MemberName::set_modifiers(mname(), mods); |
589 java_lang_invoke_MemberName::set_modifiers(mname(), mods); |
592 DEBUG_ONLY(int junk; klassOop junk2); |
590 DEBUG_ONLY(KlassHandle junk1; int junk2); |
593 assert(decode_MemberName(mname(), junk2, junk) == result.resolved_method()(), |
591 assert(decode_MemberName(mname(), junk1, junk2) == result.resolved_method(), |
594 "properly stored for later decoding"); |
592 "properly stored for later decoding"); |
595 return; |
593 return; |
596 } |
594 } |
597 case IS_FIELD: |
595 case IS_FIELD: |
598 { |
596 { |
675 |
673 |
676 switch (flags & ALL_KINDS) { |
674 switch (flags & ALL_KINDS) { |
677 case IS_METHOD: |
675 case IS_METHOD: |
678 case IS_CONSTRUCTOR: |
676 case IS_CONSTRUCTOR: |
679 { |
677 { |
680 klassOop receiver_limit = NULL; |
678 KlassHandle receiver_limit; int decode_flags = 0; |
681 int decode_flags = 0; |
679 methodHandle m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit, decode_flags); |
682 methodHandle m(THREAD, decode_vmtarget(vmtarget, vmindex, NULL, |
|
683 receiver_limit, decode_flags)); |
|
684 if (m.is_null()) break; |
680 if (m.is_null()) break; |
685 if (!have_defc) { |
681 if (!have_defc) { |
686 klassOop defc = m->method_holder(); |
682 klassOop defc = m->method_holder(); |
687 if (receiver_limit != NULL && receiver_limit != defc |
683 if (receiver_limit.not_null() && receiver_limit() != defc |
688 && Klass::cast(receiver_limit)->is_subtype_of(defc)) |
684 && Klass::cast(receiver_limit())->is_subtype_of(defc)) |
689 defc = receiver_limit; |
685 defc = receiver_limit(); |
690 java_lang_invoke_MemberName::set_clazz(mname(), Klass::cast(defc)->java_mirror()); |
686 java_lang_invoke_MemberName::set_clazz(mname(), Klass::cast(defc)->java_mirror()); |
691 } |
687 } |
692 if (!have_name) { |
688 if (!have_name) { |
693 //not java_lang_String::create_from_symbol; let's intern member names |
689 //not java_lang_String::create_from_symbol; let's intern member names |
694 Handle name = StringTable::intern(m->name(), CHECK); |
690 Handle name = StringTable::intern(m->name(), CHECK); |
882 } |
878 } |
883 // cases of metadata in MH.vmtarget: |
879 // cases of metadata in MH.vmtarget: |
884 // - AMH can have methodOop for static invoke with bound receiver |
880 // - AMH can have methodOop for static invoke with bound receiver |
885 // - DMH can have methodOop for static invoke (on variable receiver) |
881 // - DMH can have methodOop for static invoke (on variable receiver) |
886 // - DMH can have klassOop for dispatched (non-static) invoke |
882 // - DMH can have klassOop for dispatched (non-static) invoke |
887 klassOop receiver_limit = NULL; |
883 KlassHandle receiver_limit; int decode_flags = 0; |
888 int decode_flags = 0; |
884 methodHandle m = decode_MethodHandle(mh(), receiver_limit, decode_flags); |
889 methodOop m = decode_MethodHandle(mh(), receiver_limit, decode_flags); |
885 if (m.is_null()) return NULL; |
890 if (m == NULL) return NULL; |
|
891 switch (format) { |
886 switch (format) { |
892 case ETF_REFLECT_METHOD: |
887 case ETF_REFLECT_METHOD: |
893 // same as jni_ToReflectedMethod: |
888 // same as jni_ToReflectedMethod: |
894 if (m->is_initializer()) { |
889 if (m->is_initializer()) { |
895 return Reflection::new_constructor(m, THREAD); |
890 return Reflection::new_constructor(m, THREAD); |
901 case ETF_METHOD_NAME: |
896 case ETF_METHOD_NAME: |
902 { |
897 { |
903 if (SystemDictionary::MemberName_klass() == NULL) break; |
898 if (SystemDictionary::MemberName_klass() == NULL) break; |
904 instanceKlassHandle mname_klass(THREAD, SystemDictionary::MemberName_klass()); |
899 instanceKlassHandle mname_klass(THREAD, SystemDictionary::MemberName_klass()); |
905 mname_klass->initialize(CHECK_NULL); |
900 mname_klass->initialize(CHECK_NULL); |
906 Handle mname = mname_klass->allocate_instance_handle(CHECK_NULL); |
901 Handle mname = mname_klass->allocate_instance_handle(CHECK_NULL); // possible safepoint |
907 java_lang_invoke_MemberName::set_vmindex(mname(), VM_INDEX_UNINITIALIZED); |
902 java_lang_invoke_MemberName::set_vmindex(mname(), VM_INDEX_UNINITIALIZED); |
908 bool do_dispatch = ((decode_flags & MethodHandles::_dmf_does_dispatch) != 0); |
903 bool do_dispatch = ((decode_flags & MethodHandles::_dmf_does_dispatch) != 0); |
909 init_MemberName(mname(), m, do_dispatch); |
904 init_MemberName(mname(), m(), do_dispatch); |
910 expand_MemberName(mname, 0, CHECK_NULL); |
905 expand_MemberName(mname, 0, CHECK_NULL); |
911 return mname(); |
906 return mname(); |
912 } |
907 } |
913 } |
908 } |
914 |
909 |
1457 // InterpreterRuntime::resolve_invoke(), which first finds the method |
1452 // InterpreterRuntime::resolve_invoke(), which first finds the method |
1458 // and then decides how to populate the constant pool cache entry |
1453 // and then decides how to populate the constant pool cache entry |
1459 // that links the interpreter calls to the method. We need the same |
1454 // that links the interpreter calls to the method. We need the same |
1460 // bits, and will use the same calling sequence code. |
1455 // bits, and will use the same calling sequence code. |
1461 |
1456 |
1462 int vmindex = methodOopDesc::garbage_vtable_index; |
1457 int vmindex = methodOopDesc::garbage_vtable_index; |
1463 oop vmtarget = NULL; |
1458 Handle vmtarget; |
1464 |
1459 |
1465 instanceKlass::cast(m->method_holder())->link_class(CHECK); |
1460 instanceKlass::cast(m->method_holder())->link_class(CHECK); |
1466 |
1461 |
1467 MethodHandleEntry* me = NULL; |
1462 MethodHandleEntry* me = NULL; |
1468 if (do_dispatch && Klass::cast(m->method_holder())->is_interface()) { |
1463 if (do_dispatch && Klass::cast(m->method_holder())->is_interface()) { |
1476 vmtarget = m->method_holder(); // the interface |
1471 vmtarget = m->method_holder(); // the interface |
1477 me = MethodHandles::entry(MethodHandles::_invokeinterface_mh); |
1472 me = MethodHandles::entry(MethodHandles::_invokeinterface_mh); |
1478 } else if (!do_dispatch || m->can_be_statically_bound()) { |
1473 } else if (!do_dispatch || m->can_be_statically_bound()) { |
1479 // We are simulating an invokestatic or invokespecial instruction. |
1474 // We are simulating an invokestatic or invokespecial instruction. |
1480 // Set up the method pointer, just like ConstantPoolCacheEntry::set_method(). |
1475 // Set up the method pointer, just like ConstantPoolCacheEntry::set_method(). |
1481 vmtarget = m(); |
1476 vmtarget = m; |
1482 // this does not help dispatch, but it will make it possible to parse this MH: |
1477 // this does not help dispatch, but it will make it possible to parse this MH: |
1483 vmindex = methodOopDesc::nonvirtual_vtable_index; |
1478 vmindex = methodOopDesc::nonvirtual_vtable_index; |
1484 assert(vmindex < 0, "(>=0) == do_dispatch"); |
1479 assert(vmindex < 0, "(>=0) == do_dispatch"); |
1485 if (!m->is_static()) { |
1480 if (!m->is_static()) { |
1486 me = MethodHandles::entry(MethodHandles::_invokespecial_mh); |
1481 me = MethodHandles::entry(MethodHandles::_invokespecial_mh); |
1488 me = MethodHandles::entry(MethodHandles::_invokestatic_mh); |
1483 me = MethodHandles::entry(MethodHandles::_invokestatic_mh); |
1489 // Part of the semantics of a static call is an initialization barrier. |
1484 // Part of the semantics of a static call is an initialization barrier. |
1490 // For a DMH, it is done now, when the handle is created. |
1485 // For a DMH, it is done now, when the handle is created. |
1491 Klass* k = Klass::cast(m->method_holder()); |
1486 Klass* k = Klass::cast(m->method_holder()); |
1492 if (k->should_be_initialized()) { |
1487 if (k->should_be_initialized()) { |
1493 k->initialize(CHECK); |
1488 k->initialize(CHECK); // possible safepoint |
1494 } |
1489 } |
1495 } |
1490 } |
1496 } else { |
1491 } else { |
1497 // We are simulating an invokevirtual instruction. |
1492 // We are simulating an invokevirtual instruction. |
1498 // Set up the vtable index, just like ConstantPoolCacheEntry::set_method(). |
1493 // Set up the vtable index, just like ConstantPoolCacheEntry::set_method(). |
1502 me = MethodHandles::entry(MethodHandles::_invokevirtual_mh); |
1497 me = MethodHandles::entry(MethodHandles::_invokevirtual_mh); |
1503 } |
1498 } |
1504 |
1499 |
1505 if (me == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
1500 if (me == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
1506 |
1501 |
1507 java_lang_invoke_DirectMethodHandle::set_vmtarget(mh(), vmtarget); |
1502 java_lang_invoke_DirectMethodHandle::set_vmtarget(mh(), vmtarget()); |
1508 java_lang_invoke_DirectMethodHandle::set_vmindex(mh(), vmindex); |
1503 java_lang_invoke_DirectMethodHandle::set_vmindex( mh(), vmindex); |
1509 DEBUG_ONLY(int flags; klassOop rlimit); |
1504 DEBUG_ONLY(KlassHandle rlimit; int flags); |
1510 assert(MethodHandles::decode_method(mh(), rlimit, flags) == m(), |
1505 assert(MethodHandles::decode_method(mh(), rlimit, flags) == m, |
1511 "properly stored for later decoding"); |
1506 "properly stored for later decoding"); |
1512 DEBUG_ONLY(bool actual_do_dispatch = ((flags & _dmf_does_dispatch) != 0)); |
1507 DEBUG_ONLY(bool actual_do_dispatch = ((flags & _dmf_does_dispatch) != 0)); |
1513 assert(!(actual_do_dispatch && !do_dispatch), |
1508 assert(!(actual_do_dispatch && !do_dispatch), |
1514 "do not perform dispatch if !do_dispatch specified"); |
1509 "do not perform dispatch if !do_dispatch specified"); |
1515 assert(actual_do_dispatch == (vmindex >= 0), "proper later decoding of do_dispatch"); |
1510 assert(actual_do_dispatch == (vmindex >= 0), "proper later decoding of do_dispatch"); |
1521 |
1516 |
1522 void MethodHandles::verify_BoundMethodHandle_with_receiver(Handle mh, |
1517 void MethodHandles::verify_BoundMethodHandle_with_receiver(Handle mh, |
1523 methodHandle m, |
1518 methodHandle m, |
1524 TRAPS) { |
1519 TRAPS) { |
1525 // Verify type. |
1520 // Verify type. |
1526 oop receiver = java_lang_invoke_BoundMethodHandle::argument(mh()); |
1521 KlassHandle bound_recv_type; |
|
1522 { |
|
1523 oop receiver = java_lang_invoke_BoundMethodHandle::argument(mh()); |
|
1524 if (receiver != NULL) |
|
1525 bound_recv_type = KlassHandle(THREAD, receiver->klass()); |
|
1526 } |
1527 Handle mtype(THREAD, java_lang_invoke_MethodHandle::type(mh())); |
1527 Handle mtype(THREAD, java_lang_invoke_MethodHandle::type(mh())); |
1528 KlassHandle bound_recv_type; |
|
1529 if (receiver != NULL) bound_recv_type = KlassHandle(THREAD, receiver->klass()); |
|
1530 verify_method_type(m, mtype, true, bound_recv_type, CHECK); |
1528 verify_method_type(m, mtype, true, bound_recv_type, CHECK); |
1531 |
1529 |
1532 int receiver_pos = m->size_of_parameters() - 1; |
1530 int receiver_pos = m->size_of_parameters() - 1; |
1533 |
1531 |
1534 // Verify MH.vmargslot, which should point at the bound receiver. |
1532 // Verify MH.vmargslot, which should point at the bound receiver. |
1571 verify_BoundMethodHandle_with_receiver(mh, m, CHECK); |
1569 verify_BoundMethodHandle_with_receiver(mh, m, CHECK); |
1572 } |
1570 } |
1573 |
1571 |
1574 java_lang_invoke_BoundMethodHandle::set_vmtarget(mh(), m()); |
1572 java_lang_invoke_BoundMethodHandle::set_vmtarget(mh(), m()); |
1575 |
1573 |
1576 DEBUG_ONLY(int junk; klassOop junk2); |
1574 DEBUG_ONLY(KlassHandle junk1; int junk2); |
1577 assert(MethodHandles::decode_method(mh(), junk2, junk) == m(), "properly stored for later decoding"); |
1575 assert(MethodHandles::decode_method(mh(), junk1, junk2) == m, "properly stored for later decoding"); |
1578 assert(decode_MethodHandle_stack_pushes(mh()) == 1, "BMH pushes one stack slot"); |
1576 assert(decode_MethodHandle_stack_pushes(mh()) == 1, "BMH pushes one stack slot"); |
1579 |
1577 |
1580 // Done! |
1578 // Done! |
1581 java_lang_invoke_MethodHandle::set_vmentry(mh(), MethodHandles::entry(MethodHandles::_bound_ref_direct_mh)); |
1579 java_lang_invoke_MethodHandle::set_vmentry(mh(), MethodHandles::entry(MethodHandles::_bound_ref_direct_mh)); |
1582 } |
1580 } |
1680 verify_vmargslot(mh, insert_after, java_lang_invoke_BoundMethodHandle::vmargslot(mh()), CHECK); |
1678 verify_vmargslot(mh, insert_after, java_lang_invoke_BoundMethodHandle::vmargslot(mh()), CHECK); |
1681 verify_vmslots(mh, CHECK); |
1679 verify_vmslots(mh, CHECK); |
1682 } |
1680 } |
1683 |
1681 |
1684 // Get bound type and required slots. |
1682 // Get bound type and required slots. |
1685 oop ptype_oop = java_lang_invoke_MethodType::ptype(java_lang_invoke_MethodHandle::type(target()), argnum); |
1683 BasicType ptype; |
1686 BasicType ptype = java_lang_Class::as_BasicType(ptype_oop); |
1684 { |
|
1685 oop ptype_oop = java_lang_invoke_MethodType::ptype(java_lang_invoke_MethodHandle::type(target()), argnum); |
|
1686 ptype = java_lang_Class::as_BasicType(ptype_oop); |
|
1687 } |
1687 int slots_pushed = type2size[ptype]; |
1688 int slots_pushed = type2size[ptype]; |
1688 |
1689 |
1689 // If (a) the target is a direct non-dispatched method handle, |
1690 // If (a) the target is a direct non-dispatched method handle, |
1690 // or (b) the target is a dispatched direct method handle and we |
1691 // or (b) the target is a dispatched direct method handle and we |
1691 // are binding the receiver, cut out the middle-man. |
1692 // are binding the receiver, cut out the middle-man. |
1692 // Do this by decoding the DMH and using its methodOop directly as vmtarget. |
1693 // Do this by decoding the DMH and using its methodOop directly as vmtarget. |
1693 bool direct_to_method = false; |
1694 bool direct_to_method = false; |
1694 if (OptimizeMethodHandles && |
1695 if (OptimizeMethodHandles && |
1695 target->klass() == SystemDictionary::DirectMethodHandle_klass() && |
1696 target->klass() == SystemDictionary::DirectMethodHandle_klass() && |
1696 (argnum == 0 || java_lang_invoke_DirectMethodHandle::vmindex(target()) < 0)) { |
1697 (argnum == 0 || java_lang_invoke_DirectMethodHandle::vmindex(target()) < 0)) { |
1697 int decode_flags = 0; klassOop receiver_limit_oop = NULL; |
1698 KlassHandle receiver_limit; int decode_flags = 0; |
1698 methodHandle m(THREAD, decode_method(target(), receiver_limit_oop, decode_flags)); |
1699 methodHandle m = decode_method(target(), receiver_limit, decode_flags); |
1699 if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "DMH failed to decode"); } |
1700 if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "DMH failed to decode"); } |
1700 DEBUG_ONLY(int m_vmslots = m->size_of_parameters() - slots_pushed); // pos. of 1st arg. |
1701 DEBUG_ONLY(int m_vmslots = m->size_of_parameters() - slots_pushed); // pos. of 1st arg. |
1701 assert(java_lang_invoke_BoundMethodHandle::vmslots(mh()) == m_vmslots, "type w/ m sig"); |
1702 assert(java_lang_invoke_BoundMethodHandle::vmslots(mh()) == m_vmslots, "type w/ m sig"); |
1702 if (argnum == 0 && (decode_flags & _dmf_has_receiver) != 0) { |
1703 if (argnum == 0 && (decode_flags & _dmf_has_receiver) != 0) { |
1703 KlassHandle receiver_limit(THREAD, receiver_limit_oop); |
|
1704 init_BoundMethodHandle_with_receiver(mh, m, |
1704 init_BoundMethodHandle_with_receiver(mh, m, |
1705 receiver_limit, decode_flags, |
1705 receiver_limit, decode_flags, |
1706 CHECK); |
1706 CHECK); |
1707 return; |
1707 return; |
1708 } |
1708 } |
2213 // Early returns out of this method leave the DMH in an unfinished state. |
2212 // Early returns out of this method leave the DMH in an unfinished state. |
2214 assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null"); |
2213 assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null"); |
2215 |
2214 |
2216 // which method are we really talking about? |
2215 // which method are we really talking about? |
2217 if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
2216 if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
2218 oop target_oop = JNIHandles::resolve_non_null(target_jh); |
2217 Handle target(THREAD, JNIHandles::resolve_non_null(target_jh)); |
2219 if (java_lang_invoke_MemberName::is_instance(target_oop) && |
2218 if (java_lang_invoke_MemberName::is_instance(target()) && |
2220 java_lang_invoke_MemberName::vmindex(target_oop) == VM_INDEX_UNINITIALIZED) { |
2219 java_lang_invoke_MemberName::vmindex(target()) == VM_INDEX_UNINITIALIZED) { |
2221 Handle mname(THREAD, target_oop); |
2220 MethodHandles::resolve_MemberName(target, CHECK); |
2222 MethodHandles::resolve_MemberName(mname, CHECK); |
2221 } |
2223 target_oop = mname(); // in case of GC |
2222 |
2224 } |
2223 KlassHandle receiver_limit; int decode_flags = 0; |
2225 |
2224 methodHandle m = MethodHandles::decode_method(target(), receiver_limit, decode_flags); |
2226 int decode_flags = 0; klassOop receiver_limit = NULL; |
|
2227 methodHandle m(THREAD, |
|
2228 MethodHandles::decode_method(target_oop, |
|
2229 receiver_limit, decode_flags)); |
|
2230 if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "no such method"); } |
2225 if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "no such method"); } |
2231 |
2226 |
2232 // The trusted Java code that calls this method should already have performed |
2227 // The trusted Java code that calls this method should already have performed |
2233 // access checks on behalf of the given caller. But, we can verify this. |
2228 // access checks on behalf of the given caller. But, we can verify this. |
2234 if (VerifyMethodHandles && caller_jh != NULL) { |
2229 if (VerifyMethodHandles && caller_jh != NULL) { |
2282 |
2277 |
2283 if (!java_lang_invoke_MethodHandle::is_instance(target())) { |
2278 if (!java_lang_invoke_MethodHandle::is_instance(target())) { |
2284 // Target object is a reflective method. (%%% Do we need this alternate path?) |
2279 // Target object is a reflective method. (%%% Do we need this alternate path?) |
2285 Untested("init_BMH of non-MH"); |
2280 Untested("init_BMH of non-MH"); |
2286 if (argnum != 0) { THROW(vmSymbols::java_lang_InternalError()); } |
2281 if (argnum != 0) { THROW(vmSymbols::java_lang_InternalError()); } |
2287 int decode_flags = 0; klassOop receiver_limit_oop = NULL; |
2282 KlassHandle receiver_limit; int decode_flags = 0; |
2288 methodHandle m(THREAD, |
2283 methodHandle m = MethodHandles::decode_method(target(), receiver_limit, decode_flags); |
2289 MethodHandles::decode_method(target(), |
|
2290 receiver_limit_oop, |
|
2291 decode_flags)); |
|
2292 KlassHandle receiver_limit(THREAD, receiver_limit_oop); |
|
2293 MethodHandles::init_BoundMethodHandle_with_receiver(mh, m, |
2284 MethodHandles::init_BoundMethodHandle_with_receiver(mh, m, |
2294 receiver_limit, |
2285 receiver_limit, |
2295 decode_flags, |
2286 decode_flags, |
2296 CHECK); |
2287 CHECK); |
2297 return; |
2288 return; |
2422 |
2413 |
2423 JVM_ENTRY(jint, MHN_getNamedCon(JNIEnv *env, jobject igcls, jint which, jobjectArray box_jh)) { |
2414 JVM_ENTRY(jint, MHN_getNamedCon(JNIEnv *env, jobject igcls, jint which, jobjectArray box_jh)) { |
2424 #ifndef PRODUCT |
2415 #ifndef PRODUCT |
2425 if (which >= 0 && which < con_value_count) { |
2416 if (which >= 0 && which < con_value_count) { |
2426 int con = con_values[which]; |
2417 int con = con_values[which]; |
2427 objArrayOop box = (objArrayOop) JNIHandles::resolve(box_jh); |
2418 objArrayHandle box(THREAD, (objArrayOop) JNIHandles::resolve(box_jh)); |
2428 if (box != NULL && box->klass() == Universe::objectArrayKlassObj() && box->length() > 0) { |
2419 if (box.not_null() && box->klass() == Universe::objectArrayKlassObj() && box->length() > 0) { |
2429 const char* str = &con_names[0]; |
2420 const char* str = &con_names[0]; |
2430 for (int i = 0; i < which; i++) |
2421 for (int i = 0; i < which; i++) |
2431 str += strlen(str) + 1; // skip name and null |
2422 str += strlen(str) + 1; // skip name and null |
2432 oop name = java_lang_String::create_oop_from_str(str, CHECK_0); |
2423 oop name = java_lang_String::create_oop_from_str(str, CHECK_0); // possible safepoint |
2433 box->obj_at_put(0, name); |
2424 box->obj_at_put(0, name); |
2434 } |
2425 } |
2435 return con; |
2426 return con; |
2436 } |
2427 } |
2437 #endif |
2428 #endif |
2484 // int matchFlags, Class<?> caller, int skip, MemberName[] results); |
2475 // int matchFlags, Class<?> caller, int skip, MemberName[] results); |
2485 JVM_ENTRY(jint, MHN_getMembers(JNIEnv *env, jobject igcls, |
2476 JVM_ENTRY(jint, MHN_getMembers(JNIEnv *env, jobject igcls, |
2486 jclass clazz_jh, jstring name_jh, jstring sig_jh, |
2477 jclass clazz_jh, jstring name_jh, jstring sig_jh, |
2487 int mflags, jclass caller_jh, jint skip, jobjectArray results_jh)) { |
2478 int mflags, jclass caller_jh, jint skip, jobjectArray results_jh)) { |
2488 if (clazz_jh == NULL || results_jh == NULL) return -1; |
2479 if (clazz_jh == NULL || results_jh == NULL) return -1; |
2489 klassOop k_oop = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz_jh)); |
2480 KlassHandle k(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz_jh))); |
2490 |
2481 |
2491 objArrayOop results = (objArrayOop) JNIHandles::resolve(results_jh); |
2482 objArrayHandle results(THREAD, (objArrayOop) JNIHandles::resolve(results_jh)); |
2492 if (results == NULL || !results->is_objArray()) return -1; |
2483 if (results.is_null() || !results->is_objArray()) return -1; |
2493 |
2484 |
2494 TempNewSymbol name = NULL; |
2485 TempNewSymbol name = NULL; |
2495 TempNewSymbol sig = NULL; |
2486 TempNewSymbol sig = NULL; |
2496 if (name_jh != NULL) { |
2487 if (name_jh != NULL) { |
2497 name = java_lang_String::as_symbol_or_null(JNIHandles::resolve_non_null(name_jh)); |
2488 name = java_lang_String::as_symbol_or_null(JNIHandles::resolve_non_null(name_jh)); |
2500 if (sig_jh != NULL) { |
2491 if (sig_jh != NULL) { |
2501 sig = java_lang_String::as_symbol_or_null(JNIHandles::resolve_non_null(sig_jh)); |
2492 sig = java_lang_String::as_symbol_or_null(JNIHandles::resolve_non_null(sig_jh)); |
2502 if (sig == NULL) return 0; // a match is not possible |
2493 if (sig == NULL) return 0; // a match is not possible |
2503 } |
2494 } |
2504 |
2495 |
2505 klassOop caller = NULL; |
2496 KlassHandle caller; |
2506 if (caller_jh != NULL) { |
2497 if (caller_jh != NULL) { |
2507 oop caller_oop = JNIHandles::resolve_non_null(caller_jh); |
2498 oop caller_oop = JNIHandles::resolve_non_null(caller_jh); |
2508 if (!java_lang_Class::is_instance(caller_oop)) return -1; |
2499 if (!java_lang_Class::is_instance(caller_oop)) return -1; |
2509 caller = java_lang_Class::as_klassOop(caller_oop); |
2500 caller = KlassHandle(THREAD, java_lang_Class::as_klassOop(caller_oop)); |
2510 } |
2501 } |
2511 |
2502 |
2512 if (name != NULL && sig != NULL && results != NULL) { |
2503 if (name != NULL && sig != NULL && results.not_null()) { |
2513 // try a direct resolve |
2504 // try a direct resolve |
2514 // %%% TO DO |
2505 // %%% TO DO |
2515 } |
2506 } |
2516 |
2507 |
2517 int res = MethodHandles::find_MemberNames(k_oop, name, sig, mflags, |
2508 int res = MethodHandles::find_MemberNames(k(), name, sig, mflags, |
2518 caller, skip, results); |
2509 caller(), skip, results()); |
2519 // TO DO: expand at least some of the MemberNames, to avoid massive callbacks |
2510 // TO DO: expand at least some of the MemberNames, to avoid massive callbacks |
2520 return res; |
2511 return res; |
2521 } |
2512 } |
2522 JVM_END |
2513 JVM_END |
2523 |
2514 |