8064524: Compiler code generation improvements

Mon, 01 Dec 2014 13:06:20 -0500

author
drchase
date
Mon, 01 Dec 2014 13:06:20 -0500
changeset 7714
d5b74c583ec1
parent 7713
b7e8193d0b53
child 7716
d6a05415f1f4

8064524: Compiler code generation improvements
Reviewed-by: jrose, acorn, vlivanov

src/share/vm/code/dependencies.cpp file | annotate | diff | comparison | revisions
src/share/vm/code/dependencies.hpp file | annotate | diff | comparison | revisions
src/share/vm/interpreter/linkResolver.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/instanceKlass.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/instanceKlass.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/code/dependencies.cpp	Wed Nov 19 15:02:01 2014 -0800
     1.2 +++ b/src/share/vm/code/dependencies.cpp	Mon Dec 01 13:06:20 2014 -0500
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2005, 2014, 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 @@ -560,7 +560,7 @@
    1.11        put_star = !Dependencies::is_concrete_klass((Klass*)arg.metadata_value());
    1.12      } else if (arg.is_method()) {
    1.13        what = "method ";
    1.14 -      put_star = !Dependencies::is_concrete_method((Method*)arg.metadata_value());
    1.15 +      put_star = !Dependencies::is_concrete_method((Method*)arg.metadata_value(), NULL);
    1.16      } else if (arg.is_klass()) {
    1.17        what = "class  ";
    1.18      } else {
    1.19 @@ -845,8 +845,8 @@
    1.20          // Static methods don't override non-static so punt
    1.21          return true;
    1.22        }
    1.23 -      if (   !Dependencies::is_concrete_method(lm)
    1.24 -          && !Dependencies::is_concrete_method(m)
    1.25 +      if (   !Dependencies::is_concrete_method(lm, k)
    1.26 +          && !Dependencies::is_concrete_method(m, ctxk)
    1.27            && lm->method_holder()->is_subtype_of(m->method_holder()))
    1.28          // Method m is overridden by lm, but both are non-concrete.
    1.29          return true;
    1.30 @@ -880,8 +880,17 @@
    1.31      if (doing_subtype_search()) {
    1.32        return Dependencies::is_concrete_klass(k);
    1.33      } else {
    1.34 -      Method* m = InstanceKlass::cast(k)->find_method(_name, _signature);
    1.35 -      if (m == NULL || !Dependencies::is_concrete_method(m))  return false;
    1.36 +      // Search class hierarchy first.
    1.37 +      Method* m = InstanceKlass::cast(k)->find_instance_method(_name, _signature);
    1.38 +      if (!Dependencies::is_concrete_method(m, k)) {
    1.39 +        // Check interface defaults also, if any exist.
    1.40 +        Array<Method*>* default_methods = InstanceKlass::cast(k)->default_methods();
    1.41 +        if (default_methods == NULL)
    1.42 +            return false;
    1.43 +        m = InstanceKlass::cast(k)->find_method(default_methods, _name, _signature);
    1.44 +        if (!Dependencies::is_concrete_method(m, NULL))
    1.45 +            return false;
    1.46 +      }
    1.47        _found_methods[_num_participants] = m;
    1.48        // Note:  If add_participant(k) is called,
    1.49        // the method m will already be memoized for it.
    1.50 @@ -1172,15 +1181,17 @@
    1.51    return true;
    1.52  }
    1.53  
    1.54 -bool Dependencies::is_concrete_method(Method* m) {
    1.55 -  // Statics are irrelevant to virtual call sites.
    1.56 -  if (m->is_static())  return false;
    1.57 -
    1.58 -  // We could also return false if m does not yet appear to be
    1.59 -  // executed, if the VM version supports this distinction also.
    1.60 -  // Default methods are considered "concrete" as well.
    1.61 -  return !m->is_abstract() &&
    1.62 -         !m->is_overpass(); // error functions aren't concrete
    1.63 +bool Dependencies::is_concrete_method(Method* m, Klass * k) {
    1.64 +  // NULL is not a concrete method,
    1.65 +  // statics are irrelevant to virtual call sites,
    1.66 +  // abstract methods are not concrete,
    1.67 +  // overpass (error) methods are not concrete if k is abstract
    1.68 +  //
    1.69 +  // note "true" is conservative answer --
    1.70 +  //     overpass clause is false if k == NULL, implies return true if
    1.71 +  //     answer depends on overpass clause.
    1.72 +  return ! ( m == NULL || m -> is_static() || m -> is_abstract() ||
    1.73 +             m->is_overpass() && k != NULL && k -> is_abstract() );
    1.74  }
    1.75  
    1.76  
    1.77 @@ -1205,16 +1216,6 @@
    1.78    return true;
    1.79  }
    1.80  
    1.81 -bool Dependencies::is_concrete_method(ciMethod* m) {
    1.82 -  // Statics are irrelevant to virtual call sites.
    1.83 -  if (m->is_static())  return false;
    1.84 -
    1.85 -  // We could also return false if m does not yet appear to be
    1.86 -  // executed, if the VM version supports this distinction also.
    1.87 -  return !m->is_abstract();
    1.88 -}
    1.89 -
    1.90 -
    1.91  bool Dependencies::has_finalizable_subclass(ciInstanceKlass* k) {
    1.92    return k->has_finalizable_subclass();
    1.93  }
    1.94 @@ -1428,7 +1429,7 @@
    1.95    Klass* wit = wf.find_witness_definer(ctxk);
    1.96    if (wit != NULL)  return NULL;  // Too many witnesses.
    1.97    Method* fm = wf.found_method(0);  // Will be NULL if num_parts == 0.
    1.98 -  if (Dependencies::is_concrete_method(m)) {
    1.99 +  if (Dependencies::is_concrete_method(m, ctxk)) {
   1.100      if (fm == NULL) {
   1.101        // It turns out that m was always the only implementation.
   1.102        fm = m;
   1.103 @@ -1458,61 +1459,6 @@
   1.104    return wf.find_witness_definer(ctxk, changes);
   1.105  }
   1.106  
   1.107 -// Find the set of all non-abstract methods under ctxk that match m[0].
   1.108 -// (The method m[0] must be defined or inherited in ctxk.)
   1.109 -// Include m itself in the set, unless it is abstract.
   1.110 -// Fill the given array m[0..(mlen-1)] with this set, and return the length.
   1.111 -// (The length may be zero if no concrete methods are found anywhere.)
   1.112 -// If there are too many concrete methods to fit in marray, return -1.
   1.113 -int Dependencies::find_exclusive_concrete_methods(Klass* ctxk,
   1.114 -                                                  int mlen,
   1.115 -                                                  Method* marray[]) {
   1.116 -  Method* m0 = marray[0];
   1.117 -  ClassHierarchyWalker wf(m0);
   1.118 -  assert(wf.check_method_context(ctxk, m0), "proper context");
   1.119 -  wf.record_witnesses(mlen);
   1.120 -  bool participants_hide_witnesses = true;
   1.121 -  Klass* wit = wf.find_witness_definer(ctxk);
   1.122 -  if (wit != NULL)  return -1;  // Too many witnesses.
   1.123 -  int num = wf.num_participants();
   1.124 -  assert(num <= mlen, "oob");
   1.125 -  // Keep track of whether m is also part of the result set.
   1.126 -  int mfill = 0;
   1.127 -  assert(marray[mfill] == m0, "sanity");
   1.128 -  if (Dependencies::is_concrete_method(m0))
   1.129 -    mfill++;  // keep m0 as marray[0], the first result
   1.130 -  for (int i = 0; i < num; i++) {
   1.131 -    Method* fm = wf.found_method(i);
   1.132 -    if (fm == m0)  continue;  // Already put this guy in the list.
   1.133 -    if (mfill == mlen) {
   1.134 -      return -1;              // Oops.  Too many methods after all!
   1.135 -    }
   1.136 -    marray[mfill++] = fm;
   1.137 -  }
   1.138 -#ifndef PRODUCT
   1.139 -  // Make sure the dependency mechanism will pass this discovery:
   1.140 -  if (VerifyDependencies) {
   1.141 -    // Turn off dependency tracing while actually testing deps.
   1.142 -    FlagSetting fs(TraceDependencies, false);
   1.143 -    switch (mfill) {
   1.144 -    case 1:
   1.145 -      guarantee(NULL == (void *)check_unique_concrete_method(ctxk, marray[0]),
   1.146 -                "verify dep.");
   1.147 -      break;
   1.148 -    case 2:
   1.149 -      guarantee(NULL == (void *)
   1.150 -                check_exclusive_concrete_methods(ctxk, marray[0], marray[1]),
   1.151 -                "verify dep.");
   1.152 -      break;
   1.153 -    default:
   1.154 -      ShouldNotReachHere();  // mlen > 2 yet supported
   1.155 -    }
   1.156 -  }
   1.157 -#endif //PRODUCT
   1.158 -  return mfill;
   1.159 -}
   1.160 -
   1.161 -
   1.162  Klass* Dependencies::check_has_no_finalizable_subclasses(Klass* ctxk, KlassDepChange* changes) {
   1.163    Klass* search_at = ctxk;
   1.164    if (changes != NULL)
   1.165 @@ -1520,7 +1466,6 @@
   1.166    return find_finalizable_subclass(search_at);
   1.167  }
   1.168  
   1.169 -
   1.170  Klass* Dependencies::check_call_site_target_value(oop call_site, oop method_handle, CallSiteDepChange* changes) {
   1.171    assert(call_site    ->is_a(SystemDictionary::CallSite_klass()),     "sanity");
   1.172    assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "sanity");
     2.1 --- a/src/share/vm/code/dependencies.hpp	Wed Nov 19 15:02:01 2014 -0800
     2.2 +++ b/src/share/vm/code/dependencies.hpp	Mon Dec 01 13:06:20 2014 -0500
     2.3 @@ -1,5 +1,5 @@
     2.4  /*
     2.5 - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
     2.6 + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
     2.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.8   *
     2.9   * This code is free software; you can redistribute it and/or modify it
    2.10 @@ -287,7 +287,7 @@
    2.11    // In that case, there would be a middle ground between concrete
    2.12    // and abstract (as defined by the Java language and VM).
    2.13    static bool is_concrete_klass(Klass* k);    // k is instantiable
    2.14 -  static bool is_concrete_method(Method* m);  // m is invocable
    2.15 +  static bool is_concrete_method(Method* m, Klass* k);  // m is invocable
    2.16    static Klass* find_finalizable_subclass(Klass* k);
    2.17  
    2.18    // These versions of the concreteness queries work through the CI.
    2.19 @@ -301,7 +301,6 @@
    2.20    // not go back into the VM to get their value; they must cache the
    2.21    // bit in the CI, either eagerly or lazily.)
    2.22    static bool is_concrete_klass(ciInstanceKlass* k); // k appears instantiable
    2.23 -  static bool is_concrete_method(ciMethod* m);       // m appears invocable
    2.24    static bool has_finalizable_subclass(ciInstanceKlass* k);
    2.25  
    2.26    // As a general rule, it is OK to compile under the assumption that
    2.27 @@ -348,7 +347,6 @@
    2.28    static Klass*    find_unique_concrete_subtype(Klass* ctxk);
    2.29    static Method*   find_unique_concrete_method(Klass* ctxk, Method* m);
    2.30    static int       find_exclusive_concrete_subtypes(Klass* ctxk, int klen, Klass* k[]);
    2.31 -  static int       find_exclusive_concrete_methods(Klass* ctxk, int mlen, Method* m[]);
    2.32  
    2.33    // Create the encoding which will be stored in an nmethod.
    2.34    void encode_content_bytes();
     3.1 --- a/src/share/vm/interpreter/linkResolver.cpp	Wed Nov 19 15:02:01 2014 -0800
     3.2 +++ b/src/share/vm/interpreter/linkResolver.cpp	Mon Dec 01 13:06:20 2014 -0500
     3.3 @@ -320,7 +320,7 @@
     3.4    // First check in default method array
     3.5    if (!resolved_method->is_abstract() &&
     3.6      (InstanceKlass::cast(klass())->default_methods() != NULL)) {
     3.7 -    int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(), name, signature, false);
     3.8 +    int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(), name, signature, false, false);
     3.9      if (index >= 0 ) {
    3.10        vtable_index = InstanceKlass::cast(klass())->default_vtable_indices()->at(index);
    3.11      }
     4.1 --- a/src/share/vm/oops/instanceKlass.cpp	Wed Nov 19 15:02:01 2014 -0800
     4.2 +++ b/src/share/vm/oops/instanceKlass.cpp	Mon Dec 01 13:06:20 2014 -0500
     4.3 @@ -1453,32 +1453,41 @@
     4.4  }
     4.5  
     4.6  Method* InstanceKlass::find_method_impl(Symbol* name, Symbol* signature, bool skipping_overpass) const {
     4.7 -  return InstanceKlass::find_method_impl(methods(), name, signature, skipping_overpass);
     4.8 +  return InstanceKlass::find_method_impl(methods(), name, signature, skipping_overpass, false);
     4.9  }
    4.10  
    4.11  // find_instance_method looks up the name/signature in the local methods array
    4.12  // and skips over static methods
    4.13  Method* InstanceKlass::find_instance_method(
    4.14      Array<Method*>* methods, Symbol* name, Symbol* signature) {
    4.15 -  Method* meth = InstanceKlass::find_method(methods, name, signature);
    4.16 -  if (meth != NULL && meth->is_static()) {
    4.17 -      meth = NULL;
    4.18 -  }
    4.19 +  Method* meth = InstanceKlass::find_method_impl(methods, name, signature, false, true);
    4.20    return meth;
    4.21  }
    4.22  
    4.23 +// find_instance_method looks up the name/signature in the local methods array
    4.24 +// and skips over static methods
    4.25 +Method* InstanceKlass::find_instance_method(Symbol* name, Symbol* signature) {
    4.26 +    return InstanceKlass::find_instance_method(methods(), name, signature);
    4.27 +}
    4.28 +
    4.29  // find_method looks up the name/signature in the local methods array
    4.30  Method* InstanceKlass::find_method(
    4.31      Array<Method*>* methods, Symbol* name, Symbol* signature) {
    4.32 -  return InstanceKlass::find_method_impl(methods, name, signature, false);
    4.33 +  return InstanceKlass::find_method_impl(methods, name, signature, false, false);
    4.34  }
    4.35  
    4.36  Method* InstanceKlass::find_method_impl(
    4.37 -    Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass) {
    4.38 -  int hit = find_method_index(methods, name, signature, skipping_overpass);
    4.39 +    Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass, bool skipping_static) {
    4.40 +  int hit = find_method_index(methods, name, signature, skipping_overpass, skipping_static);
    4.41    return hit >= 0 ? methods->at(hit): NULL;
    4.42  }
    4.43  
    4.44 +bool InstanceKlass::method_matches(Method* m, Symbol* signature, bool skipping_overpass, bool skipping_static) {
    4.45 +    return (m->signature() == signature) &&
    4.46 +            (!skipping_overpass || !m->is_overpass()) &&
    4.47 +            (!skipping_static || !m->is_static());
    4.48 +}
    4.49 +
    4.50  // Used directly for default_methods to find the index into the
    4.51  // default_vtable_indices, and indirectly by find_method
    4.52  // find_method_index looks in the local methods array to return the index
    4.53 @@ -1487,13 +1496,14 @@
    4.54  // is important during method resolution to prefer a static method, for example,
    4.55  // over an overpass method.
    4.56  int InstanceKlass::find_method_index(
    4.57 -    Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass) {
    4.58 +    Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass, bool skipping_static) {
    4.59    int hit = binary_search(methods, name);
    4.60    if (hit != -1) {
    4.61      Method* m = methods->at(hit);
    4.62 +
    4.63      // Do linear search to find matching signature.  First, quick check
    4.64      // for common case, ignoring overpasses if requested.
    4.65 -    if ((m->signature() == signature) && (!skipping_overpass || !m->is_overpass())) return hit;
    4.66 +    if (method_matches(m, signature, skipping_overpass, skipping_static)) return hit;
    4.67  
    4.68      // search downwards through overloaded methods
    4.69      int i;
    4.70 @@ -1501,18 +1511,18 @@
    4.71          Method* m = methods->at(i);
    4.72          assert(m->is_method(), "must be method");
    4.73          if (m->name() != name) break;
    4.74 -        if ((m->signature() == signature) && (!skipping_overpass || !m->is_overpass())) return i;
    4.75 +        if (method_matches(m, signature, skipping_overpass, skipping_static)) return i;
    4.76      }
    4.77      // search upwards
    4.78      for (i = hit + 1; i < methods->length(); ++i) {
    4.79          Method* m = methods->at(i);
    4.80          assert(m->is_method(), "must be method");
    4.81          if (m->name() != name) break;
    4.82 -        if ((m->signature() == signature) && (!skipping_overpass || !m->is_overpass())) return i;
    4.83 +        if (method_matches(m, signature, skipping_overpass, skipping_static)) return i;
    4.84      }
    4.85      // not found
    4.86  #ifdef ASSERT
    4.87 -    int index = skipping_overpass ? -1 : linear_search(methods, name, signature);
    4.88 +    int index = skipping_overpass || skipping_static ? -1 : linear_search(methods, name, signature);
    4.89      assert(index == -1, err_msg("binary search should have found entry %d", index));
    4.90  #endif
    4.91    }
     5.1 --- a/src/share/vm/oops/instanceKlass.hpp	Wed Nov 19 15:02:01 2014 -0800
     5.2 +++ b/src/share/vm/oops/instanceKlass.hpp	Mon Dec 01 13:06:20 2014 -0500
     5.3 @@ -520,10 +520,16 @@
     5.4    // find a local method (returns NULL if not found)
     5.5    Method* find_method(Symbol* name, Symbol* signature) const;
     5.6    static Method* find_method(Array<Method*>* methods, Symbol* name, Symbol* signature);
     5.7 +
     5.8 +  // find a local method, but skip static methods
     5.9 +  Method* find_instance_method(Symbol* name, Symbol* signature);
    5.10    static Method* find_instance_method(Array<Method*>* methods, Symbol* name, Symbol* signature);
    5.11  
    5.12 +  // true if method matches signature and conforms to skipping_X conditions.
    5.13 +  static bool method_matches(Method* m, Symbol* signature, bool skipping_overpass, bool skipping_static);
    5.14 +
    5.15    // find a local method index in default_methods (returns -1 if not found)
    5.16 -  static int find_method_index(Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass);
    5.17 +  static int find_method_index(Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass, bool skipping_static);
    5.18  
    5.19    // lookup operation (returns NULL if not found)
    5.20    Method* uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const;
    5.21 @@ -1076,7 +1082,7 @@
    5.22  
    5.23    // find a local method (returns NULL if not found)
    5.24    Method* find_method_impl(Symbol* name, Symbol* signature, bool skipping_overpass) const;
    5.25 -  static Method* find_method_impl(Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass);
    5.26 +  static Method* find_method_impl(Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass, bool skipping_static);
    5.27  
    5.28    // Free CHeap allocated fields.
    5.29    void release_C_heap_structures();

mercurial