src/share/vm/classfile/dictionary.hpp

Sat, 01 May 2010 02:42:18 -0700

author
jrose
date
Sat, 01 May 2010 02:42:18 -0700
changeset 1862
cd5dbf694d45
parent 1145
e5b0439ef4ae
child 1907
c18cbe5936b8
permissions
-rw-r--r--

6939134: JSR 292 adjustments to method handle invocation
Summary: split MethodHandle.invoke into invokeExact and invokeGeneric; also clean up JVM-to-Java interfaces
Reviewed-by: twisti

     1 /*
     2  * Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
    21  * have any questions.
    22  *
    23  */
    25 class DictionaryEntry;
    27 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    28 // The data structure for the system dictionary (and the shared system
    29 // dictionary).
    31 class Dictionary : public TwoOopHashtable {
    32   friend class VMStructs;
    33 private:
    34   // current iteration index.
    35   static int                    _current_class_index;
    36   // pointer to the current hash table entry.
    37   static DictionaryEntry*       _current_class_entry;
    39   DictionaryEntry* get_entry(int index, unsigned int hash,
    40                              symbolHandle name, Handle loader);
    42   DictionaryEntry* bucket(int i) {
    43     return (DictionaryEntry*)Hashtable::bucket(i);
    44   }
    46   // The following method is not MT-safe and must be done under lock.
    47   DictionaryEntry** bucket_addr(int i) {
    48     return (DictionaryEntry**)Hashtable::bucket_addr(i);
    49   }
    51   void add_entry(int index, DictionaryEntry* new_entry) {
    52     Hashtable::add_entry(index, (HashtableEntry*)new_entry);
    53   }
    56 public:
    57   Dictionary(int table_size);
    58   Dictionary(int table_size, HashtableBucket* t, int number_of_entries);
    60   DictionaryEntry* new_entry(unsigned int hash, klassOop klass, oop loader);
    62   DictionaryEntry* new_entry();
    64   void free_entry(DictionaryEntry* entry);
    66   void add_klass(symbolHandle class_name, Handle class_loader,KlassHandle obj);
    68   klassOop find_class(int index, unsigned int hash,
    69                       symbolHandle name, Handle loader);
    71   klassOop find_shared_class(int index, unsigned int hash, symbolHandle name);
    73   // Compiler support
    74   klassOop try_get_next_class();
    76   // GC support
    78   void oops_do(OopClosure* f);
    79   void always_strong_classes_do(OopClosure* blk);
    80   void classes_do(void f(klassOop));
    81   void classes_do(void f(klassOop, TRAPS), TRAPS);
    82   void classes_do(void f(klassOop, oop));
    83   void classes_do(void f(klassOop, oop, TRAPS), TRAPS);
    85   void methods_do(void f(methodOop));
    88   // Classes loaded by the bootstrap loader are always strongly reachable.
    89   // If we're not doing class unloading, all classes are strongly reachable.
    90   static bool is_strongly_reachable(oop class_loader, oop klass) {
    91     assert (klass != NULL, "should have non-null klass");
    92     return (class_loader == NULL || !ClassUnloading);
    93   }
    95   // Unload (that is, break root links to) all unmarked classes and
    96   // loaders.  Returns "true" iff something was unloaded.
    97   bool do_unloading(BoolObjectClosure* is_alive);
    99   // Protection domains
   100   klassOop find(int index, unsigned int hash, symbolHandle name,
   101                 Handle loader, Handle protection_domain, TRAPS);
   102   bool is_valid_protection_domain(int index, unsigned int hash,
   103                                   symbolHandle name, Handle class_loader,
   104                                   Handle protection_domain);
   105   void add_protection_domain(int index, unsigned int hash,
   106                              instanceKlassHandle klass, Handle loader,
   107                              Handle protection_domain, TRAPS);
   109   // Sharing support
   110   void dump(SerializeOopClosure* soc);
   111   void restore(SerializeOopClosure* soc);
   112   void reorder_dictionary();
   115 #ifndef PRODUCT
   116   void print();
   117 #endif
   118   void verify();
   119 };
   121 // The following classes can be in dictionary.cpp, but we need these
   122 // to be in header file so that SA's vmStructs can access.
   124 class ProtectionDomainEntry :public CHeapObj {
   125   friend class VMStructs;
   126  public:
   127   ProtectionDomainEntry* _next;
   128   oop                    _protection_domain;
   130   ProtectionDomainEntry(oop protection_domain, ProtectionDomainEntry* next) {
   131     _protection_domain = protection_domain;
   132     _next              = next;
   133   }
   135   ProtectionDomainEntry* next() { return _next; }
   136   oop protection_domain() { return _protection_domain; }
   137 };
   139 // An entry in the system dictionary, this describes a class as
   140 // { klassOop, loader, protection_domain }.
   142 class DictionaryEntry : public HashtableEntry {
   143   friend class VMStructs;
   144  private:
   145   // Contains the set of approved protection domains that can access
   146   // this system dictionary entry.
   147   ProtectionDomainEntry* _pd_set;
   148   oop                    _loader;
   151  public:
   152   // Tells whether a protection is in the approved set.
   153   bool contains_protection_domain(oop protection_domain) const;
   154   // Adds a protection domain to the approved set.
   155   void add_protection_domain(oop protection_domain);
   157   klassOop klass() const { return (klassOop)literal(); }
   158   klassOop* klass_addr() { return (klassOop*)literal_addr(); }
   160   DictionaryEntry* next() const {
   161     return (DictionaryEntry*)HashtableEntry::next();
   162   }
   164   DictionaryEntry** next_addr() {
   165     return (DictionaryEntry**)HashtableEntry::next_addr();
   166   }
   168   oop loader() const { return _loader; }
   169   void set_loader(oop loader) { _loader = loader; }
   170   oop* loader_addr() { return &_loader; }
   172   ProtectionDomainEntry* pd_set() const { return _pd_set; }
   173   void set_pd_set(ProtectionDomainEntry* pd_set) { _pd_set = pd_set; }
   175   bool has_protection_domain() { return _pd_set != NULL; }
   177   // Tells whether the initiating class' protection can access the this _klass
   178   bool is_valid_protection_domain(Handle protection_domain) {
   179     if (!ProtectionDomainVerification) return true;
   180     if (!SystemDictionary::has_checkPackageAccess()) return true;
   182     return protection_domain() == NULL
   183          ? true
   184          : contains_protection_domain(protection_domain());
   185   }
   188   void protection_domain_set_oops_do(OopClosure* f) {
   189     for (ProtectionDomainEntry* current = _pd_set;
   190                                 current != NULL;
   191                                 current = current->_next) {
   192       f->do_oop(&(current->_protection_domain));
   193     }
   194   }
   196   void verify_protection_domain_set() {
   197     for (ProtectionDomainEntry* current = _pd_set;
   198                                 current != NULL;
   199                                 current = current->_next) {
   200       current->_protection_domain->verify();
   201     }
   202   }
   204   bool equals(symbolOop class_name, oop class_loader) const {
   205     klassOop klass = (klassOop)literal();
   206     return (instanceKlass::cast(klass)->name() == class_name &&
   207             _loader == class_loader);
   208   }
   210   void print() {
   211     int count = 0;
   212     for (ProtectionDomainEntry* current = _pd_set;
   213                                 current != NULL;
   214                                 current = current->_next) {
   215       count++;
   216     }
   217     tty->print_cr("pd set = #%d", count);
   218   }
   219 };
   221 // Entry in a SymbolPropertyTable, mapping a single symbolOop
   222 // to a managed and an unmanaged pointer.
   223 class SymbolPropertyEntry : public HashtableEntry {
   224   friend class VMStructs;
   225  private:
   226   intptr_t _symbol_mode;  // secondary key
   227   oop     _property_oop;
   228   address _property_data;
   230  public:
   231   symbolOop symbol() const          { return (symbolOop) literal(); }
   233   intptr_t symbol_mode() const      { return _symbol_mode; }
   234   void set_symbol_mode(intptr_t m)  { _symbol_mode = m; }
   236   oop      property_oop() const     { return _property_oop; }
   237   void set_property_oop(oop p)      { _property_oop = p; }
   239   address  property_data() const    { return _property_data; }
   240   void set_property_data(address p) { _property_data = p; }
   242   SymbolPropertyEntry* next() const {
   243     return (SymbolPropertyEntry*)HashtableEntry::next();
   244   }
   246   SymbolPropertyEntry** next_addr() {
   247     return (SymbolPropertyEntry**)HashtableEntry::next_addr();
   248   }
   250   oop* symbol_addr()                { return literal_addr(); }
   251   oop* property_oop_addr()          { return &_property_oop; }
   253   void print_on(outputStream* st) const {
   254     symbol()->print_value_on(st);
   255     st->print("/mode="INTX_FORMAT, symbol_mode());
   256     st->print(" -> ");
   257     bool printed = false;
   258     if (property_oop() != NULL) {
   259       property_oop()->print_value_on(st);
   260       printed = true;
   261     }
   262     if (property_data() != NULL) {
   263       if (printed)  st->print(" and ");
   264       st->print(INTPTR_FORMAT, property_data());
   265       printed = true;
   266     }
   267     st->print_cr(printed ? "" : "(empty)");
   268   }
   269 };
   271 // A system-internal mapping of symbols to pointers, both managed
   272 // and unmanaged.  Used to record the auto-generation of each method
   273 // MethodHandle.invoke(S)T, for all signatures (S)T.
   274 class SymbolPropertyTable : public Hashtable {
   275   friend class VMStructs;
   276 private:
   277   SymbolPropertyEntry* bucket(int i) {
   278     return (SymbolPropertyEntry*) Hashtable::bucket(i);
   279   }
   281   // The following method is not MT-safe and must be done under lock.
   282   SymbolPropertyEntry** bucket_addr(int i) {
   283     return (SymbolPropertyEntry**) Hashtable::bucket_addr(i);
   284   }
   286   void add_entry(int index, SymbolPropertyEntry* new_entry) {
   287     ShouldNotReachHere();
   288   }
   289   void set_entry(int index, SymbolPropertyEntry* new_entry) {
   290     ShouldNotReachHere();
   291   }
   293   SymbolPropertyEntry* new_entry(unsigned int hash, symbolOop symbol, intptr_t symbol_mode) {
   294     SymbolPropertyEntry* entry = (SymbolPropertyEntry*) Hashtable::new_entry(hash, symbol);
   295     entry->set_symbol_mode(symbol_mode);
   296     entry->set_property_oop(NULL);
   297     entry->set_property_data(NULL);
   298     return entry;
   299   }
   301 public:
   302   SymbolPropertyTable(int table_size);
   303   SymbolPropertyTable(int table_size, HashtableBucket* t, int number_of_entries);
   305   void free_entry(SymbolPropertyEntry* entry) {
   306     Hashtable::free_entry(entry);
   307   }
   309   unsigned int compute_hash(symbolHandle sym, intptr_t symbol_mode) {
   310     // Use the regular identity_hash.
   311     return Hashtable::compute_hash(sym) ^ symbol_mode;
   312   }
   314   int index_for(symbolHandle name, intptr_t symbol_mode) {
   315     return hash_to_index(compute_hash(name, symbol_mode));
   316   }
   318   // need not be locked; no state change
   319   SymbolPropertyEntry* find_entry(int index, unsigned int hash, symbolHandle name, intptr_t name_mode);
   321   // must be done under SystemDictionary_lock
   322   SymbolPropertyEntry* add_entry(int index, unsigned int hash, symbolHandle name, intptr_t name_mode);
   324   // GC support
   325   void oops_do(OopClosure* f);
   326   void methods_do(void f(methodOop));
   328   // Sharing support
   329   void dump(SerializeOopClosure* soc);
   330   void restore(SerializeOopClosure* soc);
   331   void reorder_dictionary();
   333 #ifndef PRODUCT
   334   void print();
   335 #endif
   336   void verify();
   337 };

mercurial