src/share/vm/interpreter/linkResolver.cpp

Thu, 27 May 2010 19:08:38 -0700

author
trims
date
Thu, 27 May 2010 19:08:38 -0700
changeset 1907
c18cbe5936b8
parent 1863
2ffde6cfe049
child 2015
083fde3b838e
permissions
-rw-r--r--

6941466: Oracle rebranding changes for Hotspot repositories
Summary: Change all the Sun copyrights to Oracle copyright
Reviewed-by: ohair

     1 /*
     2  * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #include "incls/_precompiled.incl"
    26 #include "incls/_linkResolver.cpp.incl"
    28 //------------------------------------------------------------------------------------------------------------------------
    29 // Implementation of FieldAccessInfo
    31 void FieldAccessInfo::set(KlassHandle klass, symbolHandle name, int field_index, int field_offset,
    32 BasicType field_type, AccessFlags access_flags) {
    33   _klass        = klass;
    34   _name         = name;
    35   _field_index  = field_index;
    36   _field_offset = field_offset;
    37   _field_type   = field_type;
    38   _access_flags = access_flags;
    39 }
    42 //------------------------------------------------------------------------------------------------------------------------
    43 // Implementation of CallInfo
    46 void CallInfo::set_static(KlassHandle resolved_klass, methodHandle resolved_method, TRAPS) {
    47   int vtable_index = methodOopDesc::nonvirtual_vtable_index;
    48   set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, vtable_index, CHECK);
    49 }
    52 void CallInfo::set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, TRAPS) {
    53   // This is only called for interface methods. If the resolved_method
    54   // comes from java/lang/Object, it can be the subject of a virtual call, so
    55   // we should pick the vtable index from the resolved method.
    56   // Other than that case, there is no valid vtable index to specify.
    57   int vtable_index = methodOopDesc::invalid_vtable_index;
    58   if (resolved_method->method_holder() == SystemDictionary::Object_klass()) {
    59     assert(resolved_method->vtable_index() == selected_method->vtable_index(), "sanity check");
    60     vtable_index = resolved_method->vtable_index();
    61   }
    62   set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK);
    63 }
    65 void CallInfo::set_virtual(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) {
    66   assert(vtable_index >= 0 || vtable_index == methodOopDesc::nonvirtual_vtable_index, "valid index");
    67   set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK);
    68 }
    70 void CallInfo::set_common(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) {
    71   assert(resolved_method->signature() == selected_method->signature(), "signatures must correspond");
    72   _resolved_klass  = resolved_klass;
    73   _selected_klass  = selected_klass;
    74   _resolved_method = resolved_method;
    75   _selected_method = selected_method;
    76   _vtable_index    = vtable_index;
    77   if (CompilationPolicy::mustBeCompiled(selected_method)) {
    78     // This path is unusual, mostly used by the '-Xcomp' stress test mode.
    80     // Note: with several active threads, the mustBeCompiled may be true
    81     //       while canBeCompiled is false; remove assert
    82     // assert(CompilationPolicy::canBeCompiled(selected_method), "cannot compile");
    83     if (THREAD->is_Compiler_thread()) {
    84       // don't force compilation, resolve was on behalf of compiler
    85       return;
    86     }
    87     if (instanceKlass::cast(selected_method->method_holder())->is_not_initialized()) {
    88       // 'is_not_initialized' means not only '!is_initialized', but also that
    89       // initialization has not been started yet ('!being_initialized')
    90       // Do not force compilation of methods in uninitialized classes.
    91       // Note that doing this would throw an assert later,
    92       // in CompileBroker::compile_method.
    93       // We sometimes use the link resolver to do reflective lookups
    94       // even before classes are initialized.
    95       return;
    96     }
    97     CompileBroker::compile_method(selected_method, InvocationEntryBci,
    98                                   methodHandle(), 0, "mustBeCompiled", CHECK);
    99   }
   100 }
   103 //------------------------------------------------------------------------------------------------------------------------
   104 // Klass resolution
   106 void LinkResolver::check_klass_accessability(KlassHandle ref_klass, KlassHandle sel_klass, TRAPS) {
   107   if (!Reflection::verify_class_access(ref_klass->as_klassOop(),
   108                                        sel_klass->as_klassOop(),
   109                                        true)) {
   110     ResourceMark rm(THREAD);
   111     Exceptions::fthrow(
   112       THREAD_AND_LOCATION,
   113       vmSymbolHandles::java_lang_IllegalAccessError(),
   114       "tried to access class %s from class %s",
   115       sel_klass->external_name(),
   116       ref_klass->external_name()
   117     );
   118     return;
   119   }
   120 }
   122 void LinkResolver::resolve_klass(KlassHandle& result, constantPoolHandle pool, int index, TRAPS) {
   123   klassOop result_oop = pool->klass_ref_at(index, CHECK);
   124   result = KlassHandle(THREAD, result_oop);
   125 }
   127 void LinkResolver::resolve_klass_no_update(KlassHandle& result, constantPoolHandle pool, int index, TRAPS) {
   128   klassOop result_oop =
   129          constantPoolOopDesc::klass_ref_at_if_loaded_check(pool, index, CHECK);
   130   result = KlassHandle(THREAD, result_oop);
   131 }
   134 //------------------------------------------------------------------------------------------------------------------------
   135 // Method resolution
   136 //
   137 // According to JVM spec. $5.4.3c & $5.4.3d
   139 void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS) {
   140   methodOop result_oop = klass->uncached_lookup_method(name(), signature());
   141   if (EnableMethodHandles && result_oop != NULL) {
   142     switch (result_oop->intrinsic_id()) {
   143     case vmIntrinsics::_invokeExact:
   144     case vmIntrinsics::_invokeGeneric:
   145     case vmIntrinsics::_invokeDynamic:
   146       // Do not link directly to these.  The VM must produce a synthetic one using lookup_implicit_method.
   147       return;
   148     }
   149   }
   150   result = methodHandle(THREAD, result_oop);
   151 }
   153 // returns first instance method
   154 void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS) {
   155   methodOop result_oop = klass->uncached_lookup_method(name(), signature());
   156   result = methodHandle(THREAD, result_oop);
   157   while (!result.is_null() && result->is_static()) {
   158     klass = KlassHandle(THREAD, Klass::cast(result->method_holder())->super());
   159     result = methodHandle(THREAD, klass->uncached_lookup_method(name(), signature()));
   160   }
   161 }
   164 int LinkResolver::vtable_index_of_miranda_method(KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS) {
   165   ResourceMark rm(THREAD);
   166   klassVtable *vt = instanceKlass::cast(klass())->vtable();
   167   return vt->index_of_miranda(name(), signature());
   168 }
   170 void LinkResolver::lookup_method_in_interfaces(methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS) {
   171   instanceKlass *ik = instanceKlass::cast(klass());
   172   result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name(), signature()));
   173 }
   175 void LinkResolver::lookup_implicit_method(methodHandle& result,
   176                                           KlassHandle klass, symbolHandle name, symbolHandle signature,
   177                                           KlassHandle current_klass,
   178                                           TRAPS) {
   179   if (EnableMethodHandles && MethodHandles::enabled() &&
   180       klass() == SystemDictionary::MethodHandle_klass() &&
   181       methodOopDesc::is_method_handle_invoke_name(name())) {
   182     methodOop result_oop = SystemDictionary::find_method_handle_invoke(name,
   183                                                                        signature,
   184                                                                        current_klass,
   185                                                                        CHECK);
   186     if (result_oop != NULL) {
   187       assert(result_oop->is_method_handle_invoke() && result_oop->signature() == signature(), "consistent");
   188       result = methodHandle(THREAD, result_oop);
   189     }
   190   }
   191 }
   193 void LinkResolver::check_method_accessability(KlassHandle ref_klass,
   194                                               KlassHandle resolved_klass,
   195                                               KlassHandle sel_klass,
   196                                               methodHandle sel_method,
   197                                               TRAPS) {
   199   AccessFlags flags = sel_method->access_flags();
   201   // Special case:  arrays always override "clone". JVMS 2.15.
   202   // If the resolved klass is an array class, and the declaring class
   203   // is java.lang.Object and the method is "clone", set the flags
   204   // to public.
   205   //
   206   // We'll check for the method name first, as that's most likely
   207   // to be false (so we'll short-circuit out of these tests).
   208   if (sel_method->name() == vmSymbols::clone_name() &&
   209       sel_klass() == SystemDictionary::Object_klass() &&
   210       resolved_klass->oop_is_array()) {
   211     // We need to change "protected" to "public".
   212     assert(flags.is_protected(), "clone not protected?");
   213     jint new_flags = flags.as_int();
   214     new_flags = new_flags & (~JVM_ACC_PROTECTED);
   215     new_flags = new_flags | JVM_ACC_PUBLIC;
   216     flags.set_flags(new_flags);
   217   }
   219   if (!Reflection::verify_field_access(ref_klass->as_klassOop(),
   220                                        resolved_klass->as_klassOop(),
   221                                        sel_klass->as_klassOop(),
   222                                        flags,
   223                                        true)) {
   224     ResourceMark rm(THREAD);
   225     Exceptions::fthrow(
   226       THREAD_AND_LOCATION,
   227       vmSymbolHandles::java_lang_IllegalAccessError(),
   228       "tried to access method %s.%s%s from class %s",
   229       sel_klass->external_name(),
   230       sel_method->name()->as_C_string(),
   231       sel_method->signature()->as_C_string(),
   232       ref_klass->external_name()
   233     );
   234     return;
   235   }
   236 }
   238 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle& resolved_klass,
   239                                   constantPoolHandle pool, int index, TRAPS) {
   241   // resolve klass
   242   resolve_klass(resolved_klass, pool, index, CHECK);
   244   symbolHandle method_name      (THREAD, pool->name_ref_at(index));
   245   symbolHandle method_signature (THREAD, pool->signature_ref_at(index));
   246   KlassHandle  current_klass(THREAD, pool->pool_holder());
   248   resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
   249 }
   251 void LinkResolver::resolve_dynamic_method(methodHandle& resolved_method, KlassHandle& resolved_klass, constantPoolHandle pool, int index, TRAPS) {
   252   // The class is java.dyn.MethodHandle
   253   resolved_klass = SystemDictionaryHandles::MethodHandle_klass();
   255   symbolHandle method_name = vmSymbolHandles::invokeExact_name();
   257   symbolHandle method_signature(THREAD, pool->signature_ref_at(index));
   258   KlassHandle  current_klass   (THREAD, pool->pool_holder());
   260   resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
   261 }
   263 void LinkResolver::resolve_interface_method(methodHandle& resolved_method, KlassHandle& resolved_klass, constantPoolHandle pool, int index, TRAPS) {
   265   // resolve klass
   266   resolve_klass(resolved_klass, pool, index, CHECK);
   267   symbolHandle method_name      (THREAD, pool->name_ref_at(index));
   268   symbolHandle method_signature (THREAD, pool->signature_ref_at(index));
   269   KlassHandle  current_klass(THREAD, pool->pool_holder());
   271   resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
   272 }
   275 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass,
   276                                   symbolHandle method_name, symbolHandle method_signature,
   277                                   KlassHandle current_klass, bool check_access, TRAPS) {
   279   // 1. check if klass is not interface
   280   if (resolved_klass->is_interface()) {
   281     char buf[200];
   282     jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected", Klass::cast(resolved_klass())->external_name());
   283     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   284   }
   286   // 2. lookup method in resolved klass and its super klasses
   287   lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK);
   289   if (resolved_method.is_null()) { // not found in the class hierarchy
   290     // 3. lookup method in all the interfaces implemented by the resolved klass
   291     lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
   293     if (resolved_method.is_null()) {
   294       // JSR 292:  see if this is an implicitly generated method MethodHandle.invoke(*...)
   295       lookup_implicit_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, CHECK);
   296     }
   298     if (resolved_method.is_null()) {
   299       // 4. method lookup failed
   300       ResourceMark rm(THREAD);
   301       THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
   302                 methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   303                                                         method_name(),
   304                                                         method_signature()));
   305     }
   306   }
   308   // 5. check if method is concrete
   309   if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) {
   310     ResourceMark rm(THREAD);
   311     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
   312               methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   313                                                       method_name(),
   314                                                       method_signature()));
   315   }
   317   // 6. access checks, access checking may be turned off when calling from within the VM.
   318   if (check_access) {
   319     assert(current_klass.not_null() , "current_klass should not be null");
   321     // check if method can be accessed by the referring class
   322     check_method_accessability(current_klass,
   323                                resolved_klass,
   324                                KlassHandle(THREAD, resolved_method->method_holder()),
   325                                resolved_method,
   326                                CHECK);
   328     // check loader constraints
   329     Handle loader (THREAD, instanceKlass::cast(current_klass())->class_loader());
   330     Handle class_loader (THREAD, instanceKlass::cast(resolved_method->method_holder())->class_loader());
   331     {
   332       ResourceMark rm(THREAD);
   333       char* failed_type_name =
   334         SystemDictionary::check_signature_loaders(method_signature, loader,
   335                                                   class_loader, true, CHECK);
   336       if (failed_type_name != NULL) {
   337         const char* msg = "loader constraint violation: when resolving method"
   338           " \"%s\" the class loader (instance of %s) of the current class, %s,"
   339           " and the class loader (instance of %s) for resolved class, %s, have"
   340           " different Class objects for the type %s used in the signature";
   341         char* sig = methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name(),method_signature());
   342         const char* loader1 = SystemDictionary::loader_name(loader());
   343         char* current = instanceKlass::cast(current_klass())->name()->as_C_string();
   344         const char* loader2 = SystemDictionary::loader_name(class_loader());
   345         char* resolved = instanceKlass::cast(resolved_klass())->name()->as_C_string();
   346         size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) +
   347           strlen(current) + strlen(loader2) + strlen(resolved) +
   348           strlen(failed_type_name);
   349         char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
   350         jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2,
   351                      resolved, failed_type_name);
   352         THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
   353       }
   354     }
   355   }
   356 }
   358 void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
   359                                             KlassHandle resolved_klass,
   360                                             symbolHandle method_name,
   361                                             symbolHandle method_signature,
   362                                             KlassHandle current_klass,
   363                                             bool check_access, TRAPS) {
   365  // check if klass is interface
   366   if (!resolved_klass->is_interface()) {
   367     char buf[200];
   368     jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", Klass::cast(resolved_klass())->external_name());
   369     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   370   }
   372   // lookup method in this interface or its super, java.lang.Object
   373   lookup_instance_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK);
   375   if (resolved_method.is_null()) {
   376     // lookup method in all the super-interfaces
   377     lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
   378     if (resolved_method.is_null()) {
   379       // no method found
   380       ResourceMark rm(THREAD);
   381       THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
   382                 methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   383                                                         method_name(),
   384                                                         method_signature()));
   385     }
   386   }
   388   if (check_access) {
   389     HandleMark hm(THREAD);
   390     Handle loader (THREAD, instanceKlass::cast(current_klass())->class_loader());
   391     Handle class_loader (THREAD, instanceKlass::cast(resolved_method->method_holder())->class_loader());
   392     {
   393       ResourceMark rm(THREAD);
   394       char* failed_type_name =
   395         SystemDictionary::check_signature_loaders(method_signature, loader,
   396                                                   class_loader, true, CHECK);
   397       if (failed_type_name != NULL) {
   398         const char* msg = "loader constraint violation: when resolving "
   399           "interface method \"%s\" the class loader (instance of %s) of the "
   400           "current class, %s, and the class loader (instance of %s) for "
   401           "resolved class, %s, have different Class objects for the type %s "
   402           "used in the signature";
   403         char* sig = methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name(),method_signature());
   404         const char* loader1 = SystemDictionary::loader_name(loader());
   405         char* current = instanceKlass::cast(current_klass())->name()->as_C_string();
   406         const char* loader2 = SystemDictionary::loader_name(class_loader());
   407         char* resolved = instanceKlass::cast(resolved_klass())->name()->as_C_string();
   408         size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) +
   409           strlen(current) + strlen(loader2) + strlen(resolved) +
   410           strlen(failed_type_name);
   411         char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
   412         jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2,
   413                      resolved, failed_type_name);
   414         THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
   415       }
   416     }
   417   }
   418 }
   420 //------------------------------------------------------------------------------------------------------------------------
   421 // Field resolution
   423 void LinkResolver::check_field_accessability(KlassHandle ref_klass,
   424                                              KlassHandle resolved_klass,
   425                                              KlassHandle sel_klass,
   426                                              fieldDescriptor& fd,
   427                                              TRAPS) {
   428   if (!Reflection::verify_field_access(ref_klass->as_klassOop(),
   429                                        resolved_klass->as_klassOop(),
   430                                        sel_klass->as_klassOop(),
   431                                        fd.access_flags(),
   432                                        true)) {
   433     ResourceMark rm(THREAD);
   434     Exceptions::fthrow(
   435       THREAD_AND_LOCATION,
   436       vmSymbolHandles::java_lang_IllegalAccessError(),
   437       "tried to access field %s.%s from class %s",
   438       sel_klass->external_name(),
   439       fd.name()->as_C_string(),
   440       ref_klass->external_name()
   441     );
   442     return;
   443   }
   444 }
   446 void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, TRAPS) {
   447   resolve_field(result, pool, index, byte, check_only, true, CHECK);
   448 }
   450 void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, bool update_pool, TRAPS) {
   451   assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
   452          byte == Bytecodes::_getfield  || byte == Bytecodes::_putfield, "bad bytecode");
   454   bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic);
   455   bool is_put    = (byte == Bytecodes::_putfield  || byte == Bytecodes::_putstatic);
   457   // resolve specified klass
   458   KlassHandle resolved_klass;
   459   if (update_pool) {
   460     resolve_klass(resolved_klass, pool, index, CHECK);
   461   } else {
   462     resolve_klass_no_update(resolved_klass, pool, index, CHECK);
   463   }
   464   // Load these early in case the resolve of the containing klass fails
   465   symbolOop field = pool->name_ref_at(index);
   466   symbolHandle field_h (THREAD, field); // preserve in case we need the name
   467   symbolOop sig   = pool->signature_ref_at(index);
   468   // Check if there's a resolved klass containing the field
   469   if( resolved_klass.is_null() ) {
   470     ResourceMark rm(THREAD);
   471     THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
   472   }
   474   // Resolve instance field
   475   fieldDescriptor fd; // find_field initializes fd if found
   476   KlassHandle sel_klass(THREAD, instanceKlass::cast(resolved_klass())->find_field(field, sig, &fd));
   477   // check if field exists; i.e., if a klass containing the field def has been selected
   478   if (sel_klass.is_null()){
   479     ResourceMark rm(THREAD);
   480     THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
   481   }
   483   // check access
   484   KlassHandle ref_klass(THREAD, pool->pool_holder());
   485   check_field_accessability(ref_klass, resolved_klass, sel_klass, fd, CHECK);
   487   // check for errors
   488   if (is_static != fd.is_static()) {
   489     char msg[200];
   490     jio_snprintf(msg, sizeof(msg), "Expected %s field %s.%s", is_static ? "static" : "non-static", Klass::cast(resolved_klass())->external_name(), fd.name()->as_C_string());
   491     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), msg);
   492   }
   494   // Final fields can only be accessed from its own class.
   495   if (is_put && fd.access_flags().is_final() && sel_klass() != pool->pool_holder()) {
   496     THROW(vmSymbols::java_lang_IllegalAccessError());
   497   }
   499   // initialize resolved_klass if necessary
   500   // note 1: the klass which declared the field must be initialized (i.e, sel_klass)
   501   //         according to the newest JVM spec (5.5, p.170) - was bug (gri 7/28/99)
   502   //
   503   // note 2: we don't want to force initialization if we are just checking
   504   //         if the field access is legal; e.g., during compilation
   505   if (is_static && !check_only) {
   506     sel_klass->initialize(CHECK);
   507   }
   509   {
   510     HandleMark hm(THREAD);
   511     Handle ref_loader (THREAD, instanceKlass::cast(ref_klass())->class_loader());
   512     Handle sel_loader (THREAD, instanceKlass::cast(sel_klass())->class_loader());
   513     symbolHandle signature_ref (THREAD, pool->signature_ref_at(index));
   514     {
   515       ResourceMark rm(THREAD);
   516       char* failed_type_name =
   517         SystemDictionary::check_signature_loaders(signature_ref,
   518                                                   ref_loader, sel_loader,
   519                                                   false,
   520                                                   CHECK);
   521       if (failed_type_name != NULL) {
   522         const char* msg = "loader constraint violation: when resolving field"
   523           " \"%s\" the class loader (instance of %s) of the referring class, "
   524           "%s, and the class loader (instance of %s) for the field's resolved "
   525           "type, %s, have different Class objects for that type";
   526         char* field_name = field_h()->as_C_string();
   527         const char* loader1 = SystemDictionary::loader_name(ref_loader());
   528         char* sel = instanceKlass::cast(sel_klass())->name()->as_C_string();
   529         const char* loader2 = SystemDictionary::loader_name(sel_loader());
   530         size_t buflen = strlen(msg) + strlen(field_name) + strlen(loader1) +
   531           strlen(sel) + strlen(loader2) + strlen(failed_type_name);
   532         char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
   533         jio_snprintf(buf, buflen, msg, field_name, loader1, sel, loader2,
   534                      failed_type_name);
   535         THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
   536       }
   537     }
   538   }
   540   // return information. note that the klass is set to the actual klass containing the
   541   // field, otherwise access of static fields in superclasses will not work.
   542   KlassHandle holder (THREAD, fd.field_holder());
   543   symbolHandle name  (THREAD, fd.name());
   544   result.set(holder, name, fd.index(), fd.offset(), fd.field_type(), fd.access_flags());
   545 }
   548 //------------------------------------------------------------------------------------------------------------------------
   549 // Invoke resolution
   550 //
   551 // Naming conventions:
   552 //
   553 // resolved_method    the specified method (i.e., static receiver specified via constant pool index)
   554 // sel_method         the selected method  (selected via run-time lookup; e.g., based on dynamic receiver class)
   555 // resolved_klass     the specified klass  (i.e., specified via constant pool index)
   556 // recv_klass         the receiver klass
   559 void LinkResolver::resolve_static_call(CallInfo& result, KlassHandle& resolved_klass, symbolHandle method_name,
   560                                        symbolHandle method_signature, KlassHandle current_klass,
   561                                        bool check_access, bool initialize_class, TRAPS) {
   562   methodHandle resolved_method;
   563   linktime_resolve_static_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
   564   resolved_klass = KlassHandle(THREAD, Klass::cast(resolved_method->method_holder()));
   566   // Initialize klass (this should only happen if everything is ok)
   567   if (initialize_class && resolved_klass->should_be_initialized()) {
   568     resolved_klass->initialize(CHECK);
   569     linktime_resolve_static_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
   570   }
   572   // setup result
   573   result.set_static(resolved_klass, resolved_method, CHECK);
   574 }
   576 // throws linktime exceptions
   577 void LinkResolver::linktime_resolve_static_method(methodHandle& resolved_method, KlassHandle resolved_klass,
   578                                                   symbolHandle method_name, symbolHandle method_signature,
   579                                                   KlassHandle current_klass, bool check_access, TRAPS) {
   581   resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
   582   assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
   584   // check if static
   585   if (!resolved_method->is_static()) {
   586     char buf[200];
   587     jio_snprintf(buf, sizeof(buf), "Expected static method %s", methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   588                                                       resolved_method->name(),
   589                                                       resolved_method->signature()));
   590     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   591   }
   592 }
   595 void LinkResolver::resolve_special_call(CallInfo& result, KlassHandle resolved_klass, symbolHandle method_name,
   596                                         symbolHandle method_signature, KlassHandle current_klass, bool check_access, TRAPS) {
   597   methodHandle resolved_method;
   598   linktime_resolve_special_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
   599   runtime_resolve_special_method(result, resolved_method, resolved_klass, current_klass, check_access, CHECK);
   600 }
   602 // throws linktime exceptions
   603 void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method, KlassHandle resolved_klass,
   604                                                    symbolHandle method_name, symbolHandle method_signature,
   605                                                    KlassHandle current_klass, bool check_access, TRAPS) {
   607   resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
   609   // check if method name is <init>, that it is found in same klass as static type
   610   if (resolved_method->name() == vmSymbols::object_initializer_name() &&
   611       resolved_method->method_holder() != resolved_klass()) {
   612     ResourceMark rm(THREAD);
   613     Exceptions::fthrow(
   614       THREAD_AND_LOCATION,
   615       vmSymbolHandles::java_lang_NoSuchMethodError(),
   616       "%s: method %s%s not found",
   617       resolved_klass->external_name(),
   618       resolved_method->name()->as_C_string(),
   619       resolved_method->signature()->as_C_string()
   620     );
   621     return;
   622   }
   624   // check if not static
   625   if (resolved_method->is_static()) {
   626     char buf[200];
   627     jio_snprintf(buf, sizeof(buf),
   628                  "Expecting non-static method %s",
   629                  methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   630                                                          resolved_method->name(),
   631                                                          resolved_method->signature()));
   632     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   633   }
   634 }
   636 // throws runtime exceptions
   637 void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass,
   638                                                   KlassHandle current_klass, bool check_access, TRAPS) {
   640   // resolved method is selected method unless we have an old-style lookup
   641   methodHandle sel_method(THREAD, resolved_method());
   643   // check if this is an old-style super call and do a new lookup if so
   644   { KlassHandle method_klass  = KlassHandle(THREAD,
   645                                             resolved_method->method_holder());
   647     if (check_access &&
   648         // a) check if ACC_SUPER flag is set for the current class
   649         current_klass->is_super() &&
   650         // b) check if the method class is a superclass of the current class (superclass relation is not reflexive!)
   651         current_klass->is_subtype_of(method_klass()) && current_klass() != method_klass() &&
   652         // c) check if the method is not <init>
   653         resolved_method->name() != vmSymbols::object_initializer_name()) {
   654       // Lookup super method
   655       KlassHandle super_klass(THREAD, current_klass->super());
   656       lookup_instance_method_in_klasses(sel_method, super_klass,
   657                            symbolHandle(THREAD, resolved_method->name()),
   658                            symbolHandle(THREAD, resolved_method->signature()), CHECK);
   659       // check if found
   660       if (sel_method.is_null()) {
   661         ResourceMark rm(THREAD);
   662         THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
   663                   methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   664                                             resolved_method->name(),
   665                                             resolved_method->signature()));
   666       }
   667     }
   668   }
   670   // check if not static
   671   if (sel_method->is_static()) {
   672     char buf[200];
   673     jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   674                                                                                                              resolved_method->name(),
   675                                                                                                              resolved_method->signature()));
   676     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   677   }
   679   // check if abstract
   680   if (sel_method->is_abstract()) {
   681     ResourceMark rm(THREAD);
   682     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
   683               methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   684                                                       sel_method->name(),
   685                                                       sel_method->signature()));
   686   }
   688   // setup result
   689   result.set_static(resolved_klass, sel_method, CHECK);
   690 }
   692 void LinkResolver::resolve_virtual_call(CallInfo& result, Handle recv, KlassHandle receiver_klass, KlassHandle resolved_klass,
   693                                         symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass,
   694                                         bool check_access, bool check_null_and_abstract, TRAPS) {
   695   methodHandle resolved_method;
   696   linktime_resolve_virtual_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
   697   runtime_resolve_virtual_method(result, resolved_method, resolved_klass, recv, receiver_klass, check_null_and_abstract, CHECK);
   698 }
   700 // throws linktime exceptions
   701 void LinkResolver::linktime_resolve_virtual_method(methodHandle &resolved_method, KlassHandle resolved_klass,
   702                                                    symbolHandle method_name, symbolHandle method_signature,
   703                                                    KlassHandle current_klass, bool check_access, TRAPS) {
   704   // normal method resolution
   705   resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
   707   assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
   708   assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
   710   // check if not static
   711   if (resolved_method->is_static()) {
   712     char buf[200];
   713     jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   714                                                                                                              resolved_method->name(),
   715                                                                                                              resolved_method->signature()));
   716     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   717   }
   718 }
   720 // throws runtime exceptions
   721 void LinkResolver::runtime_resolve_virtual_method(CallInfo& result,
   722                                                   methodHandle resolved_method,
   723                                                   KlassHandle resolved_klass,
   724                                                   Handle recv,
   725                                                   KlassHandle recv_klass,
   726                                                   bool check_null_and_abstract,
   727                                                   TRAPS) {
   729   // setup default return values
   730   int vtable_index = methodOopDesc::invalid_vtable_index;
   731   methodHandle selected_method;
   733   assert(recv.is_null() || recv->is_oop(), "receiver is not an oop");
   735   // runtime method resolution
   736   if (check_null_and_abstract && recv.is_null()) { // check if receiver exists
   737     THROW(vmSymbols::java_lang_NullPointerException());
   738   }
   740   // Virtual methods cannot be resolved before its klass has been linked, for otherwise the methodOop's
   741   // has not been rewritten, and the vtable initialized.
   742   assert(instanceKlass::cast(resolved_method->method_holder())->is_linked(), "must be linked");
   744   // Virtual methods cannot be resolved before its klass has been linked, for otherwise the methodOop's
   745   // has not been rewritten, and the vtable initialized. Make sure to do this after the nullcheck, since
   746   // a missing receiver might result in a bogus lookup.
   747   assert(instanceKlass::cast(resolved_method->method_holder())->is_linked(), "must be linked");
   749   // do lookup based on receiver klass using the vtable index
   750   if (resolved_method->method_holder()->klass_part()->is_interface()) { // miranda method
   751     vtable_index = vtable_index_of_miranda_method(resolved_klass,
   752                            symbolHandle(THREAD, resolved_method->name()),
   753                            symbolHandle(THREAD, resolved_method->signature()), CHECK);
   754     assert(vtable_index >= 0 , "we should have valid vtable index at this point");
   756     instanceKlass* inst = instanceKlass::cast(recv_klass());
   757     selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index));
   758   } else {
   759     // at this point we are sure that resolved_method is virtual and not
   760     // a miranda method; therefore, it must have a valid vtable index.
   761     vtable_index = resolved_method->vtable_index();
   762     // We could get a negative vtable_index for final methods,
   763     // because as an optimization they are they are never put in the vtable,
   764     // unless they override an existing method.
   765     // If we do get a negative, it means the resolved method is the the selected
   766     // method, and it can never be changed by an override.
   767     if (vtable_index == methodOopDesc::nonvirtual_vtable_index) {
   768       assert(resolved_method->can_be_statically_bound(), "cannot override this method");
   769       selected_method = resolved_method;
   770     } else {
   771       // recv_klass might be an arrayKlassOop but all vtables start at
   772       // the same place. The cast is to avoid virtual call and assertion.
   773       instanceKlass* inst = (instanceKlass*)recv_klass()->klass_part();
   774       selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index));
   775     }
   776   }
   778   // check if method exists
   779   if (selected_method.is_null()) {
   780     ResourceMark rm(THREAD);
   781     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
   782               methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   783                                                       resolved_method->name(),
   784                                                       resolved_method->signature()));
   785   }
   787   // check if abstract
   788   if (check_null_and_abstract && selected_method->is_abstract()) {
   789     ResourceMark rm(THREAD);
   790     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
   791               methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   792                                                       selected_method->name(),
   793                                                       selected_method->signature()));
   794   }
   796   // setup result
   797   result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK);
   798 }
   800 void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass,
   801                                           symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass,
   802                                           bool check_access, bool check_null_and_abstract, TRAPS) {
   803   methodHandle resolved_method;
   804   linktime_resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
   805   runtime_resolve_interface_method(result, resolved_method, resolved_klass, recv, recv_klass, check_null_and_abstract, CHECK);
   806 }
   808 // throws linktime exceptions
   809 void LinkResolver::linktime_resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, symbolHandle method_name,
   810                                                      symbolHandle method_signature, KlassHandle current_klass, bool check_access, TRAPS) {
   811   // normal interface method resolution
   812   resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
   814   assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
   815   assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
   816 }
   818 // throws runtime exceptions
   819 void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass,
   820                                                     Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS) {
   821   // check if receiver exists
   822   if (check_null_and_abstract && recv.is_null()) {
   823     THROW(vmSymbols::java_lang_NullPointerException());
   824   }
   826   // check if receiver klass implements the resolved interface
   827   if (!recv_klass->is_subtype_of(resolved_klass())) {
   828     char buf[200];
   829     jio_snprintf(buf, sizeof(buf), "Class %s does not implement the requested interface %s",
   830                  (Klass::cast(recv_klass()))->external_name(),
   831                  (Klass::cast(resolved_klass()))->external_name());
   832     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   833   }
   834   // do lookup based on receiver klass
   835   methodHandle sel_method;
   836   lookup_instance_method_in_klasses(sel_method, recv_klass,
   837             symbolHandle(THREAD, resolved_method->name()),
   838             symbolHandle(THREAD, resolved_method->signature()), CHECK);
   839   // check if method exists
   840   if (sel_method.is_null()) {
   841     ResourceMark rm(THREAD);
   842     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
   843               methodOopDesc::name_and_sig_as_C_string(Klass::cast(recv_klass()),
   844                                                       resolved_method->name(),
   845                                                       resolved_method->signature()));
   846   }
   847   // check if public
   848   if (!sel_method->is_public()) {
   849     ResourceMark rm(THREAD);
   850     THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
   851               methodOopDesc::name_and_sig_as_C_string(Klass::cast(recv_klass()),
   852                                                       sel_method->name(),
   853                                                       sel_method->signature()));
   854   }
   855   // check if abstract
   856   if (check_null_and_abstract && sel_method->is_abstract()) {
   857     ResourceMark rm(THREAD);
   858     THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
   859               methodOopDesc::name_and_sig_as_C_string(Klass::cast(recv_klass()),
   860                                                       sel_method->name(),
   861                                                       sel_method->signature()));
   862   }
   863   // setup result
   864   result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, CHECK);
   865 }
   868 methodHandle LinkResolver::linktime_resolve_interface_method_or_null(
   869                                                  KlassHandle resolved_klass,
   870                                                  symbolHandle method_name,
   871                                                  symbolHandle method_signature,
   872                                                  KlassHandle current_klass,
   873                                                  bool check_access) {
   874   EXCEPTION_MARK;
   875   methodHandle method_result;
   876   linktime_resolve_interface_method(method_result, resolved_klass, method_name, method_signature, current_klass, check_access, THREAD);
   877   if (HAS_PENDING_EXCEPTION) {
   878     CLEAR_PENDING_EXCEPTION;
   879     return methodHandle();
   880   } else {
   881     return method_result;
   882   }
   883 }
   885 methodHandle LinkResolver::linktime_resolve_virtual_method_or_null(
   886                                                  KlassHandle resolved_klass,
   887                                                  symbolHandle method_name,
   888                                                  symbolHandle method_signature,
   889                                                  KlassHandle current_klass,
   890                                                  bool check_access) {
   891   EXCEPTION_MARK;
   892   methodHandle method_result;
   893   linktime_resolve_virtual_method(method_result, resolved_klass, method_name, method_signature, current_klass, check_access, THREAD);
   894   if (HAS_PENDING_EXCEPTION) {
   895     CLEAR_PENDING_EXCEPTION;
   896     return methodHandle();
   897   } else {
   898     return method_result;
   899   }
   900 }
   902 methodHandle LinkResolver::resolve_virtual_call_or_null(
   903                                                  KlassHandle receiver_klass,
   904                                                  KlassHandle resolved_klass,
   905                                                  symbolHandle name,
   906                                                  symbolHandle signature,
   907                                                  KlassHandle current_klass) {
   908   EXCEPTION_MARK;
   909   CallInfo info;
   910   resolve_virtual_call(info, Handle(), receiver_klass, resolved_klass, name, signature, current_klass, true, false, THREAD);
   911   if (HAS_PENDING_EXCEPTION) {
   912     CLEAR_PENDING_EXCEPTION;
   913     return methodHandle();
   914   }
   915   return info.selected_method();
   916 }
   918 methodHandle LinkResolver::resolve_interface_call_or_null(
   919                                                  KlassHandle receiver_klass,
   920                                                  KlassHandle resolved_klass,
   921                                                  symbolHandle name,
   922                                                  symbolHandle signature,
   923                                                  KlassHandle current_klass) {
   924   EXCEPTION_MARK;
   925   CallInfo info;
   926   resolve_interface_call(info, Handle(), receiver_klass, resolved_klass, name, signature, current_klass, true, false, THREAD);
   927   if (HAS_PENDING_EXCEPTION) {
   928     CLEAR_PENDING_EXCEPTION;
   929     return methodHandle();
   930   }
   931   return info.selected_method();
   932 }
   934 int LinkResolver::resolve_virtual_vtable_index(
   935                                                KlassHandle receiver_klass,
   936                                                KlassHandle resolved_klass,
   937                                                symbolHandle name,
   938                                                symbolHandle signature,
   939                                                KlassHandle current_klass) {
   940   EXCEPTION_MARK;
   941   CallInfo info;
   942   resolve_virtual_call(info, Handle(), receiver_klass, resolved_klass, name, signature, current_klass, true, false, THREAD);
   943   if (HAS_PENDING_EXCEPTION) {
   944     CLEAR_PENDING_EXCEPTION;
   945     return methodOopDesc::invalid_vtable_index;
   946   }
   947   return info.vtable_index();
   948 }
   950 methodHandle LinkResolver::resolve_static_call_or_null(
   951                                                   KlassHandle resolved_klass,
   952                                                   symbolHandle name,
   953                                                   symbolHandle signature,
   954                                                   KlassHandle current_klass) {
   955   EXCEPTION_MARK;
   956   CallInfo info;
   957   resolve_static_call(info, resolved_klass, name, signature, current_klass, true, false, THREAD);
   958   if (HAS_PENDING_EXCEPTION) {
   959     CLEAR_PENDING_EXCEPTION;
   960     return methodHandle();
   961   }
   962   return info.selected_method();
   963 }
   965 methodHandle LinkResolver::resolve_special_call_or_null(KlassHandle resolved_klass, symbolHandle name, symbolHandle signature,
   966                                                         KlassHandle current_klass) {
   967   EXCEPTION_MARK;
   968   CallInfo info;
   969   resolve_special_call(info, resolved_klass, name, signature, current_klass, true, THREAD);
   970   if (HAS_PENDING_EXCEPTION) {
   971     CLEAR_PENDING_EXCEPTION;
   972     return methodHandle();
   973   }
   974   return info.selected_method();
   975 }
   979 //------------------------------------------------------------------------------------------------------------------------
   980 // ConstantPool entries
   982 void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS) {
   983   switch (byte) {
   984     case Bytecodes::_invokestatic   : resolve_invokestatic   (result,       pool, index, CHECK); break;
   985     case Bytecodes::_invokespecial  : resolve_invokespecial  (result,       pool, index, CHECK); break;
   986     case Bytecodes::_invokevirtual  : resolve_invokevirtual  (result, recv, pool, index, CHECK); break;
   987     case Bytecodes::_invokedynamic  : resolve_invokedynamic  (result,       pool, index, CHECK); break;
   988     case Bytecodes::_invokeinterface: resolve_invokeinterface(result, recv, pool, index, CHECK); break;
   989   }
   990   return;
   991 }
   993 void LinkResolver::resolve_pool(KlassHandle& resolved_klass, symbolHandle& method_name, symbolHandle& method_signature,
   994                                 KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS) {
   995    // resolve klass
   996   resolve_klass(resolved_klass, pool, index, CHECK);
   998   // Get name, signature, and static klass
   999   method_name      = symbolHandle(THREAD, pool->name_ref_at(index));
  1000   method_signature = symbolHandle(THREAD, pool->signature_ref_at(index));
  1001   current_klass    = KlassHandle(THREAD, pool->pool_holder());
  1005 void LinkResolver::resolve_invokestatic(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
  1006   KlassHandle  resolved_klass;
  1007   symbolHandle method_name;
  1008   symbolHandle method_signature;
  1009   KlassHandle  current_klass;
  1010   resolve_pool(resolved_klass, method_name,  method_signature, current_klass, pool, index, CHECK);
  1011   resolve_static_call(result, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
  1015 void LinkResolver::resolve_invokespecial(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
  1016   KlassHandle  resolved_klass;
  1017   symbolHandle method_name;
  1018   symbolHandle method_signature;
  1019   KlassHandle  current_klass;
  1020   resolve_pool(resolved_klass, method_name,  method_signature, current_klass, pool, index, CHECK);
  1021   resolve_special_call(result, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
  1025 void LinkResolver::resolve_invokevirtual(CallInfo& result, Handle recv,
  1026                                           constantPoolHandle pool, int index,
  1027                                           TRAPS) {
  1029   KlassHandle  resolved_klass;
  1030   symbolHandle method_name;
  1031   symbolHandle method_signature;
  1032   KlassHandle  current_klass;
  1033   resolve_pool(resolved_klass, method_name,  method_signature, current_klass, pool, index, CHECK);
  1034   KlassHandle recvrKlass (THREAD, recv.is_null() ? (klassOop)NULL : recv->klass());
  1035   resolve_virtual_call(result, recv, recvrKlass, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
  1039 void LinkResolver::resolve_invokeinterface(CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS) {
  1040   KlassHandle  resolved_klass;
  1041   symbolHandle method_name;
  1042   symbolHandle method_signature;
  1043   KlassHandle  current_klass;
  1044   resolve_pool(resolved_klass, method_name,  method_signature, current_klass, pool, index, CHECK);
  1045   KlassHandle recvrKlass (THREAD, recv.is_null() ? (klassOop)NULL : recv->klass());
  1046   resolve_interface_call(result, recv, recvrKlass, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
  1050 void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle pool, int raw_index, TRAPS) {
  1051   assert(EnableInvokeDynamic, "");
  1053   // This guy is reached from InterpreterRuntime::resolve_invokedynamic.
  1055   // At this point, we only need the signature, and can ignore the name.
  1056   symbolHandle method_signature(THREAD, pool->signature_ref_at(raw_index));  // raw_index works directly
  1057   symbolHandle method_name = vmSymbolHandles::invokeExact_name();
  1058   KlassHandle resolved_klass = SystemDictionaryHandles::MethodHandle_klass();
  1060   // JSR 292:  this must be an implicitly generated method MethodHandle.invokeExact(*...)
  1061   // The extra MH receiver will be inserted into the stack on every call.
  1062   methodHandle resolved_method;
  1063   KlassHandle current_klass(THREAD, pool->pool_holder());
  1064   lookup_implicit_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, CHECK);
  1065   if (resolved_method.is_null()) {
  1066     THROW(vmSymbols::java_lang_InternalError());
  1068   result.set_virtual(resolved_klass, KlassHandle(), resolved_method, resolved_method, resolved_method->vtable_index(), CHECK);
  1071 //------------------------------------------------------------------------------------------------------------------------
  1072 #ifndef PRODUCT
  1074 void FieldAccessInfo::print() {
  1075   ResourceMark rm;
  1076   tty->print_cr("Field %s@%d", name()->as_C_string(), field_offset());
  1079 #endif

mercurial