src/share/vm/interpreter/linkResolver.cpp

changeset 5732
b2e698d2276c
parent 4960
41ed397cc0cd
child 5784
190899198332
     1.1 --- a/src/share/vm/interpreter/linkResolver.cpp	Tue Sep 17 23:12:27 2013 +0200
     1.2 +++ b/src/share/vm/interpreter/linkResolver.cpp	Fri Sep 13 22:38:02 2013 -0400
     1.3 @@ -46,19 +46,6 @@
     1.4  #include "runtime/thread.inline.hpp"
     1.5  #include "runtime/vmThread.hpp"
     1.6  
     1.7 -//------------------------------------------------------------------------------------------------------------------------
     1.8 -// Implementation of FieldAccessInfo
     1.9 -
    1.10 -void FieldAccessInfo::set(KlassHandle klass, Symbol* name, int field_index, int field_offset,
    1.11 -BasicType field_type, AccessFlags access_flags) {
    1.12 -  _klass        = klass;
    1.13 -  _name         = name;
    1.14 -  _field_index  = field_index;
    1.15 -  _field_offset = field_offset;
    1.16 -  _field_type   = field_type;
    1.17 -  _access_flags = access_flags;
    1.18 -}
    1.19 -
    1.20  
    1.21  //------------------------------------------------------------------------------------------------------------------------
    1.22  // Implementation of CallInfo
    1.23 @@ -66,26 +53,25 @@
    1.24  
    1.25  void CallInfo::set_static(KlassHandle resolved_klass, methodHandle resolved_method, TRAPS) {
    1.26    int vtable_index = Method::nonvirtual_vtable_index;
    1.27 -  set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, vtable_index, CHECK);
    1.28 +  set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, CallInfo::direct_call, vtable_index, CHECK);
    1.29  }
    1.30  
    1.31  
    1.32 -void CallInfo::set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, TRAPS) {
    1.33 +void CallInfo::set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int itable_index, TRAPS) {
    1.34    // This is only called for interface methods. If the resolved_method
    1.35    // comes from java/lang/Object, it can be the subject of a virtual call, so
    1.36    // we should pick the vtable index from the resolved method.
    1.37 -  // Other than that case, there is no valid vtable index to specify.
    1.38 -  int vtable_index = Method::invalid_vtable_index;
    1.39 -  if (resolved_method->method_holder() == SystemDictionary::Object_klass()) {
    1.40 -    assert(resolved_method->vtable_index() == selected_method->vtable_index(), "sanity check");
    1.41 -    vtable_index = resolved_method->vtable_index();
    1.42 -  }
    1.43 -  set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK);
    1.44 +  // In that case, the caller must call set_virtual instead of set_interface.
    1.45 +  assert(resolved_method->method_holder()->is_interface(), "");
    1.46 +  assert(itable_index == resolved_method()->itable_index(), "");
    1.47 +  set_common(resolved_klass, selected_klass, resolved_method, selected_method, CallInfo::itable_call, itable_index, CHECK);
    1.48  }
    1.49  
    1.50  void CallInfo::set_virtual(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) {
    1.51    assert(vtable_index >= 0 || vtable_index == Method::nonvirtual_vtable_index, "valid index");
    1.52 -  set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK);
    1.53 +  assert(vtable_index < 0 || !resolved_method->has_vtable_index() || vtable_index == resolved_method->vtable_index(), "");
    1.54 +  CallKind kind = (vtable_index >= 0 && !resolved_method->can_be_statically_bound() ? CallInfo::vtable_call : CallInfo::direct_call);
    1.55 +  set_common(resolved_klass, selected_klass, resolved_method, selected_method, kind, vtable_index, CHECK);
    1.56    assert(!resolved_method->is_compiled_lambda_form(), "these must be handled via an invokehandle call");
    1.57  }
    1.58  
    1.59 @@ -98,20 +84,29 @@
    1.60           resolved_method->is_compiled_lambda_form(),
    1.61           "linkMethod must return one of these");
    1.62    int vtable_index = Method::nonvirtual_vtable_index;
    1.63 -  assert(resolved_method->vtable_index() == vtable_index, "");
    1.64 -  set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, vtable_index, CHECK);
    1.65 +  assert(!resolved_method->has_vtable_index(), "");
    1.66 +  set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, CallInfo::direct_call, vtable_index, CHECK);
    1.67    _resolved_appendix    = resolved_appendix;
    1.68    _resolved_method_type = resolved_method_type;
    1.69  }
    1.70  
    1.71 -void CallInfo::set_common(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) {
    1.72 +void CallInfo::set_common(KlassHandle resolved_klass,
    1.73 +                          KlassHandle selected_klass,
    1.74 +                          methodHandle resolved_method,
    1.75 +                          methodHandle selected_method,
    1.76 +                          CallKind kind,
    1.77 +                          int index,
    1.78 +                          TRAPS) {
    1.79    assert(resolved_method->signature() == selected_method->signature(), "signatures must correspond");
    1.80    _resolved_klass  = resolved_klass;
    1.81    _selected_klass  = selected_klass;
    1.82    _resolved_method = resolved_method;
    1.83    _selected_method = selected_method;
    1.84 -  _vtable_index    = vtable_index;
    1.85 +  _call_kind       = kind;
    1.86 +  _call_index      = index;
    1.87    _resolved_appendix = Handle();
    1.88 +  DEBUG_ONLY(verify());  // verify before making side effects
    1.89 +
    1.90    if (CompilationPolicy::must_be_compiled(selected_method)) {
    1.91      // This path is unusual, mostly used by the '-Xcomp' stress test mode.
    1.92  
    1.93 @@ -138,6 +133,65 @@
    1.94    }
    1.95  }
    1.96  
    1.97 +// utility query for unreflecting a method
    1.98 +CallInfo::CallInfo(Method* resolved_method, Klass* resolved_klass) {
    1.99 +  Klass* resolved_method_holder = resolved_method->method_holder();
   1.100 +  if (resolved_klass == NULL) { // 2nd argument defaults to holder of 1st
   1.101 +    resolved_klass = resolved_method_holder;
   1.102 +  }
   1.103 +  _resolved_klass  = resolved_klass;
   1.104 +  _selected_klass  = resolved_klass;
   1.105 +  _resolved_method = resolved_method;
   1.106 +  _selected_method = resolved_method;
   1.107 +  // classify:
   1.108 +  CallKind kind = CallInfo::unknown_kind;
   1.109 +  int index = resolved_method->vtable_index();
   1.110 +  if (resolved_method->can_be_statically_bound()) {
   1.111 +    kind = CallInfo::direct_call;
   1.112 +  } else if (!resolved_method_holder->is_interface()) {
   1.113 +    // Could be an Object method inherited into an interface, but still a vtable call.
   1.114 +    kind = CallInfo::vtable_call;
   1.115 +  } else if (!resolved_klass->is_interface()) {
   1.116 +    // A miranda method.  Compute the vtable index.
   1.117 +    ResourceMark rm;
   1.118 +    klassVtable* vt = InstanceKlass::cast(resolved_klass)->vtable();
   1.119 +    index = vt->index_of_miranda(resolved_method->name(),
   1.120 +                                 resolved_method->signature());
   1.121 +    kind = CallInfo::vtable_call;
   1.122 +  } else {
   1.123 +    // A regular interface call.
   1.124 +    kind = CallInfo::itable_call;
   1.125 +    index = resolved_method->itable_index();
   1.126 +  }
   1.127 +  assert(index == Method::nonvirtual_vtable_index || index >= 0, err_msg("bad index %d", index));
   1.128 +  _call_kind  = kind;
   1.129 +  _call_index = index;
   1.130 +  _resolved_appendix = Handle();
   1.131 +  DEBUG_ONLY(verify());
   1.132 +}
   1.133 +
   1.134 +#ifdef ASSERT
   1.135 +void CallInfo::verify() {
   1.136 +  switch (call_kind()) {  // the meaning and allowed value of index depends on kind
   1.137 +  case CallInfo::direct_call:
   1.138 +    if (_call_index == Method::nonvirtual_vtable_index)  break;
   1.139 +    // else fall through to check vtable index:
   1.140 +  case CallInfo::vtable_call:
   1.141 +    assert(resolved_klass()->verify_vtable_index(_call_index), "");
   1.142 +    break;
   1.143 +  case CallInfo::itable_call:
   1.144 +    assert(resolved_method()->method_holder()->verify_itable_index(_call_index), "");
   1.145 +    break;
   1.146 +  case CallInfo::unknown_kind:
   1.147 +    assert(call_kind() != CallInfo::unknown_kind, "CallInfo must be set");
   1.148 +    break;
   1.149 +  default:
   1.150 +    fatal(err_msg_res("Unexpected call kind %d", call_kind()));
   1.151 +  }
   1.152 +}
   1.153 +#endif //ASSERT
   1.154 +
   1.155 +
   1.156  
   1.157  //------------------------------------------------------------------------------------------------------------------------
   1.158  // Klass resolution
   1.159 @@ -163,13 +217,6 @@
   1.160    result = KlassHandle(THREAD, result_oop);
   1.161  }
   1.162  
   1.163 -void LinkResolver::resolve_klass_no_update(KlassHandle& result, constantPoolHandle pool, int index, TRAPS) {
   1.164 -  Klass* result_oop =
   1.165 -         ConstantPool::klass_ref_at_if_loaded_check(pool, index, CHECK);
   1.166 -  result = KlassHandle(THREAD, result_oop);
   1.167 -}
   1.168 -
   1.169 -
   1.170  //------------------------------------------------------------------------------------------------------------------------
   1.171  // Method resolution
   1.172  //
   1.173 @@ -360,7 +407,12 @@
   1.174  
   1.175  void LinkResolver::resolve_method_statically(methodHandle& resolved_method, KlassHandle& resolved_klass,
   1.176                                               Bytecodes::Code code, constantPoolHandle pool, int index, TRAPS) {
   1.177 -
   1.178 +  // This method is used only
   1.179 +  // (1) in C2 from InlineTree::ok_to_inline (via ciMethod::check_call),
   1.180 +  // and
   1.181 +  // (2) in Bytecode_invoke::static_target
   1.182 +  // It appears to fail when applied to an invokeinterface call site.
   1.183 +  // FIXME: Remove this method and ciMethod::check_call; refactor to use the other LinkResolver entry points.
   1.184    // resolve klass
   1.185    if (code == Bytecodes::_invokedynamic) {
   1.186      resolved_klass = SystemDictionary::MethodHandle_klass();
   1.187 @@ -580,45 +632,49 @@
   1.188    }
   1.189  }
   1.190  
   1.191 -void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, TRAPS) {
   1.192 -  resolve_field(result, pool, index, byte, check_only, true, CHECK);
   1.193 +void LinkResolver::resolve_field_access(fieldDescriptor& result, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS) {
   1.194 +  // Load these early in case the resolve of the containing klass fails
   1.195 +  Symbol* field = pool->name_ref_at(index);
   1.196 +  Symbol* sig   = pool->signature_ref_at(index);
   1.197 +
   1.198 +  // resolve specified klass
   1.199 +  KlassHandle resolved_klass;
   1.200 +  resolve_klass(resolved_klass, pool, index, CHECK);
   1.201 +
   1.202 +  KlassHandle  current_klass(THREAD, pool->pool_holder());
   1.203 +  resolve_field(result, resolved_klass, field, sig, current_klass, byte, true, true, CHECK);
   1.204  }
   1.205  
   1.206 -void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, bool update_pool, TRAPS) {
   1.207 +void LinkResolver::resolve_field(fieldDescriptor& fd, KlassHandle resolved_klass, Symbol* field, Symbol* sig,
   1.208 +                                 KlassHandle current_klass, Bytecodes::Code byte, bool check_access, bool initialize_class,
   1.209 +                                 TRAPS) {
   1.210    assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
   1.211 -         byte == Bytecodes::_getfield  || byte == Bytecodes::_putfield, "bad bytecode");
   1.212 +         byte == Bytecodes::_getfield  || byte == Bytecodes::_putfield  ||
   1.213 +         (byte == Bytecodes::_nop && !check_access), "bad field access bytecode");
   1.214  
   1.215    bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic);
   1.216    bool is_put    = (byte == Bytecodes::_putfield  || byte == Bytecodes::_putstatic);
   1.217  
   1.218 -  // resolve specified klass
   1.219 -  KlassHandle resolved_klass;
   1.220 -  if (update_pool) {
   1.221 -    resolve_klass(resolved_klass, pool, index, CHECK);
   1.222 -  } else {
   1.223 -    resolve_klass_no_update(resolved_klass, pool, index, CHECK);
   1.224 -  }
   1.225 -  // Load these early in case the resolve of the containing klass fails
   1.226 -  Symbol* field = pool->name_ref_at(index);
   1.227 -  Symbol* sig   = pool->signature_ref_at(index);
   1.228    // Check if there's a resolved klass containing the field
   1.229 -  if( resolved_klass.is_null() ) {
   1.230 +  if (resolved_klass.is_null()) {
   1.231      ResourceMark rm(THREAD);
   1.232      THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
   1.233    }
   1.234  
   1.235    // Resolve instance field
   1.236 -  fieldDescriptor fd; // find_field initializes fd if found
   1.237    KlassHandle sel_klass(THREAD, InstanceKlass::cast(resolved_klass())->find_field(field, sig, &fd));
   1.238    // check if field exists; i.e., if a klass containing the field def has been selected
   1.239 -  if (sel_klass.is_null()){
   1.240 +  if (sel_klass.is_null()) {
   1.241      ResourceMark rm(THREAD);
   1.242      THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
   1.243    }
   1.244  
   1.245 +  if (!check_access)
   1.246 +    // Access checking may be turned off when calling from within the VM.
   1.247 +    return;
   1.248 +
   1.249    // check access
   1.250 -  KlassHandle ref_klass(THREAD, pool->pool_holder());
   1.251 -  check_field_accessability(ref_klass, resolved_klass, sel_klass, fd, CHECK);
   1.252 +  check_field_accessability(current_klass, resolved_klass, sel_klass, fd, CHECK);
   1.253  
   1.254    // check for errors
   1.255    if (is_static != fd.is_static()) {
   1.256 @@ -629,7 +685,7 @@
   1.257    }
   1.258  
   1.259    // Final fields can only be accessed from its own class.
   1.260 -  if (is_put && fd.access_flags().is_final() && sel_klass() != pool->pool_holder()) {
   1.261 +  if (is_put && fd.access_flags().is_final() && sel_klass() != current_klass()) {
   1.262      THROW(vmSymbols::java_lang_IllegalAccessError());
   1.263    }
   1.264  
   1.265 @@ -639,19 +695,18 @@
   1.266    //
   1.267    // note 2: we don't want to force initialization if we are just checking
   1.268    //         if the field access is legal; e.g., during compilation
   1.269 -  if (is_static && !check_only) {
   1.270 +  if (is_static && initialize_class) {
   1.271      sel_klass->initialize(CHECK);
   1.272    }
   1.273  
   1.274 -  {
   1.275 +  if (sel_klass() != current_klass()) {
   1.276      HandleMark hm(THREAD);
   1.277 -    Handle ref_loader (THREAD, InstanceKlass::cast(ref_klass())->class_loader());
   1.278 +    Handle ref_loader (THREAD, InstanceKlass::cast(current_klass())->class_loader());
   1.279      Handle sel_loader (THREAD, InstanceKlass::cast(sel_klass())->class_loader());
   1.280 -    Symbol*  signature_ref  = pool->signature_ref_at(index);
   1.281      {
   1.282        ResourceMark rm(THREAD);
   1.283        Symbol* failed_type_symbol =
   1.284 -        SystemDictionary::check_signature_loaders(signature_ref,
   1.285 +        SystemDictionary::check_signature_loaders(sig,
   1.286                                                    ref_loader, sel_loader,
   1.287                                                    false,
   1.288                                                    CHECK);
   1.289 @@ -677,9 +732,6 @@
   1.290  
   1.291    // return information. note that the klass is set to the actual klass containing the
   1.292    // field, otherwise access of static fields in superclasses will not work.
   1.293 -  KlassHandle holder (THREAD, fd.field_holder());
   1.294 -  Symbol*  name   = fd.name();
   1.295 -  result.set(holder, name, fd.index(), fd.offset(), fd.field_type(), fd.access_flags());
   1.296  }
   1.297  
   1.298  
   1.299 @@ -907,10 +959,6 @@
   1.300    }
   1.301  
   1.302    // Virtual methods cannot be resolved before its klass has been linked, for otherwise the Method*'s
   1.303 -  // has not been rewritten, and the vtable initialized.
   1.304 -  assert(resolved_method->method_holder()->is_linked(), "must be linked");
   1.305 -
   1.306 -  // Virtual methods cannot be resolved before its klass has been linked, for otherwise the Method*'s
   1.307    // has not been rewritten, and the vtable initialized. Make sure to do this after the nullcheck, since
   1.308    // a missing receiver might result in a bogus lookup.
   1.309    assert(resolved_method->method_holder()->is_linked(), "must be linked");
   1.310 @@ -920,6 +968,7 @@
   1.311      vtable_index = vtable_index_of_miranda_method(resolved_klass,
   1.312                             resolved_method->name(),
   1.313                             resolved_method->signature(), CHECK);
   1.314 +
   1.315      assert(vtable_index >= 0 , "we should have valid vtable index at this point");
   1.316  
   1.317      InstanceKlass* inst = InstanceKlass::cast(recv_klass());
   1.318 @@ -927,6 +976,7 @@
   1.319    } else {
   1.320      // at this point we are sure that resolved_method is virtual and not
   1.321      // a miranda method; therefore, it must have a valid vtable index.
   1.322 +    assert(!resolved_method->has_itable_index(), "");
   1.323      vtable_index = resolved_method->vtable_index();
   1.324      // We could get a negative vtable_index for final methods,
   1.325      // because as an optimization they are they are never put in the vtable,
   1.326 @@ -1006,6 +1056,12 @@
   1.327    lookup_instance_method_in_klasses(sel_method, recv_klass,
   1.328              resolved_method->name(),
   1.329              resolved_method->signature(), CHECK);
   1.330 +  if (sel_method.is_null() && !check_null_and_abstract) {
   1.331 +    // In theory this is a harmless placeholder value, but
   1.332 +    // in practice leaving in null affects the nsk default method tests.
   1.333 +    // This needs further study.
   1.334 +    sel_method = resolved_method;
   1.335 +  }
   1.336    // check if method exists
   1.337    if (sel_method.is_null()) {
   1.338      ResourceMark rm(THREAD);
   1.339 @@ -1046,7 +1102,14 @@
   1.340                                                        sel_method->signature()));
   1.341    }
   1.342    // setup result
   1.343 -  result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, CHECK);
   1.344 +  if (!resolved_method->has_itable_index()) {
   1.345 +    int vtable_index = resolved_method->vtable_index();
   1.346 +    assert(vtable_index == sel_method->vtable_index(), "sanity check");
   1.347 +    result.set_virtual(resolved_klass, recv_klass, resolved_method, sel_method, vtable_index, CHECK);
   1.348 +    return;
   1.349 +  }
   1.350 +  int itable_index = resolved_method()->itable_index();
   1.351 +  result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK);
   1.352  }
   1.353  
   1.354  
   1.355 @@ -1293,7 +1356,8 @@
   1.356    }
   1.357  
   1.358    if (TraceMethodHandles) {
   1.359 -    tty->print_cr("resolve_invokedynamic #%d %s %s",
   1.360 +      ResourceMark rm(THREAD);
   1.361 +      tty->print_cr("resolve_invokedynamic #%d %s %s",
   1.362                    ConstantPool::decode_invokedynamic_index(index),
   1.363                    method_name->as_C_string(), method_signature->as_C_string());
   1.364      tty->print("  BSM info: "); bootstrap_specifier->print();
   1.365 @@ -1342,9 +1406,16 @@
   1.366  //------------------------------------------------------------------------------------------------------------------------
   1.367  #ifndef PRODUCT
   1.368  
   1.369 -void FieldAccessInfo::print() {
   1.370 +void CallInfo::print() {
   1.371    ResourceMark rm;
   1.372 -  tty->print_cr("Field %s@%d", name()->as_C_string(), field_offset());
   1.373 +  const char* kindstr = "unknown";
   1.374 +  switch (_call_kind) {
   1.375 +  case direct_call: kindstr = "direct"; break;
   1.376 +  case vtable_call: kindstr = "vtable"; break;
   1.377 +  case itable_call: kindstr = "itable"; break;
   1.378 +  }
   1.379 +  tty->print_cr("Call %s@%d %s", kindstr, _call_index,
   1.380 +                _resolved_method.is_null() ? "(none)" : _resolved_method->name_and_sig_as_C_string());
   1.381  }
   1.382  
   1.383  #endif

mercurial