src/share/vm/oops/instanceKlass.cpp

changeset 5848
ac9cb1d5a202
parent 5836
3374b92de2d9
child 5853
d25557d03ec0
     1.1 --- a/src/share/vm/oops/instanceKlass.cpp	Sun Oct 06 16:13:50 2013 +0200
     1.2 +++ b/src/share/vm/oops/instanceKlass.cpp	Mon Oct 07 12:20:28 2013 -0400
     1.3 @@ -238,6 +238,13 @@
     1.4    }
     1.5  }
     1.6  
     1.7 +// create a new array of vtable_indices for default methods
     1.8 +Array<int>* InstanceKlass::create_new_default_vtable_indices(int len, TRAPS) {
     1.9 +  Array<int>* vtable_indices = MetadataFactory::new_array<int>(class_loader_data(), len, CHECK_NULL);
    1.10 +  assert(default_vtable_indices() == NULL, "only create once");
    1.11 +  set_default_vtable_indices(vtable_indices);
    1.12 +  return vtable_indices;
    1.13 +}
    1.14  
    1.15  InstanceKlass::InstanceKlass(int vtable_len,
    1.16                               int itable_len,
    1.17 @@ -263,6 +270,8 @@
    1.18    set_array_klasses(NULL);
    1.19    set_methods(NULL);
    1.20    set_method_ordering(NULL);
    1.21 +  set_default_methods(NULL);
    1.22 +  set_default_vtable_indices(NULL);
    1.23    set_local_interfaces(NULL);
    1.24    set_transitive_interfaces(NULL);
    1.25    init_implementor();
    1.26 @@ -376,6 +385,21 @@
    1.27    }
    1.28    set_method_ordering(NULL);
    1.29  
    1.30 +  // default methods can be empty
    1.31 +  if (default_methods() != NULL &&
    1.32 +      default_methods() != Universe::the_empty_method_array()) {
    1.33 +    MetadataFactory::free_array<Method*>(loader_data, default_methods());
    1.34 +  }
    1.35 +  // Do NOT deallocate the default methods, they are owned by superinterfaces.
    1.36 +  set_default_methods(NULL);
    1.37 +
    1.38 +  // default methods vtable indices can be empty
    1.39 +  if (default_vtable_indices() != NULL) {
    1.40 +    MetadataFactory::free_array<int>(loader_data, default_vtable_indices());
    1.41 +  }
    1.42 +  set_default_vtable_indices(NULL);
    1.43 +
    1.44 +
    1.45    // This array is in Klass, but remove it with the InstanceKlass since
    1.46    // this place would be the only caller and it can share memory with transitive
    1.47    // interfaces.
    1.48 @@ -1354,32 +1378,44 @@
    1.49    return -1;
    1.50  }
    1.51  
    1.52 +// find_method looks up the name/signature in the local methods array
    1.53  Method* InstanceKlass::find_method(Symbol* name, Symbol* signature) const {
    1.54    return InstanceKlass::find_method(methods(), name, signature);
    1.55  }
    1.56  
    1.57 +// find_method looks up the name/signature in the local methods array
    1.58  Method* InstanceKlass::find_method(
    1.59      Array<Method*>* methods, Symbol* name, Symbol* signature) {
    1.60 +  int hit = find_method_index(methods, name, signature);
    1.61 +  return hit >= 0 ? methods->at(hit): NULL;
    1.62 +}
    1.63 +
    1.64 +// Used directly for default_methods to find the index into the
    1.65 +// default_vtable_indices, and indirectly by find_method
    1.66 +// find_method_index looks in the local methods array to return the index
    1.67 +// of the matching name/signature
    1.68 +int InstanceKlass::find_method_index(
    1.69 +    Array<Method*>* methods, Symbol* name, Symbol* signature) {
    1.70    int hit = binary_search(methods, name);
    1.71    if (hit != -1) {
    1.72      Method* m = methods->at(hit);
    1.73      // Do linear search to find matching signature.  First, quick check
    1.74      // for common case
    1.75 -    if (m->signature() == signature) return m;
    1.76 +    if (m->signature() == signature) return hit;
    1.77      // search downwards through overloaded methods
    1.78      int i;
    1.79      for (i = hit - 1; i >= 0; --i) {
    1.80          Method* m = methods->at(i);
    1.81          assert(m->is_method(), "must be method");
    1.82          if (m->name() != name) break;
    1.83 -        if (m->signature() == signature) return m;
    1.84 +        if (m->signature() == signature) return i;
    1.85      }
    1.86      // search upwards
    1.87      for (i = hit + 1; i < methods->length(); ++i) {
    1.88          Method* m = methods->at(i);
    1.89          assert(m->is_method(), "must be method");
    1.90          if (m->name() != name) break;
    1.91 -        if (m->signature() == signature) return m;
    1.92 +        if (m->signature() == signature) return i;
    1.93      }
    1.94      // not found
    1.95  #ifdef ASSERT
    1.96 @@ -1387,9 +1423,8 @@
    1.97      assert(index == -1, err_msg("binary search should have found entry %d", index));
    1.98  #endif
    1.99    }
   1.100 -  return NULL;
   1.101 +  return -1;
   1.102  }
   1.103 -
   1.104  int InstanceKlass::find_method_by_name(Symbol* name, int* end) {
   1.105    return find_method_by_name(methods(), name, end);
   1.106  }
   1.107 @@ -1408,6 +1443,7 @@
   1.108    return -1;
   1.109  }
   1.110  
   1.111 +// lookup_method searches both the local methods array and all superclasses methods arrays
   1.112  Method* InstanceKlass::uncached_lookup_method(Symbol* name, Symbol* signature) const {
   1.113    Klass* klass = const_cast<InstanceKlass*>(this);
   1.114    while (klass != NULL) {
   1.115 @@ -1418,6 +1454,21 @@
   1.116    return NULL;
   1.117  }
   1.118  
   1.119 +// lookup a method in the default methods list then in all transitive interfaces
   1.120 +// Do NOT return private or static methods
   1.121 +Method* InstanceKlass::lookup_method_in_ordered_interfaces(Symbol* name,
   1.122 +                                                         Symbol* signature) const {
   1.123 +  Method* m;
   1.124 +  if (default_methods() != NULL) {
   1.125 +    m = find_method(default_methods(), name, signature);
   1.126 +  }
   1.127 +  // Look up interfaces
   1.128 +  if (m == NULL) {
   1.129 +    m = lookup_method_in_all_interfaces(name, signature);
   1.130 +  }
   1.131 +  return m;
   1.132 +}
   1.133 +
   1.134  // lookup a method in all the interfaces that this class implements
   1.135  // Do NOT return private or static methods, new in JDK8 which are not externally visible
   1.136  // They should only be found in the initial InterfaceMethodRef
   1.137 @@ -2548,6 +2599,42 @@
   1.138    return m;
   1.139  }
   1.140  
   1.141 +
   1.142 +#if INCLUDE_JVMTI
   1.143 +// update default_methods for redefineclasses for methods that are
   1.144 +// not yet in the vtable due to concurrent subclass define and superinterface
   1.145 +// redefinition
   1.146 +// Note: those in the vtable, should have been updated via adjust_method_entries
   1.147 +void InstanceKlass::adjust_default_methods(Method** old_methods, Method** new_methods,
   1.148 +                                           int methods_length, bool* trace_name_printed) {
   1.149 +  // search the default_methods for uses of either obsolete or EMCP methods
   1.150 +  if (default_methods() != NULL) {
   1.151 +    for (int j = 0; j < methods_length; j++) {
   1.152 +      Method* old_method = old_methods[j];
   1.153 +      Method* new_method = new_methods[j];
   1.154 +
   1.155 +      for (int index = 0; index < default_methods()->length(); index ++) {
   1.156 +        if (default_methods()->at(index) == old_method) {
   1.157 +          default_methods()->at_put(index, new_method);
   1.158 +          if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
   1.159 +            if (!(*trace_name_printed)) {
   1.160 +              // RC_TRACE_MESG macro has an embedded ResourceMark
   1.161 +              RC_TRACE_MESG(("adjust: klassname=%s default methods from name=%s",
   1.162 +                             external_name(),
   1.163 +                             old_method->method_holder()->external_name()));
   1.164 +              *trace_name_printed = true;
   1.165 +            }
   1.166 +            RC_TRACE(0x00100000, ("default method update: %s(%s) ",
   1.167 +                                  new_method->name()->as_C_string(),
   1.168 +                                  new_method->signature()->as_C_string()));
   1.169 +          }
   1.170 +        }
   1.171 +      }
   1.172 +    }
   1.173 +  }
   1.174 +}
   1.175 +#endif // INCLUDE_JVMTI
   1.176 +
   1.177  // On-stack replacement stuff
   1.178  void InstanceKlass::add_osr_nmethod(nmethod* n) {
   1.179    // only one compilation can be active
   1.180 @@ -2742,11 +2829,21 @@
   1.181    st->print(BULLET"methods:           "); methods()->print_value_on(st);                  st->cr();
   1.182    if (Verbose || WizardMode) {
   1.183      Array<Method*>* method_array = methods();
   1.184 -    for(int i = 0; i < method_array->length(); i++) {
   1.185 +    for (int i = 0; i < method_array->length(); i++) {
   1.186        st->print("%d : ", i); method_array->at(i)->print_value(); st->cr();
   1.187      }
   1.188    }
   1.189 -  st->print(BULLET"method ordering:   "); method_ordering()->print_value_on(st);       st->cr();
   1.190 +  st->print(BULLET"method ordering:   "); method_ordering()->print_value_on(st);      st->cr();
   1.191 +  st->print(BULLET"default_methods:   "); default_methods()->print_value_on(st);      st->cr();
   1.192 +  if (Verbose && default_methods() != NULL) {
   1.193 +    Array<Method*>* method_array = default_methods();
   1.194 +    for (int i = 0; i < method_array->length(); i++) {
   1.195 +      st->print("%d : ", i); method_array->at(i)->print_value(); st->cr();
   1.196 +    }
   1.197 +  }
   1.198 +  if (default_vtable_indices() != NULL) {
   1.199 +    st->print(BULLET"default vtable indices:   "); default_vtable_indices()->print_value_on(st);       st->cr();
   1.200 +  }
   1.201    st->print(BULLET"local interfaces:  "); local_interfaces()->print_value_on(st);      st->cr();
   1.202    st->print(BULLET"trans. interfaces: "); transitive_interfaces()->print_value_on(st); st->cr();
   1.203    st->print(BULLET"constants:         "); constants()->print_value_on(st);         st->cr();
   1.204 @@ -3099,6 +3196,19 @@
   1.205      }
   1.206    }
   1.207  
   1.208 +  // Verify default methods
   1.209 +  if (default_methods() != NULL) {
   1.210 +    Array<Method*>* methods = this->default_methods();
   1.211 +    for (int j = 0; j < methods->length(); j++) {
   1.212 +      guarantee(methods->at(j)->is_method(), "non-method in methods array");
   1.213 +    }
   1.214 +    for (int j = 0; j < methods->length() - 1; j++) {
   1.215 +      Method* m1 = methods->at(j);
   1.216 +      Method* m2 = methods->at(j + 1);
   1.217 +      guarantee(m1->name()->fast_compare(m2->name()) <= 0, "methods not sorted correctly");
   1.218 +    }
   1.219 +  }
   1.220 +
   1.221    // Verify JNI static field identifiers
   1.222    if (jni_ids() != NULL) {
   1.223      jni_ids()->verify(this);

mercurial