1/*
2 * Copyright (c) 2003, 2019, 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 "runtime/thread.hpp"
29#include "utilities/hashtable.hpp"
30
31class PlaceholderEntry;
32
33// Placeholder objects. These represent classes currently
34// being loaded, as well as arrays of primitives.
35//
36
37class PlaceholderTable : public Hashtable<Symbol*, mtClass> {
38
39public:
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.
112class SeenThread: public CHeapObj<mtInternal> {
113private:
114 Thread *_thread;
115 SeenThread* _stnext;
116 SeenThread* _stprev;
117public:
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
146class 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_CLASSFILE_PLACEHOLDERS_HPP
325