Mercurial > hg > truffle
diff src/share/vm/interpreter/linkResolver.cpp @ 6948:e522a00b91aa
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/ after NPG - C++ build works
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Mon, 12 Nov 2012 23:14:12 +0100 |
parents | 18fb7da42534 |
children | 070d523b96a7 |
line wrap: on
line diff
--- a/src/share/vm/interpreter/linkResolver.cpp Mon Nov 12 18:11:17 2012 +0100 +++ b/src/share/vm/interpreter/linkResolver.cpp Mon Nov 12 23:14:12 2012 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "classfile/defaultMethods.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "compiler/compileBroker.hpp" @@ -75,7 +76,7 @@ void CallInfo::set_static(KlassHandle resolved_klass, methodHandle resolved_method, TRAPS) { - int vtable_index = methodOopDesc::nonvirtual_vtable_index; + int vtable_index = Method::nonvirtual_vtable_index; set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, vtable_index, CHECK); } @@ -85,7 +86,7 @@ // comes from java/lang/Object, it can be the subject of a virtual call, so // we should pick the vtable index from the resolved method. // Other than that case, there is no valid vtable index to specify. - int vtable_index = methodOopDesc::invalid_vtable_index; + int vtable_index = Method::invalid_vtable_index; if (resolved_method->method_holder() == SystemDictionary::Object_klass()) { assert(resolved_method->vtable_index() == selected_method->vtable_index(), "sanity check"); vtable_index = resolved_method->vtable_index(); @@ -94,23 +95,24 @@ } void CallInfo::set_virtual(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) { - assert(vtable_index >= 0 || vtable_index == methodOopDesc::nonvirtual_vtable_index, "valid index"); + assert(vtable_index >= 0 || vtable_index == Method::nonvirtual_vtable_index, "valid index"); set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK); assert(!resolved_method->is_compiled_lambda_form(), "these must be handled via an invokehandle call"); } -void CallInfo::set_handle(methodHandle resolved_method, Handle resolved_appendix, TRAPS) { +void CallInfo::set_handle(methodHandle resolved_method, Handle resolved_appendix, Handle resolved_method_type, TRAPS) { if (resolved_method.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "resolved method is null"); } - KlassHandle resolved_klass = SystemDictionaryHandles::MethodHandle_klass(); + KlassHandle resolved_klass = SystemDictionary::MethodHandle_klass(); assert(resolved_method->intrinsic_id() == vmIntrinsics::_invokeBasic || resolved_method->is_compiled_lambda_form(), "linkMethod must return one of these"); - int vtable_index = methodOopDesc::nonvirtual_vtable_index; + int vtable_index = Method::nonvirtual_vtable_index; assert(resolved_method->vtable_index() == vtable_index, ""); set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, vtable_index, CHECK); - _resolved_appendix = resolved_appendix; + _resolved_appendix = resolved_appendix; + _resolved_method_type = resolved_method_type; } void CallInfo::set_common(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) { @@ -131,7 +133,7 @@ // don't force compilation, resolve was on behalf of compiler return; } - if (instanceKlass::cast(selected_method->method_holder())->is_not_initialized()) { + if (selected_method->method_holder()->is_not_initialized()) { // 'is_not_initialized' means not only '!is_initialized', but also that // initialization has not been started yet ('!being_initialized') // Do not force compilation of methods in uninitialized classes. @@ -152,8 +154,8 @@ // Klass resolution void LinkResolver::check_klass_accessability(KlassHandle ref_klass, KlassHandle sel_klass, TRAPS) { - if (!Reflection::verify_class_access(ref_klass->as_klassOop(), - sel_klass->as_klassOop(), + if (!Reflection::verify_class_access(ref_klass(), + sel_klass(), true)) { ResourceMark rm(THREAD); Exceptions::fthrow( @@ -168,13 +170,13 @@ } void LinkResolver::resolve_klass(KlassHandle& result, constantPoolHandle pool, int index, TRAPS) { - klassOop result_oop = pool->klass_ref_at(index, CHECK); + Klass* result_oop = pool->klass_ref_at(index, CHECK); result = KlassHandle(THREAD, result_oop); } void LinkResolver::resolve_klass_no_update(KlassHandle& result, constantPoolHandle pool, int index, TRAPS) { - klassOop result_oop = - constantPoolOopDesc::klass_ref_at_if_loaded_check(pool, index, CHECK); + Klass* result_oop = + ConstantPool::klass_ref_at_if_loaded_check(pool, index, CHECK); result = KlassHandle(THREAD, result_oop); } @@ -185,7 +187,7 @@ // According to JVM spec. $5.4.3c & $5.4.3d void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { - methodOop result_oop = klass->uncached_lookup_method(name, signature); + Method* result_oop = klass->uncached_lookup_method(name, signature); if (EnableInvokeDynamic && result_oop != NULL) { vmIntrinsics::ID iid = result_oop->intrinsic_id(); if (MethodHandles::is_signature_polymorphic(iid)) { @@ -198,7 +200,7 @@ // returns first instance method void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { - methodOop result_oop = klass->uncached_lookup_method(name, signature); + Method* result_oop = klass->uncached_lookup_method(name, signature); result = methodHandle(THREAD, result_oop); while (!result.is_null() && result->is_static()) { klass = KlassHandle(THREAD, Klass::cast(result->method_holder())->super()); @@ -209,19 +211,20 @@ int LinkResolver::vtable_index_of_miranda_method(KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { ResourceMark rm(THREAD); - klassVtable *vt = instanceKlass::cast(klass())->vtable(); + klassVtable *vt = InstanceKlass::cast(klass())->vtable(); return vt->index_of_miranda(name, signature); } void LinkResolver::lookup_method_in_interfaces(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { - instanceKlass *ik = instanceKlass::cast(klass()); + InstanceKlass *ik = InstanceKlass::cast(klass()); result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature)); } void LinkResolver::lookup_polymorphic_method(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* full_signature, KlassHandle current_klass, - Handle* appendix_result_or_null, + Handle *appendix_result_or_null, + Handle *method_type_result, TRAPS) { vmIntrinsics::ID iid = MethodHandles::signature_polymorphic_name_id(name); if (TraceMethodHandles) { @@ -264,8 +267,8 @@ // We will ask Java code to spin an adapter method for it. if (!MethodHandles::enabled()) { // Make sure the Java part of the runtime has been booted up. - klassOop natives = SystemDictionary::MethodHandleNatives_klass(); - if (natives == NULL || instanceKlass::cast(natives)->is_not_initialized()) { + Klass* natives = SystemDictionary::MethodHandleNatives_klass(); + if (natives == NULL || InstanceKlass::cast(natives)->is_not_initialized()) { SystemDictionary::resolve_or_fail(vmSymbols::java_lang_invoke_MethodHandleNatives(), Handle(), Handle(), @@ -275,10 +278,12 @@ } Handle appendix; + Handle method_type; result = SystemDictionary::find_method_handle_invoker(name, full_signature, current_klass, &appendix, + &method_type, CHECK); if (TraceMethodHandles) { tty->print("lookup_polymorphic_method => (via Java) "); @@ -307,6 +312,7 @@ assert(appendix_result_or_null != NULL, ""); (*appendix_result_or_null) = appendix; + (*method_type_result) = method_type; return; } } @@ -340,9 +346,9 @@ } // assert(extra_arg_result_or_null != NULL, "must be able to return extra argument"); - if (!Reflection::verify_field_access(ref_klass->as_klassOop(), - resolved_klass->as_klassOop(), - sel_klass->as_klassOop(), + if (!Reflection::verify_field_access(ref_klass(), + resolved_klass(), + sel_klass(), flags, true)) { ResourceMark rm(THREAD); @@ -364,7 +370,7 @@ // resolve klass if (code == Bytecodes::_invokedynamic) { - resolved_klass = SystemDictionaryHandles::MethodHandle_klass(); + resolved_klass = SystemDictionary::MethodHandle_klass(); Symbol* method_name = vmSymbols::invoke_name(); Symbol* method_signature = pool->signature_ref_at(index); KlassHandle current_klass(THREAD, pool->pool_holder()); @@ -381,7 +387,7 @@ if (pool->has_preresolution() || (resolved_klass() == SystemDictionary::MethodHandle_klass() && MethodHandles::is_signature_polymorphic_name(resolved_klass(), method_name))) { - methodOop result_oop = constantPoolOopDesc::method_at_if_loaded(pool, index); + Method* result_oop = ConstantPool::method_at_if_loaded(pool, index); if (result_oop != NULL) { resolved_method = methodHandle(THREAD, result_oop); return; @@ -399,27 +405,19 @@ Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) { - // 1. check if klass is not interface - if (resolved_klass->is_interface()) { - ResourceMark rm(THREAD); - char buf[200]; - jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected", Klass::cast(resolved_klass())->external_name()); - THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); - } - Handle nested_exception; - // 2. lookup method in resolved klass and its super klasses + // 1. lookup method in resolved klass and its super klasses lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK); if (resolved_method.is_null()) { // not found in the class hierarchy - // 3. lookup method in all the interfaces implemented by the resolved klass + // 2. lookup method in all the interfaces implemented by the resolved klass lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK); if (resolved_method.is_null()) { // JSR 292: see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc lookup_polymorphic_method(resolved_method, resolved_klass, method_name, method_signature, - current_klass, (Handle*)NULL, THREAD); + current_klass, (Handle*)NULL, (Handle*)NULL, THREAD); if (HAS_PENDING_EXCEPTION) { nested_exception = Handle(THREAD, PENDING_EXCEPTION); CLEAR_PENDING_EXCEPTION; @@ -427,21 +425,30 @@ } if (resolved_method.is_null()) { - // 4. method lookup failed + // 3. method lookup failed ResourceMark rm(THREAD); THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(), - methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), + Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()), method_name, method_signature), nested_exception); } } + // 4. check if klass is not interface + if (resolved_klass->is_interface() && resolved_method->is_abstract()) { + ResourceMark rm(THREAD); + char buf[200]; + jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected", + resolved_klass()->external_name()); + THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); + } + // 5. check if method is concrete if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) { ResourceMark rm(THREAD); THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), - methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), + Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()), method_name, method_signature)); } @@ -458,8 +465,8 @@ CHECK); // check loader constraints - Handle loader (THREAD, instanceKlass::cast(current_klass())->class_loader()); - Handle class_loader (THREAD, instanceKlass::cast(resolved_method->method_holder())->class_loader()); + Handle loader (THREAD, InstanceKlass::cast(current_klass())->class_loader()); + Handle class_loader (THREAD, resolved_method->method_holder()->class_loader()); { ResourceMark rm(THREAD); char* failed_type_name = @@ -470,11 +477,11 @@ " \"%s\" the class loader (instance of %s) of the current class, %s," " and the class loader (instance of %s) for resolved class, %s, have" " different Class objects for the type %s used in the signature"; - char* sig = methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name,method_signature); + char* sig = Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name,method_signature); const char* loader1 = SystemDictionary::loader_name(loader()); - char* current = instanceKlass::cast(current_klass())->name()->as_C_string(); + char* current = InstanceKlass::cast(current_klass())->name()->as_C_string(); const char* loader2 = SystemDictionary::loader_name(class_loader()); - char* resolved = instanceKlass::cast(resolved_klass())->name()->as_C_string(); + char* resolved = InstanceKlass::cast(resolved_klass())->name()->as_C_string(); size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) + strlen(current) + strlen(loader2) + strlen(resolved) + strlen(failed_type_name); @@ -512,7 +519,7 @@ // no method found ResourceMark rm(THREAD); THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(), - methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), + Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()), method_name, method_signature)); } @@ -520,8 +527,8 @@ if (check_access) { HandleMark hm(THREAD); - Handle loader (THREAD, instanceKlass::cast(current_klass())->class_loader()); - Handle class_loader (THREAD, instanceKlass::cast(resolved_method->method_holder())->class_loader()); + Handle loader (THREAD, InstanceKlass::cast(current_klass())->class_loader()); + Handle class_loader (THREAD, resolved_method->method_holder()->class_loader()); { ResourceMark rm(THREAD); char* failed_type_name = @@ -533,11 +540,11 @@ "current class, %s, and the class loader (instance of %s) for " "resolved class, %s, have different Class objects for the type %s " "used in the signature"; - char* sig = methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name,method_signature); + char* sig = Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name,method_signature); const char* loader1 = SystemDictionary::loader_name(loader()); - char* current = instanceKlass::cast(current_klass())->name()->as_C_string(); + char* current = InstanceKlass::cast(current_klass())->name()->as_C_string(); const char* loader2 = SystemDictionary::loader_name(class_loader()); - char* resolved = instanceKlass::cast(resolved_klass())->name()->as_C_string(); + char* resolved = InstanceKlass::cast(resolved_klass())->name()->as_C_string(); size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) + strlen(current) + strlen(loader2) + strlen(resolved) + strlen(failed_type_name); @@ -558,9 +565,9 @@ KlassHandle sel_klass, fieldDescriptor& fd, TRAPS) { - if (!Reflection::verify_field_access(ref_klass->as_klassOop(), - resolved_klass->as_klassOop(), - sel_klass->as_klassOop(), + if (!Reflection::verify_field_access(ref_klass(), + resolved_klass(), + sel_klass(), fd.access_flags(), true)) { ResourceMark rm(THREAD); @@ -605,7 +612,7 @@ // Resolve instance field fieldDescriptor fd; // find_field initializes fd if found - KlassHandle sel_klass(THREAD, instanceKlass::cast(resolved_klass())->find_field(field, sig, &fd)); + KlassHandle sel_klass(THREAD, InstanceKlass::cast(resolved_klass())->find_field(field, sig, &fd)); // check if field exists; i.e., if a klass containing the field def has been selected if (sel_klass.is_null()){ ResourceMark rm(THREAD); @@ -641,8 +648,8 @@ { HandleMark hm(THREAD); - Handle ref_loader (THREAD, instanceKlass::cast(ref_klass())->class_loader()); - Handle sel_loader (THREAD, instanceKlass::cast(sel_klass())->class_loader()); + Handle ref_loader (THREAD, InstanceKlass::cast(ref_klass())->class_loader()); + Handle sel_loader (THREAD, InstanceKlass::cast(sel_klass())->class_loader()); Symbol* signature_ref = pool->signature_ref_at(index); { ResourceMark rm(THREAD); @@ -658,7 +665,7 @@ "type, %s, have different Class objects for that type"; char* field_name = field->as_C_string(); const char* loader1 = SystemDictionary::loader_name(ref_loader()); - char* sel = instanceKlass::cast(sel_klass())->name()->as_C_string(); + char* sel = InstanceKlass::cast(sel_klass())->name()->as_C_string(); const char* loader2 = SystemDictionary::loader_name(sel_loader()); size_t buflen = strlen(msg) + strlen(field_name) + strlen(loader1) + strlen(sel) + strlen(loader2) + strlen(failed_type_name); @@ -718,7 +725,7 @@ if (!resolved_method->is_static()) { ResourceMark rm(THREAD); char buf[200]; - jio_snprintf(buf, sizeof(buf), "Expected static method %s", methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), + jio_snprintf(buf, sizeof(buf), "Expected static method %s", Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()), resolved_method->name(), resolved_method->signature())); THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); @@ -738,6 +745,27 @@ Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) { + if (resolved_klass->is_interface() && current_klass() != NULL) { + // If the target class is a direct interface, treat this as a "super" + // default call. + // + // If the current method is an overpass that happens to call a direct + // super-interface's method, then we'll end up rerunning the default method + // analysis even though we don't need to, but that's ok since it will end + // up with the same answer. + InstanceKlass* ik = InstanceKlass::cast(current_klass()); + Array<Klass*>* interfaces = ik->local_interfaces(); + int num_interfaces = interfaces->length(); + for (int index = 0; index < num_interfaces; index++) { + if (interfaces->at(index) == resolved_klass()) { + Method* method = DefaultMethods::find_super_default(current_klass(), + resolved_klass(), method_name, method_signature, CHECK); + resolved_method = methodHandle(THREAD, method); + return; + } + } + } + resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); // check if method name is <init>, that it is found in same klass as static type @@ -761,7 +789,7 @@ char buf[200]; jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", - methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), + Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()), resolved_method->name(), resolved_method->signature())); THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); @@ -779,11 +807,17 @@ { KlassHandle method_klass = KlassHandle(THREAD, resolved_method->method_holder()); - if (check_access && + const bool direct_calling_default_method = + resolved_klass() != NULL && resolved_method() != NULL && + resolved_klass->is_interface() && !resolved_method->is_abstract(); + + if (!direct_calling_default_method && + check_access && // a) check if ACC_SUPER flag is set for the current class current_klass->is_super() && // b) check if the method class is a superclass of the current class (superclass relation is not reflexive!) - current_klass->is_subtype_of(method_klass()) && current_klass() != method_klass() && + current_klass->is_subtype_of(method_klass()) && + current_klass() != method_klass() && // c) check if the method is not <init> resolved_method->name() != vmSymbols::object_initializer_name()) { // Lookup super method @@ -795,7 +829,7 @@ if (sel_method.is_null()) { ResourceMark rm(THREAD); THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), - methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), + Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()), resolved_method->name(), resolved_method->signature())); } @@ -806,7 +840,7 @@ if (sel_method->is_static()) { ResourceMark rm(THREAD); char buf[200]; - jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), + jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()), resolved_method->name(), resolved_method->signature())); THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); @@ -816,7 +850,7 @@ if (sel_method->is_abstract()) { ResourceMark rm(THREAD); THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), - methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), + Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()), sel_method->name(), sel_method->signature())); } @@ -847,7 +881,7 @@ if (resolved_method->is_static()) { ResourceMark rm(THREAD); char buf[200]; - jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), + jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()), resolved_method->name(), resolved_method->signature())); THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); @@ -864,7 +898,7 @@ TRAPS) { // setup default return values - int vtable_index = methodOopDesc::invalid_vtable_index; + int vtable_index = Method::invalid_vtable_index; methodHandle selected_method; assert(recv.is_null() || recv->is_oop(), "receiver is not an oop"); @@ -874,23 +908,23 @@ THROW(vmSymbols::java_lang_NullPointerException()); } - // Virtual methods cannot be resolved before its klass has been linked, for otherwise the methodOop's + // Virtual methods cannot be resolved before its klass has been linked, for otherwise the Method*'s // has not been rewritten, and the vtable initialized. - assert(instanceKlass::cast(resolved_method->method_holder())->is_linked(), "must be linked"); + assert(resolved_method->method_holder()->is_linked(), "must be linked"); - // Virtual methods cannot be resolved before its klass has been linked, for otherwise the methodOop's + // Virtual methods cannot be resolved before its klass has been linked, for otherwise the Method*'s // has not been rewritten, and the vtable initialized. Make sure to do this after the nullcheck, since // a missing receiver might result in a bogus lookup. - assert(instanceKlass::cast(resolved_method->method_holder())->is_linked(), "must be linked"); + assert(resolved_method->method_holder()->is_linked(), "must be linked"); // do lookup based on receiver klass using the vtable index - if (resolved_method->method_holder()->klass_part()->is_interface()) { // miranda method + if (resolved_method->method_holder()->is_interface()) { // miranda method vtable_index = vtable_index_of_miranda_method(resolved_klass, resolved_method->name(), resolved_method->signature(), CHECK); assert(vtable_index >= 0 , "we should have valid vtable index at this point"); - instanceKlass* inst = instanceKlass::cast(recv_klass()); + InstanceKlass* inst = InstanceKlass::cast(recv_klass()); selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index)); } else { // at this point we are sure that resolved_method is virtual and not @@ -901,13 +935,13 @@ // unless they override an existing method. // If we do get a negative, it means the resolved method is the the selected // method, and it can never be changed by an override. - if (vtable_index == methodOopDesc::nonvirtual_vtable_index) { + if (vtable_index == Method::nonvirtual_vtable_index) { assert(resolved_method->can_be_statically_bound(), "cannot override this method"); selected_method = resolved_method; } else { // recv_klass might be an arrayKlassOop but all vtables start at // the same place. The cast is to avoid virtual call and assertion. - instanceKlass* inst = (instanceKlass*)recv_klass()->klass_part(); + InstanceKlass* inst = (InstanceKlass*)recv_klass(); selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index)); } } @@ -916,7 +950,7 @@ if (selected_method.is_null()) { ResourceMark rm(THREAD); THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), - methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), + Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()), resolved_method->name(), resolved_method->signature())); } @@ -925,7 +959,7 @@ if (check_null_and_abstract && selected_method->is_abstract()) { ResourceMark rm(THREAD); THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), - methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), + Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()), selected_method->name(), selected_method->signature())); } @@ -978,7 +1012,7 @@ if (sel_method.is_null()) { ResourceMark rm(THREAD); THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), - methodOopDesc::name_and_sig_as_C_string(Klass::cast(recv_klass()), + Method::name_and_sig_as_C_string(Klass::cast(recv_klass()), resolved_method->name(), resolved_method->signature())); } @@ -986,7 +1020,7 @@ if (!sel_method->is_public()) { ResourceMark rm(THREAD); THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), - methodOopDesc::name_and_sig_as_C_string(Klass::cast(recv_klass()), + Method::name_and_sig_as_C_string(Klass::cast(recv_klass()), sel_method->name(), sel_method->signature())); } @@ -994,7 +1028,7 @@ if (check_null_and_abstract && sel_method->is_abstract()) { ResourceMark rm(THREAD); THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), - methodOopDesc::name_and_sig_as_C_string(Klass::cast(recv_klass()), + Method::name_and_sig_as_C_string(Klass::cast(recv_klass()), sel_method->name(), sel_method->signature())); } @@ -1080,7 +1114,7 @@ resolve_virtual_call(info, Handle(), receiver_klass, resolved_klass, name, signature, current_klass, true, false, THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; - return methodOopDesc::invalid_vtable_index; + return Method::invalid_vtable_index; } return info.vtable_index(); } @@ -1170,7 +1204,7 @@ Symbol* method_signature = NULL; KlassHandle current_klass; resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK); - KlassHandle recvrKlass (THREAD, recv.is_null() ? (klassOop)NULL : recv->klass()); + KlassHandle recvrKlass (THREAD, recv.is_null() ? (Klass*)NULL : recv->klass()); resolve_virtual_call(result, recv, recvrKlass, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK); } @@ -1181,7 +1215,7 @@ Symbol* method_signature = NULL; KlassHandle current_klass; resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK); - KlassHandle recvrKlass (THREAD, recv.is_null() ? (klassOop)NULL : recv->klass()); + KlassHandle recvrKlass (THREAD, recv.is_null() ? (Klass*)NULL : recv->klass()); resolve_interface_call(result, recv, recvrKlass, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK); } @@ -1207,11 +1241,12 @@ assert(resolved_klass() == SystemDictionary::MethodHandle_klass(), ""); assert(MethodHandles::is_signature_polymorphic_name(method_name), ""); methodHandle resolved_method; - Handle resolved_appendix; + Handle resolved_appendix; + Handle resolved_method_type; lookup_polymorphic_method(resolved_method, resolved_klass, method_name, method_signature, - current_klass, &resolved_appendix, CHECK); - result.set_handle(resolved_method, resolved_appendix, CHECK); + current_klass, &resolved_appendix, &resolved_method_type, CHECK); + result.set_handle(resolved_method, resolved_appendix, resolved_method_type, CHECK); } @@ -1219,7 +1254,7 @@ assert(EnableInvokeDynamic, ""); pool->set_invokedynamic(); // mark header to flag active call sites - //resolve_pool(<resolved_klass>, method_name, method_signature, current_klass, pool, index, CHECK); + //resolve_pool(<resolved_klass>, method_name, method_signature, current_klass, pool, index, CHECK); Symbol* method_name = pool->name_ref_at(index); Symbol* method_signature = pool->signature_ref_at(index); KlassHandle current_klass = KlassHandle(THREAD, pool->pool_holder()); @@ -1227,24 +1262,25 @@ // Resolve the bootstrap specifier (BSM + optional arguments). Handle bootstrap_specifier; // Check if CallSite has been bound already: - ConstantPoolCacheEntry* cpce = pool->cache()->secondary_entry_at(index); + ConstantPoolCacheEntry* cpce = pool->invokedynamic_cp_cache_entry_at(index); if (cpce->is_f1_null()) { - int pool_index = pool->cache()->main_entry_at(index)->constant_pool_index(); + int pool_index = cpce->constant_pool_index(); oop bsm_info = pool->resolve_bootstrap_specifier_at(pool_index, CHECK); assert(bsm_info != NULL, ""); // FIXME: Cache this once per BootstrapMethods entry, not once per CONSTANT_InvokeDynamic. bootstrap_specifier = Handle(THREAD, bsm_info); } if (!cpce->is_f1_null()) { - methodHandle method(THREAD, cpce->f2_as_vfinal_method()); - Handle appendix(THREAD, cpce->has_appendix() ? cpce->f1_appendix() : (oop)NULL); - result.set_handle(method, appendix, CHECK); + methodHandle method( THREAD, cpce->f1_as_method()); + Handle appendix( THREAD, cpce->appendix_if_resolved(pool)); + Handle method_type(THREAD, cpce->method_type_if_resolved(pool)); + result.set_handle(method, appendix, method_type, CHECK); return; } if (TraceMethodHandles) { tty->print_cr("resolve_invokedynamic #%d %s %s", - constantPoolCacheOopDesc::decode_secondary_index(index), + ConstantPool::decode_invokedynamic_index(index), method_name->as_C_string(), method_signature->as_C_string()); tty->print(" BSM info: "); bootstrap_specifier->print(); } @@ -1260,11 +1296,13 @@ // JSR 292: this must resolve to an implicitly generated method MH.linkToCallSite(*...) // The appendix argument is likely to be a freshly-created CallSite. Handle resolved_appendix; + Handle resolved_method_type; methodHandle resolved_method = SystemDictionary::find_dynamic_call_site_invoker(current_klass, bootstrap_specifier, method_name, method_signature, &resolved_appendix, + &resolved_method_type, THREAD); if (HAS_PENDING_EXCEPTION) { if (TraceMethodHandles) { @@ -1284,7 +1322,7 @@ CLEAR_PENDING_EXCEPTION; THROW_CAUSE(vmSymbols::java_lang_BootstrapMethodError(), nested_exception) } - result.set_handle(resolved_method, resolved_appendix, CHECK); + result.set_handle(resolved_method, resolved_appendix, resolved_method_type, CHECK); } //------------------------------------------------------------------------------------------------------------------------