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