Mercurial > hg > truffle
comparison src/share/vm/ci/ciEnv.cpp @ 3461:81d815b05abb
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
Reviewed-by: never
author | jrose |
---|---|
date | Thu, 23 Jun 2011 17:14:06 -0700 |
parents | 08ccee2c4dbf |
children | be4ca325525a b27c72d69fd1 |
comparison
equal
deleted
inserted
replaced
3460:e9b51b4bdcc7 | 3461:81d815b05abb |
---|---|
48 #include "oops/methodDataOop.hpp" | 48 #include "oops/methodDataOop.hpp" |
49 #include "oops/objArrayKlass.hpp" | 49 #include "oops/objArrayKlass.hpp" |
50 #include "oops/oop.inline.hpp" | 50 #include "oops/oop.inline.hpp" |
51 #include "oops/oop.inline2.hpp" | 51 #include "oops/oop.inline2.hpp" |
52 #include "prims/jvmtiExport.hpp" | 52 #include "prims/jvmtiExport.hpp" |
53 #include "prims/methodHandleWalk.hpp" | |
53 #include "runtime/init.hpp" | 54 #include "runtime/init.hpp" |
54 #include "runtime/reflection.hpp" | 55 #include "runtime/reflection.hpp" |
55 #include "runtime/sharedRuntime.hpp" | 56 #include "runtime/sharedRuntime.hpp" |
56 #include "utilities/dtrace.hpp" | 57 #include "utilities/dtrace.hpp" |
57 #ifdef COMPILER1 | 58 #ifdef COMPILER1 |
369 } | 370 } |
370 | 371 |
371 // ------------------------------------------------------------------ | 372 // ------------------------------------------------------------------ |
372 // ciEnv::get_klass_by_name_impl | 373 // ciEnv::get_klass_by_name_impl |
373 ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass, | 374 ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass, |
375 constantPoolHandle cpool, | |
374 ciSymbol* name, | 376 ciSymbol* name, |
375 bool require_local) { | 377 bool require_local) { |
376 ASSERT_IN_VM; | 378 ASSERT_IN_VM; |
377 EXCEPTION_CONTEXT; | 379 EXCEPTION_CONTEXT; |
378 | 380 |
384 // Call recursive to keep scope of strippedsym. | 386 // Call recursive to keep scope of strippedsym. |
385 TempNewSymbol strippedsym = SymbolTable::new_symbol(sym->as_utf8()+1, | 387 TempNewSymbol strippedsym = SymbolTable::new_symbol(sym->as_utf8()+1, |
386 sym->utf8_length()-2, | 388 sym->utf8_length()-2, |
387 KILL_COMPILE_ON_FATAL_(_unloaded_ciinstance_klass)); | 389 KILL_COMPILE_ON_FATAL_(_unloaded_ciinstance_klass)); |
388 ciSymbol* strippedname = get_symbol(strippedsym); | 390 ciSymbol* strippedname = get_symbol(strippedsym); |
389 return get_klass_by_name_impl(accessing_klass, strippedname, require_local); | 391 return get_klass_by_name_impl(accessing_klass, cpool, strippedname, require_local); |
390 } | 392 } |
391 | 393 |
392 // Check for prior unloaded klass. The SystemDictionary's answers | 394 // Check for prior unloaded klass. The SystemDictionary's answers |
393 // can vary over time but the compiler needs consistency. | 395 // can vary over time but the compiler needs consistency. |
394 ciKlass* unloaded_klass = check_get_unloaded_klass(accessing_klass, name); | 396 ciKlass* unloaded_klass = check_get_unloaded_klass(accessing_klass, name); |
441 KILL_COMPILE_ON_FATAL_(fail_type)); | 443 KILL_COMPILE_ON_FATAL_(fail_type)); |
442 | 444 |
443 // Get element ciKlass recursively. | 445 // Get element ciKlass recursively. |
444 ciKlass* elem_klass = | 446 ciKlass* elem_klass = |
445 get_klass_by_name_impl(accessing_klass, | 447 get_klass_by_name_impl(accessing_klass, |
448 cpool, | |
446 get_symbol(elem_sym), | 449 get_symbol(elem_sym), |
447 require_local); | 450 require_local); |
448 if (elem_klass != NULL && elem_klass->is_loaded()) { | 451 if (elem_klass != NULL && elem_klass->is_loaded()) { |
449 // Now make an array for it | 452 // Now make an array for it |
450 return ciObjArrayKlass::make_impl(elem_klass); | 453 return ciObjArrayKlass::make_impl(elem_klass); |
451 } | 454 } |
452 } | 455 } |
453 | 456 |
457 if (found_klass() == NULL && !cpool.is_null() && cpool->has_preresolution()) { | |
458 // Look inside the constant pool for pre-resolved class entries. | |
459 for (int i = cpool->length() - 1; i >= 1; i--) { | |
460 if (cpool->tag_at(i).is_klass()) { | |
461 klassOop kls = cpool->resolved_klass_at(i); | |
462 if (Klass::cast(kls)->name() == sym) { | |
463 found_klass = KlassHandle(THREAD, kls); | |
464 break; | |
465 } | |
466 } | |
467 } | |
468 } | |
469 | |
454 if (found_klass() != NULL) { | 470 if (found_klass() != NULL) { |
455 // Found it. Build a CI handle. | 471 // Found it. Build a CI handle. |
456 return get_object(found_klass())->as_klass(); | 472 return get_object(found_klass())->as_klass(); |
457 } | 473 } |
458 | 474 |
466 // ciEnv::get_klass_by_name | 482 // ciEnv::get_klass_by_name |
467 ciKlass* ciEnv::get_klass_by_name(ciKlass* accessing_klass, | 483 ciKlass* ciEnv::get_klass_by_name(ciKlass* accessing_klass, |
468 ciSymbol* klass_name, | 484 ciSymbol* klass_name, |
469 bool require_local) { | 485 bool require_local) { |
470 GUARDED_VM_ENTRY(return get_klass_by_name_impl(accessing_klass, | 486 GUARDED_VM_ENTRY(return get_klass_by_name_impl(accessing_klass, |
487 constantPoolHandle(), | |
471 klass_name, | 488 klass_name, |
472 require_local);) | 489 require_local);) |
473 } | 490 } |
474 | 491 |
475 // ------------------------------------------------------------------ | 492 // ------------------------------------------------------------------ |
506 } | 523 } |
507 | 524 |
508 if (klass.is_null()) { | 525 if (klass.is_null()) { |
509 // Not found in constant pool. Use the name to do the lookup. | 526 // Not found in constant pool. Use the name to do the lookup. |
510 ciKlass* k = get_klass_by_name_impl(accessor, | 527 ciKlass* k = get_klass_by_name_impl(accessor, |
528 cpool, | |
511 get_symbol(klass_name), | 529 get_symbol(klass_name), |
512 false); | 530 false); |
513 // Calculate accessibility the hard way. | 531 // Calculate accessibility the hard way. |
514 if (!k->is_loaded()) { | 532 if (!k->is_loaded()) { |
515 is_accessible = false; | 533 is_accessible = false; |
516 } else if (k->loader() != accessor->loader() && | 534 } else if (k->loader() != accessor->loader() && |
517 get_klass_by_name_impl(accessor, k->name(), true) == NULL) { | 535 get_klass_by_name_impl(accessor, cpool, k->name(), true) == NULL) { |
518 // Loaded only remotely. Not linked yet. | 536 // Loaded only remotely. Not linked yet. |
519 is_accessible = false; | 537 is_accessible = false; |
520 } else { | 538 } else { |
521 // Linked locally, and we must also check public/private, etc. | 539 // Linked locally, and we must also check public/private, etc. |
522 is_accessible = check_klass_accessibility(accessor, k->get_klassOop()); | 540 is_accessible = check_klass_accessibility(accessor, k->get_klassOop()); |
563 assert(index < 0, "only one kind of index at a time"); | 581 assert(index < 0, "only one kind of index at a time"); |
564 ConstantPoolCacheEntry* cpc_entry = cpool->cache()->entry_at(cache_index); | 582 ConstantPoolCacheEntry* cpc_entry = cpool->cache()->entry_at(cache_index); |
565 index = cpc_entry->constant_pool_index(); | 583 index = cpc_entry->constant_pool_index(); |
566 oop obj = cpc_entry->f1(); | 584 oop obj = cpc_entry->f1(); |
567 if (obj != NULL) { | 585 if (obj != NULL) { |
568 assert(obj->is_instance(), "must be an instance"); | 586 assert(obj->is_instance() || obj->is_array(), "must be a Java reference"); |
569 ciObject* ciobj = get_object(obj); | 587 ciObject* ciobj = get_object(obj); |
570 return ciConstant(T_OBJECT, ciobj); | 588 return ciConstant(T_OBJECT, ciobj); |
571 } | 589 } |
572 } | 590 } |
573 constantTag tag = cpool->tag_at(index); | 591 constantTag tag = cpool->tag_at(index); |
605 assert (klass->is_instance_klass() || klass->is_array_klass(), | 623 assert (klass->is_instance_klass() || klass->is_array_klass(), |
606 "must be an instance or array klass "); | 624 "must be an instance or array klass "); |
607 return ciConstant(T_OBJECT, klass->java_mirror()); | 625 return ciConstant(T_OBJECT, klass->java_mirror()); |
608 } else if (tag.is_object()) { | 626 } else if (tag.is_object()) { |
609 oop obj = cpool->object_at(index); | 627 oop obj = cpool->object_at(index); |
610 assert(obj->is_instance(), "must be an instance"); | 628 assert(obj->is_instance() || obj->is_array(), "must be a Java reference"); |
611 ciObject* ciobj = get_object(obj); | 629 ciObject* ciobj = get_object(obj); |
612 return ciConstant(T_OBJECT, ciobj); | 630 return ciConstant(T_OBJECT, ciobj); |
613 } else if (tag.is_method_type()) { | 631 } else if (tag.is_method_type()) { |
614 // must execute Java code to link this CP entry into cache[i].f1 | 632 // must execute Java code to link this CP entry into cache[i].f1 |
615 ciSymbol* signature = get_symbol(cpool->method_type_signature_at(index)); | 633 ciSymbol* signature = get_symbol(cpool->method_type_signature_at(index)); |
727 | 745 |
728 // Get the method's name and signature. | 746 // Get the method's name and signature. |
729 Symbol* name_sym = cpool->name_ref_at(index); | 747 Symbol* name_sym = cpool->name_ref_at(index); |
730 Symbol* sig_sym = cpool->signature_ref_at(index); | 748 Symbol* sig_sym = cpool->signature_ref_at(index); |
731 | 749 |
750 if (cpool->has_preresolution() | |
751 || (holder == ciEnv::MethodHandle_klass() && | |
752 methodOopDesc::is_method_handle_invoke_name(name_sym))) { | |
753 // Short-circuit lookups for JSR 292-related call sites. | |
754 // That is, do not rely only on name-based lookups, because they may fail | |
755 // if the names are not resolvable in the boot class loader (7056328). | |
756 switch (bc) { | |
757 case Bytecodes::_invokevirtual: | |
758 case Bytecodes::_invokeinterface: | |
759 case Bytecodes::_invokespecial: | |
760 case Bytecodes::_invokestatic: | |
761 { | |
762 methodOop m = constantPoolOopDesc::method_at_if_loaded(cpool, index, bc); | |
763 if (m != NULL) { | |
764 return get_object(m)->as_method(); | |
765 } | |
766 } | |
767 } | |
768 } | |
769 | |
732 if (holder_is_accessible) { // Our declared holder is loaded. | 770 if (holder_is_accessible) { // Our declared holder is loaded. |
733 instanceKlass* lookup = declared_holder->get_instanceKlass(); | 771 instanceKlass* lookup = declared_holder->get_instanceKlass(); |
734 methodOop m = lookup_method(accessor->get_instanceKlass(), lookup, name_sym, sig_sym, bc); | 772 methodOop m = lookup_method(accessor->get_instanceKlass(), lookup, name_sym, sig_sym, bc); |
773 if (m != NULL && | |
774 (bc == Bytecodes::_invokestatic | |
775 ? instanceKlass::cast(m->method_holder())->is_not_initialized() | |
776 : !instanceKlass::cast(m->method_holder())->is_loaded())) { | |
777 m = NULL; | |
778 } | |
735 if (m != NULL) { | 779 if (m != NULL) { |
736 // We found the method. | 780 // We found the method. |
737 return get_object(m)->as_method(); | 781 return get_object(m)->as_method(); |
738 } | 782 } |
739 } | 783 } |
1044 | 1088 |
1045 // ------------------------------------------------------------------ | 1089 // ------------------------------------------------------------------ |
1046 // ciEnv::find_system_klass | 1090 // ciEnv::find_system_klass |
1047 ciKlass* ciEnv::find_system_klass(ciSymbol* klass_name) { | 1091 ciKlass* ciEnv::find_system_klass(ciSymbol* klass_name) { |
1048 VM_ENTRY_MARK; | 1092 VM_ENTRY_MARK; |
1049 return get_klass_by_name_impl(NULL, klass_name, false); | 1093 return get_klass_by_name_impl(NULL, constantPoolHandle(), klass_name, false); |
1050 } | 1094 } |
1051 | 1095 |
1052 // ------------------------------------------------------------------ | 1096 // ------------------------------------------------------------------ |
1053 // ciEnv::comp_level | 1097 // ciEnv::comp_level |
1054 int ciEnv::comp_level() { | 1098 int ciEnv::comp_level() { |