diff -r 97a23be06f4e -r 5ad4627e792a hotspot/src/share/vm/ci/ciEnv.cpp --- a/hotspot/src/share/vm/ci/ciEnv.cpp Mon Aug 27 15:17:17 2012 -0700 +++ b/hotspot/src/share/vm/ci/ciEnv.cpp Tue Aug 28 15:24:39 2012 -0700 @@ -738,91 +738,81 @@ ciMethod* ciEnv::get_method_by_index_impl(constantPoolHandle cpool, int index, Bytecodes::Code bc, ciInstanceKlass* accessor) { - int holder_index = cpool->klass_ref_index_at(index); - bool holder_is_accessible; - ciKlass* holder = get_klass_by_index_impl(cpool, holder_index, holder_is_accessible, accessor); - ciInstanceKlass* declared_holder = get_instance_klass_for_declared_method_holder(holder); - - // Get the method's name and signature. - Symbol* name_sym = cpool->name_ref_at(index); - Symbol* sig_sym = cpool->signature_ref_at(index); - - if (cpool->has_preresolution() - || (holder == ciEnv::MethodHandle_klass() && - MethodHandles::is_signature_polymorphic_name(holder->get_klassOop(), 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: - { - oop appendix_oop = NULL; - methodOop m = constantPoolOopDesc::method_at_if_loaded(cpool, index); - if (m != NULL) { - return get_object(m)->as_method(); - } - } - break; - } - } + if (bc == Bytecodes::_invokedynamic) { + ConstantPoolCacheEntry* secondary_entry = cpool->cache()->secondary_entry_at(index); + const bool is_resolved = !secondary_entry->is_f1_null(); + // FIXME: code generation could allow for null (unlinked) call site + // The call site could be made patchable as follows: + // Load the appendix argument from the constant pool. + // Test the appendix argument and jump to a known deopt routine if it is null. + // Jump through a patchable call site, which is initially a deopt routine. + // Patch the call site to the nmethod entry point of the static compiled lambda form. + // As with other two-component call sites, both values must be independently verified. - 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 (is_resolved) { + // Get the invoker methodOop and the extra argument from the constant pool. + methodOop adapter = secondary_entry->f2_as_vfinal_method(); + return get_object(adapter)->as_method(); } - if (m != NULL) { - // We found the method. - return get_object(m)->as_method(); - } - } - - // Either the declared holder was not loaded, or the method could - // not be found. Create a dummy ciMethod to represent the failed - // lookup. - ciSymbol* name = get_symbol(name_sym); - ciSymbol* signature = get_symbol(sig_sym); - return get_unloaded_method(declared_holder, name, signature, accessor); -} - -// ------------------------------------------------------------------ -// ciEnv::get_fake_invokedynamic_method_impl -ciMethod* ciEnv::get_fake_invokedynamic_method_impl(constantPoolHandle cpool, - int index, Bytecodes::Code bc, - ciInstanceKlass* accessor) { - // Compare the following logic with InterpreterRuntime::resolve_invokedynamic. - assert(bc == Bytecodes::_invokedynamic, "must be invokedynamic"); - - ConstantPoolCacheEntry* secondary_entry = cpool->cache()->secondary_entry_at(index); - bool is_resolved = !secondary_entry->is_f1_null(); - // FIXME: code generation could allow for null (unlinked) call site - // The call site could be made patchable as follows: - // Load the appendix argument from the constant pool. - // Test the appendix argument and jump to a known deopt routine if it is null. - // Jump through a patchable call site, which is initially a deopt routine. - // Patch the call site to the nmethod entry point of the static compiled lambda form. - // As with other two-component call sites, both values must be independently verified. - - // Call site might not be resolved yet. - // Stop the code path here with an unlinked method. - if (!is_resolved) { + // Fake a method that is equivalent to a declared method. ciInstanceKlass* holder = get_object(SystemDictionary::MethodHandle_klass())->as_instance_klass(); ciSymbol* name = ciSymbol::invokeBasic_name(); ciSymbol* signature = get_symbol(cpool->signature_ref_at(index)); return get_unloaded_method(holder, name, signature, accessor); - } + } else { + const int holder_index = cpool->klass_ref_index_at(index); + bool holder_is_accessible; + ciKlass* holder = get_klass_by_index_impl(cpool, holder_index, holder_is_accessible, accessor); + ciInstanceKlass* declared_holder = get_instance_klass_for_declared_method_holder(holder); + + // Get the method's name and signature. + Symbol* name_sym = cpool->name_ref_at(index); + Symbol* sig_sym = cpool->signature_ref_at(index); - // Get the invoker methodOop and the extra argument from the constant pool. - methodOop adapter = secondary_entry->f2_as_vfinal_method(); - return get_object(adapter)->as_method(); + if (cpool->has_preresolution() + || (holder == ciEnv::MethodHandle_klass() && + MethodHandles::is_signature_polymorphic_name(holder->get_klassOop(), 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); + if (m != NULL) { + return get_object(m)->as_method(); + } + } + break; + } + } + + 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(); + } + } + + // Either the declared holder was not loaded, or the method could + // not be found. Create a dummy ciMethod to represent the failed + // lookup. + ciSymbol* name = get_symbol(name_sym); + ciSymbol* signature = get_symbol(sig_sym); + return get_unloaded_method(declared_holder, name, signature, accessor); + } } @@ -853,11 +843,7 @@ ciMethod* ciEnv::get_method_by_index(constantPoolHandle cpool, int index, Bytecodes::Code bc, ciInstanceKlass* accessor) { - if (bc == Bytecodes::_invokedynamic) { - GUARDED_VM_ENTRY(return get_fake_invokedynamic_method_impl(cpool, index, bc, accessor);) - } else { - GUARDED_VM_ENTRY(return get_method_by_index_impl( cpool, index, bc, accessor);) - } + GUARDED_VM_ENTRY(return get_method_by_index_impl(cpool, index, bc, accessor);) }