Mercurial > hg > truffle
annotate src/share/vm/classfile/placeholders.hpp @ 7090:05ce1defa4f9
Common out some parts of UnsafeLoad/Store in UnsafeAccess
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Thu, 29 Nov 2012 13:24:08 +0100 |
parents | 070d523b96a7 |
children | aefb345d3f5e |
rev | line source |
---|---|
0 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
2 * Copyright (c) 2003, 2012, 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 | |
85 // If no entry exists, add a placeholder entry and push SeenThread | |
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 |
95 // Remove placeholder information | |
96 void find_and_remove(int index, unsigned int hash, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
97 Symbol* name, ClassLoaderData* loader_data, Thread* thread); |
0 | 98 |
99 // GC support. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
100 void classes_do(KlassClosure* f); |
0 | 101 |
102 // JVMTI support | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
103 void entries_do(void f(Symbol*)); |
0 | 104 |
105 #ifndef PRODUCT | |
106 void print(); | |
107 #endif | |
108 void verify(); | |
109 }; | |
110 | |
111 // SeenThread objects represent list of threads that are | |
112 // currently performing a load action on a class. | |
113 // For class circularity, set before loading a superclass. | |
114 // For bootclasssearchpath, set before calling load_instance_class. | |
115 // Defining must be single threaded on a class/classloader basis | |
116 // For DEFINE_CLASS, the head of the queue owns the | |
117 // define token and the rest of the threads wait to return the | |
118 // result the first thread gets. | |
6197 | 119 class SeenThread: public CHeapObj<mtInternal> { |
0 | 120 private: |
121 Thread *_thread; | |
122 SeenThread* _stnext; | |
123 SeenThread* _stprev; | |
124 public: | |
125 SeenThread(Thread *thread) { | |
126 _thread = thread; | |
127 _stnext = NULL; | |
128 _stprev = NULL; | |
129 } | |
130 Thread* thread() const { return _thread;} | |
131 void set_thread(Thread *thread) { _thread = thread; } | |
132 | |
133 SeenThread* next() const { return _stnext;} | |
134 void set_next(SeenThread *seen) { _stnext = seen; } | |
135 void set_prev(SeenThread *seen) { _stprev = seen; } | |
136 | |
137 #ifndef PRODUCT | |
138 void printActionQ() { | |
139 SeenThread* seen = this; | |
140 while (seen != NULL) { | |
141 seen->thread()->print_value(); | |
142 tty->print(", "); | |
143 seen = seen->next(); | |
144 } | |
145 } | |
146 #endif // PRODUCT | |
147 }; | |
148 | |
149 // Placeholder objects represent classes currently being loaded. | |
150 // All threads examining the placeholder table must hold the | |
151 // SystemDictionary_lock, so we don't need special precautions | |
152 // on store ordering here. | |
153 // The system dictionary is the only user of this class. | |
154 | |
6197 | 155 class PlaceholderEntry : public HashtableEntry<Symbol*, mtClass> { |
0 | 156 friend class VMStructs; |
157 | |
158 | |
159 private: | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
160 ClassLoaderData* _loader_data; // initiating loader |
0 | 161 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
|
162 Symbol* _supername; |
0 | 163 Thread* _definer; // owner of define token |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
164 Klass* _instanceKlass; // InstanceKlass from successful define |
0 | 165 SeenThread* _superThreadQ; // doubly-linked queue of Threads loading a superclass for this class |
166 SeenThread* _loadInstanceThreadQ; // loadInstance thread | |
167 // can be multiple threads if classloader object lock broken by application | |
168 // or if classloader supports parallel classloading | |
169 | |
170 SeenThread* _defineThreadQ; // queue of Threads trying to define this class | |
171 // including _definer | |
172 // _definer owns token | |
173 // queue waits for and returns results from _definer | |
174 | |
175 public: | |
176 // Simple accessors, used only by SystemDictionary | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
177 Symbol* klassname() const { return literal(); } |
0 | 178 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
179 ClassLoaderData* loader_data() const { return _loader_data; } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
180 void set_loader_data(ClassLoaderData* loader_data) { _loader_data = loader_data; } |
0 | 181 |
182 bool havesupername() const { return _havesupername; } | |
183 void set_havesupername(bool havesupername) { _havesupername = havesupername; } | |
184 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
185 Symbol* supername() const { return _supername; } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
186 void set_supername(Symbol* supername) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
187 _supername = supername; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
188 if (_supername != NULL) _supername->increment_refcount(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
189 } |
0 | 190 |
191 Thread* definer() const {return _definer; } | |
192 void set_definer(Thread* definer) { _definer = definer; } | |
193 | |
6983 | 194 Klass* instance_klass() const {return _instanceKlass; } |
195 void set_instance_klass(Klass* ik) { _instanceKlass = ik; } | |
0 | 196 |
197 SeenThread* superThreadQ() const { return _superThreadQ; } | |
198 void set_superThreadQ(SeenThread* SeenThread) { _superThreadQ = SeenThread; } | |
199 | |
200 SeenThread* loadInstanceThreadQ() const { return _loadInstanceThreadQ; } | |
201 void set_loadInstanceThreadQ(SeenThread* SeenThread) { _loadInstanceThreadQ = SeenThread; } | |
202 | |
203 SeenThread* defineThreadQ() const { return _defineThreadQ; } | |
204 void set_defineThreadQ(SeenThread* SeenThread) { _defineThreadQ = SeenThread; } | |
205 | |
206 PlaceholderEntry* next() const { | |
6197 | 207 return (PlaceholderEntry*)HashtableEntry<Symbol*, mtClass>::next(); |
0 | 208 } |
209 | |
210 PlaceholderEntry** next_addr() { | |
6197 | 211 return (PlaceholderEntry**)HashtableEntry<Symbol*, mtClass>::next_addr(); |
0 | 212 } |
213 | |
214 // Test for equality | |
215 // 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
|
216 bool equals(Symbol* class_name, ClassLoaderData* loader) const { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
217 return (klassname() == class_name && loader_data() == loader); |
0 | 218 } |
219 | |
220 SeenThread* actionToQueue(PlaceholderTable::classloadAction action) { | |
221 SeenThread* queuehead; | |
222 switch (action) { | |
223 case PlaceholderTable::LOAD_INSTANCE: | |
224 queuehead = _loadInstanceThreadQ; | |
225 break; | |
226 case PlaceholderTable::LOAD_SUPER: | |
227 queuehead = _superThreadQ; | |
228 break; | |
229 case PlaceholderTable::DEFINE_CLASS: | |
230 queuehead = _defineThreadQ; | |
231 break; | |
232 default: Unimplemented(); | |
233 } | |
234 return queuehead; | |
235 } | |
236 | |
237 void set_threadQ(SeenThread* seenthread, PlaceholderTable::classloadAction action) { | |
238 switch (action) { | |
239 case PlaceholderTable::LOAD_INSTANCE: | |
240 _loadInstanceThreadQ = seenthread; | |
241 break; | |
242 case PlaceholderTable::LOAD_SUPER: | |
243 _superThreadQ = seenthread; | |
244 break; | |
245 case PlaceholderTable::DEFINE_CLASS: | |
246 _defineThreadQ = seenthread; | |
247 break; | |
248 default: Unimplemented(); | |
249 } | |
250 return; | |
251 } | |
252 | |
253 bool super_load_in_progress() { | |
254 return (_superThreadQ != NULL); | |
255 } | |
256 | |
257 bool instance_load_in_progress() { | |
258 return (_loadInstanceThreadQ != NULL); | |
259 } | |
260 | |
261 bool define_class_in_progress() { | |
262 return (_defineThreadQ != NULL); | |
263 } | |
264 | |
265 // Doubly-linked list of Threads per action for class/classloader pair | |
266 // Class circularity support: links in thread before loading superclass | |
267 // bootstrapsearchpath support: links in a thread before load_instance_class | |
268 // definers: use as queue of define requestors, including owner of | |
269 // define token. Appends for debugging of requestor order | |
270 void add_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) { | |
271 assert_lock_strong(SystemDictionary_lock); | |
272 SeenThread* threadEntry = new SeenThread(thread); | |
273 SeenThread* seen = actionToQueue(action); | |
274 | |
275 if (seen == NULL) { | |
276 set_threadQ(threadEntry, action); | |
277 return; | |
278 } | |
279 SeenThread* next; | |
280 while ((next = seen->next()) != NULL) { | |
281 seen = next; | |
282 } | |
283 seen->set_next(threadEntry); | |
284 threadEntry->set_prev(seen); | |
285 return; | |
286 } | |
287 | |
288 bool check_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) { | |
289 assert_lock_strong(SystemDictionary_lock); | |
290 SeenThread* threadQ = actionToQueue(action); | |
291 SeenThread* seen = threadQ; | |
292 while (seen) { | |
293 if (thread == seen->thread()) { | |
294 return true; | |
295 } | |
296 seen = seen->next(); | |
297 } | |
298 return false; | |
299 } | |
300 | |
301 // returns true if seenthreadQ is now empty | |
302 // Note, caller must ensure probe still exists while holding | |
303 // SystemDictionary_lock | |
304 // ignores if cleanup has already been done | |
305 // if found, deletes SeenThread | |
306 bool remove_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) { | |
307 assert_lock_strong(SystemDictionary_lock); | |
308 SeenThread* threadQ = actionToQueue(action); | |
309 SeenThread* seen = threadQ; | |
310 SeenThread* prev = NULL; | |
311 while (seen) { | |
312 if (thread == seen->thread()) { | |
313 if (prev) { | |
314 prev->set_next(seen->next()); | |
315 } else { | |
316 set_threadQ(seen->next(), action); | |
317 } | |
318 if (seen->next()) { | |
319 seen->next()->set_prev(prev); | |
320 } | |
321 delete seen; | |
322 break; | |
323 } | |
324 prev = seen; | |
325 seen = seen->next(); | |
326 } | |
327 return (actionToQueue(action) == NULL); | |
328 } | |
329 | |
330 // GC support | |
331 // 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
|
332 void classes_do(KlassClosure* closure); |
0 | 333 |
334 // Print method doesn't append a cr | |
335 void print() const PRODUCT_RETURN; | |
336 void verify() const; | |
337 }; | |
1972 | 338 |
339 #endif // SHARE_VM_CLASSFILE_PLACEHOLDERS_HPP |