< prev index next >

src/share/vm/code/dependencies.hpp

Print this page

        

@@ -57,10 +57,11 @@
 class xmlStream;
 class CompileLog;
 class DepChange;
 class   KlassDepChange;
 class   CallSiteDepChange;
+class   ConstantFieldDepChange;
 class No_Safepoint_Verifier;
 
 class Dependencies: public ResourceObj {
  public:
   // Note: In the comments on dependency types, most uses of the terms

@@ -160,10 +161,13 @@
     no_finalizable_subclasses,
 
     // This dependency asserts when the CallSite.target value changed.
     call_site_target_value,
 
+    constant_field_value_instance,
+    constant_field_value_klass,
+
     TYPE_LIMIT
   };
   enum {
     LG2_TYPE_LIMIT = 4,  // assert(TYPE_LIMIT <= (1<<LG2_TYPE_LIMIT))
 

@@ -277,10 +281,13 @@
   void assert_abstract_with_exclusive_concrete_subtypes(ciKlass* ctxk, ciKlass* k1, ciKlass* k2);
   void assert_exclusive_concrete_methods(ciKlass* ctxk, ciMethod* m1, ciMethod* m2);
   void assert_has_no_finalizable_subclasses(ciKlass* ctxk);
   void assert_call_site_target_value(ciCallSite* call_site, ciMethodHandle* method_handle);
 
+  void assert_constant_field_value_klass(ciField* field, ciKlass* ctxk);
+  void assert_constant_field_value_instance(ciField* field, ciObject* obj);
+
   // Define whether a given method or type is concrete.
   // These methods define the term "concrete" as used in this module.
   // For this module, an "abstract" class is one which is non-concrete.
   //
   // Future optimizations may allow some classes to remain

@@ -348,10 +355,12 @@
   // Detecting possible new assertions:
   static Klass*    find_unique_concrete_subtype(Klass* ctxk);
   static Method*   find_unique_concrete_method(Klass* ctxk, Method* m);
   static int       find_exclusive_concrete_subtypes(Klass* ctxk, int klen, Klass* k[]);
 
+  static void invalidate_dependent_nmethods(instanceKlassHandle ctxk, DepChange& changes, TRAPS);
+
   // Create the encoding which will be stored in an nmethod.
   void encode_content_bytes();
 
   address content_bytes() {
     assert(_content_bytes != NULL, "encode it first");

@@ -398,10 +407,16 @@
     }
     assert(ciargs->length() == dep_args(dept), "");
     log_dependency(dept, ciargs);
   }
 
+  static PerfCounter* _perf_dependency_checking_time;
+  static PerfCounter* _perf_dependencies_checked_count;
+  static PerfCounter* _perf_dependencies_context_traversals;
+  static PerfCounter* _perf_dependencies_invalidated;
+  static PerfCounter* _perf_dependencies_total_count;
+
   class DepArgument : public ResourceObj {
    private:
     bool  _is_oop;
     bool  _valid;
     void* _value;

@@ -494,18 +509,34 @@
     }
 
     bool next();
 
     DepType type()               { return _type; }
-    bool is_oop_argument(int i)  { return type() == call_site_target_value; }
+    bool is_oop_argument(int i)  {
+      assert(0 <= i && i < argument_count(), "oob");
+      switch (type()) {
+        case call_site_target_value:        return true;
+        case constant_field_value_instance: return (i == 1);
+        default:                            return false;
+      }
+    }
+    bool is_int_argument(int i) {
+      assert(0 <= i && i < argument_count(), "oob");
+      switch (type()) {
+        case constant_field_value_instance: return (i == 2);
+        case constant_field_value_klass:    return (i == 1);
+        default:                            return false;
+      }
+    }
     uintptr_t get_identifier(int i);
 
     int argument_count()         { return dep_args(type()); }
     int argument_index(int i)    { assert(0 <= i && i < argument_count(), "oob");
                                    return _xi[i]; }
     Metadata* argument(int i);     // => recorded_oop_at(argument_index(i))
     oop argument_oop(int i);         // => recorded_oop_at(argument_index(i))
+    int argument_int(int i)      { return argument_index(i); }
     Klass* context_type();
 
     bool is_klass_type()         { return Dependencies::is_klass_type(type()); }
 
     Method* method_argument(int i) {

@@ -571,20 +602,25 @@
 class DepChange : public StackObj {
  public:
   // What kind of DepChange is this?
   virtual bool is_klass_change()     const { return false; }
   virtual bool is_call_site_change() const { return false; }
+  virtual bool is_constant_field_change() const { return false; }
 
   // Subclass casting with assertions.
   KlassDepChange*    as_klass_change() {
     assert(is_klass_change(), "bad cast");
     return (KlassDepChange*) this;
   }
   CallSiteDepChange* as_call_site_change() {
     assert(is_call_site_change(), "bad cast");
     return (CallSiteDepChange*) this;
   }
+  ConstantFieldDepChange* as_constant_field_change() {
+    assert(is_constant_field_change(), "bad cast");
+    return (ConstantFieldDepChange*) this;
+  }
 
   void print();
 
  public:
   enum ChangeType {

@@ -690,6 +726,22 @@
 
   oop call_site()     const { return _call_site();     }
   oop method_handle() const { return _method_handle(); }
 };
 
+class ConstantFieldDepChange : public DepChange {
+ private:
+  Handle _holder;
+  int _offset;
+
+ public:
+  ConstantFieldDepChange(Handle holder, int offset) : _holder(holder), _offset(offset) {}
+
+  // What kind of DepChange is this?
+  virtual bool is_constant_field_change() const { return true; }
+
+  oop holder() const { return _holder(); }
+  int offset() const { return _offset;   }
+};
+
+
 #endif // SHARE_VM_CODE_DEPENDENCIES_HPP
< prev index next >