placeholders.hpp revision 13353:46bb2774fc88
1151497Sru/*
2104862Sru * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
3104862Sru * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4104862Sru *
5104862Sru * This code is free software; you can redistribute it and/or modify it
6104862Sru * under the terms of the GNU General Public License version 2 only, as
7104862Sru * published by the Free Software Foundation.
8104862Sru *
9104862Sru * This code is distributed in the hope that it will be useful, but WITHOUT
10104862Sru * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11104862Sru * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12104862Sru * version 2 for more details (a copy is included in the LICENSE file that
13104862Sru * accompanied this code).
14104862Sru *
15104862Sru * You should have received a copy of the GNU General Public License version
16104862Sru * 2 along with this work; if not, write to the Free Software Foundation,
17104862Sru * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18151497Sru *
19104862Sru * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20114402Sru * or visit www.oracle.com if you need additional information or have any
21114402Sru * questions.
22151497Sru *
23114402Sru */
24151497Sru
25151497Sru#ifndef SHARE_VM_CLASSFILE_PLACEHOLDERS_HPP
26151497Sru#define SHARE_VM_CLASSFILE_PLACEHOLDERS_HPP
27104862Sru
28104862Sru#include "runtime/thread.hpp"
29104862Sru#include "utilities/hashtable.hpp"
30104862Sru
31104862Sruclass PlaceholderEntry;
32104862Sru
33104862Sru// Placeholder objects. These represent classes currently
34104862Sru// being loaded, as well as arrays of primitives.
35104862Sru//
36104862Sru
37104862Sruclass PlaceholderTable : public Hashtable<Symbol*, mtClass> {
38104862Sru
39104862Srupublic:
40104862Sru  PlaceholderTable(int table_size);
41104862Sru
42104862Sru  PlaceholderEntry* new_entry(int hash, Symbol* name, ClassLoaderData* loader_data, bool havesupername, Symbol* supername);
43104862Sru  void free_entry(PlaceholderEntry* entry);
44104862Sru
45104862Sru  PlaceholderEntry* bucket(int i) {
46104862Sru    return (PlaceholderEntry*)Hashtable<Symbol*, mtClass>::bucket(i);
47104862Sru  }
48114402Sru
49104862Sru  PlaceholderEntry** bucket_addr(int i) {
50104862Sru    return (PlaceholderEntry**)Hashtable<Symbol*, mtClass>::bucket_addr(i);
51114402Sru  }
52104862Sru
53104862Sru  void add_entry(int index, PlaceholderEntry* new_entry) {
54104862Sru    Hashtable<Symbol*, mtClass>::add_entry(index, (HashtableEntry<Symbol*, mtClass>*)new_entry);
55104862Sru  }
56104862Sru
57104862Sru  void add_entry(int index, unsigned int hash, Symbol* name,
58104862Sru                ClassLoaderData* loader_data, bool havesupername, Symbol* supername);
59104862Sru
60104862Sru  // This returns a Symbol* to match type for SystemDictionary
61104862Sru  Symbol* find_entry(int index, unsigned int hash,
62104862Sru                       Symbol* name, ClassLoaderData* loader_data);
63104862Sru
64104862Sru  PlaceholderEntry* get_entry(int index, unsigned int hash,
65104862Sru                       Symbol* name, ClassLoaderData* loader_data);
66151497Sru
67151497Sru// caller to create a placeholder entry must enumerate an action
68151497Sru// caller claims ownership of that action
69104862Sru// For parallel classloading:
70104862Sru// multiple LOAD_INSTANCE threads can proceed in parallel
71104862Sru// multiple LOAD_SUPER threads can proceed in parallel
72104862Sru// LOAD_SUPER needed to check for class circularity
73104862Sru// DEFINE_CLASS: ultimately define class must be single threaded
74151497Sru// on a class/classloader basis
75104862Sru// so the head of that queue owns the token
76104862Sru// and the rest of the threads return the result the first thread gets
77104862Sru enum classloadAction {
78104862Sru    LOAD_INSTANCE = 1,             // calling load_instance_class
79104862Sru    LOAD_SUPER = 2,                // loading superclass for this class
80104862Sru    DEFINE_CLASS = 3               // find_or_define class
81104862Sru };
82104862Sru
83104862Sru  // find_and_add returns probe pointer - old or new
84104862Sru  // If no entry exists, add a placeholder entry and push SeenThread for classloadAction
85104862Sru  // If entry exists, reuse entry and push SeenThread for classloadAction
86104862Sru  PlaceholderEntry* find_and_add(int index, unsigned int hash,
87104862Sru                                 Symbol* name, ClassLoaderData* loader_data,
88104862Sru                                 classloadAction action, Symbol* supername,
89104862Sru                                 Thread* thread);
90104862Sru
91104862Sru  void remove_entry(int index, unsigned int hash,
92104862Sru                    Symbol* name, ClassLoaderData* loader_data);
93104862Sru
94104862Sru  // find_and_remove first removes SeenThread for classloadAction
95104862Sru  // If all queues are empty and definer is null, remove the PlacheholderEntry completely
96151497Sru  void find_and_remove(int index, unsigned int hash,
97151497Sru                       Symbol* name, ClassLoaderData* loader_data,
98151497Sru                       classloadAction action, Thread* thread);
99151497Sru
100151497Sru#ifndef PRODUCT
101104862Sru  void print();
102104862Sru#endif
103104862Sru  void verify();
104104862Sru};
105104862Sru
106151497Sru// SeenThread objects represent list of threads that are
107104862Sru// currently performing a load action on a class.
108104862Sru// For class circularity, set before loading a superclass.
109104862Sru// For bootclasssearchpath, set before calling load_instance_class.
110104862Sru// Defining must be single threaded on a class/classloader basis
111104862Sru// For DEFINE_CLASS, the head of the queue owns the
112104862Sru// define token and the rest of the threads wait to return the
113104862Sru// result the first thread gets.
114104862Sruclass SeenThread: public CHeapObj<mtInternal> {
115104862Sruprivate:
116104862Sru   Thread *_thread;
117104862Sru   SeenThread* _stnext;
118104862Sru   SeenThread* _stprev;
119104862Srupublic:
120104862Sru   SeenThread(Thread *thread) {
121104862Sru       _thread = thread;
122104862Sru       _stnext = NULL;
123104862Sru       _stprev = NULL;
124104862Sru   }
125104862Sru   Thread* thread()                const { return _thread;}
126104862Sru   void set_thread(Thread *thread) { _thread = thread; }
127104862Sru
128104862Sru   SeenThread* next()              const { return _stnext;}
129104862Sru   void set_next(SeenThread *seen) { _stnext = seen; }
130104862Sru   void set_prev(SeenThread *seen) { _stprev = seen; }
131151497Sru
132151497Sru#ifndef PRODUCT
133151497Sru  void printActionQ() {
134104862Sru    SeenThread* seen = this;
135151497Sru    while (seen != NULL) {
136151497Sru      seen->thread()->print_value();
137151497Sru      tty->print(", ");
138151497Sru      seen = seen->next();
139151497Sru    }
140151497Sru  }
141151497Sru#endif // PRODUCT
142151497Sru};
143151497Sru
144104862Sru// Placeholder objects represent classes currently being loaded.
145104862Sru// All threads examining the placeholder table must hold the
146151497Sru// SystemDictionary_lock, so we don't need special precautions
147104862Sru// on store ordering here.
148104862Sru// The system dictionary is the only user of this class.
149114402Sru
150114402Sruclass PlaceholderEntry : public HashtableEntry<Symbol*, mtClass> {
151151497Sru
152104862Sru private:
153104862Sru  ClassLoaderData*  _loader_data;   // initiating loader
154104862Sru  bool              _havesupername; // distinguish between null supername, and unknown
155151497Sru  Symbol*           _supername;
156151497Sru  Thread*           _definer;       // owner of define token
157151497Sru  InstanceKlass*    _instanceKlass; // InstanceKlass from successful define
158151497Sru  SeenThread*       _superThreadQ;  // doubly-linked queue of Threads loading a superclass for this class
159151497Sru  SeenThread*       _loadInstanceThreadQ;  // loadInstance thread
160151497Sru                                    // can be multiple threads if classloader object lock broken by application
161104862Sru                                    // or if classloader supports parallel classloading
162104862Sru
163104862Sru  SeenThread*       _defineThreadQ; // queue of Threads trying to define this class
164104862Sru                                    // including _definer
165104862Sru                                    // _definer owns token
166104862Sru                                    // queue waits for and returns results from _definer
167104862Sru
168104862Sru public:
169104862Sru  // Simple accessors, used only by SystemDictionary
170104862Sru  Symbol*            klassname()           const { return literal(); }
171104862Sru
172104862Sru  ClassLoaderData*   loader_data()         const { return _loader_data; }
173104862Sru  void               set_loader_data(ClassLoaderData* loader_data) { _loader_data = loader_data; }
174151497Sru
175104862Sru  bool               havesupername()       const { return _havesupername; }
176104862Sru  void               set_havesupername(bool havesupername) { _havesupername = havesupername; }
177104862Sru
178104862Sru  Symbol*            supername()           const { return _supername; }
179104862Sru  void               set_supername(Symbol* supername) {
180104862Sru    _supername = supername;
181104862Sru    if (_supername != NULL) _supername->increment_refcount();
182104862Sru  }
183104862Sru
184104862Sru  Thread*            definer()             const {return _definer; }
185104862Sru  void               set_definer(Thread* definer) { _definer = definer; }
186104862Sru
187104862Sru  InstanceKlass*     instance_klass()      const {return _instanceKlass; }
188104862Sru  void               set_instance_klass(InstanceKlass* ik) { _instanceKlass = ik; }
189104862Sru
190104862Sru  SeenThread*        superThreadQ()        const { return _superThreadQ; }
191104862Sru  void               set_superThreadQ(SeenThread* SeenThread) { _superThreadQ = SeenThread; }
192104862Sru
193104862Sru  SeenThread*        loadInstanceThreadQ() const { return _loadInstanceThreadQ; }
194104862Sru  void               set_loadInstanceThreadQ(SeenThread* SeenThread) { _loadInstanceThreadQ = SeenThread; }
195104862Sru
196104862Sru  SeenThread*        defineThreadQ()        const { return _defineThreadQ; }
197104862Sru  void               set_defineThreadQ(SeenThread* SeenThread) { _defineThreadQ = SeenThread; }
198104862Sru
199104862Sru  PlaceholderEntry* next() const {
200151497Sru    return (PlaceholderEntry*)HashtableEntry<Symbol*, mtClass>::next();
201104862Sru  }
202104862Sru
203104862Sru  PlaceholderEntry** next_addr() {
204104862Sru    return (PlaceholderEntry**)HashtableEntry<Symbol*, mtClass>::next_addr();
205104862Sru  }
206104862Sru
207104862Sru  // Test for equality
208104862Sru  // Entries are unique for class/classloader name pair
209104862Sru  bool equals(Symbol* class_name, ClassLoaderData* loader) const {
210104862Sru    return (klassname() == class_name && loader_data() == loader);
211104862Sru  }
212104862Sru
213104862Sru  SeenThread* actionToQueue(PlaceholderTable::classloadAction action) {
214104862Sru    SeenThread* queuehead = NULL;
215104862Sru    switch (action) {
216104862Sru      case PlaceholderTable::LOAD_INSTANCE:
217151497Sru         queuehead = _loadInstanceThreadQ;
218104862Sru         break;
219104862Sru      case PlaceholderTable::LOAD_SUPER:
220151497Sru         queuehead = _superThreadQ;
221104862Sru         break;
222104862Sru      case PlaceholderTable::DEFINE_CLASS:
223104862Sru         queuehead = _defineThreadQ;
224151497Sru         break;
225104862Sru      default: Unimplemented();
226104862Sru    }
227104862Sru    return queuehead;
228104862Sru  }
229151497Sru
230104862Sru  void set_threadQ(SeenThread* seenthread, PlaceholderTable::classloadAction action) {
231104862Sru    switch (action) {
232104862Sru      case PlaceholderTable::LOAD_INSTANCE:
233104862Sru         _loadInstanceThreadQ = seenthread;
234         break;
235      case PlaceholderTable::LOAD_SUPER:
236         _superThreadQ = seenthread;
237         break;
238      case PlaceholderTable::DEFINE_CLASS:
239         _defineThreadQ = seenthread;
240         break;
241      default: Unimplemented();
242    }
243    return;
244  }
245
246  bool super_load_in_progress() {
247     return (_superThreadQ != NULL);
248  }
249
250  bool instance_load_in_progress() {
251    return (_loadInstanceThreadQ != NULL);
252  }
253
254  bool define_class_in_progress() {
255    return (_defineThreadQ != NULL);
256  }
257
258// Doubly-linked list of Threads per action for class/classloader pair
259// Class circularity support: links in thread before loading superclass
260// bootstrapsearchpath support: links in a thread before load_instance_class
261// definers: use as queue of define requestors, including owner of
262// define token. Appends for debugging of requestor order
263  void add_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) {
264    assert_lock_strong(SystemDictionary_lock);
265    SeenThread* threadEntry = new SeenThread(thread);
266    SeenThread* seen = actionToQueue(action);
267
268    if (seen == NULL) {
269      set_threadQ(threadEntry, action);
270      return;
271    }
272    SeenThread* next;
273    while ((next = seen->next()) != NULL) {
274      seen = next;
275    }
276    seen->set_next(threadEntry);
277    threadEntry->set_prev(seen);
278    return;
279  }
280
281  bool check_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) {
282    assert_lock_strong(SystemDictionary_lock);
283    SeenThread* threadQ = actionToQueue(action);
284    SeenThread* seen = threadQ;
285    while (seen) {
286      if (thread == seen->thread()) {
287        return true;
288      }
289      seen = seen->next();
290    }
291    return false;
292  }
293
294  // returns true if seenthreadQ is now empty
295  // Note, caller must ensure probe still exists while holding
296  // SystemDictionary_lock
297  // ignores if cleanup has already been done
298  // if found, deletes SeenThread
299  bool remove_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) {
300    assert_lock_strong(SystemDictionary_lock);
301    SeenThread* threadQ = actionToQueue(action);
302    SeenThread* seen = threadQ;
303    SeenThread* prev = NULL;
304    while (seen) {
305      if (thread == seen->thread()) {
306        if (prev) {
307          prev->set_next(seen->next());
308        } else {
309          set_threadQ(seen->next(), action);
310        }
311        if (seen->next()) {
312          seen->next()->set_prev(prev);
313        }
314        delete seen;
315        break;
316      }
317      prev = seen;
318      seen = seen->next();
319    }
320    return (actionToQueue(action) == NULL);
321  }
322
323  // Print method doesn't append a cr
324  void print() const  PRODUCT_RETURN;
325  void verify() const;
326};
327
328#endif // SHARE_VM_CLASSFILE_PLACEHOLDERS_HPP
329