diff src/share/vm/code/dependencies.hpp @ 6725:da91efe96a93

6964458: Reimplement class meta-data storage to use native memory Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author coleenp
date Sat, 01 Sep 2012 13:25:18 -0400
parents b27c72d69fd1
children eec7173947a1 3aaa4b9966f6 3c048df3ef8b 9906d432d6db
line wrap: on
line diff
--- a/src/share/vm/code/dependencies.hpp	Fri Aug 31 16:39:35 2012 -0700
+++ b/src/share/vm/code/dependencies.hpp	Sat Sep 01 13:25:18 2012 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -203,7 +203,7 @@
  private:
   // State for writing a new set of dependencies:
   GrowableArray<int>*       _dep_seen;  // (seen[h->ident] & (1<<dept))
-  GrowableArray<ciObject*>* _deps[TYPE_LIMIT];
+  GrowableArray<ciBaseObject*>*  _deps[TYPE_LIMIT];
 
   static const char* _dep_name[TYPE_LIMIT];
   static int         _dep_args[TYPE_LIMIT];
@@ -212,7 +212,7 @@
     return (int)dept >= 0 && dept < TYPE_LIMIT && ((1<<dept) & mask) != 0;
   }
 
-  bool note_dep_seen(int dept, ciObject* x) {
+  bool note_dep_seen(int dept, ciBaseObject* x) {
     assert(dept < BitsPerInt, "oob");
     int x_id = x->ident();
     assert(_dep_seen != NULL, "deps must be writable");
@@ -222,7 +222,7 @@
     return (seen & (1<<dept)) != 0;
   }
 
-  bool maybe_merge_ctxk(GrowableArray<ciObject*>* deps,
+  bool maybe_merge_ctxk(GrowableArray<ciBaseObject*>* deps,
                         int ctxk_i, ciKlass* ctxk);
 
   void sort_all_deps();
@@ -260,9 +260,9 @@
     assert(!is_concrete_klass(ctxk->as_instance_klass()), "must be abstract");
   }
 
-  void assert_common_1(DepType dept, ciObject* x);
-  void assert_common_2(DepType dept, ciObject* x0, ciObject* x1);
-  void assert_common_3(DepType dept, ciKlass* ctxk, ciObject* x1, ciObject* x2);
+  void assert_common_1(DepType dept, ciBaseObject* x);
+  void assert_common_2(DepType dept, ciBaseObject* x0, ciBaseObject* x1);
+  void assert_common_3(DepType dept, ciKlass* ctxk, ciBaseObject* x1, ciBaseObject* x2);
 
  public:
   // Adding assertions to a new dependency set at compile time:
@@ -286,8 +286,8 @@
   // methods to remain non-concrete until their first invocation.
   // In that case, there would be a middle ground between concrete
   // and abstract (as defined by the Java language and VM).
-  static bool is_concrete_klass(klassOop k);    // k is instantiable
-  static bool is_concrete_method(methodOop m);  // m is invocable
+  static bool is_concrete_klass(Klass* k);    // k is instantiable
+  static bool is_concrete_method(Method* m);  // m is invocable
   static Klass* find_finalizable_subclass(Klass* k);
 
   // These versions of the concreteness queries work through the CI.
@@ -314,24 +314,24 @@
   // dependency on it must fail.
 
   // Checking old assertions at run-time (in the VM only):
-  static klassOop check_evol_method(methodOop m);
-  static klassOop check_leaf_type(klassOop ctxk);
-  static klassOop check_abstract_with_unique_concrete_subtype(klassOop ctxk, klassOop conck,
+  static Klass* check_evol_method(Method* m);
+  static Klass* check_leaf_type(Klass* ctxk);
+  static Klass* check_abstract_with_unique_concrete_subtype(Klass* ctxk, Klass* conck,
                                                               KlassDepChange* changes = NULL);
-  static klassOop check_abstract_with_no_concrete_subtype(klassOop ctxk,
+  static Klass* check_abstract_with_no_concrete_subtype(Klass* ctxk,
                                                           KlassDepChange* changes = NULL);
-  static klassOop check_concrete_with_no_concrete_subtype(klassOop ctxk,
+  static Klass* check_concrete_with_no_concrete_subtype(Klass* ctxk,
                                                           KlassDepChange* changes = NULL);
-  static klassOop check_unique_concrete_method(klassOop ctxk, methodOop uniqm,
+  static Klass* check_unique_concrete_method(Klass* ctxk, Method* uniqm,
                                                KlassDepChange* changes = NULL);
-  static klassOop check_abstract_with_exclusive_concrete_subtypes(klassOop ctxk, klassOop k1, klassOop k2,
+  static Klass* check_abstract_with_exclusive_concrete_subtypes(Klass* ctxk, Klass* k1, Klass* k2,
                                                                   KlassDepChange* changes = NULL);
-  static klassOop check_exclusive_concrete_methods(klassOop ctxk, methodOop m1, methodOop m2,
+  static Klass* check_exclusive_concrete_methods(Klass* ctxk, Method* m1, Method* m2,
                                                    KlassDepChange* changes = NULL);
-  static klassOop check_has_no_finalizable_subclasses(klassOop ctxk, KlassDepChange* changes = NULL);
-  static klassOop check_call_site_target_value(oop call_site, oop method_handle, CallSiteDepChange* changes = NULL);
-  // A returned klassOop is NULL if the dependency assertion is still
-  // valid.  A non-NULL klassOop is a 'witness' to the assertion
+  static Klass* check_has_no_finalizable_subclasses(Klass* ctxk, KlassDepChange* changes = NULL);
+  static Klass* check_call_site_target_value(oop call_site, oop method_handle, CallSiteDepChange* changes = NULL);
+  // A returned Klass* is NULL if the dependency assertion is still
+  // valid.  A non-NULL Klass* is a 'witness' to the assertion
   // failure, a point in the class hierarchy where the assertion has
   // been proven false.  For example, if check_leaf_type returns
   // non-NULL, the value is a subtype of the supposed leaf type.  This
@@ -345,10 +345,10 @@
   // It is used by DepStream::spot_check_dependency_at.
 
   // Detecting possible new assertions:
-  static klassOop  find_unique_concrete_subtype(klassOop ctxk);
-  static methodOop find_unique_concrete_method(klassOop ctxk, methodOop m);
-  static int       find_exclusive_concrete_subtypes(klassOop ctxk, int klen, klassOop k[]);
-  static int       find_exclusive_concrete_methods(klassOop ctxk, int mlen, methodOop m[]);
+  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 int       find_exclusive_concrete_methods(Klass* ctxk, int mlen, Method* m[]);
 
   // Create the encoding which will be stored in an nmethod.
   void encode_content_bytes();
@@ -368,15 +368,15 @@
   void copy_to(nmethod* nm);
 
   void log_all_dependencies();
-  void log_dependency(DepType dept, int nargs, ciObject* args[]) {
+  void log_dependency(DepType dept, int nargs, ciBaseObject* args[]) {
     write_dependency_to(log(), dept, nargs, args);
   }
   void log_dependency(DepType dept,
-                      ciObject* x0,
-                      ciObject* x1 = NULL,
-                      ciObject* x2 = NULL) {
+                      ciBaseObject* x0,
+                      ciBaseObject* x1 = NULL,
+                      ciBaseObject* x2 = NULL) {
     if (log() == NULL)  return;
-    ciObject* args[max_arg_count];
+    ciBaseObject* args[max_arg_count];
     args[0] = x0;
     args[1] = x1;
     args[2] = x2;
@@ -384,27 +384,47 @@
     log_dependency(dept, dep_args(dept), args);
   }
 
-  static void write_dependency_to(CompileLog* log,
-                                  DepType dept,
-                                  int nargs, ciObject* args[],
-                                  klassOop witness = NULL);
+  class DepArgument : public ResourceObj {
+   private:
+    bool  _is_oop;
+    bool  _valid;
+    void* _value;
+   public:
+    DepArgument() : _is_oop(false), _value(NULL), _valid(false) {}
+    DepArgument(oop v): _is_oop(true), _value(v), _valid(true) {}
+    DepArgument(Metadata* v): _is_oop(false), _value(v), _valid(true) {}
+
+    bool is_null() const               { return _value == NULL; }
+    bool is_oop() const                { return _is_oop; }
+    bool is_metadata() const           { return !_is_oop; }
+    bool is_klass() const              { return is_metadata() && metadata_value()->is_klass(); }
+    bool is_method() const              { return is_metadata() && metadata_value()->is_method(); }
+
+    oop oop_value() const              { assert(_is_oop && _valid, "must be"); return (oop) _value; }
+    Metadata* metadata_value() const { assert(!_is_oop && _valid, "must be"); return (Metadata*) _value; }
+  };
+
   static void write_dependency_to(CompileLog* log,
                                   DepType dept,
-                                  int nargs, oop args[],
-                                  klassOop witness = NULL);
+                                  int nargs, ciBaseObject* args[],
+                                  Klass* witness = NULL);
+  static void write_dependency_to(CompileLog* log,
+                                  DepType dept,
+                                  int nargs, DepArgument args[],
+                                  Klass* witness = NULL);
   static void write_dependency_to(xmlStream* xtty,
                                   DepType dept,
-                                  int nargs, oop args[],
-                                  klassOop witness = NULL);
+                                  int nargs, DepArgument args[],
+                                  Klass* witness = NULL);
   static void print_dependency(DepType dept,
-                               int nargs, oop args[],
-                               klassOop witness = NULL);
+                               int nargs, DepArgument args[],
+                               Klass* witness = NULL);
 
  private:
   // helper for encoding common context types as zero:
-  static ciKlass* ctxk_encoded_as_null(DepType dept, ciObject* x);
+  static ciKlass* ctxk_encoded_as_null(DepType dept, ciBaseObject* x);
 
-  static klassOop ctxk_encoded_as_null(DepType dept, oop x);
+  static Klass* ctxk_encoded_as_null(DepType dept, Metadata* x);
 
  public:
   // Use this to iterate over an nmethod's dependency set.
@@ -433,13 +453,13 @@
 
     void initial_asserts(size_t byte_limit) NOT_DEBUG({});
 
+    inline Metadata* recorded_metadata_at(int i);
     inline oop recorded_oop_at(int i);
-        // => _code? _code->oop_at(i): *_deps->_oop_recorder->handle_at(i)
 
-    klassOop check_klass_dependency(KlassDepChange* changes);
-    klassOop check_call_site_dependency(CallSiteDepChange* changes);
+    Klass* check_klass_dependency(KlassDepChange* changes);
+    Klass* check_call_site_dependency(CallSiteDepChange* changes);
 
-    void trace_and_log_witness(klassOop witness);
+    void trace_and_log_witness(Klass* witness);
 
   public:
     DepStream(Dependencies* deps)
@@ -463,38 +483,39 @@
     int argument_count()         { return dep_args(type()); }
     int argument_index(int i)    { assert(0 <= i && i < argument_count(), "oob");
                                    return _xi[i]; }
-    oop argument(int i);         // => recorded_oop_at(argument_index(i))
-    klassOop context_type();
+    Metadata* argument(int i);     // => recorded_oop_at(argument_index(i))
+    oop argument_oop(int i);         // => recorded_oop_at(argument_index(i))
+    Klass* context_type();
 
     bool is_klass_type()         { return Dependencies::is_klass_type(type()); }
 
-    methodOop method_argument(int i) {
-      oop x = argument(i);
+    Method* method_argument(int i) {
+      Metadata* x = argument(i);
       assert(x->is_method(), "type");
-      return (methodOop) x;
+      return (Method*) x;
     }
-    klassOop type_argument(int i) {
-      oop x = argument(i);
+    Klass* type_argument(int i) {
+      Metadata* x = argument(i);
       assert(x->is_klass(), "type");
-      return (klassOop) x;
+      return (Klass*) x;
     }
 
     // The point of the whole exercise:  Is this dep still OK?
-    klassOop check_dependency() {
-      klassOop result = check_klass_dependency(NULL);
+    Klass* check_dependency() {
+      Klass* result = check_klass_dependency(NULL);
       if (result != NULL)  return result;
       return check_call_site_dependency(NULL);
     }
 
     // A lighter version:  Checks only around recent changes in a class
     // hierarchy.  (See Universe::flush_dependents_on.)
-    klassOop spot_check_dependency_at(DepChange& changes);
+    Klass* spot_check_dependency_at(DepChange& changes);
 
     // Log the current dependency to xtty or compilation log.
-    void log_dependency(klassOop witness = NULL);
+    void log_dependency(Klass* witness = NULL);
 
     // Print the current dependency to tty.
-    void print_dependency(klassOop witness = NULL, bool verbose = false);
+    void print_dependency(Klass* witness = NULL, bool verbose = false);
   };
   friend class Dependencies::DepStream;
 
@@ -533,7 +554,7 @@
 
   // Usage:
   // for (DepChange::ContextStream str(changes); str.next(); ) {
-  //   klassOop k = str.klass();
+  //   Klass* k = str.klass();
   //   switch (str.change_type()) {
   //     ...
   //   }
@@ -545,8 +566,8 @@
 
     // iteration variables:
     ChangeType  _change_type;
-    klassOop    _klass;
-    objArrayOop _ti_base;    // i.e., transitive_interfaces
+    Klass*      _klass;
+    Array<Klass*>* _ti_base;    // i.e., transitive_interfaces
     int         _ti_index;
     int         _ti_limit;
 
@@ -566,7 +587,7 @@
     bool next();
 
     ChangeType change_type()     { return _change_type; }
-    klassOop   klass()           { return _klass; }
+    Klass*     klass()           { return _klass; }
   };
   friend class DepChange::ContextStream;
 };
@@ -598,10 +619,10 @@
   // What kind of DepChange is this?
   virtual bool is_klass_change() const { return true; }
 
-  klassOop new_type() { return _new_type(); }
+  Klass* new_type() { return _new_type(); }
 
   // involves_context(k) is true if k is new_type or any of the super types
-  bool involves_context(klassOop k);
+  bool involves_context(Klass* k);
 };