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 
bucket(int i) const45   PlaceholderEntry* bucket(int i) const {
46     return (PlaceholderEntry*)Hashtable<Symbol*, mtClass>::bucket(i);
47   }
48 
bucket_addr(int i)49   PlaceholderEntry** bucket_addr(int i) {
50     return (PlaceholderEntry**)Hashtable<Symbol*, mtClass>::bucket_addr(i);
51   }
52 
add_entry(int index,PlaceholderEntry * new_entry)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:
SeenThread(Thread * thread)118    SeenThread(Thread *thread) {
119        _thread = thread;
120        _stnext = NULL;
121        _stprev = NULL;
122    }
thread() const123    Thread* thread()                const { return _thread;}
set_thread(Thread * thread)124    void set_thread(Thread *thread) { _thread = thread; }
125 
next() const126    SeenThread* next()              const { return _stnext;}
set_next(SeenThread * seen)127    void set_next(SeenThread *seen) { _stnext = seen; }
set_prev(SeenThread * seen)128    void set_prev(SeenThread *seen) { _stprev = seen; }
129 
print_action_queue(outputStream * st)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
klassname() const166   Symbol*            klassname()           const { return literal(); }
167 
loader_data() const168   ClassLoaderData*   loader_data()         const { return _loader_data; }
set_loader_data(ClassLoaderData * loader_data)169   void               set_loader_data(ClassLoaderData* loader_data) { _loader_data = loader_data; }
170 
havesupername() const171   bool               havesupername()       const { return _havesupername; }
set_havesupername(bool havesupername)172   void               set_havesupername(bool havesupername) { _havesupername = havesupername; }
173 
supername() const174   Symbol*            supername()           const { return _supername; }
set_supername(Symbol * supername)175   void               set_supername(Symbol* supername) {
176     _supername = supername;
177     if (_supername != NULL) _supername->increment_refcount();
178   }
179 
definer() const180   Thread*            definer()             const {return _definer; }
set_definer(Thread * definer)181   void               set_definer(Thread* definer) { _definer = definer; }
182 
instance_klass() const183   InstanceKlass*     instance_klass()      const {return _instanceKlass; }
set_instance_klass(InstanceKlass * ik)184   void               set_instance_klass(InstanceKlass* ik) { _instanceKlass = ik; }
185 
superThreadQ() const186   SeenThread*        superThreadQ()        const { return _superThreadQ; }
set_superThreadQ(SeenThread * SeenThread)187   void               set_superThreadQ(SeenThread* SeenThread) { _superThreadQ = SeenThread; }
188 
loadInstanceThreadQ() const189   SeenThread*        loadInstanceThreadQ() const { return _loadInstanceThreadQ; }
set_loadInstanceThreadQ(SeenThread * SeenThread)190   void               set_loadInstanceThreadQ(SeenThread* SeenThread) { _loadInstanceThreadQ = SeenThread; }
191 
defineThreadQ() const192   SeenThread*        defineThreadQ()        const { return _defineThreadQ; }
set_defineThreadQ(SeenThread * SeenThread)193   void               set_defineThreadQ(SeenThread* SeenThread) { _defineThreadQ = SeenThread; }
194 
next() const195   PlaceholderEntry* next() const {
196     return (PlaceholderEntry*)HashtableEntry<Symbol*, mtClass>::next();
197   }
198 
next_addr()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
equals(Symbol * class_name,ClassLoaderData * loader) const205   bool equals(Symbol* class_name, ClassLoaderData* loader) const {
206     return (klassname() == class_name && loader_data() == loader);
207   }
208 
actionToQueue(PlaceholderTable::classloadAction action)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 
set_threadQ(SeenThread * seenthread,PlaceholderTable::classloadAction action)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 
super_load_in_progress()242   bool super_load_in_progress() {
243      return (_superThreadQ != NULL);
244   }
245 
instance_load_in_progress()246   bool instance_load_in_progress() {
247     return (_loadInstanceThreadQ != NULL);
248   }
249 
define_class_in_progress()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
add_seen_thread(Thread * thread,PlaceholderTable::classloadAction action)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 
check_seen_thread(Thread * thread,PlaceholderTable::classloadAction action)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
remove_seen_thread(Thread * thread,PlaceholderTable::classloadAction action)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
325