1 /*
  2  * Copyright (c) 2003, 2021, 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_CLASSFILE_PLACEHOLDERS_HPP
 26 #define SHARE_CLASSFILE_PLACEHOLDERS_HPP
 27 
 28 #include "utilities/hashtable.hpp"
 29 
 30 class PlaceholderEntry;
 31 class Thread;
 32 class ClassLoaderData;
 33 class Symbol;
 34 
 35 // Placeholder objects. These represent classes currently
 36 // being loaded, as well as arrays of primitives.
 37 //
 38 
 39 class PlaceholderTable : public Hashtable<Symbol*, mtClass> {
 40 
 41 public:
 42   PlaceholderTable(int table_size);
 43 
 44   PlaceholderEntry* new_entry(int hash, Symbol* name, ClassLoaderData* loader_data, Symbol* supername);
 45   void free_entry(PlaceholderEntry* entry);
 46 
 47   PlaceholderEntry* bucket(int i) const {
 48     return (PlaceholderEntry*)Hashtable<Symbol*, mtClass>::bucket(i);
 49   }
 50 
 51   PlaceholderEntry** bucket_addr(int i) {
 52     return (PlaceholderEntry**)Hashtable<Symbol*, mtClass>::bucket_addr(i);
 53   }
 54 
 55   PlaceholderEntry* add_entry(unsigned int hash, Symbol* name,
 56                               ClassLoaderData* loader_data,
 57                               Symbol* supername);
 58 
 59   // This returns a Symbol* to match type for SystemDictionary
 60   Symbol* find_entry(unsigned int hash,
 61                      Symbol* name, ClassLoaderData* loader_data);
 62 
 63   PlaceholderEntry* get_entry(unsigned int hash,
 64                               Symbol* name, ClassLoaderData* loader_data);
 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 for classloadAction
 84   // If entry exists, reuse entry and push SeenThread for classloadAction
 85   PlaceholderEntry* find_and_add(unsigned int hash,
 86                                  Symbol* name, ClassLoaderData* loader_data,
 87                                  classloadAction action, Symbol* supername,
 88                                  JavaThread* thread);
 89 
 90   void remove_entry(unsigned int hash,
 91                     Symbol* name, ClassLoaderData* loader_data);
 92 
 93   // find_and_remove first removes SeenThread for classloadAction
 94   // If all queues are empty and definer is null, remove the PlacheholderEntry completely
 95   void find_and_remove(unsigned int hash,
 96                        Symbol* name, ClassLoaderData* loader_data,
 97                        classloadAction action, JavaThread* thread);
 98 
 99   void print_on(outputStream* st) const;
100   void print() const;
101   void verify();
102 };
103 
104 class SeenThread;
105 
106 // Placeholder objects represent classes currently being loaded.
107 // All threads examining the placeholder table must hold the
108 // SystemDictionary_lock, so we don't need special precautions
109 // on store ordering here.
110 // The system dictionary is the only user of this class.
111 
112 class PlaceholderEntry : public HashtableEntry<Symbol*, mtClass> {
113 
114   friend class PlaceholderTable;
115 
116  private:
117   ClassLoaderData*  _loader_data;   // initiating loader
118   Symbol*           _supername;
119   JavaThread*       _definer;       // owner of define token
120   InstanceKlass*    _instanceKlass; // InstanceKlass from successful define
121   SeenThread*       _superThreadQ;  // doubly-linked queue of Threads loading a superclass for this class
122   SeenThread*       _loadInstanceThreadQ;  // loadInstance thread
123                                     // This can't be multiple threads since class loading waits for
124                                     // this token to be removed.
125 
126   SeenThread*       _defineThreadQ; // queue of Threads trying to define this class
127                                     // including _definer
128                                     // _definer owns token
129                                     // queue waits for and returns results from _definer
130 
131   SeenThread* actionToQueue(PlaceholderTable::classloadAction action);
132   void set_threadQ(SeenThread* seenthread, PlaceholderTable::classloadAction action);
133   void add_seen_thread(JavaThread* thread, PlaceholderTable::classloadAction action);
134   bool remove_seen_thread(JavaThread* thread, PlaceholderTable::classloadAction action);
135 
136  public:
137   // Simple accessors, used only by SystemDictionary
138   Symbol*            klassname()           const { return literal(); }
139 
140   ClassLoaderData*   loader_data()         const { return _loader_data; }
141   void               set_loader_data(ClassLoaderData* loader_data) { _loader_data = loader_data; }
142 
143   Symbol*            supername()           const { return _supername; }
144   void               set_supername(Symbol* supername) {
145     _supername = supername;
146     if (_supername != NULL) _supername->increment_refcount();
147   }
148 
149   JavaThread*        definer()             const {return _definer; }
150   void               set_definer(JavaThread* definer) { _definer = definer; }
151 
152   InstanceKlass*     instance_klass()      const {return _instanceKlass; }
153   void               set_instance_klass(InstanceKlass* ik) { _instanceKlass = ik; }
154 
155   SeenThread*        superThreadQ()        const { return _superThreadQ; }
156   void               set_superThreadQ(SeenThread* SeenThread) { _superThreadQ = SeenThread; }
157 
158   SeenThread*        loadInstanceThreadQ() const { return _loadInstanceThreadQ; }
159   void               set_loadInstanceThreadQ(SeenThread* SeenThread) { _loadInstanceThreadQ = SeenThread; }
160 
161   SeenThread*        defineThreadQ()       const { return _defineThreadQ; }
162   void               set_defineThreadQ(SeenThread* SeenThread) { _defineThreadQ = SeenThread; }
163 
164   PlaceholderEntry* next() const {
165     return (PlaceholderEntry*)HashtableEntry<Symbol*, mtClass>::next();
166   }
167 
168   PlaceholderEntry** next_addr() {
169     return (PlaceholderEntry**)HashtableEntry<Symbol*, mtClass>::next_addr();
170   }
171 
172   // Test for equality
173   // Entries are unique for class/classloader name pair
174   bool equals(Symbol* class_name, ClassLoaderData* loader) const {
175     return (klassname() == class_name && loader_data() == loader);
176   }
177 
178   bool super_load_in_progress() {
179      return (_superThreadQ != NULL);
180   }
181 
182   bool instance_load_in_progress() {
183     return (_loadInstanceThreadQ != NULL);
184   }
185 
186   bool define_class_in_progress() {
187     return (_defineThreadQ != NULL);
188   }
189 
190   // Used for ClassCircularityError checking
191   bool check_seen_thread(JavaThread* thread, PlaceholderTable::classloadAction action);
192 
193   // Print method doesn't append a cr
194   void print_entry(outputStream* st) const;
195   void verify() const;
196 };
197 
198 #endif // SHARE_CLASSFILE_PLACEHOLDERS_HPP