src/share/vm/oops/cpCache.cpp

changeset 8997
f8a45a60bc6b
parent 8739
0b85ccd62409
child 9041
95a08233f46c
child 9076
07275619e52e
     1.1 --- a/src/share/vm/oops/cpCache.cpp	Tue Aug 08 12:02:01 2017 +0100
     1.2 +++ b/src/share/vm/oops/cpCache.cpp	Fri Sep 29 14:30:05 2017 -0400
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -259,14 +259,16 @@
    1.11    set_direct_or_vtable_call(invoke_code, method, index, false);
    1.12  }
    1.13  
    1.14 -void ConstantPoolCacheEntry::set_itable_call(Bytecodes::Code invoke_code, methodHandle method, int index) {
    1.15 +void ConstantPoolCacheEntry::set_itable_call(Bytecodes::Code invoke_code,
    1.16 +                                                        KlassHandle referenced_klass,
    1.17 +                                                        methodHandle method, int index) {
    1.18    assert(method->method_holder()->verify_itable_index(index), "");
    1.19    assert(invoke_code == Bytecodes::_invokeinterface, "");
    1.20    InstanceKlass* interf = method->method_holder();
    1.21    assert(interf->is_interface(), "must be an interface");
    1.22    assert(!method->is_final_method(), "interfaces do not have final methods; cannot link to one here");
    1.23 -  set_f1(interf);
    1.24 -  set_f2(index);
    1.25 +  set_f1(referenced_klass());
    1.26 +  set_f2((intx)method());
    1.27    set_method_flags(as_TosState(method->result_type()),
    1.28                     0,  // no option bits
    1.29                     method()->size_of_parameters());
    1.30 @@ -433,10 +435,27 @@
    1.31  
    1.32  
    1.33  #if INCLUDE_JVMTI
    1.34 +
    1.35 +void log_adjust(const char* entry_type, Method* old_method, Method* new_method, bool* trace_name_printed) {
    1.36 +  if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
    1.37 +    if (!(*trace_name_printed)) {
    1.38 +      // RC_TRACE_MESG macro has an embedded ResourceMark
    1.39 +      RC_TRACE_MESG(("adjust: name=%s",
    1.40 +        old_method->method_holder()->external_name()));
    1.41 +      *trace_name_printed = true;
    1.42 +    }
    1.43 +    // RC_TRACE macro has an embedded ResourceMark
    1.44 +    RC_TRACE(0x00400000, ("cpc %s entry update: %s(%s)",
    1.45 +      entry_type,
    1.46 +      new_method->name()->as_C_string(),
    1.47 +      new_method->signature()->as_C_string()));
    1.48 +  }
    1.49 +}
    1.50 +
    1.51  // RedefineClasses() API support:
    1.52  // If this ConstantPoolCacheEntry refers to old_method then update it
    1.53  // to refer to new_method.
    1.54 -bool ConstantPoolCacheEntry::adjust_method_entry(Method* old_method,
    1.55 +void ConstantPoolCacheEntry::adjust_method_entry(Method* old_method,
    1.56         Method* new_method, bool * trace_name_printed) {
    1.57  
    1.58    if (is_vfinal()) {
    1.59 @@ -445,69 +464,34 @@
    1.60        // match old_method so need an update
    1.61        // NOTE: can't use set_f2_as_vfinal_method as it asserts on different values
    1.62        _f2 = (intptr_t)new_method;
    1.63 -      if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
    1.64 -        if (!(*trace_name_printed)) {
    1.65 -          // RC_TRACE_MESG macro has an embedded ResourceMark
    1.66 -          RC_TRACE_MESG(("adjust: name=%s",
    1.67 -            old_method->method_holder()->external_name()));
    1.68 -          *trace_name_printed = true;
    1.69 -        }
    1.70 -        // RC_TRACE macro has an embedded ResourceMark
    1.71 -        RC_TRACE(0x00400000, ("cpc vf-entry update: %s(%s)",
    1.72 -          new_method->name()->as_C_string(),
    1.73 -          new_method->signature()->as_C_string()));
    1.74 -      }
    1.75 -      return true;
    1.76      }
    1.77 -
    1.78 -    // f1() is not used with virtual entries so bail out
    1.79 -    return false;
    1.80 +    return;
    1.81    }
    1.82  
    1.83 -  if (_f1 == NULL) {
    1.84 -    // NULL f1() means this is a virtual entry so bail out
    1.85 -    // We are assuming that the vtable index does not need change.
    1.86 -    return false;
    1.87 +  assert (_f1 != NULL, "should not call with uninteresting entry");
    1.88 +
    1.89 +  if (!(_f1->is_method())) {
    1.90 +    // _f1 is a Klass* for an interface, _f2 is the method
    1.91 +    if (f2_as_interface_method() == old_method) {
    1.92 +      _f2 = (intptr_t)new_method;
    1.93 +      log_adjust("interface", old_method, new_method, trace_name_printed);
    1.94 +    }
    1.95 +  } else if (_f1 == old_method) {
    1.96 +    _f1 = new_method;
    1.97 +    log_adjust("special, static or dynamic", old_method, new_method, trace_name_printed);
    1.98    }
    1.99 -
   1.100 -  if (_f1 == old_method) {
   1.101 -    _f1 = new_method;
   1.102 -    if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
   1.103 -      if (!(*trace_name_printed)) {
   1.104 -        // RC_TRACE_MESG macro has an embedded ResourceMark
   1.105 -        RC_TRACE_MESG(("adjust: name=%s",
   1.106 -          old_method->method_holder()->external_name()));
   1.107 -        *trace_name_printed = true;
   1.108 -      }
   1.109 -      // RC_TRACE macro has an embedded ResourceMark
   1.110 -      RC_TRACE(0x00400000, ("cpc entry update: %s(%s)",
   1.111 -        new_method->name()->as_C_string(),
   1.112 -        new_method->signature()->as_C_string()));
   1.113 -    }
   1.114 -    return true;
   1.115 -  }
   1.116 -
   1.117 -  return false;
   1.118  }
   1.119  
   1.120  // a constant pool cache entry should never contain old or obsolete methods
   1.121  bool ConstantPoolCacheEntry::check_no_old_or_obsolete_entries() {
   1.122 -  if (is_vfinal()) {
   1.123 -    // virtual and final so _f2 contains method ptr instead of vtable index
   1.124 -    Metadata* f2 = (Metadata*)_f2;
   1.125 -    // Return false if _f2 refers to an old or an obsolete method.
   1.126 -    // _f2 == NULL || !_f2->is_method() are just as unexpected here.
   1.127 -    return (f2 != NULL NOT_PRODUCT(&& f2->is_valid()) && f2->is_method() &&
   1.128 -            !((Method*)f2)->is_old() && !((Method*)f2)->is_obsolete());
   1.129 -  } else if (_f1 == NULL ||
   1.130 -             (NOT_PRODUCT(_f1->is_valid() &&) !_f1->is_method())) {
   1.131 -    // _f1 == NULL || !_f1->is_method() are OK here
   1.132 +  Method* m = get_interesting_method_entry(NULL);
   1.133 +  // return false if m refers to a non-deleted old or obsolete method
   1.134 +  if (m != NULL) {
   1.135 +    assert(m->is_valid() && m->is_method(), "m is a valid method");
   1.136 +    return !m->is_old() && !m->is_obsolete(); // old is always set for old and obsolete
   1.137 +  } else {
   1.138      return true;
   1.139    }
   1.140 -  // return false if _f1 refers to a non-deleted old or obsolete method
   1.141 -  return (NOT_PRODUCT(_f1->is_valid() &&) _f1->is_method() &&
   1.142 -          (f1_as_method()->is_deleted() ||
   1.143 -          (!f1_as_method()->is_old() && !f1_as_method()->is_obsolete())));
   1.144  }
   1.145  
   1.146  Method* ConstantPoolCacheEntry::get_interesting_method_entry(Klass* k) {
   1.147 @@ -524,10 +508,11 @@
   1.148      return NULL;
   1.149    } else {
   1.150      if (!(_f1->is_method())) {
   1.151 -      // _f1 can also contain a Klass* for an interface
   1.152 -      return NULL;
   1.153 +      // _f1 is a Klass* for an interface
   1.154 +      m = f2_as_interface_method();
   1.155 +    } else {
   1.156 +      m = f1_as_method();
   1.157      }
   1.158 -    m = f1_as_method();
   1.159    }
   1.160    assert(m != NULL && m->is_method(), "sanity check");
   1.161    if (m == NULL || !m->is_method() || (k != NULL && m->method_holder() != k)) {

mercurial