Mercurial > hg > truffle
annotate src/share/vm/classfile/placeholders.cpp @ 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 #include "precompiled.hpp" |
26 #include "classfile/placeholders.hpp" | |
27 #include "classfile/systemDictionary.hpp" | |
28 #include "oops/oop.inline.hpp" | |
29 #include "runtime/fieldType.hpp" | |
30 #include "utilities/hashtable.inline.hpp" | |
0 | 31 |
32 // Placeholder methods | |
33 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
34 PlaceholderEntry* PlaceholderTable::new_entry(int hash, Symbol* name, |
0 | 35 oop loader, bool havesupername, |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
36 Symbol* supername) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
37 PlaceholderEntry* entry = (PlaceholderEntry*)Hashtable<Symbol*>::new_entry(hash, name); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
38 // Hashtable with Symbol* literal must increment and decrement refcount. |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
39 name->increment_refcount(); |
0 | 40 entry->set_loader(loader); |
41 entry->set_havesupername(havesupername); | |
42 entry->set_supername(supername); | |
43 entry->set_superThreadQ(NULL); | |
44 entry->set_loadInstanceThreadQ(NULL); | |
45 entry->set_defineThreadQ(NULL); | |
46 entry->set_definer(NULL); | |
47 entry->set_instanceKlass(NULL); | |
48 return entry; | |
49 } | |
50 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
51 void PlaceholderTable::free_entry(PlaceholderEntry* entry) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
52 // decrement Symbol refcount here because Hashtable doesn't. |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
53 entry->literal()->decrement_refcount(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
54 if (entry->supername() != NULL) entry->supername()->decrement_refcount(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
55 Hashtable<Symbol*>::free_entry(entry); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
56 } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
57 |
0 | 58 |
59 // Placeholder objects represent classes currently being loaded. | |
60 // All threads examining the placeholder table must hold the | |
61 // SystemDictionary_lock, so we don't need special precautions | |
62 // on store ordering here. | |
63 void PlaceholderTable::add_entry(int index, unsigned int hash, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
64 Symbol* class_name, Handle class_loader, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
65 bool havesupername, Symbol* supername){ |
0 | 66 assert_locked_or_safepoint(SystemDictionary_lock); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
67 assert(class_name != NULL, "adding NULL obj"); |
0 | 68 |
69 // Both readers and writers are locked so it's safe to just | |
70 // create the placeholder and insert it in the list without a membar. | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
71 PlaceholderEntry* entry = new_entry(hash, class_name, class_loader(), havesupername, supername); |
0 | 72 add_entry(index, entry); |
73 } | |
74 | |
75 | |
76 // Remove a placeholder object. | |
77 void PlaceholderTable::remove_entry(int index, unsigned int hash, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
78 Symbol* class_name, |
0 | 79 Handle class_loader) { |
80 assert_locked_or_safepoint(SystemDictionary_lock); | |
81 PlaceholderEntry** p = bucket_addr(index); | |
82 while (*p) { | |
83 PlaceholderEntry *probe = *p; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
84 if (probe->hash() == hash && probe->equals(class_name, class_loader())) { |
0 | 85 // Delete entry |
86 *p = probe->next(); | |
87 free_entry(probe); | |
88 return; | |
89 } | |
90 p = probe->next_addr(); | |
91 } | |
92 } | |
93 | |
94 PlaceholderEntry* PlaceholderTable::get_entry(int index, unsigned int hash, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
95 Symbol* class_name, |
0 | 96 Handle class_loader) { |
97 assert_locked_or_safepoint(SystemDictionary_lock); | |
98 | |
99 oop class_loader_ = class_loader(); | |
100 | |
101 for (PlaceholderEntry *place_probe = bucket(index); | |
102 place_probe != NULL; | |
103 place_probe = place_probe->next()) { | |
104 if (place_probe->hash() == hash && | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
105 place_probe->equals(class_name, class_loader_)) { |
0 | 106 return place_probe; |
107 } | |
108 } | |
109 return NULL; | |
110 } | |
111 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
112 Symbol* PlaceholderTable::find_entry(int index, unsigned int hash, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
113 Symbol* class_name, |
0 | 114 Handle class_loader) { |
115 PlaceholderEntry* probe = get_entry(index, hash, class_name, class_loader); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
116 return (probe? probe->klassname(): (Symbol*)NULL); |
0 | 117 } |
118 | |
119 // find_and_add returns probe pointer - old or new | |
120 // If no entry exists, add a placeholder entry | |
121 // If entry exists, reuse entry | |
122 // For both, push SeenThread for classloadAction | |
123 // if havesupername: this is used for circularity for instanceklass loading | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
124 PlaceholderEntry* PlaceholderTable::find_and_add(int index, unsigned int hash, Symbol* name, Handle loader, classloadAction action, Symbol* supername, Thread* thread) { |
0 | 125 PlaceholderEntry* probe = get_entry(index, hash, name, loader); |
126 if (probe == NULL) { | |
127 // Nothing found, add place holder | |
128 add_entry(index, hash, name, loader, (action == LOAD_SUPER), supername); | |
129 probe = get_entry(index, hash, name, loader); | |
130 } else { | |
131 if (action == LOAD_SUPER) { | |
132 probe->set_havesupername(true); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
133 probe->set_supername(supername); |
0 | 134 } |
135 } | |
136 if (probe) probe->add_seen_thread(thread, action); | |
137 return probe; | |
138 } | |
139 | |
140 | |
141 // placeholder used to track class loading internal states | |
142 // placeholder existence now for loading superclass/superinterface | |
143 // superthreadQ tracks class circularity, while loading superclass/superinterface | |
144 // loadInstanceThreadQ tracks load_instance_class calls | |
145 // definer() tracks the single thread that owns define token | |
146 // defineThreadQ tracks waiters on defining thread's results | |
147 // 1st claimant creates placeholder | |
148 // find_and_add adds SeenThread entry for appropriate queue | |
149 // All claimants remove SeenThread after completing action | |
150 // On removal: if definer and all queues empty, remove entry | |
151 // Note: you can be in both placeholders and systemDictionary | |
152 // see parse_stream for redefine classes | |
153 // Therefore - must always check SD first | |
154 // Ignores the case where entry is not found | |
155 void PlaceholderTable::find_and_remove(int index, unsigned int hash, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
156 Symbol* name, Handle loader, Thread* thread) { |
0 | 157 assert_locked_or_safepoint(SystemDictionary_lock); |
158 PlaceholderEntry *probe = get_entry(index, hash, name, loader); | |
159 if (probe != NULL) { | |
160 // No other threads using this entry | |
161 if ((probe->superThreadQ() == NULL) && (probe->loadInstanceThreadQ() == NULL) | |
162 && (probe->defineThreadQ() == NULL) && (probe->definer() == NULL)) { | |
163 remove_entry(index, hash, name, loader); | |
164 } | |
165 } | |
166 } | |
167 | |
168 PlaceholderTable::PlaceholderTable(int table_size) | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
169 : TwoOopHashtable<Symbol*>(table_size, sizeof(PlaceholderEntry)) { |
0 | 170 } |
171 | |
172 | |
173 void PlaceholderTable::oops_do(OopClosure* f) { | |
174 for (int index = 0; index < table_size(); index++) { | |
175 for (PlaceholderEntry* probe = bucket(index); | |
176 probe != NULL; | |
177 probe = probe->next()) { | |
178 probe->oops_do(f); | |
179 } | |
180 } | |
181 } | |
182 | |
183 | |
184 void PlaceholderEntry::oops_do(OopClosure* blk) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
185 assert(klassname() != NULL, "should have a non-null klass"); |
0 | 186 if (_loader != NULL) { |
187 blk->do_oop(loader_addr()); | |
188 } | |
189 if (_instanceKlass != NULL) { | |
190 blk->do_oop((oop*)instanceKlass_addr()); | |
191 } | |
192 } | |
193 | |
194 // do all entries in the placeholder table | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
195 void PlaceholderTable::entries_do(void f(Symbol*, oop)) { |
0 | 196 for (int index = 0; index < table_size(); index++) { |
197 for (PlaceholderEntry* probe = bucket(index); | |
198 probe != NULL; | |
199 probe = probe->next()) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
200 f(probe->klassname(), probe->loader()); |
0 | 201 } |
202 } | |
203 } | |
204 | |
205 | |
206 #ifndef PRODUCT | |
207 // Note, doesn't append a cr | |
208 void PlaceholderEntry::print() const { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
209 klassname()->print_value(); |
0 | 210 if (loader() != NULL) { |
211 tty->print(", loader "); | |
212 loader()->print_value(); | |
213 } | |
214 if (supername() != NULL) { | |
215 tty->print(", supername "); | |
216 supername()->print_value(); | |
217 } | |
218 if (definer() != NULL) { | |
219 tty->print(", definer "); | |
220 definer()->print_value(); | |
221 } | |
222 if (instanceKlass() != NULL) { | |
223 tty->print(", instanceKlass "); | |
224 instanceKlass()->print_value(); | |
225 } | |
226 tty->print("\n"); | |
227 tty->print("loadInstanceThreadQ threads:"); | |
228 loadInstanceThreadQ()->printActionQ(); | |
229 tty->print("\n"); | |
230 tty->print("superThreadQ threads:"); | |
231 superThreadQ()->printActionQ(); | |
232 tty->print("\n"); | |
233 tty->print("defineThreadQ threads:"); | |
234 defineThreadQ()->printActionQ(); | |
235 tty->print("\n"); | |
236 } | |
237 #endif | |
238 | |
239 void PlaceholderEntry::verify() const { | |
240 guarantee(loader() == NULL || loader()->is_instance(), | |
241 "checking type of _loader"); | |
242 guarantee(instanceKlass() == NULL | |
243 || Klass::cast(instanceKlass())->oop_is_instance(), | |
244 "checking type of instanceKlass result"); | |
245 } | |
246 | |
247 void PlaceholderTable::verify() { | |
248 int element_count = 0; | |
249 for (int pindex = 0; pindex < table_size(); pindex++) { | |
250 for (PlaceholderEntry* probe = bucket(pindex); | |
251 probe != NULL; | |
252 probe = probe->next()) { | |
253 probe->verify(); | |
254 element_count++; // both klasses and place holders count | |
255 } | |
256 } | |
257 guarantee(number_of_entries() == element_count, | |
258 "Verify of system dictionary failed"); | |
259 } | |
260 | |
261 | |
262 #ifndef PRODUCT | |
263 void PlaceholderTable::print() { | |
264 for (int pindex = 0; pindex < table_size(); pindex++) { | |
265 for (PlaceholderEntry* probe = bucket(pindex); | |
266 probe != NULL; | |
267 probe = probe->next()) { | |
268 if (Verbose) tty->print("%4d: ", pindex); | |
269 tty->print(" place holder "); | |
270 | |
271 probe->print(); | |
272 tty->cr(); | |
273 } | |
274 } | |
275 } | |
276 #endif |