Mercurial > hg > truffle
annotate src/share/vm/classfile/placeholders.hpp @ 12837:82af7d7a0128
8003420: NPG: make new GC root for pd_set
Summary: Move protection domain oops from system dictionary entries into a seperate set; the system dictionary references entries in that set now. This allows fast iteration during non-classunloading garbage collection. Implementation based on initial prototype from Ioi Lam (iklam).
Reviewed-by: coleenp, iklam
author | tschatzl |
---|---|
date | Wed, 09 Oct 2013 10:57:01 +0200 |
parents | aefb345d3f5e |
children |
rev | line source |
---|---|
0 | 1 /* |
7582
aefb345d3f5e
7199207: NPG: Crash in PlaceholderTable::verify after StackOverflow
acorn
parents:
6983
diff
changeset
|
2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_CLASSFILE_PLACEHOLDERS_HPP |
26 #define SHARE_VM_CLASSFILE_PLACEHOLDERS_HPP | |
27 | |
1983
c760f78e0a53
7003125: precompiled.hpp is included when precompiled headers are not used
stefank
parents:
1972
diff
changeset
|
28 #include "runtime/thread.hpp" |
1972 | 29 #include "utilities/hashtable.hpp" |
30 | |
0 | 31 class PlaceholderEntry; |
32 | |
33 // Placeholder objects. These represent classes currently | |
34 // being loaded, as well as arrays of primitives. | |
35 // | |
36 | |
6197 | 37 class PlaceholderTable : public TwoOopHashtable<Symbol*, mtClass> { |
0 | 38 friend class VMStructs; |
39 | |
40 public: | |
41 PlaceholderTable(int table_size); | |
42 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
43 PlaceholderEntry* new_entry(int hash, Symbol* name, ClassLoaderData* loader_data, bool havesupername, Symbol* supername); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
44 void free_entry(PlaceholderEntry* entry); |
0 | 45 |
46 PlaceholderEntry* bucket(int i) { | |
6197 | 47 return (PlaceholderEntry*)Hashtable<Symbol*, mtClass>::bucket(i); |
0 | 48 } |
49 | |
50 PlaceholderEntry** bucket_addr(int i) { | |
6197 | 51 return (PlaceholderEntry**)Hashtable<Symbol*, mtClass>::bucket_addr(i); |
0 | 52 } |
53 | |
54 void add_entry(int index, PlaceholderEntry* new_entry) { | |
6197 | 55 Hashtable<Symbol*, mtClass>::add_entry(index, (HashtableEntry<Symbol*, mtClass>*)new_entry); |
0 | 56 } |
57 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
58 void add_entry(int index, unsigned int hash, Symbol* name, |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
59 ClassLoaderData* loader_data, bool havesupername, Symbol* supername); |
0 | 60 |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
61 // This returns a Symbol* to match type for SystemDictionary |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
62 Symbol* find_entry(int index, unsigned int hash, |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
63 Symbol* name, ClassLoaderData* loader_data); |
0 | 64 |
65 PlaceholderEntry* get_entry(int index, unsigned int hash, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
66 Symbol* name, ClassLoaderData* loader_data); |
0 | 67 |
68 // caller to create a placeholder entry must enumerate an action | |
69 // caller claims ownership of that action | |
70 // For parallel classloading: | |
71 // multiple LOAD_INSTANCE threads can proceed in parallel | |
72 // multiple LOAD_SUPER threads can proceed in parallel | |
73 // LOAD_SUPER needed to check for class circularity | |
74 // DEFINE_CLASS: ultimately define class must be single threaded | |
75 // on a class/classloader basis | |
76 // so the head of that queue owns the token | |
77 // and the rest of the threads return the result the first thread gets | |
78 enum classloadAction { | |
79 LOAD_INSTANCE = 1, // calling load_instance_class | |
80 LOAD_SUPER = 2, // loading superclass for this class | |
81 DEFINE_CLASS = 3 // find_or_define class | |
82 }; | |
83 | |
84 // find_and_add returns probe pointer - old or new | |
7582
aefb345d3f5e
7199207: NPG: Crash in PlaceholderTable::verify after StackOverflow
acorn
parents:
6983
diff
changeset
|
85 // If no entry exists, add a placeholder entry and push SeenThread for classloadAction |
0 | 86 // If entry exists, reuse entry and push SeenThread for classloadAction |
87 PlaceholderEntry* find_and_add(int index, unsigned int hash, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
88 Symbol* name, ClassLoaderData* loader_data, |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
89 classloadAction action, Symbol* supername, |
0 | 90 Thread* thread); |
91 | |
92 void remove_entry(int index, unsigned int hash, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
93 Symbol* name, ClassLoaderData* loader_data); |
0 | 94 |
7582
aefb345d3f5e
7199207: NPG: Crash in PlaceholderTable::verify after StackOverflow
acorn
parents:
6983
diff
changeset
|
95 // find_and_remove first removes SeenThread for classloadAction |
aefb345d3f5e
7199207: NPG: Crash in PlaceholderTable::verify after StackOverflow
acorn
parents:
6983
diff
changeset
|
96 // If all queues are empty and definer is null, remove the PlacheholderEntry completely |
0 | 97 void find_and_remove(int index, unsigned int hash, |
7582
aefb345d3f5e
7199207: NPG: Crash in PlaceholderTable::verify after StackOverflow
acorn
parents:
6983
diff
changeset
|
98 Symbol* name, ClassLoaderData* loader_data, |
aefb345d3f5e
7199207: NPG: Crash in PlaceholderTable::verify after StackOverflow
acorn
parents:
6983
diff
changeset
|
99 classloadAction action, Thread* thread); |
0 | 100 |
101 // GC support. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
102 void classes_do(KlassClosure* f); |
0 | 103 |
104 // JVMTI support | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
105 void entries_do(void f(Symbol*)); |
0 | 106 |
107 #ifndef PRODUCT | |
108 void print(); | |
109 #endif | |
110 void verify(); | |
111 }; | |
112 | |
113 // SeenThread objects represent list of threads that are | |
114 // currently performing a load action on a class. | |
115 // For class circularity, set before loading a superclass. | |
116 // For bootclasssearchpath, set before calling load_instance_class. | |
117 // Defining must be single threaded on a class/classloader basis | |
118 // For DEFINE_CLASS, the head of the queue owns the | |
119 // define token and the rest of the threads wait to return the | |
120 // result the first thread gets. | |
6197 | 121 class SeenThread: public CHeapObj<mtInternal> { |
0 | 122 private: |
123 Thread *_thread; | |
124 SeenThread* _stnext; | |
125 SeenThread* _stprev; | |
126 public: | |
127 SeenThread(Thread *thread) { | |
128 _thread = thread; | |
129 _stnext = NULL; | |
130 _stprev = NULL; | |
131 } | |
132 Thread* thread() const { return _thread;} | |
133 void set_thread(Thread *thread) { _thread = thread; } | |
134 | |
135 SeenThread* next() const { return _stnext;} | |
136 void set_next(SeenThread *seen) { _stnext = seen; } | |
137 void set_prev(SeenThread *seen) { _stprev = seen; } | |
138 | |
139 #ifndef PRODUCT | |
140 void printActionQ() { | |
141 SeenThread* seen = this; | |
142 while (seen != NULL) { | |
143 seen->thread()->print_value(); | |
144 tty->print(", "); | |
145 seen = seen->next(); | |
146 } | |
147 } | |
148 #endif // PRODUCT | |
149 }; | |
150 | |
151 // Placeholder objects represent classes currently being loaded. | |
152 // All threads examining the placeholder table must hold the | |
153 // SystemDictionary_lock, so we don't need special precautions | |
154 // on store ordering here. | |
155 // The system dictionary is the only user of this class. | |
156 | |
6197 | 157 class PlaceholderEntry : public HashtableEntry<Symbol*, mtClass> { |
0 | 158 friend class VMStructs; |
159 | |
160 | |
161 private: | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
162 ClassLoaderData* _loader_data; // initiating loader |
0 | 163 bool _havesupername; // distinguish between null supername, and unknown |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
164 Symbol* _supername; |
0 | 165 Thread* _definer; // owner of define token |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
166 Klass* _instanceKlass; // InstanceKlass from successful define |
0 | 167 SeenThread* _superThreadQ; // doubly-linked queue of Threads loading a superclass for this class |
168 SeenThread* _loadInstanceThreadQ; // loadInstance thread | |
169 // can be multiple threads if classloader object lock broken by application | |
170 // or if classloader supports parallel classloading | |
171 | |
172 SeenThread* _defineThreadQ; // queue of Threads trying to define this class | |
173 // including _definer | |
174 // _definer owns token | |
175 // queue waits for and returns results from _definer | |
176 | |
177 public: | |
178 // Simple accessors, used only by SystemDictionary | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
179 Symbol* klassname() const { return literal(); } |
0 | 180 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
181 ClassLoaderData* loader_data() const { return _loader_data; } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
182 void set_loader_data(ClassLoaderData* loader_data) { _loader_data = loader_data; } |
0 | 183 |
184 bool havesupername() const { return _havesupername; } | |
185 void set_havesupername(bool havesupername) { _havesupername = havesupername; } | |
186 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
187 Symbol* supername() const { return _supername; } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
188 void set_supername(Symbol* supername) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
189 _supername = supername; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
190 if (_supername != NULL) _supername->increment_refcount(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
191 } |
0 | 192 |
193 Thread* definer() const {return _definer; } | |
194 void set_definer(Thread* definer) { _definer = definer; } | |
195 | |
6983 | 196 Klass* instance_klass() const {return _instanceKlass; } |
197 void set_instance_klass(Klass* ik) { _instanceKlass = ik; } | |
0 | 198 |
199 SeenThread* superThreadQ() const { return _superThreadQ; } | |
200 void set_superThreadQ(SeenThread* SeenThread) { _superThreadQ = SeenThread; } | |
201 | |
202 SeenThread* loadInstanceThreadQ() const { return _loadInstanceThreadQ; } | |
203 void set_loadInstanceThreadQ(SeenThread* SeenThread) { _loadInstanceThreadQ = SeenThread; } | |
204 | |
205 SeenThread* defineThreadQ() const { return _defineThreadQ; } | |
206 void set_defineThreadQ(SeenThread* SeenThread) { _defineThreadQ = SeenThread; } | |
207 | |
208 PlaceholderEntry* next() const { | |
6197 | 209 return (PlaceholderEntry*)HashtableEntry<Symbol*, mtClass>::next(); |
0 | 210 } |
211 | |
212 PlaceholderEntry** next_addr() { | |
6197 | 213 return (PlaceholderEntry**)HashtableEntry<Symbol*, mtClass>::next_addr(); |
0 | 214 } |
215 | |
216 // Test for equality | |
217 // Entries are unique for class/classloader name pair | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
218 bool equals(Symbol* class_name, ClassLoaderData* loader) const { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
219 return (klassname() == class_name && loader_data() == loader); |
0 | 220 } |
221 | |
222 SeenThread* actionToQueue(PlaceholderTable::classloadAction action) { | |
223 SeenThread* queuehead; | |
224 switch (action) { | |
225 case PlaceholderTable::LOAD_INSTANCE: | |
226 queuehead = _loadInstanceThreadQ; | |
227 break; | |
228 case PlaceholderTable::LOAD_SUPER: | |
229 queuehead = _superThreadQ; | |
230 break; | |
231 case PlaceholderTable::DEFINE_CLASS: | |
232 queuehead = _defineThreadQ; | |
233 break; | |
234 default: Unimplemented(); | |
235 } | |
236 return queuehead; | |
237 } | |
238 | |
239 void set_threadQ(SeenThread* seenthread, PlaceholderTable::classloadAction action) { | |
240 switch (action) { | |
241 case PlaceholderTable::LOAD_INSTANCE: | |
242 _loadInstanceThreadQ = seenthread; | |
243 break; | |
244 case PlaceholderTable::LOAD_SUPER: | |
245 _superThreadQ = seenthread; | |
246 break; | |
247 case PlaceholderTable::DEFINE_CLASS: | |
248 _defineThreadQ = seenthread; | |
249 break; | |
250 default: Unimplemented(); | |
251 } | |
252 return; | |
253 } | |
254 | |
255 bool super_load_in_progress() { | |
256 return (_superThreadQ != NULL); | |
257 } | |
258 | |
259 bool instance_load_in_progress() { | |
260 return (_loadInstanceThreadQ != NULL); | |
261 } | |
262 | |
263 bool define_class_in_progress() { | |
264 return (_defineThreadQ != NULL); | |
265 } | |
266 | |
267 // Doubly-linked list of Threads per action for class/classloader pair | |
268 // Class circularity support: links in thread before loading superclass | |
269 // bootstrapsearchpath support: links in a thread before load_instance_class | |
270 // definers: use as queue of define requestors, including owner of | |
271 // define token. Appends for debugging of requestor order | |
272 void add_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) { | |
273 assert_lock_strong(SystemDictionary_lock); | |
274 SeenThread* threadEntry = new SeenThread(thread); | |
275 SeenThread* seen = actionToQueue(action); | |
276 | |
277 if (seen == NULL) { | |
278 set_threadQ(threadEntry, action); | |
279 return; | |
280 } | |
281 SeenThread* next; | |
282 while ((next = seen->next()) != NULL) { | |
283 seen = next; | |
284 } | |
285 seen->set_next(threadEntry); | |
286 threadEntry->set_prev(seen); | |
287 return; | |
288 } | |
289 | |
290 bool check_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) { | |
291 assert_lock_strong(SystemDictionary_lock); | |
292 SeenThread* threadQ = actionToQueue(action); | |
293 SeenThread* seen = threadQ; | |
294 while (seen) { | |
295 if (thread == seen->thread()) { | |
296 return true; | |
297 } | |
298 seen = seen->next(); | |
299 } | |
300 return false; | |
301 } | |
302 | |
303 // returns true if seenthreadQ is now empty | |
304 // Note, caller must ensure probe still exists while holding | |
305 // SystemDictionary_lock | |
306 // ignores if cleanup has already been done | |
307 // if found, deletes SeenThread | |
308 bool remove_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) { | |
309 assert_lock_strong(SystemDictionary_lock); | |
310 SeenThread* threadQ = actionToQueue(action); | |
311 SeenThread* seen = threadQ; | |
312 SeenThread* prev = NULL; | |
313 while (seen) { | |
314 if (thread == seen->thread()) { | |
315 if (prev) { | |
316 prev->set_next(seen->next()); | |
317 } else { | |
318 set_threadQ(seen->next(), action); | |
319 } | |
320 if (seen->next()) { | |
321 seen->next()->set_prev(prev); | |
322 } | |
323 delete seen; | |
324 break; | |
325 } | |
326 prev = seen; | |
327 seen = seen->next(); | |
328 } | |
329 return (actionToQueue(action) == NULL); | |
330 } | |
331 | |
332 // GC support | |
333 // Applies "f->do_oop" to all root oops in the placeholder table. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
334 void classes_do(KlassClosure* closure); |
0 | 335 |
336 // Print method doesn't append a cr | |
337 void print() const PRODUCT_RETURN; | |
338 void verify() const; | |
339 }; | |
1972 | 340 |
341 #endif // SHARE_VM_CLASSFILE_PLACEHOLDERS_HPP |