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 | |
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_CLASSFILE_PLACEHOLDERS_HPP |
325 | |