diff -r 43d4a6542551 -r d84de97ad847 hotspot/src/share/vm/ci/ciEnv.cpp --- a/hotspot/src/share/vm/ci/ciEnv.cpp Wed Jun 22 14:45:37 2011 -0700 +++ b/hotspot/src/share/vm/ci/ciEnv.cpp Thu Jun 23 17:14:06 2011 -0700 @@ -50,6 +50,7 @@ #include "oops/oop.inline.hpp" #include "oops/oop.inline2.hpp" #include "prims/jvmtiExport.hpp" +#include "prims/methodHandleWalk.hpp" #include "runtime/init.hpp" #include "runtime/reflection.hpp" #include "runtime/sharedRuntime.hpp" @@ -371,6 +372,7 @@ // ------------------------------------------------------------------ // ciEnv::get_klass_by_name_impl ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass, + constantPoolHandle cpool, ciSymbol* name, bool require_local) { ASSERT_IN_VM; @@ -386,7 +388,7 @@ sym->utf8_length()-2, KILL_COMPILE_ON_FATAL_(_unloaded_ciinstance_klass)); ciSymbol* strippedname = get_symbol(strippedsym); - return get_klass_by_name_impl(accessing_klass, strippedname, require_local); + return get_klass_by_name_impl(accessing_klass, cpool, strippedname, require_local); } // Check for prior unloaded klass. The SystemDictionary's answers @@ -443,6 +445,7 @@ // Get element ciKlass recursively. ciKlass* elem_klass = get_klass_by_name_impl(accessing_klass, + cpool, get_symbol(elem_sym), require_local); if (elem_klass != NULL && elem_klass->is_loaded()) { @@ -451,6 +454,19 @@ } } + if (found_klass() == NULL && !cpool.is_null() && cpool->has_preresolution()) { + // Look inside the constant pool for pre-resolved class entries. + for (int i = cpool->length() - 1; i >= 1; i--) { + if (cpool->tag_at(i).is_klass()) { + klassOop kls = cpool->resolved_klass_at(i); + if (Klass::cast(kls)->name() == sym) { + found_klass = KlassHandle(THREAD, kls); + break; + } + } + } + } + if (found_klass() != NULL) { // Found it. Build a CI handle. return get_object(found_klass())->as_klass(); @@ -468,6 +484,7 @@ ciSymbol* klass_name, bool require_local) { GUARDED_VM_ENTRY(return get_klass_by_name_impl(accessing_klass, + constantPoolHandle(), klass_name, require_local);) } @@ -508,13 +525,14 @@ if (klass.is_null()) { // Not found in constant pool. Use the name to do the lookup. ciKlass* k = get_klass_by_name_impl(accessor, + cpool, get_symbol(klass_name), false); // Calculate accessibility the hard way. if (!k->is_loaded()) { is_accessible = false; } else if (k->loader() != accessor->loader() && - get_klass_by_name_impl(accessor, k->name(), true) == NULL) { + get_klass_by_name_impl(accessor, cpool, k->name(), true) == NULL) { // Loaded only remotely. Not linked yet. is_accessible = false; } else { @@ -565,7 +583,7 @@ index = cpc_entry->constant_pool_index(); oop obj = cpc_entry->f1(); if (obj != NULL) { - assert(obj->is_instance(), "must be an instance"); + assert(obj->is_instance() || obj->is_array(), "must be a Java reference"); ciObject* ciobj = get_object(obj); return ciConstant(T_OBJECT, ciobj); } @@ -607,7 +625,7 @@ return ciConstant(T_OBJECT, klass->java_mirror()); } else if (tag.is_object()) { oop obj = cpool->object_at(index); - assert(obj->is_instance(), "must be an instance"); + assert(obj->is_instance() || obj->is_array(), "must be a Java reference"); ciObject* ciobj = get_object(obj); return ciConstant(T_OBJECT, ciobj); } else if (tag.is_method_type()) { @@ -729,9 +747,35 @@ Symbol* name_sym = cpool->name_ref_at(index); Symbol* sig_sym = cpool->signature_ref_at(index); + if (cpool->has_preresolution() + || (holder == ciEnv::MethodHandle_klass() && + methodOopDesc::is_method_handle_invoke_name(name_sym))) { + // Short-circuit lookups for JSR 292-related call sites. + // That is, do not rely only on name-based lookups, because they may fail + // if the names are not resolvable in the boot class loader (7056328). + switch (bc) { + case Bytecodes::_invokevirtual: + case Bytecodes::_invokeinterface: + case Bytecodes::_invokespecial: + case Bytecodes::_invokestatic: + { + methodOop m = constantPoolOopDesc::method_at_if_loaded(cpool, index, bc); + if (m != NULL) { + return get_object(m)->as_method(); + } + } + } + } + if (holder_is_accessible) { // Our declared holder is loaded. instanceKlass* lookup = declared_holder->get_instanceKlass(); methodOop m = lookup_method(accessor->get_instanceKlass(), lookup, name_sym, sig_sym, bc); + if (m != NULL && + (bc == Bytecodes::_invokestatic + ? instanceKlass::cast(m->method_holder())->is_not_initialized() + : !instanceKlass::cast(m->method_holder())->is_loaded())) { + m = NULL; + } if (m != NULL) { // We found the method. return get_object(m)->as_method(); @@ -1046,7 +1090,7 @@ // ciEnv::find_system_klass ciKlass* ciEnv::find_system_klass(ciSymbol* klass_name) { VM_ENTRY_MARK; - return get_klass_by_name_impl(NULL, klass_name, false); + return get_klass_by_name_impl(NULL, constantPoolHandle(), klass_name, false); } // ------------------------------------------------------------------