Mercurial > hg > truffle
annotate src/share/vm/classfile/placeholders.hpp @ 3762:5c0a3c1858b1
7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
Summary: The LNC array is sized before the start of a scavenge, while the heap may expand during a scavenge. With CMS, the last block of an arbitrary suffice of the LNC array may expand due to coalition with the expansion delta. We now take care not to attempt access past the end of the LNC array. LNC array code will be cleaned up and suitably encapsulated as part of the forthcoming performance RFE 7043675.
Reviewed-by: brutisso
author | ysr |
---|---|
date | Thu, 02 Jun 2011 10:23:36 -0700 |
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 |