Mercurial > hg > graal-compiler
comparison src/share/vm/prims/methodHandles.cpp @ 3274:2a23b1b5a0a8
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
Reviewed-by: kvn, jrose
author | twisti |
---|---|
date | Mon, 18 Apr 2011 01:33:28 -0700 |
parents | 328926869b15 |
children | 167b70ff3abc |
comparison
equal
deleted
inserted
replaced
2485:97e8046e2562 | 3274:2a23b1b5a0a8 |
---|---|
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. |
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(!java_lang_invoke_MemberName::is_instance(x), "already checked"); | 330 assert(!java_lang_invoke_MemberName::is_instance(x), "already checked"); |
331 } | 331 } |
332 return NULL; | 332 return methodHandle(); |
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()) |
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 } |
2017 } | 2017 } |
2018 | 2018 |
2019 } | 2019 } |
2020 | 2020 |
2021 void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnum, TRAPS) { | 2021 void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnum, TRAPS) { |
2022 oop argument = java_lang_invoke_AdapterMethodHandle::argument(mh()); | |
2023 int argslot = java_lang_invoke_AdapterMethodHandle::vmargslot(mh()); | 2022 int argslot = java_lang_invoke_AdapterMethodHandle::vmargslot(mh()); |
2024 jint conversion = java_lang_invoke_AdapterMethodHandle::conversion(mh()); | 2023 jint conversion = java_lang_invoke_AdapterMethodHandle::conversion(mh()); |
2025 jint conv_op = adapter_conversion_op(conversion); | 2024 jint conv_op = adapter_conversion_op(conversion); |
2026 | 2025 |
2027 // adjust the adapter code to the internal EntryKind enumeration: | 2026 // adjust the adapter code to the internal EntryKind enumeration: |
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 |