Mercurial > hg > truffle
annotate src/share/vm/classfile/placeholders.hpp @ 3210:27ae76ed33ca
Finish implementation of loop inversion
author | Gilles Duboscq <gilles.duboscq@oracle.com> |
---|---|
date | Tue, 12 Jul 2011 13:10:33 +0200 |
parents | 1d1603768966 |
children | d2a62e0f25eb |
rev | line source |
---|---|
0 | 1 /* |
2426
1d1603768966
7010070: Update all 2010 Oracle-changed OpenJDK files to have the proper copyright dates - second pass
trims
parents:
2177
diff
changeset
|
2 * Copyright (c) 2003, 2011, 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 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
37 class PlaceholderTable : public TwoOopHashtable<Symbol*> { |
0 | 38 friend class VMStructs; |
39 | |
40 public: | |
41 PlaceholderTable(int table_size); | |
42 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
43 PlaceholderEntry* new_entry(int hash, Symbol* name, oop loader, bool havesupername, Symbol* supername); |
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) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
47 return (PlaceholderEntry*)Hashtable<Symbol*>::bucket(i); |
0 | 48 } |
49 | |
50 PlaceholderEntry** bucket_addr(int i) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
51 return (PlaceholderEntry**)Hashtable<Symbol*>::bucket_addr(i); |
0 | 52 } |
53 | |
54 void add_entry(int index, PlaceholderEntry* new_entry) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
55 Hashtable<Symbol*>::add_entry(index, (HashtableEntry<Symbol*>*)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, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
59 Handle loader, 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, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
63 Symbol* name, Handle loader); |
0 | 64 |
65 PlaceholderEntry* get_entry(int index, unsigned int hash, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
66 Symbol* name, Handle loader); |
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, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
88 Symbol* name, Handle loader, |
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, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
93 Symbol* name, Handle loader); |
0 | 94 |
95 // Remove placeholder information | |
96 void find_and_remove(int index, unsigned int hash, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
97 Symbol* name, Handle loader, Thread* thread); |
0 | 98 |
99 // GC support. | |
100 void oops_do(OopClosure* f); | |
101 | |
102 // JVMTI support | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
103 void entries_do(void f(Symbol*, oop)); |
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. | |
119 class SeenThread: public CHeapObj { | |
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 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
155 class PlaceholderEntry : public HashtableEntry<Symbol*> { |
0 | 156 friend class VMStructs; |
157 | |
158 | |
159 private: | |
160 oop _loader; // initiating loader | |
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 |
164 klassOop _instanceKlass; // instanceKlass from successful define | |
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 |
179 oop loader() const { return _loader; } | |
180 void set_loader(oop loader) { _loader = loader; } | |
181 oop* loader_addr() { return &_loader; } | |
182 | |
183 bool havesupername() const { return _havesupername; } | |
184 void set_havesupername(bool havesupername) { _havesupername = havesupername; } | |
185 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
186 Symbol* supername() const { return _supername; } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
187 void set_supername(Symbol* supername) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
188 _supername = supername; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
189 if (_supername != NULL) _supername->increment_refcount(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
190 } |
0 | 191 |
192 Thread* definer() const {return _definer; } | |
193 void set_definer(Thread* definer) { _definer = definer; } | |
194 | |
195 klassOop instanceKlass() const {return _instanceKlass; } | |
196 void set_instanceKlass(klassOop instanceKlass) { _instanceKlass = instanceKlass; } | |
197 klassOop* instanceKlass_addr() { return &_instanceKlass; } | |
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 { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
209 return (PlaceholderEntry*)HashtableEntry<Symbol*>::next(); |
0 | 210 } |
211 | |
212 PlaceholderEntry** next_addr() { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
213 return (PlaceholderEntry**)HashtableEntry<Symbol*>::next_addr(); |
0 | 214 } |
215 | |
216 // Test for equality | |
217 // Entries are unique for class/classloader name pair | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
218 bool equals(Symbol* class_name, oop class_loader) const { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1983
diff
changeset
|
219 return (klassname() == class_name && loader() == class_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. | |
334 void oops_do(OopClosure* blk); | |
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 |