28 #include "classfile/systemDictionary.hpp"
29 #include "oops/oop.inline.hpp"
30 #include "runtime/fieldType.hpp"
31 #include "utilities/hashtable.inline.hpp"
32
33 // Placeholder methods
34
35 PlaceholderEntry* PlaceholderTable::new_entry(int hash, Symbol* name,
36 ClassLoaderData* loader_data,
37 bool havesupername,
38 Symbol* supername) {
39 PlaceholderEntry* entry = (PlaceholderEntry*)Hashtable<Symbol*, mtClass>::new_entry(hash, name);
40 // Hashtable with Symbol* literal must increment and decrement refcount.
41 name->increment_refcount();
42 entry->set_loader_data(loader_data);
43 entry->set_havesupername(havesupername);
44 entry->set_supername(supername);
45 entry->set_superThreadQ(NULL);
46 entry->set_loadInstanceThreadQ(NULL);
47 entry->set_defineThreadQ(NULL);
48 entry->set_definer(NULL);
49 entry->set_instance_klass(NULL);
50 return entry;
51 }
52
53 void PlaceholderTable::free_entry(PlaceholderEntry* entry) {
54 // decrement Symbol refcount here because Hashtable doesn't.
55 entry->literal()->decrement_refcount();
56 if (entry->supername() != NULL) entry->supername()->decrement_refcount();
57 Hashtable<Symbol*, mtClass>::free_entry(entry);
58 }
59
60
61 // Placeholder objects represent classes currently being loaded.
62 // All threads examining the placeholder table must hold the
63 // SystemDictionary_lock, so we don't need special precautions
64 // on store ordering here.
65 void PlaceholderTable::add_entry(int index, unsigned int hash,
66 Symbol* class_name, ClassLoaderData* loader_data,
67 bool havesupername, Symbol* supername){
149 // loadInstanceThreadQ tracks load_instance_class calls
150 // definer() tracks the single thread that owns define token
151 // defineThreadQ tracks waiters on defining thread's results
152 // 1st claimant creates placeholder
153 // find_and_add adds SeenThread entry for appropriate queue
154 // All claimants remove SeenThread after completing action
155 // On removal: if definer and all queues empty, remove entry
156 // Note: you can be in both placeholders and systemDictionary
157 // Therefore - must always check SD first
158 // Ignores the case where entry is not found
159 void PlaceholderTable::find_and_remove(int index, unsigned int hash,
160 Symbol* name, ClassLoaderData* loader_data,
161 classloadAction action,
162 Thread* thread) {
163 assert_locked_or_safepoint(SystemDictionary_lock);
164 PlaceholderEntry *probe = get_entry(index, hash, name, loader_data);
165 if (probe != NULL) {
166 probe->remove_seen_thread(thread, action);
167 // If no other threads using this entry, and this thread is not using this entry for other states
168 if ((probe->superThreadQ() == NULL) && (probe->loadInstanceThreadQ() == NULL)
169 && (probe->defineThreadQ() == NULL) && (probe->definer() == NULL)) {
170 remove_entry(index, hash, name, loader_data);
171 }
172 }
173 }
174
175 PlaceholderTable::PlaceholderTable(int table_size)
176 : Hashtable<Symbol*, mtClass>(table_size, sizeof(PlaceholderEntry)) {
177 }
178
179 void PlaceholderEntry::verify() const {
180 guarantee(loader_data() != NULL, "Must have been setup.");
181 guarantee(loader_data()->class_loader() == NULL || loader_data()->class_loader()->is_instance(),
182 "checking type of _loader");
183 guarantee(instance_klass() == NULL
184 || instance_klass()->is_instance_klass(),
185 "checking type of instance_klass result");
186 }
187
188 void PlaceholderTable::verify() {
189 verify_table<PlaceholderEntry>("Placeholder Table");
203 st->print(", supername ");
204 supername()->print_value_on(st);
205 }
206 if (definer() != NULL) {
207 st->print(", definer ");
208 definer()->print_value_on(st);
209 }
210 if (instance_klass() != NULL) {
211 st->print(", InstanceKlass ");
212 instance_klass()->print_value_on(st);
213 }
214 st->cr();
215 st->print("loadInstanceThreadQ threads:");
216 loadInstanceThreadQ()->print_action_queue(st);
217 st->cr();
218 st->print("superThreadQ threads:");
219 superThreadQ()->print_action_queue(st);
220 st->cr();
221 st->print("defineThreadQ threads:");
222 defineThreadQ()->print_action_queue(st);
223 st->cr();
224 }
225
226 void PlaceholderTable::print_on(outputStream* st) const {
227 st->print_cr("Placeholder table (table_size=%d, placeholders=%d)",
228 table_size(), number_of_entries());
229 for (int pindex = 0; pindex < table_size(); pindex++) {
230 for (PlaceholderEntry* probe = bucket(pindex);
231 probe != NULL;
232 probe = probe->next()) {
233 st->print("%4d: placeholder ", pindex);
234 probe->print_entry(st);
235 }
236 }
237 }
|
28 #include "classfile/systemDictionary.hpp"
29 #include "oops/oop.inline.hpp"
30 #include "runtime/fieldType.hpp"
31 #include "utilities/hashtable.inline.hpp"
32
33 // Placeholder methods
34
35 PlaceholderEntry* PlaceholderTable::new_entry(int hash, Symbol* name,
36 ClassLoaderData* loader_data,
37 bool havesupername,
38 Symbol* supername) {
39 PlaceholderEntry* entry = (PlaceholderEntry*)Hashtable<Symbol*, mtClass>::new_entry(hash, name);
40 // Hashtable with Symbol* literal must increment and decrement refcount.
41 name->increment_refcount();
42 entry->set_loader_data(loader_data);
43 entry->set_havesupername(havesupername);
44 entry->set_supername(supername);
45 entry->set_superThreadQ(NULL);
46 entry->set_loadInstanceThreadQ(NULL);
47 entry->set_defineThreadQ(NULL);
48 entry->set_flattenableFieldQ(NULL);
49 entry->set_definer(NULL);
50 entry->set_instance_klass(NULL);
51 return entry;
52 }
53
54 void PlaceholderTable::free_entry(PlaceholderEntry* entry) {
55 // decrement Symbol refcount here because Hashtable doesn't.
56 entry->literal()->decrement_refcount();
57 if (entry->supername() != NULL) entry->supername()->decrement_refcount();
58 Hashtable<Symbol*, mtClass>::free_entry(entry);
59 }
60
61
62 // Placeholder objects represent classes currently being loaded.
63 // All threads examining the placeholder table must hold the
64 // SystemDictionary_lock, so we don't need special precautions
65 // on store ordering here.
66 void PlaceholderTable::add_entry(int index, unsigned int hash,
67 Symbol* class_name, ClassLoaderData* loader_data,
68 bool havesupername, Symbol* supername){
150 // loadInstanceThreadQ tracks load_instance_class calls
151 // definer() tracks the single thread that owns define token
152 // defineThreadQ tracks waiters on defining thread's results
153 // 1st claimant creates placeholder
154 // find_and_add adds SeenThread entry for appropriate queue
155 // All claimants remove SeenThread after completing action
156 // On removal: if definer and all queues empty, remove entry
157 // Note: you can be in both placeholders and systemDictionary
158 // Therefore - must always check SD first
159 // Ignores the case where entry is not found
160 void PlaceholderTable::find_and_remove(int index, unsigned int hash,
161 Symbol* name, ClassLoaderData* loader_data,
162 classloadAction action,
163 Thread* thread) {
164 assert_locked_or_safepoint(SystemDictionary_lock);
165 PlaceholderEntry *probe = get_entry(index, hash, name, loader_data);
166 if (probe != NULL) {
167 probe->remove_seen_thread(thread, action);
168 // If no other threads using this entry, and this thread is not using this entry for other states
169 if ((probe->superThreadQ() == NULL) && (probe->loadInstanceThreadQ() == NULL)
170 && (probe->defineThreadQ() == NULL) && (probe->definer() == NULL)
171 && (probe->flattenableFieldQ() == NULL)) {
172 remove_entry(index, hash, name, loader_data);
173 }
174 }
175 }
176
177 PlaceholderTable::PlaceholderTable(int table_size)
178 : Hashtable<Symbol*, mtClass>(table_size, sizeof(PlaceholderEntry)) {
179 }
180
181 void PlaceholderEntry::verify() const {
182 guarantee(loader_data() != NULL, "Must have been setup.");
183 guarantee(loader_data()->class_loader() == NULL || loader_data()->class_loader()->is_instance(),
184 "checking type of _loader");
185 guarantee(instance_klass() == NULL
186 || instance_klass()->is_instance_klass(),
187 "checking type of instance_klass result");
188 }
189
190 void PlaceholderTable::verify() {
191 verify_table<PlaceholderEntry>("Placeholder Table");
205 st->print(", supername ");
206 supername()->print_value_on(st);
207 }
208 if (definer() != NULL) {
209 st->print(", definer ");
210 definer()->print_value_on(st);
211 }
212 if (instance_klass() != NULL) {
213 st->print(", InstanceKlass ");
214 instance_klass()->print_value_on(st);
215 }
216 st->cr();
217 st->print("loadInstanceThreadQ threads:");
218 loadInstanceThreadQ()->print_action_queue(st);
219 st->cr();
220 st->print("superThreadQ threads:");
221 superThreadQ()->print_action_queue(st);
222 st->cr();
223 st->print("defineThreadQ threads:");
224 defineThreadQ()->print_action_queue(st);
225 st->cr();
226 st->print("flattenableFieldQ threads:");
227 flattenableFieldQ()->print_action_queue(st);
228 st->cr();
229 }
230
231 void PlaceholderTable::print_on(outputStream* st) const {
232 st->print_cr("Placeholder table (table_size=%d, placeholders=%d)",
233 table_size(), number_of_entries());
234 for (int pindex = 0; pindex < table_size(); pindex++) {
235 for (PlaceholderEntry* probe = bucket(pindex);
236 probe != NULL;
237 probe = probe->next()) {
238 st->print("%4d: placeholder ", pindex);
239 probe->print_entry(st);
240 }
241 }
242 }
|