src/share/vm/classfile/placeholders.hpp

Thu, 27 May 2010 19:08:38 -0700

author
trims
date
Thu, 27 May 2010 19:08:38 -0700
changeset 1907
c18cbe5936b8
parent 435
a61af66fc99e
child 2314
f95d63e2154a
permissions
-rw-r--r--

6941466: Oracle rebranding changes for Hotspot repositories
Summary: Change all the Sun copyrights to Oracle copyright
Reviewed-by: ohair

     1 /*
     2  * Copyright (c) 2003, 2007, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 class PlaceholderEntry;
    27 // Placeholder objects. These represent classes currently
    28 // being loaded, as well as arrays of primitives.
    29 //
    31 class PlaceholderTable : public TwoOopHashtable {
    32   friend class VMStructs;
    34 public:
    35   PlaceholderTable(int table_size);
    37   PlaceholderEntry* new_entry(int hash, symbolOop name, oop loader, bool havesupername, symbolOop supername);
    39   PlaceholderEntry* bucket(int i) {
    40     return (PlaceholderEntry*)Hashtable::bucket(i);
    41   }
    43   PlaceholderEntry** bucket_addr(int i) {
    44     return (PlaceholderEntry**)Hashtable::bucket_addr(i);
    45   }
    47   void add_entry(int index, PlaceholderEntry* new_entry) {
    48     Hashtable::add_entry(index, (HashtableEntry*)new_entry);
    49   }
    51   void add_entry(int index, unsigned int hash, symbolHandle name,
    52                 Handle loader, bool havesupername, symbolHandle supername);
    54 // This returns a symbolOop to match type for SystemDictionary
    55   symbolOop find_entry(int index, unsigned int hash,
    56                        symbolHandle name, Handle loader);
    58   PlaceholderEntry* get_entry(int index, unsigned int hash,
    59                        symbolHandle name, Handle loader);
    61 // caller to create a placeholder entry must enumerate an action
    62 // caller claims ownership of that action
    63 // For parallel classloading:
    64 // multiple LOAD_INSTANCE threads can proceed in parallel
    65 // multiple LOAD_SUPER threads can proceed in parallel
    66 // LOAD_SUPER needed to check for class circularity
    67 // DEFINE_CLASS: ultimately define class must be single threaded
    68 // on a class/classloader basis
    69 // so the head of that queue owns the token
    70 // and the rest of the threads return the result the first thread gets
    71  enum classloadAction {
    72     LOAD_INSTANCE = 1,             // calling load_instance_class
    73     LOAD_SUPER = 2,                // loading superclass for this class
    74     DEFINE_CLASS = 3               // find_or_define class
    75  };
    77   // find_and_add returns probe pointer - old or new
    78   // If no entry exists, add a placeholder entry and push SeenThread
    79   // If entry exists, reuse entry and push SeenThread for classloadAction
    80   PlaceholderEntry* find_and_add(int index, unsigned int hash,
    81                                  symbolHandle name, Handle loader,
    82                                  classloadAction action, symbolHandle supername,
    83                                  Thread* thread);
    85   void remove_entry(int index, unsigned int hash,
    86                     symbolHandle name, Handle loader);
    88 // Remove placeholder information
    89   void find_and_remove(int index, unsigned int hash,
    90                        symbolHandle name, Handle loader, Thread* thread);
    92   // GC support.
    93   void oops_do(OopClosure* f);
    95   // JVMTI support
    96   void entries_do(void f(symbolOop, oop));
    98 #ifndef PRODUCT
    99   void print();
   100 #endif
   101   void verify();
   102 };
   104 // SeenThread objects represent list of threads that are
   105 // currently performing a load action on a class.
   106 // For class circularity, set before loading a superclass.
   107 // For bootclasssearchpath, set before calling load_instance_class.
   108 // Defining must be single threaded on a class/classloader basis
   109 // For DEFINE_CLASS, the head of the queue owns the
   110 // define token and the rest of the threads wait to return the
   111 // result the first thread gets.
   112 class SeenThread: public CHeapObj {
   113 private:
   114    Thread *_thread;
   115    SeenThread* _stnext;
   116    SeenThread* _stprev;
   117 public:
   118    SeenThread(Thread *thread) {
   119        _thread = thread;
   120        _stnext = NULL;
   121        _stprev = NULL;
   122    }
   123    Thread* thread()                const { return _thread;}
   124    void set_thread(Thread *thread) { _thread = thread; }
   126    SeenThread* next()              const { return _stnext;}
   127    void set_next(SeenThread *seen) { _stnext = seen; }
   128    void set_prev(SeenThread *seen) { _stprev = seen; }
   130 #ifndef PRODUCT
   131   void printActionQ() {
   132     SeenThread* seen = this;
   133     while (seen != NULL) {
   134       seen->thread()->print_value();
   135       tty->print(", ");
   136       seen = seen->next();
   137     }
   138   }
   139 #endif // PRODUCT
   140 };
   142 // Placeholder objects represent classes currently being loaded.
   143 // All threads examining the placeholder table must hold the
   144 // SystemDictionary_lock, so we don't need special precautions
   145 // on store ordering here.
   146 // The system dictionary is the only user of this class.
   148 class PlaceholderEntry : public HashtableEntry {
   149   friend class VMStructs;
   152  private:
   153   oop               _loader;        // initiating loader
   154   bool              _havesupername; // distinguish between null supername, and unknown
   155   symbolOop         _supername;
   156   Thread*           _definer;       // owner of define token
   157   klassOop          _instanceKlass; // instanceKlass from successful define
   158   SeenThread*       _superThreadQ;  // doubly-linked queue of Threads loading a superclass for this class
   159   SeenThread*       _loadInstanceThreadQ;  // loadInstance thread
   160                                     // can be multiple threads if classloader object lock broken by application
   161                                     // or if classloader supports parallel classloading
   163   SeenThread*       _defineThreadQ; // queue of Threads trying to define this class
   164                                     // including _definer
   165                                     // _definer owns token
   166                                     // queue waits for and returns results from _definer
   168  public:
   169   // Simple accessors, used only by SystemDictionary
   170   symbolOop          klass()               const { return (symbolOop)literal(); }
   171   symbolOop*         klass_addr()          { return (symbolOop*)literal_addr(); }
   173   oop                loader()              const { return _loader; }
   174   void               set_loader(oop loader) { _loader = loader; }
   175   oop*               loader_addr()         { return &_loader; }
   177   bool               havesupername()       const { return _havesupername; }
   178   void               set_havesupername(bool havesupername) { _havesupername = havesupername; }
   180   symbolOop          supername()           const { return _supername; }
   181   void               set_supername(symbolOop supername) { _supername = supername; }
   182   symbolOop*         supername_addr()      { return &_supername; }
   184   Thread*            definer()             const {return _definer; }
   185   void               set_definer(Thread* definer) { _definer = definer; }
   187   klassOop           instanceKlass()     const {return _instanceKlass; }
   188   void               set_instanceKlass(klassOop instanceKlass) { _instanceKlass = instanceKlass; }
   189   klassOop*          instanceKlass_addr()   { return &_instanceKlass; }
   191   SeenThread*        superThreadQ()        const { return _superThreadQ; }
   192   void               set_superThreadQ(SeenThread* SeenThread) { _superThreadQ = SeenThread; }
   194   SeenThread*        loadInstanceThreadQ() const { return _loadInstanceThreadQ; }
   195   void               set_loadInstanceThreadQ(SeenThread* SeenThread) { _loadInstanceThreadQ = SeenThread; }
   197   SeenThread*        defineThreadQ()        const { return _defineThreadQ; }
   198   void               set_defineThreadQ(SeenThread* SeenThread) { _defineThreadQ = SeenThread; }
   200   PlaceholderEntry* next() const {
   201     return (PlaceholderEntry*)HashtableEntry::next();
   202   }
   204   PlaceholderEntry** next_addr() {
   205     return (PlaceholderEntry**)HashtableEntry::next_addr();
   206   }
   208   // Test for equality
   209   // Entries are unique for class/classloader name pair
   210   bool equals(symbolOop class_name, oop class_loader) const {
   211     return (klass() == class_name && loader() == class_loader);
   212   }
   214   SeenThread* actionToQueue(PlaceholderTable::classloadAction action) {
   215     SeenThread* queuehead;
   216     switch (action) {
   217       case PlaceholderTable::LOAD_INSTANCE:
   218          queuehead = _loadInstanceThreadQ;
   219          break;
   220       case PlaceholderTable::LOAD_SUPER:
   221          queuehead = _superThreadQ;
   222          break;
   223       case PlaceholderTable::DEFINE_CLASS:
   224          queuehead = _defineThreadQ;
   225          break;
   226       default: Unimplemented();
   227     }
   228     return queuehead;
   229   }
   231   void set_threadQ(SeenThread* seenthread, PlaceholderTable::classloadAction action) {
   232     switch (action) {
   233       case PlaceholderTable::LOAD_INSTANCE:
   234          _loadInstanceThreadQ = seenthread;
   235          break;
   236       case PlaceholderTable::LOAD_SUPER:
   237          _superThreadQ = seenthread;
   238          break;
   239       case PlaceholderTable::DEFINE_CLASS:
   240          _defineThreadQ = seenthread;
   241          break;
   242       default: Unimplemented();
   243     }
   244     return;
   245   }
   247   bool super_load_in_progress() {
   248      return (_superThreadQ != NULL);
   249   }
   251   bool instance_load_in_progress() {
   252     return (_loadInstanceThreadQ != NULL);
   253   }
   255   bool define_class_in_progress() {
   256     return (_defineThreadQ != NULL);
   257   }
   259 // Doubly-linked list of Threads per action for class/classloader pair
   260 // Class circularity support: links in thread before loading superclass
   261 // bootstrapsearchpath support: links in a thread before load_instance_class
   262 // definers: use as queue of define requestors, including owner of
   263 // define token. Appends for debugging of requestor order
   264   void add_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) {
   265     assert_lock_strong(SystemDictionary_lock);
   266     SeenThread* threadEntry = new SeenThread(thread);
   267     SeenThread* seen = actionToQueue(action);
   269     if (seen == NULL) {
   270       set_threadQ(threadEntry, action);
   271       return;
   272     }
   273     SeenThread* next;
   274     while ((next = seen->next()) != NULL) {
   275       seen = next;
   276     }
   277     seen->set_next(threadEntry);
   278     threadEntry->set_prev(seen);
   279     return;
   280   }
   282   bool check_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) {
   283     assert_lock_strong(SystemDictionary_lock);
   284     SeenThread* threadQ = actionToQueue(action);
   285     SeenThread* seen = threadQ;
   286     while (seen) {
   287       if (thread == seen->thread()) {
   288         return true;
   289       }
   290       seen = seen->next();
   291     }
   292     return false;
   293   }
   295   // returns true if seenthreadQ is now empty
   296   // Note, caller must ensure probe still exists while holding
   297   // SystemDictionary_lock
   298   // ignores if cleanup has already been done
   299   // if found, deletes SeenThread
   300   bool remove_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) {
   301     assert_lock_strong(SystemDictionary_lock);
   302     SeenThread* threadQ = actionToQueue(action);
   303     SeenThread* seen = threadQ;
   304     SeenThread* prev = NULL;
   305     while (seen) {
   306       if (thread == seen->thread()) {
   307         if (prev) {
   308           prev->set_next(seen->next());
   309         } else {
   310           set_threadQ(seen->next(), action);
   311         }
   312         if (seen->next()) {
   313           seen->next()->set_prev(prev);
   314         }
   315         delete seen;
   316         break;
   317       }
   318       prev = seen;
   319       seen = seen->next();
   320     }
   321     return (actionToQueue(action) == NULL);
   322   }
   324   // GC support
   325   // Applies "f->do_oop" to all root oops in the placeholder table.
   326   void oops_do(OopClosure* blk);
   328   // Print method doesn't append a cr
   329   void print() const  PRODUCT_RETURN;
   330   void verify() const;
   331 };

mercurial