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