Mercurial > hg > truffle
comparison src/share/vm/ci/ciEnv.cpp @ 3464:be4ca325525a
Merge.
author | Thomas Wuerthinger <thomas@wuerthinger.net> |
---|---|
date | Wed, 27 Jul 2011 17:32:44 -0700 |
parents | 0654ee04b214 81d815b05abb |
children | 22d11b3bc561 |
comparison
equal
deleted
inserted
replaced
3239:7c4b4daac19b | 3464:be4ca325525a |
---|---|
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 |
370 } | 371 } |
371 | 372 |
372 // ------------------------------------------------------------------ | 373 // ------------------------------------------------------------------ |
373 // ciEnv::get_klass_by_name_impl | 374 // ciEnv::get_klass_by_name_impl |
374 ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass, | 375 ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass, |
376 constantPoolHandle cpool, | |
375 ciSymbol* name, | 377 ciSymbol* name, |
376 bool require_local) { | 378 bool require_local) { |
377 ASSERT_IN_VM; | 379 ASSERT_IN_VM; |
378 EXCEPTION_CONTEXT; | 380 EXCEPTION_CONTEXT; |
379 | 381 |
385 // Call recursive to keep scope of strippedsym. | 387 // Call recursive to keep scope of strippedsym. |
386 TempNewSymbol strippedsym = SymbolTable::new_symbol(sym->as_utf8()+1, | 388 TempNewSymbol strippedsym = SymbolTable::new_symbol(sym->as_utf8()+1, |
387 sym->utf8_length()-2, | 389 sym->utf8_length()-2, |
388 KILL_COMPILE_ON_FATAL_(_unloaded_ciinstance_klass)); | 390 KILL_COMPILE_ON_FATAL_(_unloaded_ciinstance_klass)); |
389 ciSymbol* strippedname = get_symbol(strippedsym); | 391 ciSymbol* strippedname = get_symbol(strippedsym); |
390 return get_klass_by_name_impl(accessing_klass, strippedname, require_local); | 392 return get_klass_by_name_impl(accessing_klass, cpool, strippedname, require_local); |
391 } | 393 } |
392 | 394 |
393 // Check for prior unloaded klass. The SystemDictionary's answers | 395 // Check for prior unloaded klass. The SystemDictionary's answers |
394 // can vary over time but the compiler needs consistency. | 396 // can vary over time but the compiler needs consistency. |
395 ciKlass* unloaded_klass = check_get_unloaded_klass(accessing_klass, name); | 397 ciKlass* unloaded_klass = check_get_unloaded_klass(accessing_klass, name); |
442 KILL_COMPILE_ON_FATAL_(fail_type)); | 444 KILL_COMPILE_ON_FATAL_(fail_type)); |
443 | 445 |
444 // Get element ciKlass recursively. | 446 // Get element ciKlass recursively. |
445 ciKlass* elem_klass = | 447 ciKlass* elem_klass = |
446 get_klass_by_name_impl(accessing_klass, | 448 get_klass_by_name_impl(accessing_klass, |
449 cpool, | |
447 get_symbol(elem_sym), | 450 get_symbol(elem_sym), |
448 require_local); | 451 require_local); |
449 if (elem_klass != NULL && elem_klass->is_loaded()) { | 452 if (elem_klass != NULL && elem_klass->is_loaded()) { |
450 // Now make an array for it | 453 // Now make an array for it |
451 return ciObjArrayKlass::make_impl(elem_klass); | 454 return ciObjArrayKlass::make_impl(elem_klass); |
452 } | 455 } |
453 } | 456 } |
454 | 457 |
458 if (found_klass() == NULL && !cpool.is_null() && cpool->has_preresolution()) { | |
459 // Look inside the constant pool for pre-resolved class entries. | |
460 for (int i = cpool->length() - 1; i >= 1; i--) { | |
461 if (cpool->tag_at(i).is_klass()) { | |
462 klassOop kls = cpool->resolved_klass_at(i); | |
463 if (Klass::cast(kls)->name() == sym) { | |
464 found_klass = KlassHandle(THREAD, kls); | |
465 break; | |
466 } | |
467 } | |
468 } | |
469 } | |
470 | |
455 if (found_klass() != NULL) { | 471 if (found_klass() != NULL) { |
456 // Found it. Build a CI handle. | 472 // Found it. Build a CI handle. |
457 return get_object(found_klass())->as_klass(); | 473 return get_object(found_klass())->as_klass(); |
458 } | 474 } |
459 | 475 |
467 // ciEnv::get_klass_by_name | 483 // ciEnv::get_klass_by_name |
468 ciKlass* ciEnv::get_klass_by_name(ciKlass* accessing_klass, | 484 ciKlass* ciEnv::get_klass_by_name(ciKlass* accessing_klass, |
469 ciSymbol* klass_name, | 485 ciSymbol* klass_name, |
470 bool require_local) { | 486 bool require_local) { |
471 GUARDED_VM_ENTRY(return get_klass_by_name_impl(accessing_klass, | 487 GUARDED_VM_ENTRY(return get_klass_by_name_impl(accessing_klass, |
488 constantPoolHandle(), | |
472 klass_name, | 489 klass_name, |
473 require_local);) | 490 require_local);) |
474 } | 491 } |
475 | 492 |
476 // ------------------------------------------------------------------ | 493 // ------------------------------------------------------------------ |
507 } | 524 } |
508 | 525 |
509 if (klass.is_null()) { | 526 if (klass.is_null()) { |
510 // Not found in constant pool. Use the name to do the lookup. | 527 // Not found in constant pool. Use the name to do the lookup. |
511 ciKlass* k = get_klass_by_name_impl(accessor, | 528 ciKlass* k = get_klass_by_name_impl(accessor, |
529 cpool, | |
512 get_symbol(klass_name), | 530 get_symbol(klass_name), |
513 false); | 531 false); |
514 // Calculate accessibility the hard way. | 532 // Calculate accessibility the hard way. |
515 if (!k->is_loaded()) { | 533 if (!k->is_loaded()) { |
516 is_accessible = false; | 534 is_accessible = false; |
517 } else if (k->loader() != accessor->loader() && | 535 } else if (k->loader() != accessor->loader() && |
518 get_klass_by_name_impl(accessor, k->name(), true) == NULL) { | 536 get_klass_by_name_impl(accessor, cpool, k->name(), true) == NULL) { |
519 // Loaded only remotely. Not linked yet. | 537 // Loaded only remotely. Not linked yet. |
520 is_accessible = false; | 538 is_accessible = false; |
521 } else { | 539 } else { |
522 // Linked locally, and we must also check public/private, etc. | 540 // Linked locally, and we must also check public/private, etc. |
523 is_accessible = check_klass_accessibility(accessor, k->get_klassOop()); | 541 is_accessible = check_klass_accessibility(accessor, k->get_klassOop()); |
564 assert(index < 0, "only one kind of index at a time"); | 582 assert(index < 0, "only one kind of index at a time"); |
565 ConstantPoolCacheEntry* cpc_entry = cpool->cache()->entry_at(cache_index); | 583 ConstantPoolCacheEntry* cpc_entry = cpool->cache()->entry_at(cache_index); |
566 index = cpc_entry->constant_pool_index(); | 584 index = cpc_entry->constant_pool_index(); |
567 oop obj = cpc_entry->f1(); | 585 oop obj = cpc_entry->f1(); |
568 if (obj != NULL) { | 586 if (obj != NULL) { |
569 assert(obj->is_instance(), "must be an instance"); | 587 assert(obj->is_instance() || obj->is_array(), "must be a Java reference"); |
570 ciObject* ciobj = get_object(obj); | 588 ciObject* ciobj = get_object(obj); |
571 return ciConstant(T_OBJECT, ciobj); | 589 return ciConstant(T_OBJECT, ciobj); |
572 } | 590 } |
573 } | 591 } |
574 constantTag tag = cpool->tag_at(index); | 592 constantTag tag = cpool->tag_at(index); |
606 assert (klass->is_instance_klass() || klass->is_array_klass(), | 624 assert (klass->is_instance_klass() || klass->is_array_klass(), |
607 "must be an instance or array klass "); | 625 "must be an instance or array klass "); |
608 return ciConstant(T_OBJECT, klass->java_mirror()); | 626 return ciConstant(T_OBJECT, klass->java_mirror()); |
609 } else if (tag.is_object()) { | 627 } else if (tag.is_object()) { |
610 oop obj = cpool->object_at(index); | 628 oop obj = cpool->object_at(index); |
611 assert(obj->is_instance(), "must be an instance"); | 629 assert(obj->is_instance() || obj->is_array(), "must be a Java reference"); |
612 ciObject* ciobj = get_object(obj); | 630 ciObject* ciobj = get_object(obj); |
613 return ciConstant(T_OBJECT, ciobj); | 631 return ciConstant(T_OBJECT, ciobj); |
614 } else if (tag.is_method_type()) { | 632 } else if (tag.is_method_type()) { |
615 // must execute Java code to link this CP entry into cache[i].f1 | 633 // must execute Java code to link this CP entry into cache[i].f1 |
616 ciSymbol* signature = get_symbol(cpool->method_type_signature_at(index)); | 634 ciSymbol* signature = get_symbol(cpool->method_type_signature_at(index)); |
728 | 746 |
729 // Get the method's name and signature. | 747 // Get the method's name and signature. |
730 Symbol* name_sym = cpool->name_ref_at(index); | 748 Symbol* name_sym = cpool->name_ref_at(index); |
731 Symbol* sig_sym = cpool->signature_ref_at(index); | 749 Symbol* sig_sym = cpool->signature_ref_at(index); |
732 | 750 |
751 if (cpool->has_preresolution() | |
752 || (holder == ciEnv::MethodHandle_klass() && | |
753 methodOopDesc::is_method_handle_invoke_name(name_sym))) { | |
754 // Short-circuit lookups for JSR 292-related call sites. | |
755 // That is, do not rely only on name-based lookups, because they may fail | |
756 // if the names are not resolvable in the boot class loader (7056328). | |
757 switch (bc) { | |
758 case Bytecodes::_invokevirtual: | |
759 case Bytecodes::_invokeinterface: | |
760 case Bytecodes::_invokespecial: | |
761 case Bytecodes::_invokestatic: | |
762 { | |
763 methodOop m = constantPoolOopDesc::method_at_if_loaded(cpool, index, bc); | |
764 if (m != NULL) { | |
765 return get_object(m)->as_method(); | |
766 } | |
767 } | |
768 } | |
769 } | |
770 | |
733 if (holder_is_accessible) { // Our declared holder is loaded. | 771 if (holder_is_accessible) { // Our declared holder is loaded. |
734 instanceKlass* lookup = declared_holder->get_instanceKlass(); | 772 instanceKlass* lookup = declared_holder->get_instanceKlass(); |
735 methodOop m = lookup_method(accessor->get_instanceKlass(), lookup, name_sym, sig_sym, bc); | 773 methodOop m = lookup_method(accessor->get_instanceKlass(), lookup, name_sym, sig_sym, bc); |
774 if (m != NULL && | |
775 (bc == Bytecodes::_invokestatic | |
776 ? instanceKlass::cast(m->method_holder())->is_not_initialized() | |
777 : !instanceKlass::cast(m->method_holder())->is_loaded())) { | |
778 m = NULL; | |
779 } | |
736 if (m != NULL) { | 780 if (m != NULL) { |
737 // We found the method. | 781 // We found the method. |
738 return get_object(m)->as_method(); | 782 return get_object(m)->as_method(); |
739 } | 783 } |
740 } | 784 } |
755 int index, Bytecodes::Code bc) { | 799 int index, Bytecodes::Code bc) { |
756 // Compare the following logic with InterpreterRuntime::resolve_invokedynamic. | 800 // Compare the following logic with InterpreterRuntime::resolve_invokedynamic. |
757 assert(bc == Bytecodes::_invokedynamic, "must be invokedynamic"); | 801 assert(bc == Bytecodes::_invokedynamic, "must be invokedynamic"); |
758 | 802 |
759 bool is_resolved = cpool->cache()->main_entry_at(index)->is_resolved(bc); | 803 bool is_resolved = cpool->cache()->main_entry_at(index)->is_resolved(bc); |
760 if (is_resolved && (oop) cpool->cache()->secondary_entry_at(index)->f1() == NULL) | 804 if (is_resolved && cpool->cache()->secondary_entry_at(index)->is_f1_null()) |
761 // FIXME: code generation could allow for null (unlinked) call site | 805 // FIXME: code generation could allow for null (unlinked) call site |
762 is_resolved = false; | 806 is_resolved = false; |
763 | 807 |
764 // Call site might not be resolved yet. We could create a real invoker method from the | 808 // Call site might not be resolved yet. We could create a real invoker method from the |
765 // compiler, but it is simpler to stop the code path here with an unlinked method. | 809 // compiler, but it is simpler to stop the code path here with an unlinked method. |
769 return get_unloaded_method(mh_klass, ciSymbol::invokeExact_name(), sig_sym); | 813 return get_unloaded_method(mh_klass, ciSymbol::invokeExact_name(), sig_sym); |
770 } | 814 } |
771 | 815 |
772 // Get the invoker methodOop from the constant pool. | 816 // Get the invoker methodOop from the constant pool. |
773 oop f1_value = cpool->cache()->main_entry_at(index)->f1(); | 817 oop f1_value = cpool->cache()->main_entry_at(index)->f1(); |
774 methodOop signature_invoker = methodOop(f1_value); | 818 methodOop signature_invoker = (methodOop) f1_value; |
775 assert(signature_invoker != NULL && signature_invoker->is_method() && signature_invoker->is_method_handle_invoke(), | 819 assert(signature_invoker != NULL && signature_invoker->is_method() && signature_invoker->is_method_handle_invoke(), |
776 "correct result from LinkResolver::resolve_invokedynamic"); | 820 "correct result from LinkResolver::resolve_invokedynamic"); |
777 | 821 |
778 return get_object(signature_invoker)->as_method(); | 822 return get_object(signature_invoker)->as_method(); |
779 } | 823 } |
1045 | 1089 |
1046 // ------------------------------------------------------------------ | 1090 // ------------------------------------------------------------------ |
1047 // ciEnv::find_system_klass | 1091 // ciEnv::find_system_klass |
1048 ciKlass* ciEnv::find_system_klass(ciSymbol* klass_name) { | 1092 ciKlass* ciEnv::find_system_klass(ciSymbol* klass_name) { |
1049 VM_ENTRY_MARK; | 1093 VM_ENTRY_MARK; |
1050 return get_klass_by_name_impl(NULL, klass_name, false); | 1094 return get_klass_by_name_impl(NULL, constantPoolHandle(), klass_name, false); |
1051 } | 1095 } |
1052 | 1096 |
1053 // ------------------------------------------------------------------ | 1097 // ------------------------------------------------------------------ |
1054 // ciEnv::comp_level | 1098 // ciEnv::comp_level |
1055 int ciEnv::comp_level() { | 1099 int ciEnv::comp_level() { |