src/share/vm/interpreter/linkResolver.cpp

changeset 435
a61af66fc99e
child 1145
e5b0439ef4ae
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/interpreter/linkResolver.cpp	Sat Dec 01 00:00:00 2007 +0000
     1.3 @@ -0,0 +1,1000 @@
     1.4 +/*
     1.5 + * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.
    1.11 + *
    1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.15 + * version 2 for more details (a copy is included in the LICENSE file that
    1.16 + * accompanied this code).
    1.17 + *
    1.18 + * You should have received a copy of the GNU General Public License version
    1.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 + *
    1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
    1.24 + * have any questions.
    1.25 + *
    1.26 + */
    1.27 +
    1.28 +#include "incls/_precompiled.incl"
    1.29 +#include "incls/_linkResolver.cpp.incl"
    1.30 +
    1.31 +//------------------------------------------------------------------------------------------------------------------------
    1.32 +// Implementation of FieldAccessInfo
    1.33 +
    1.34 +void FieldAccessInfo::set(KlassHandle klass, symbolHandle name, int field_index, int field_offset,
    1.35 +BasicType field_type, AccessFlags access_flags) {
    1.36 +  _klass        = klass;
    1.37 +  _name         = name;
    1.38 +  _field_index  = field_index;
    1.39 +  _field_offset = field_offset;
    1.40 +  _field_type   = field_type;
    1.41 +  _access_flags = access_flags;
    1.42 +}
    1.43 +
    1.44 +
    1.45 +//------------------------------------------------------------------------------------------------------------------------
    1.46 +// Implementation of CallInfo
    1.47 +
    1.48 +
    1.49 +void CallInfo::set_static(KlassHandle resolved_klass, methodHandle resolved_method, TRAPS) {
    1.50 +  int vtable_index = methodOopDesc::nonvirtual_vtable_index;
    1.51 +  set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, vtable_index, CHECK);
    1.52 +}
    1.53 +
    1.54 +
    1.55 +void CallInfo::set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, TRAPS) {
    1.56 +  // This is only called for interface methods. If the resolved_method
    1.57 +  // comes from java/lang/Object, it can be the subject of a virtual call, so
    1.58 +  // we should pick the vtable index from the resolved method.
    1.59 +  // Other than that case, there is no valid vtable index to specify.
    1.60 +  int vtable_index = methodOopDesc::invalid_vtable_index;
    1.61 +  if (resolved_method->method_holder() == SystemDictionary::object_klass()) {
    1.62 +    assert(resolved_method->vtable_index() == selected_method->vtable_index(), "sanity check");
    1.63 +    vtable_index = resolved_method->vtable_index();
    1.64 +  }
    1.65 +  set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK);
    1.66 +}
    1.67 +
    1.68 +void CallInfo::set_virtual(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) {
    1.69 +  assert(vtable_index >= 0 || vtable_index == methodOopDesc::nonvirtual_vtable_index, "valid index");
    1.70 +  set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK);
    1.71 +}
    1.72 +
    1.73 +void CallInfo::set_common(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) {
    1.74 +  assert(resolved_method->signature() == selected_method->signature(), "signatures must correspond");
    1.75 +  _resolved_klass  = resolved_klass;
    1.76 +  _selected_klass  = selected_klass;
    1.77 +  _resolved_method = resolved_method;
    1.78 +  _selected_method = selected_method;
    1.79 +  _vtable_index    = vtable_index;
    1.80 +  if (CompilationPolicy::mustBeCompiled(selected_method)) {
    1.81 +    // Note: with several active threads, the mustBeCompiled may be true
    1.82 +    //       while canBeCompiled is false; remove assert
    1.83 +    // assert(CompilationPolicy::canBeCompiled(selected_method), "cannot compile");
    1.84 +    if (THREAD->is_Compiler_thread()) {
    1.85 +      // don't force compilation, resolve was on behalf of compiler
    1.86 +      return;
    1.87 +    }
    1.88 +    CompileBroker::compile_method(selected_method, InvocationEntryBci,
    1.89 +                                  methodHandle(), 0, "mustBeCompiled", CHECK);
    1.90 +  }
    1.91 +}
    1.92 +
    1.93 +
    1.94 +//------------------------------------------------------------------------------------------------------------------------
    1.95 +// Klass resolution
    1.96 +
    1.97 +void LinkResolver::check_klass_accessability(KlassHandle ref_klass, KlassHandle sel_klass, TRAPS) {
    1.98 +  if (!Reflection::verify_class_access(ref_klass->as_klassOop(),
    1.99 +                                       sel_klass->as_klassOop(),
   1.100 +                                       true)) {
   1.101 +    ResourceMark rm(THREAD);
   1.102 +    Exceptions::fthrow(
   1.103 +      THREAD_AND_LOCATION,
   1.104 +      vmSymbolHandles::java_lang_IllegalAccessError(),
   1.105 +      "tried to access class %s from class %s",
   1.106 +      sel_klass->external_name(),
   1.107 +      ref_klass->external_name()
   1.108 +    );
   1.109 +    return;
   1.110 +  }
   1.111 +}
   1.112 +
   1.113 +void LinkResolver::resolve_klass(KlassHandle& result, constantPoolHandle pool, int index, TRAPS) {
   1.114 +  klassOop result_oop = pool->klass_ref_at(index, CHECK);
   1.115 +  result = KlassHandle(THREAD, result_oop);
   1.116 +}
   1.117 +
   1.118 +void LinkResolver::resolve_klass_no_update(KlassHandle& result, constantPoolHandle pool, int index, TRAPS) {
   1.119 +  klassOop result_oop =
   1.120 +         constantPoolOopDesc::klass_ref_at_if_loaded_check(pool, index, CHECK);
   1.121 +  result = KlassHandle(THREAD, result_oop);
   1.122 +}
   1.123 +
   1.124 +
   1.125 +//------------------------------------------------------------------------------------------------------------------------
   1.126 +// Method resolution
   1.127 +//
   1.128 +// According to JVM spec. $5.4.3c & $5.4.3d
   1.129 +
   1.130 +void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS) {
   1.131 +  methodOop result_oop = klass->uncached_lookup_method(name(), signature());
   1.132 +  result = methodHandle(THREAD, result_oop);
   1.133 +}
   1.134 +
   1.135 +// returns first instance method
   1.136 +void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS) {
   1.137 +  methodOop result_oop = klass->uncached_lookup_method(name(), signature());
   1.138 +  result = methodHandle(THREAD, result_oop);
   1.139 +  while (!result.is_null() && result->is_static()) {
   1.140 +    klass = KlassHandle(THREAD, Klass::cast(result->method_holder())->super());
   1.141 +    result = methodHandle(THREAD, klass->uncached_lookup_method(name(), signature()));
   1.142 +  }
   1.143 +}
   1.144 +
   1.145 +
   1.146 +int LinkResolver::vtable_index_of_miranda_method(KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS) {
   1.147 +  ResourceMark rm(THREAD);
   1.148 +  klassVtable *vt = instanceKlass::cast(klass())->vtable();
   1.149 +  return vt->index_of_miranda(name(), signature());
   1.150 +}
   1.151 +
   1.152 +void LinkResolver::lookup_method_in_interfaces(methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS) {
   1.153 +  instanceKlass *ik = instanceKlass::cast(klass());
   1.154 +  result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name(), signature()));
   1.155 +}
   1.156 +
   1.157 +void LinkResolver::check_method_accessability(KlassHandle ref_klass,
   1.158 +                                              KlassHandle resolved_klass,
   1.159 +                                              KlassHandle sel_klass,
   1.160 +                                              methodHandle sel_method,
   1.161 +                                              TRAPS) {
   1.162 +
   1.163 +  AccessFlags flags = sel_method->access_flags();
   1.164 +
   1.165 +  // Special case:  arrays always override "clone". JVMS 2.15.
   1.166 +  // If the resolved klass is an array class, and the declaring class
   1.167 +  // is java.lang.Object and the method is "clone", set the flags
   1.168 +  // to public.
   1.169 +  //
   1.170 +  // We'll check for the method name first, as that's most likely
   1.171 +  // to be false (so we'll short-circuit out of these tests).
   1.172 +  if (sel_method->name() == vmSymbols::clone_name() &&
   1.173 +      sel_klass() == SystemDictionary::object_klass() &&
   1.174 +      resolved_klass->oop_is_array()) {
   1.175 +    // We need to change "protected" to "public".
   1.176 +    assert(flags.is_protected(), "clone not protected?");
   1.177 +    jint new_flags = flags.as_int();
   1.178 +    new_flags = new_flags & (~JVM_ACC_PROTECTED);
   1.179 +    new_flags = new_flags | JVM_ACC_PUBLIC;
   1.180 +    flags.set_flags(new_flags);
   1.181 +  }
   1.182 +
   1.183 +  if (!Reflection::verify_field_access(ref_klass->as_klassOop(),
   1.184 +                                       resolved_klass->as_klassOop(),
   1.185 +                                       sel_klass->as_klassOop(),
   1.186 +                                       flags,
   1.187 +                                       true)) {
   1.188 +    ResourceMark rm(THREAD);
   1.189 +    Exceptions::fthrow(
   1.190 +      THREAD_AND_LOCATION,
   1.191 +      vmSymbolHandles::java_lang_IllegalAccessError(),
   1.192 +      "tried to access method %s.%s%s from class %s",
   1.193 +      sel_klass->external_name(),
   1.194 +      sel_method->name()->as_C_string(),
   1.195 +      sel_method->signature()->as_C_string(),
   1.196 +      ref_klass->external_name()
   1.197 +    );
   1.198 +    return;
   1.199 +  }
   1.200 +}
   1.201 +
   1.202 +void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle& resolved_klass,
   1.203 +                                  constantPoolHandle pool, int index, TRAPS) {
   1.204 +
   1.205 +  // resolve klass
   1.206 +  resolve_klass(resolved_klass, pool, index, CHECK);
   1.207 +
   1.208 +  symbolHandle method_name      (THREAD, pool->name_ref_at(index));
   1.209 +  symbolHandle method_signature (THREAD, pool->signature_ref_at(index));
   1.210 +  KlassHandle  current_klass(THREAD, pool->pool_holder());
   1.211 +
   1.212 +  resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
   1.213 +}
   1.214 +
   1.215 +void LinkResolver::resolve_interface_method(methodHandle& resolved_method, KlassHandle& resolved_klass, constantPoolHandle pool, int index, TRAPS) {
   1.216 +
   1.217 +  // resolve klass
   1.218 +  resolve_klass(resolved_klass, pool, index, CHECK);
   1.219 +  symbolHandle method_name      (THREAD, pool->name_ref_at(index));
   1.220 +  symbolHandle method_signature (THREAD, pool->signature_ref_at(index));
   1.221 +  KlassHandle  current_klass(THREAD, pool->pool_holder());
   1.222 +
   1.223 +  resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
   1.224 +}
   1.225 +
   1.226 +
   1.227 +void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass,
   1.228 +                                  symbolHandle method_name, symbolHandle method_signature,
   1.229 +                                  KlassHandle current_klass, bool check_access, TRAPS) {
   1.230 +
   1.231 +  // 1. check if klass is not interface
   1.232 +  if (resolved_klass->is_interface()) {
   1.233 +    char buf[200];
   1.234 +    jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected", Klass::cast(resolved_klass())->external_name());
   1.235 +    THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   1.236 +  }
   1.237 +
   1.238 +  // 2. lookup method in resolved klass and its super klasses
   1.239 +  lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK);
   1.240 +
   1.241 +  if (resolved_method.is_null()) { // not found in the class hierarchy
   1.242 +    // 3. lookup method in all the interfaces implemented by the resolved klass
   1.243 +    lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
   1.244 +
   1.245 +    if (resolved_method.is_null()) {
   1.246 +      // 4. method lookup failed
   1.247 +      ResourceMark rm(THREAD);
   1.248 +      THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
   1.249 +                methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   1.250 +                                                        method_name(),
   1.251 +                                                        method_signature()));
   1.252 +    }
   1.253 +  }
   1.254 +
   1.255 +  // 5. check if method is concrete
   1.256 +  if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) {
   1.257 +    ResourceMark rm(THREAD);
   1.258 +    THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
   1.259 +              methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   1.260 +                                                      method_name(),
   1.261 +                                                      method_signature()));
   1.262 +  }
   1.263 +
   1.264 +  // 6. access checks, access checking may be turned off when calling from within the VM.
   1.265 +  if (check_access) {
   1.266 +    assert(current_klass.not_null() , "current_klass should not be null");
   1.267 +
   1.268 +    // check if method can be accessed by the referring class
   1.269 +    check_method_accessability(current_klass,
   1.270 +                               resolved_klass,
   1.271 +                               KlassHandle(THREAD, resolved_method->method_holder()),
   1.272 +                               resolved_method,
   1.273 +                               CHECK);
   1.274 +
   1.275 +    // check loader constraints
   1.276 +    Handle loader (THREAD, instanceKlass::cast(current_klass())->class_loader());
   1.277 +    Handle class_loader (THREAD, instanceKlass::cast(resolved_method->method_holder())->class_loader());
   1.278 +    {
   1.279 +      ResourceMark rm(THREAD);
   1.280 +      char* failed_type_name =
   1.281 +        SystemDictionary::check_signature_loaders(method_signature, loader,
   1.282 +                                                  class_loader, true, CHECK);
   1.283 +      if (failed_type_name != NULL) {
   1.284 +        const char* msg = "loader constraint violation: when resolving method"
   1.285 +          " \"%s\" the class loader (instance of %s) of the current class, %s,"
   1.286 +          " and the class loader (instance of %s) for resolved class, %s, have"
   1.287 +          " different Class objects for the type %s used in the signature";
   1.288 +        char* sig = methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name(),method_signature());
   1.289 +        const char* loader1 = SystemDictionary::loader_name(loader());
   1.290 +        char* current = instanceKlass::cast(current_klass())->name()->as_C_string();
   1.291 +        const char* loader2 = SystemDictionary::loader_name(class_loader());
   1.292 +        char* resolved = instanceKlass::cast(resolved_klass())->name()->as_C_string();
   1.293 +        size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) +
   1.294 +          strlen(current) + strlen(loader2) + strlen(resolved) +
   1.295 +          strlen(failed_type_name);
   1.296 +        char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
   1.297 +        jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2,
   1.298 +                     resolved, failed_type_name);
   1.299 +        THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
   1.300 +      }
   1.301 +    }
   1.302 +  }
   1.303 +}
   1.304 +
   1.305 +void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
   1.306 +                                            KlassHandle resolved_klass,
   1.307 +                                            symbolHandle method_name,
   1.308 +                                            symbolHandle method_signature,
   1.309 +                                            KlassHandle current_klass,
   1.310 +                                            bool check_access, TRAPS) {
   1.311 +
   1.312 + // check if klass is interface
   1.313 +  if (!resolved_klass->is_interface()) {
   1.314 +    char buf[200];
   1.315 +    jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", Klass::cast(resolved_klass())->external_name());
   1.316 +    THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   1.317 +  }
   1.318 +
   1.319 +  // lookup method in this interface or its super, java.lang.Object
   1.320 +  lookup_instance_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK);
   1.321 +
   1.322 +  if (resolved_method.is_null()) {
   1.323 +    // lookup method in all the super-interfaces
   1.324 +    lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
   1.325 +    if (resolved_method.is_null()) {
   1.326 +      // no method found
   1.327 +      ResourceMark rm(THREAD);
   1.328 +      THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
   1.329 +                methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   1.330 +                                                        method_name(),
   1.331 +                                                        method_signature()));
   1.332 +    }
   1.333 +  }
   1.334 +
   1.335 +  if (check_access) {
   1.336 +    HandleMark hm(THREAD);
   1.337 +    Handle loader (THREAD, instanceKlass::cast(current_klass())->class_loader());
   1.338 +    Handle class_loader (THREAD, instanceKlass::cast(resolved_method->method_holder())->class_loader());
   1.339 +    {
   1.340 +      ResourceMark rm(THREAD);
   1.341 +      char* failed_type_name =
   1.342 +        SystemDictionary::check_signature_loaders(method_signature, loader,
   1.343 +                                                  class_loader, true, CHECK);
   1.344 +      if (failed_type_name != NULL) {
   1.345 +        const char* msg = "loader constraint violation: when resolving "
   1.346 +          "interface method \"%s\" the class loader (instance of %s) of the "
   1.347 +          "current class, %s, and the class loader (instance of %s) for "
   1.348 +          "resolved class, %s, have different Class objects for the type %s "
   1.349 +          "used in the signature";
   1.350 +        char* sig = methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name(),method_signature());
   1.351 +        const char* loader1 = SystemDictionary::loader_name(loader());
   1.352 +        char* current = instanceKlass::cast(current_klass())->name()->as_C_string();
   1.353 +        const char* loader2 = SystemDictionary::loader_name(class_loader());
   1.354 +        char* resolved = instanceKlass::cast(resolved_klass())->name()->as_C_string();
   1.355 +        size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) +
   1.356 +          strlen(current) + strlen(loader2) + strlen(resolved) +
   1.357 +          strlen(failed_type_name);
   1.358 +        char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
   1.359 +        jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2,
   1.360 +                     resolved, failed_type_name);
   1.361 +        THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
   1.362 +      }
   1.363 +    }
   1.364 +  }
   1.365 +}
   1.366 +
   1.367 +//------------------------------------------------------------------------------------------------------------------------
   1.368 +// Field resolution
   1.369 +
   1.370 +void LinkResolver::check_field_accessability(KlassHandle ref_klass,
   1.371 +                                             KlassHandle resolved_klass,
   1.372 +                                             KlassHandle sel_klass,
   1.373 +                                             fieldDescriptor& fd,
   1.374 +                                             TRAPS) {
   1.375 +  if (!Reflection::verify_field_access(ref_klass->as_klassOop(),
   1.376 +                                       resolved_klass->as_klassOop(),
   1.377 +                                       sel_klass->as_klassOop(),
   1.378 +                                       fd.access_flags(),
   1.379 +                                       true)) {
   1.380 +    ResourceMark rm(THREAD);
   1.381 +    Exceptions::fthrow(
   1.382 +      THREAD_AND_LOCATION,
   1.383 +      vmSymbolHandles::java_lang_IllegalAccessError(),
   1.384 +      "tried to access field %s.%s from class %s",
   1.385 +      sel_klass->external_name(),
   1.386 +      fd.name()->as_C_string(),
   1.387 +      ref_klass->external_name()
   1.388 +    );
   1.389 +    return;
   1.390 +  }
   1.391 +}
   1.392 +
   1.393 +void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, TRAPS) {
   1.394 +  resolve_field(result, pool, index, byte, check_only, true, CHECK);
   1.395 +}
   1.396 +
   1.397 +void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, bool update_pool, TRAPS) {
   1.398 +  assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
   1.399 +         byte == Bytecodes::_getfield  || byte == Bytecodes::_putfield, "bad bytecode");
   1.400 +
   1.401 +  bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic);
   1.402 +  bool is_put    = (byte == Bytecodes::_putfield  || byte == Bytecodes::_putstatic);
   1.403 +
   1.404 +  // resolve specified klass
   1.405 +  KlassHandle resolved_klass;
   1.406 +  if (update_pool) {
   1.407 +    resolve_klass(resolved_klass, pool, index, CHECK);
   1.408 +  } else {
   1.409 +    resolve_klass_no_update(resolved_klass, pool, index, CHECK);
   1.410 +  }
   1.411 +  // Load these early in case the resolve of the containing klass fails
   1.412 +  symbolOop field = pool->name_ref_at(index);
   1.413 +  symbolHandle field_h (THREAD, field); // preserve in case we need the name
   1.414 +  symbolOop sig   = pool->signature_ref_at(index);
   1.415 +  // Check if there's a resolved klass containing the field
   1.416 +  if( resolved_klass.is_null() ) {
   1.417 +    ResourceMark rm(THREAD);
   1.418 +    THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
   1.419 +  }
   1.420 +
   1.421 +  // Resolve instance field
   1.422 +  fieldDescriptor fd; // find_field initializes fd if found
   1.423 +  KlassHandle sel_klass(THREAD, instanceKlass::cast(resolved_klass())->find_field(field, sig, &fd));
   1.424 +  // check if field exists; i.e., if a klass containing the field def has been selected
   1.425 +  if (sel_klass.is_null()){
   1.426 +    ResourceMark rm(THREAD);
   1.427 +    THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
   1.428 +  }
   1.429 +
   1.430 +  // check access
   1.431 +  KlassHandle ref_klass(THREAD, pool->pool_holder());
   1.432 +  check_field_accessability(ref_klass, resolved_klass, sel_klass, fd, CHECK);
   1.433 +
   1.434 +  // check for errors
   1.435 +  if (is_static != fd.is_static()) {
   1.436 +    char msg[200];
   1.437 +    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());
   1.438 +    THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), msg);
   1.439 +  }
   1.440 +
   1.441 +  // Final fields can only be accessed from its own class.
   1.442 +  if (is_put && fd.access_flags().is_final() && sel_klass() != pool->pool_holder()) {
   1.443 +    THROW(vmSymbols::java_lang_IllegalAccessError());
   1.444 +  }
   1.445 +
   1.446 +  // initialize resolved_klass if necessary
   1.447 +  // note 1: the klass which declared the field must be initialized (i.e, sel_klass)
   1.448 +  //         according to the newest JVM spec (5.5, p.170) - was bug (gri 7/28/99)
   1.449 +  //
   1.450 +  // note 2: we don't want to force initialization if we are just checking
   1.451 +  //         if the field access is legal; e.g., during compilation
   1.452 +  if (is_static && !check_only) {
   1.453 +    sel_klass->initialize(CHECK);
   1.454 +  }
   1.455 +
   1.456 +  {
   1.457 +    HandleMark hm(THREAD);
   1.458 +    Handle ref_loader (THREAD, instanceKlass::cast(ref_klass())->class_loader());
   1.459 +    Handle sel_loader (THREAD, instanceKlass::cast(sel_klass())->class_loader());
   1.460 +    symbolHandle signature_ref (THREAD, pool->signature_ref_at(index));
   1.461 +    {
   1.462 +      ResourceMark rm(THREAD);
   1.463 +      char* failed_type_name =
   1.464 +        SystemDictionary::check_signature_loaders(signature_ref,
   1.465 +                                                  ref_loader, sel_loader,
   1.466 +                                                  false,
   1.467 +                                                  CHECK);
   1.468 +      if (failed_type_name != NULL) {
   1.469 +        const char* msg = "loader constraint violation: when resolving field"
   1.470 +          " \"%s\" the class loader (instance of %s) of the referring class, "
   1.471 +          "%s, and the class loader (instance of %s) for the field's resolved "
   1.472 +          "type, %s, have different Class objects for that type";
   1.473 +        char* field_name = field_h()->as_C_string();
   1.474 +        const char* loader1 = SystemDictionary::loader_name(ref_loader());
   1.475 +        char* sel = instanceKlass::cast(sel_klass())->name()->as_C_string();
   1.476 +        const char* loader2 = SystemDictionary::loader_name(sel_loader());
   1.477 +        size_t buflen = strlen(msg) + strlen(field_name) + strlen(loader1) +
   1.478 +          strlen(sel) + strlen(loader2) + strlen(failed_type_name);
   1.479 +        char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
   1.480 +        jio_snprintf(buf, buflen, msg, field_name, loader1, sel, loader2,
   1.481 +                     failed_type_name);
   1.482 +        THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
   1.483 +      }
   1.484 +    }
   1.485 +  }
   1.486 +
   1.487 +  // return information. note that the klass is set to the actual klass containing the
   1.488 +  // field, otherwise access of static fields in superclasses will not work.
   1.489 +  KlassHandle holder (THREAD, fd.field_holder());
   1.490 +  symbolHandle name  (THREAD, fd.name());
   1.491 +  result.set(holder, name, fd.index(), fd.offset(), fd.field_type(), fd.access_flags());
   1.492 +}
   1.493 +
   1.494 +
   1.495 +//------------------------------------------------------------------------------------------------------------------------
   1.496 +// Invoke resolution
   1.497 +//
   1.498 +// Naming conventions:
   1.499 +//
   1.500 +// resolved_method    the specified method (i.e., static receiver specified via constant pool index)
   1.501 +// sel_method         the selected method  (selected via run-time lookup; e.g., based on dynamic receiver class)
   1.502 +// resolved_klass     the specified klass  (i.e., specified via constant pool index)
   1.503 +// recv_klass         the receiver klass
   1.504 +
   1.505 +
   1.506 +void LinkResolver::resolve_static_call(CallInfo& result, KlassHandle& resolved_klass, symbolHandle method_name,
   1.507 +                                       symbolHandle method_signature, KlassHandle current_klass,
   1.508 +                                       bool check_access, bool initialize_class, TRAPS) {
   1.509 +  methodHandle resolved_method;
   1.510 +  linktime_resolve_static_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
   1.511 +  resolved_klass = KlassHandle(THREAD, Klass::cast(resolved_method->method_holder()));
   1.512 +
   1.513 +  // Initialize klass (this should only happen if everything is ok)
   1.514 +  if (initialize_class && resolved_klass->should_be_initialized()) {
   1.515 +    resolved_klass->initialize(CHECK);
   1.516 +    linktime_resolve_static_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
   1.517 +  }
   1.518 +
   1.519 +  // setup result
   1.520 +  result.set_static(resolved_klass, resolved_method, CHECK);
   1.521 +}
   1.522 +
   1.523 +// throws linktime exceptions
   1.524 +void LinkResolver::linktime_resolve_static_method(methodHandle& resolved_method, KlassHandle resolved_klass,
   1.525 +                                                  symbolHandle method_name, symbolHandle method_signature,
   1.526 +                                                  KlassHandle current_klass, bool check_access, TRAPS) {
   1.527 +
   1.528 +  resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
   1.529 +  assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
   1.530 +
   1.531 +  // check if static
   1.532 +  if (!resolved_method->is_static()) {
   1.533 +    char buf[200];
   1.534 +    jio_snprintf(buf, sizeof(buf), "Expected static method %s", methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   1.535 +                                                      resolved_method->name(),
   1.536 +                                                      resolved_method->signature()));
   1.537 +    THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   1.538 +  }
   1.539 +}
   1.540 +
   1.541 +
   1.542 +void LinkResolver::resolve_special_call(CallInfo& result, KlassHandle resolved_klass, symbolHandle method_name,
   1.543 +                                        symbolHandle method_signature, KlassHandle current_klass, bool check_access, TRAPS) {
   1.544 +  methodHandle resolved_method;
   1.545 +  linktime_resolve_special_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
   1.546 +  runtime_resolve_special_method(result, resolved_method, resolved_klass, current_klass, check_access, CHECK);
   1.547 +}
   1.548 +
   1.549 +// throws linktime exceptions
   1.550 +void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method, KlassHandle resolved_klass,
   1.551 +                                                   symbolHandle method_name, symbolHandle method_signature,
   1.552 +                                                   KlassHandle current_klass, bool check_access, TRAPS) {
   1.553 +
   1.554 +  resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
   1.555 +
   1.556 +  // check if method name is <init>, that it is found in same klass as static type
   1.557 +  if (resolved_method->name() == vmSymbols::object_initializer_name() &&
   1.558 +      resolved_method->method_holder() != resolved_klass()) {
   1.559 +    ResourceMark rm(THREAD);
   1.560 +    Exceptions::fthrow(
   1.561 +      THREAD_AND_LOCATION,
   1.562 +      vmSymbolHandles::java_lang_NoSuchMethodError(),
   1.563 +      "%s: method %s%s not found",
   1.564 +      resolved_klass->external_name(),
   1.565 +      resolved_method->name()->as_C_string(),
   1.566 +      resolved_method->signature()->as_C_string()
   1.567 +    );
   1.568 +    return;
   1.569 +  }
   1.570 +
   1.571 +  // check if not static
   1.572 +  if (resolved_method->is_static()) {
   1.573 +    char buf[200];
   1.574 +    jio_snprintf(buf, sizeof(buf),
   1.575 +                 "Expecting non-static method %s",
   1.576 +                 methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   1.577 +                                                         resolved_method->name(),
   1.578 +                                                         resolved_method->signature()));
   1.579 +    THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   1.580 +  }
   1.581 +}
   1.582 +
   1.583 +// throws runtime exceptions
   1.584 +void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass,
   1.585 +                                                  KlassHandle current_klass, bool check_access, TRAPS) {
   1.586 +
   1.587 +  // resolved method is selected method unless we have an old-style lookup
   1.588 +  methodHandle sel_method(THREAD, resolved_method());
   1.589 +
   1.590 +  // check if this is an old-style super call and do a new lookup if so
   1.591 +  { KlassHandle method_klass  = KlassHandle(THREAD,
   1.592 +                                            resolved_method->method_holder());
   1.593 +
   1.594 +    if (check_access &&
   1.595 +        // a) check if ACC_SUPER flag is set for the current class
   1.596 +        current_klass->is_super() &&
   1.597 +        // b) check if the method class is a superclass of the current class (superclass relation is not reflexive!)
   1.598 +        current_klass->is_subtype_of(method_klass()) && current_klass() != method_klass() &&
   1.599 +        // c) check if the method is not <init>
   1.600 +        resolved_method->name() != vmSymbols::object_initializer_name()) {
   1.601 +      // Lookup super method
   1.602 +      KlassHandle super_klass(THREAD, current_klass->super());
   1.603 +      lookup_instance_method_in_klasses(sel_method, super_klass,
   1.604 +                           symbolHandle(THREAD, resolved_method->name()),
   1.605 +                           symbolHandle(THREAD, resolved_method->signature()), CHECK);
   1.606 +      // check if found
   1.607 +      if (sel_method.is_null()) {
   1.608 +        ResourceMark rm(THREAD);
   1.609 +        THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
   1.610 +                  methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   1.611 +                                            resolved_method->name(),
   1.612 +                                            resolved_method->signature()));
   1.613 +      }
   1.614 +    }
   1.615 +  }
   1.616 +
   1.617 +  // check if not static
   1.618 +  if (sel_method->is_static()) {
   1.619 +    char buf[200];
   1.620 +    jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   1.621 +                                                                                                             resolved_method->name(),
   1.622 +                                                                                                             resolved_method->signature()));
   1.623 +    THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   1.624 +  }
   1.625 +
   1.626 +  // check if abstract
   1.627 +  if (sel_method->is_abstract()) {
   1.628 +    ResourceMark rm(THREAD);
   1.629 +    THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
   1.630 +              methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   1.631 +                                                      sel_method->name(),
   1.632 +                                                      sel_method->signature()));
   1.633 +  }
   1.634 +
   1.635 +  // setup result
   1.636 +  result.set_static(resolved_klass, sel_method, CHECK);
   1.637 +}
   1.638 +
   1.639 +void LinkResolver::resolve_virtual_call(CallInfo& result, Handle recv, KlassHandle receiver_klass, KlassHandle resolved_klass,
   1.640 +                                        symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass,
   1.641 +                                        bool check_access, bool check_null_and_abstract, TRAPS) {
   1.642 +  methodHandle resolved_method;
   1.643 +  linktime_resolve_virtual_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
   1.644 +  runtime_resolve_virtual_method(result, resolved_method, resolved_klass, recv, receiver_klass, check_null_and_abstract, CHECK);
   1.645 +}
   1.646 +
   1.647 +// throws linktime exceptions
   1.648 +void LinkResolver::linktime_resolve_virtual_method(methodHandle &resolved_method, KlassHandle resolved_klass,
   1.649 +                                                   symbolHandle method_name, symbolHandle method_signature,
   1.650 +                                                   KlassHandle current_klass, bool check_access, TRAPS) {
   1.651 +  // normal method resolution
   1.652 +  resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
   1.653 +
   1.654 +  assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
   1.655 +  assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
   1.656 +
   1.657 +  // check if not static
   1.658 +  if (resolved_method->is_static()) {
   1.659 +    char buf[200];
   1.660 +    jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   1.661 +                                                                                                             resolved_method->name(),
   1.662 +                                                                                                             resolved_method->signature()));
   1.663 +    THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   1.664 +  }
   1.665 +}
   1.666 +
   1.667 +// throws runtime exceptions
   1.668 +void LinkResolver::runtime_resolve_virtual_method(CallInfo& result,
   1.669 +                                                  methodHandle resolved_method,
   1.670 +                                                  KlassHandle resolved_klass,
   1.671 +                                                  Handle recv,
   1.672 +                                                  KlassHandle recv_klass,
   1.673 +                                                  bool check_null_and_abstract,
   1.674 +                                                  TRAPS) {
   1.675 +
   1.676 +  // setup default return values
   1.677 +  int vtable_index = methodOopDesc::invalid_vtable_index;
   1.678 +  methodHandle selected_method;
   1.679 +
   1.680 +  assert(recv.is_null() || recv->is_oop(), "receiver is not an oop");
   1.681 +
   1.682 +  // runtime method resolution
   1.683 +  if (check_null_and_abstract && recv.is_null()) { // check if receiver exists
   1.684 +    THROW(vmSymbols::java_lang_NullPointerException());
   1.685 +  }
   1.686 +
   1.687 +  // Virtual methods cannot be resolved before its klass has been linked, for otherwise the methodOop's
   1.688 +  // has not been rewritten, and the vtable initialized.
   1.689 +  assert(instanceKlass::cast(resolved_method->method_holder())->is_linked(), "must be linked");
   1.690 +
   1.691 +  // Virtual methods cannot be resolved before its klass has been linked, for otherwise the methodOop's
   1.692 +  // has not been rewritten, and the vtable initialized. Make sure to do this after the nullcheck, since
   1.693 +  // a missing receiver might result in a bogus lookup.
   1.694 +  assert(instanceKlass::cast(resolved_method->method_holder())->is_linked(), "must be linked");
   1.695 +
   1.696 +  // do lookup based on receiver klass using the vtable index
   1.697 +  if (resolved_method->method_holder()->klass_part()->is_interface()) { // miranda method
   1.698 +    vtable_index = vtable_index_of_miranda_method(resolved_klass,
   1.699 +                           symbolHandle(THREAD, resolved_method->name()),
   1.700 +                           symbolHandle(THREAD, resolved_method->signature()), CHECK);
   1.701 +    assert(vtable_index >= 0 , "we should have valid vtable index at this point");
   1.702 +
   1.703 +    instanceKlass* inst = instanceKlass::cast(recv_klass());
   1.704 +    selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index));
   1.705 +  } else {
   1.706 +    // at this point we are sure that resolved_method is virtual and not
   1.707 +    // a miranda method; therefore, it must have a valid vtable index.
   1.708 +    vtable_index = resolved_method->vtable_index();
   1.709 +    // We could get a negative vtable_index for final methods,
   1.710 +    // because as an optimization they are they are never put in the vtable,
   1.711 +    // unless they override an existing method.
   1.712 +    // If we do get a negative, it means the resolved method is the the selected
   1.713 +    // method, and it can never be changed by an override.
   1.714 +    if (vtable_index == methodOopDesc::nonvirtual_vtable_index) {
   1.715 +      assert(resolved_method->can_be_statically_bound(), "cannot override this method");
   1.716 +      selected_method = resolved_method;
   1.717 +    } else {
   1.718 +      // recv_klass might be an arrayKlassOop but all vtables start at
   1.719 +      // the same place. The cast is to avoid virtual call and assertion.
   1.720 +      instanceKlass* inst = (instanceKlass*)recv_klass()->klass_part();
   1.721 +      selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index));
   1.722 +    }
   1.723 +  }
   1.724 +
   1.725 +  // check if method exists
   1.726 +  if (selected_method.is_null()) {
   1.727 +    ResourceMark rm(THREAD);
   1.728 +    THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
   1.729 +              methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   1.730 +                                                      resolved_method->name(),
   1.731 +                                                      resolved_method->signature()));
   1.732 +  }
   1.733 +
   1.734 +  // check if abstract
   1.735 +  if (check_null_and_abstract && selected_method->is_abstract()) {
   1.736 +    ResourceMark rm(THREAD);
   1.737 +    THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
   1.738 +              methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   1.739 +                                                      selected_method->name(),
   1.740 +                                                      selected_method->signature()));
   1.741 +  }
   1.742 +
   1.743 +  // setup result
   1.744 +  result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK);
   1.745 +}
   1.746 +
   1.747 +void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass,
   1.748 +                                          symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass,
   1.749 +                                          bool check_access, bool check_null_and_abstract, TRAPS) {
   1.750 +  methodHandle resolved_method;
   1.751 +  linktime_resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
   1.752 +  runtime_resolve_interface_method(result, resolved_method, resolved_klass, recv, recv_klass, check_null_and_abstract, CHECK);
   1.753 +}
   1.754 +
   1.755 +// throws linktime exceptions
   1.756 +void LinkResolver::linktime_resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, symbolHandle method_name,
   1.757 +                                                     symbolHandle method_signature, KlassHandle current_klass, bool check_access, TRAPS) {
   1.758 +  // normal interface method resolution
   1.759 +  resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
   1.760 +
   1.761 +  assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
   1.762 +  assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
   1.763 +}
   1.764 +
   1.765 +// throws runtime exceptions
   1.766 +void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass,
   1.767 +                                                    Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS) {
   1.768 +  // check if receiver exists
   1.769 +  if (check_null_and_abstract && recv.is_null()) {
   1.770 +    THROW(vmSymbols::java_lang_NullPointerException());
   1.771 +  }
   1.772 +
   1.773 +  // check if receiver klass implements the resolved interface
   1.774 +  if (!recv_klass->is_subtype_of(resolved_klass())) {
   1.775 +    char buf[200];
   1.776 +    jio_snprintf(buf, sizeof(buf), "Class %s does not implement the requested interface %s",
   1.777 +                 (Klass::cast(recv_klass()))->external_name(),
   1.778 +                 (Klass::cast(resolved_klass()))->external_name());
   1.779 +    THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   1.780 +  }
   1.781 +  // do lookup based on receiver klass
   1.782 +  methodHandle sel_method;
   1.783 +  lookup_instance_method_in_klasses(sel_method, recv_klass,
   1.784 +            symbolHandle(THREAD, resolved_method->name()),
   1.785 +            symbolHandle(THREAD, resolved_method->signature()), CHECK);
   1.786 +  // check if method exists
   1.787 +  if (sel_method.is_null()) {
   1.788 +    ResourceMark rm(THREAD);
   1.789 +    THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
   1.790 +              methodOopDesc::name_and_sig_as_C_string(Klass::cast(recv_klass()),
   1.791 +                                                      resolved_method->name(),
   1.792 +                                                      resolved_method->signature()));
   1.793 +  }
   1.794 +  // check if public
   1.795 +  if (!sel_method->is_public()) {
   1.796 +    ResourceMark rm(THREAD);
   1.797 +    THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
   1.798 +              methodOopDesc::name_and_sig_as_C_string(Klass::cast(recv_klass()),
   1.799 +                                                      sel_method->name(),
   1.800 +                                                      sel_method->signature()));
   1.801 +  }
   1.802 +  // check if abstract
   1.803 +  if (check_null_and_abstract && sel_method->is_abstract()) {
   1.804 +    ResourceMark rm(THREAD);
   1.805 +    THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
   1.806 +              methodOopDesc::name_and_sig_as_C_string(Klass::cast(recv_klass()),
   1.807 +                                                      sel_method->name(),
   1.808 +                                                      sel_method->signature()));
   1.809 +  }
   1.810 +  // setup result
   1.811 +  result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, CHECK);
   1.812 +}
   1.813 +
   1.814 +
   1.815 +methodHandle LinkResolver::linktime_resolve_interface_method_or_null(
   1.816 +                                                 KlassHandle resolved_klass,
   1.817 +                                                 symbolHandle method_name,
   1.818 +                                                 symbolHandle method_signature,
   1.819 +                                                 KlassHandle current_klass,
   1.820 +                                                 bool check_access) {
   1.821 +  EXCEPTION_MARK;
   1.822 +  methodHandle method_result;
   1.823 +  linktime_resolve_interface_method(method_result, resolved_klass, method_name, method_signature, current_klass, check_access, THREAD);
   1.824 +  if (HAS_PENDING_EXCEPTION) {
   1.825 +    CLEAR_PENDING_EXCEPTION;
   1.826 +    return methodHandle();
   1.827 +  } else {
   1.828 +    return method_result;
   1.829 +  }
   1.830 +}
   1.831 +
   1.832 +methodHandle LinkResolver::linktime_resolve_virtual_method_or_null(
   1.833 +                                                 KlassHandle resolved_klass,
   1.834 +                                                 symbolHandle method_name,
   1.835 +                                                 symbolHandle method_signature,
   1.836 +                                                 KlassHandle current_klass,
   1.837 +                                                 bool check_access) {
   1.838 +  EXCEPTION_MARK;
   1.839 +  methodHandle method_result;
   1.840 +  linktime_resolve_virtual_method(method_result, resolved_klass, method_name, method_signature, current_klass, check_access, THREAD);
   1.841 +  if (HAS_PENDING_EXCEPTION) {
   1.842 +    CLEAR_PENDING_EXCEPTION;
   1.843 +    return methodHandle();
   1.844 +  } else {
   1.845 +    return method_result;
   1.846 +  }
   1.847 +}
   1.848 +
   1.849 +methodHandle LinkResolver::resolve_virtual_call_or_null(
   1.850 +                                                 KlassHandle receiver_klass,
   1.851 +                                                 KlassHandle resolved_klass,
   1.852 +                                                 symbolHandle name,
   1.853 +                                                 symbolHandle signature,
   1.854 +                                                 KlassHandle current_klass) {
   1.855 +  EXCEPTION_MARK;
   1.856 +  CallInfo info;
   1.857 +  resolve_virtual_call(info, Handle(), receiver_klass, resolved_klass, name, signature, current_klass, true, false, THREAD);
   1.858 +  if (HAS_PENDING_EXCEPTION) {
   1.859 +    CLEAR_PENDING_EXCEPTION;
   1.860 +    return methodHandle();
   1.861 +  }
   1.862 +  return info.selected_method();
   1.863 +}
   1.864 +
   1.865 +methodHandle LinkResolver::resolve_interface_call_or_null(
   1.866 +                                                 KlassHandle receiver_klass,
   1.867 +                                                 KlassHandle resolved_klass,
   1.868 +                                                 symbolHandle name,
   1.869 +                                                 symbolHandle signature,
   1.870 +                                                 KlassHandle current_klass) {
   1.871 +  EXCEPTION_MARK;
   1.872 +  CallInfo info;
   1.873 +  resolve_interface_call(info, Handle(), receiver_klass, resolved_klass, name, signature, current_klass, true, false, THREAD);
   1.874 +  if (HAS_PENDING_EXCEPTION) {
   1.875 +    CLEAR_PENDING_EXCEPTION;
   1.876 +    return methodHandle();
   1.877 +  }
   1.878 +  return info.selected_method();
   1.879 +}
   1.880 +
   1.881 +int LinkResolver::resolve_virtual_vtable_index(
   1.882 +                                               KlassHandle receiver_klass,
   1.883 +                                               KlassHandle resolved_klass,
   1.884 +                                               symbolHandle name,
   1.885 +                                               symbolHandle signature,
   1.886 +                                               KlassHandle current_klass) {
   1.887 +  EXCEPTION_MARK;
   1.888 +  CallInfo info;
   1.889 +  resolve_virtual_call(info, Handle(), receiver_klass, resolved_klass, name, signature, current_klass, true, false, THREAD);
   1.890 +  if (HAS_PENDING_EXCEPTION) {
   1.891 +    CLEAR_PENDING_EXCEPTION;
   1.892 +    return methodOopDesc::invalid_vtable_index;
   1.893 +  }
   1.894 +  return info.vtable_index();
   1.895 +}
   1.896 +
   1.897 +methodHandle LinkResolver::resolve_static_call_or_null(
   1.898 +                                                  KlassHandle resolved_klass,
   1.899 +                                                  symbolHandle name,
   1.900 +                                                  symbolHandle signature,
   1.901 +                                                  KlassHandle current_klass) {
   1.902 +  EXCEPTION_MARK;
   1.903 +  CallInfo info;
   1.904 +  resolve_static_call(info, resolved_klass, name, signature, current_klass, true, false, THREAD);
   1.905 +  if (HAS_PENDING_EXCEPTION) {
   1.906 +    CLEAR_PENDING_EXCEPTION;
   1.907 +    return methodHandle();
   1.908 +  }
   1.909 +  return info.selected_method();
   1.910 +}
   1.911 +
   1.912 +methodHandle LinkResolver::resolve_special_call_or_null(KlassHandle resolved_klass, symbolHandle name, symbolHandle signature,
   1.913 +                                                        KlassHandle current_klass) {
   1.914 +  EXCEPTION_MARK;
   1.915 +  CallInfo info;
   1.916 +  resolve_special_call(info, resolved_klass, name, signature, current_klass, true, THREAD);
   1.917 +  if (HAS_PENDING_EXCEPTION) {
   1.918 +    CLEAR_PENDING_EXCEPTION;
   1.919 +    return methodHandle();
   1.920 +  }
   1.921 +  return info.selected_method();
   1.922 +}
   1.923 +
   1.924 +
   1.925 +
   1.926 +//------------------------------------------------------------------------------------------------------------------------
   1.927 +// ConstantPool entries
   1.928 +
   1.929 +void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS) {
   1.930 +  switch (byte) {
   1.931 +    case Bytecodes::_invokestatic   : resolve_invokestatic   (result,       pool, index, CHECK); break;
   1.932 +    case Bytecodes::_invokespecial  : resolve_invokespecial  (result,       pool, index, CHECK); break;
   1.933 +    case Bytecodes::_invokevirtual  : resolve_invokevirtual  (result, recv, pool, index, CHECK); break;
   1.934 +    case Bytecodes::_invokeinterface: resolve_invokeinterface(result, recv, pool, index, CHECK); break;
   1.935 +  }
   1.936 +  return;
   1.937 +}
   1.938 +
   1.939 +void LinkResolver::resolve_pool(KlassHandle& resolved_klass, symbolHandle& method_name, symbolHandle& method_signature,
   1.940 +                                KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS) {
   1.941 +   // resolve klass
   1.942 +  resolve_klass(resolved_klass, pool, index, CHECK);
   1.943 +
   1.944 +  // Get name, signature, and static klass
   1.945 +  method_name      = symbolHandle(THREAD, pool->name_ref_at(index));
   1.946 +  method_signature = symbolHandle(THREAD, pool->signature_ref_at(index));
   1.947 +  current_klass    = KlassHandle(THREAD, pool->pool_holder());
   1.948 +}
   1.949 +
   1.950 +
   1.951 +void LinkResolver::resolve_invokestatic(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
   1.952 +  KlassHandle  resolved_klass;
   1.953 +  symbolHandle method_name;
   1.954 +  symbolHandle method_signature;
   1.955 +  KlassHandle  current_klass;
   1.956 +  resolve_pool(resolved_klass, method_name,  method_signature, current_klass, pool, index, CHECK);
   1.957 +  resolve_static_call(result, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
   1.958 +}
   1.959 +
   1.960 +
   1.961 +void LinkResolver::resolve_invokespecial(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
   1.962 +  KlassHandle  resolved_klass;
   1.963 +  symbolHandle method_name;
   1.964 +  symbolHandle method_signature;
   1.965 +  KlassHandle  current_klass;
   1.966 +  resolve_pool(resolved_klass, method_name,  method_signature, current_klass, pool, index, CHECK);
   1.967 +  resolve_special_call(result, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
   1.968 +}
   1.969 +
   1.970 +
   1.971 +void LinkResolver::resolve_invokevirtual(CallInfo& result, Handle recv,
   1.972 +                                          constantPoolHandle pool, int index,
   1.973 +                                          TRAPS) {
   1.974 +
   1.975 +  KlassHandle  resolved_klass;
   1.976 +  symbolHandle method_name;
   1.977 +  symbolHandle method_signature;
   1.978 +  KlassHandle  current_klass;
   1.979 +  resolve_pool(resolved_klass, method_name,  method_signature, current_klass, pool, index, CHECK);
   1.980 +  KlassHandle recvrKlass (THREAD, recv.is_null() ? (klassOop)NULL : recv->klass());
   1.981 +  resolve_virtual_call(result, recv, recvrKlass, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
   1.982 +}
   1.983 +
   1.984 +
   1.985 +void LinkResolver::resolve_invokeinterface(CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS) {
   1.986 +  KlassHandle  resolved_klass;
   1.987 +  symbolHandle method_name;
   1.988 +  symbolHandle method_signature;
   1.989 +  KlassHandle  current_klass;
   1.990 +  resolve_pool(resolved_klass, method_name,  method_signature, current_klass, pool, index, CHECK);
   1.991 +  KlassHandle recvrKlass (THREAD, recv.is_null() ? (klassOop)NULL : recv->klass());
   1.992 +  resolve_interface_call(result, recv, recvrKlass, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
   1.993 +}
   1.994 +
   1.995 +//------------------------------------------------------------------------------------------------------------------------
   1.996 +#ifndef PRODUCT
   1.997 +
   1.998 +void FieldAccessInfo::print() {
   1.999 +  ResourceMark rm;
  1.1000 +  tty->print_cr("Field %s@%d", name()->as_C_string(), field_offset());
  1.1001 +}
  1.1002 +
  1.1003 +#endif

mercurial