src/share/vm/code/dependencies.hpp

changeset 3050
fdb992d83a87
parent 2314
f95d63e2154a
child 3094
b27c72d69fd1
     1.1 --- a/src/share/vm/code/dependencies.hpp	Thu Aug 11 12:08:11 2011 -0700
     1.2 +++ b/src/share/vm/code/dependencies.hpp	Tue Aug 16 04:14:05 2011 -0700
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2005, 2011, 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 @@ -25,18 +25,21 @@
    1.11  #ifndef SHARE_VM_CODE_DEPENDENCIES_HPP
    1.12  #define SHARE_VM_CODE_DEPENDENCIES_HPP
    1.13  
    1.14 +#include "ci/ciCallSite.hpp"
    1.15  #include "ci/ciKlass.hpp"
    1.16 +#include "ci/ciMethodHandle.hpp"
    1.17 +#include "classfile/systemDictionary.hpp"
    1.18  #include "code/compressedStream.hpp"
    1.19  #include "code/nmethod.hpp"
    1.20  #include "utilities/growableArray.hpp"
    1.21  
    1.22  //** Dependencies represent assertions (approximate invariants) within
    1.23 -// the class hierarchy.  An example is an assertion that a given
    1.24 -// method is not overridden; another example is that a type has only
    1.25 -// one concrete subtype.  Compiled code which relies on such
    1.26 -// assertions must be discarded if they are overturned by changes in
    1.27 -// the class hierarchy.  We can think of these assertions as
    1.28 -// approximate invariants, because we expect them to be overturned
    1.29 +// the runtime system, e.g. class hierarchy changes.  An example is an
    1.30 +// assertion that a given method is not overridden; another example is
    1.31 +// that a type has only one concrete subtype.  Compiled code which
    1.32 +// relies on such assertions must be discarded if they are overturned
    1.33 +// by changes in the runtime system.  We can think of these assertions
    1.34 +// as approximate invariants, because we expect them to be overturned
    1.35  // very infrequently.  We are willing to perform expensive recovery
    1.36  // operations when they are overturned.  The benefit, of course, is
    1.37  // performing optimistic optimizations (!) on the object code.
    1.38 @@ -52,6 +55,8 @@
    1.39  class xmlStream;
    1.40  class CompileLog;
    1.41  class DepChange;
    1.42 +class   KlassDepChange;
    1.43 +class   CallSiteDepChange;
    1.44  class No_Safepoint_Verifier;
    1.45  
    1.46  class Dependencies: public ResourceObj {
    1.47 @@ -152,6 +157,9 @@
    1.48      // subclasses require finalization registration.
    1.49      no_finalizable_subclasses,
    1.50  
    1.51 +    // This dependency asserts when the CallSite.target value changed.
    1.52 +    call_site_target_value,
    1.53 +
    1.54      TYPE_LIMIT
    1.55    };
    1.56    enum {
    1.57 @@ -179,6 +187,7 @@
    1.58    static int  dep_context_arg(DepType dept) {
    1.59      return dept_in_mask(dept, ctxk_types)? 0: -1;
    1.60    }
    1.61 +  static void check_valid_dependency_type(DepType dept);
    1.62  
    1.63   private:
    1.64    // State for writing a new set of dependencies:
    1.65 @@ -255,6 +264,7 @@
    1.66    void assert_abstract_with_exclusive_concrete_subtypes(ciKlass* ctxk, ciKlass* k1, ciKlass* k2);
    1.67    void assert_exclusive_concrete_methods(ciKlass* ctxk, ciMethod* m1, ciMethod* m2);
    1.68    void assert_has_no_finalizable_subclasses(ciKlass* ctxk);
    1.69 +  void assert_call_site_target_value(ciKlass* ctxk, ciCallSite* call_site, ciMethodHandle* method_handle);
    1.70  
    1.71    // Define whether a given method or type is concrete.
    1.72    // These methods define the term "concrete" as used in this module.
    1.73 @@ -296,19 +306,19 @@
    1.74    static klassOop check_evol_method(methodOop m);
    1.75    static klassOop check_leaf_type(klassOop ctxk);
    1.76    static klassOop check_abstract_with_unique_concrete_subtype(klassOop ctxk, klassOop conck,
    1.77 -                                                              DepChange* changes = NULL);
    1.78 +                                                              KlassDepChange* changes = NULL);
    1.79    static klassOop check_abstract_with_no_concrete_subtype(klassOop ctxk,
    1.80 -                                                          DepChange* changes = NULL);
    1.81 +                                                          KlassDepChange* changes = NULL);
    1.82    static klassOop check_concrete_with_no_concrete_subtype(klassOop ctxk,
    1.83 -                                                          DepChange* changes = NULL);
    1.84 +                                                          KlassDepChange* changes = NULL);
    1.85    static klassOop check_unique_concrete_method(klassOop ctxk, methodOop uniqm,
    1.86 -                                               DepChange* changes = NULL);
    1.87 +                                               KlassDepChange* changes = NULL);
    1.88    static klassOop check_abstract_with_exclusive_concrete_subtypes(klassOop ctxk, klassOop k1, klassOop k2,
    1.89 -                                                                  DepChange* changes = NULL);
    1.90 +                                                                  KlassDepChange* changes = NULL);
    1.91    static klassOop check_exclusive_concrete_methods(klassOop ctxk, methodOop m1, methodOop m2,
    1.92 -                                                   DepChange* changes = NULL);
    1.93 -  static klassOop check_has_no_finalizable_subclasses(klassOop ctxk,
    1.94 -                                                      DepChange* changes = NULL);
    1.95 +                                                   KlassDepChange* changes = NULL);
    1.96 +  static klassOop check_has_no_finalizable_subclasses(klassOop ctxk, KlassDepChange* changes = NULL);
    1.97 +  static klassOop check_call_site_target_value(klassOop ctxk, oop call_site, oop method_handle, CallSiteDepChange* changes = NULL);
    1.98    // A returned klassOop is NULL if the dependency assertion is still
    1.99    // valid.  A non-NULL klassOop is a 'witness' to the assertion
   1.100    // failure, a point in the class hierarchy where the assertion has
   1.101 @@ -415,7 +425,10 @@
   1.102      inline oop recorded_oop_at(int i);
   1.103          // => _code? _code->oop_at(i): *_deps->_oop_recorder->handle_at(i)
   1.104  
   1.105 -    klassOop check_dependency_impl(DepChange* changes);
   1.106 +    klassOop check_klass_dependency(KlassDepChange* changes);
   1.107 +    klassOop check_call_site_dependency(CallSiteDepChange* changes);
   1.108 +
   1.109 +    void trace_and_log_witness(klassOop witness);
   1.110  
   1.111    public:
   1.112      DepStream(Dependencies* deps)
   1.113 @@ -453,10 +466,13 @@
   1.114        return (klassOop) x;
   1.115      }
   1.116  
   1.117 -    // The point of the whole exercise:  Is this dep is still OK?
   1.118 +    // The point of the whole exercise:  Is this dep still OK?
   1.119      klassOop check_dependency() {
   1.120 -      return check_dependency_impl(NULL);
   1.121 +      klassOop result = check_klass_dependency(NULL);
   1.122 +      if (result != NULL)  return result;
   1.123 +      return check_call_site_dependency(NULL);
   1.124      }
   1.125 +
   1.126      // A lighter version:  Checks only around recent changes in a class
   1.127      // hierarchy.  (See Universe::flush_dependents_on.)
   1.128      klassOop spot_check_dependency_at(DepChange& changes);
   1.129 @@ -472,13 +488,27 @@
   1.130    static void print_statistics() PRODUCT_RETURN;
   1.131  };
   1.132  
   1.133 -// A class hierarchy change coming through the VM (under the Compile_lock).
   1.134 -// The change is structured as a single new type with any number of supers
   1.135 -// and implemented interface types.  Other than the new type, any of the
   1.136 -// super types can be context types for a relevant dependency, which the
   1.137 -// new type could invalidate.
   1.138 +
   1.139 +// Every particular DepChange is a sub-class of this class.
   1.140  class DepChange : public StackObj {
   1.141   public:
   1.142 +  // What kind of DepChange is this?
   1.143 +  virtual bool is_klass_change()     const { return false; }
   1.144 +  virtual bool is_call_site_change() const { return false; }
   1.145 +
   1.146 +  // Subclass casting with assertions.
   1.147 +  KlassDepChange*    as_klass_change() {
   1.148 +    assert(is_klass_change(), "bad cast");
   1.149 +    return (KlassDepChange*) this;
   1.150 +  }
   1.151 +  CallSiteDepChange* as_call_site_change() {
   1.152 +    assert(is_call_site_change(), "bad cast");
   1.153 +    return (CallSiteDepChange*) this;
   1.154 +  }
   1.155 +
   1.156 +  void print();
   1.157 +
   1.158 + public:
   1.159    enum ChangeType {
   1.160      NO_CHANGE = 0,              // an uninvolved klass
   1.161      Change_new_type,            // a newly loaded type
   1.162 @@ -488,28 +518,6 @@
   1.163      Start_Klass = CHANGE_LIMIT  // internal indicator for ContextStream
   1.164    };
   1.165  
   1.166 - private:
   1.167 -  // each change set is rooted in exactly one new type (at present):
   1.168 -  KlassHandle _new_type;
   1.169 -
   1.170 -  void initialize();
   1.171 -
   1.172 - public:
   1.173 -  // notes the new type, marks it and all its super-types
   1.174 -  DepChange(KlassHandle new_type)
   1.175 -    : _new_type(new_type)
   1.176 -  {
   1.177 -    initialize();
   1.178 -  }
   1.179 -
   1.180 -  // cleans up the marks
   1.181 -  ~DepChange();
   1.182 -
   1.183 -  klassOop new_type()                   { return _new_type(); }
   1.184 -
   1.185 -  // involves_context(k) is true if k is new_type or any of the super types
   1.186 -  bool involves_context(klassOop k);
   1.187 -
   1.188    // Usage:
   1.189    // for (DepChange::ContextStream str(changes); str.next(); ) {
   1.190    //   klassOop k = str.klass();
   1.191 @@ -530,14 +538,7 @@
   1.192      int         _ti_limit;
   1.193  
   1.194      // start at the beginning:
   1.195 -    void start() {
   1.196 -      klassOop new_type = _changes.new_type();
   1.197 -      _change_type = (new_type == NULL ? NO_CHANGE: Start_Klass);
   1.198 -      _klass = new_type;
   1.199 -      _ti_base = NULL;
   1.200 -      _ti_index = 0;
   1.201 -      _ti_limit = 0;
   1.202 -    }
   1.203 +    void start();
   1.204  
   1.205     public:
   1.206      ContextStream(DepChange& changes)
   1.207 @@ -555,8 +556,62 @@
   1.208      klassOop   klass()           { return _klass; }
   1.209    };
   1.210    friend class DepChange::ContextStream;
   1.211 +};
   1.212  
   1.213 -  void print();
   1.214 +
   1.215 +// A class hierarchy change coming through the VM (under the Compile_lock).
   1.216 +// The change is structured as a single new type with any number of supers
   1.217 +// and implemented interface types.  Other than the new type, any of the
   1.218 +// super types can be context types for a relevant dependency, which the
   1.219 +// new type could invalidate.
   1.220 +class KlassDepChange : public DepChange {
   1.221 + private:
   1.222 +  // each change set is rooted in exactly one new type (at present):
   1.223 +  KlassHandle _new_type;
   1.224 +
   1.225 +  void initialize();
   1.226 +
   1.227 + public:
   1.228 +  // notes the new type, marks it and all its super-types
   1.229 +  KlassDepChange(KlassHandle new_type)
   1.230 +    : _new_type(new_type)
   1.231 +  {
   1.232 +    initialize();
   1.233 +  }
   1.234 +
   1.235 +  // cleans up the marks
   1.236 +  ~KlassDepChange();
   1.237 +
   1.238 +  // What kind of DepChange is this?
   1.239 +  virtual bool is_klass_change() const { return true; }
   1.240 +
   1.241 +  klassOop new_type() { return _new_type(); }
   1.242 +
   1.243 +  // involves_context(k) is true if k is new_type or any of the super types
   1.244 +  bool involves_context(klassOop k);
   1.245 +};
   1.246 +
   1.247 +
   1.248 +// A CallSite has changed its target.
   1.249 +class CallSiteDepChange : public DepChange {
   1.250 + private:
   1.251 +  Handle _call_site;
   1.252 +  Handle _method_handle;
   1.253 +
   1.254 + public:
   1.255 +  CallSiteDepChange(Handle call_site, Handle method_handle)
   1.256 +    : _call_site(call_site),
   1.257 +      _method_handle(method_handle)
   1.258 +  {
   1.259 +    assert(_call_site()    ->is_a(SystemDictionary::CallSite_klass()),     "must be");
   1.260 +    assert(_method_handle()->is_a(SystemDictionary::MethodHandle_klass()), "must be");
   1.261 +  }
   1.262 +
   1.263 +  // What kind of DepChange is this?
   1.264 +  virtual bool is_call_site_change() const { return true; }
   1.265 +
   1.266 +  oop call_site()     const { return _call_site();     }
   1.267 +  oop method_handle() const { return _method_handle(); }
   1.268  };
   1.269  
   1.270  #endif // SHARE_VM_CODE_DEPENDENCIES_HPP

mercurial