24
25 #include "precompiled.hpp"
26 #include "classfile/classLoaderData.inline.hpp"
27 #include "classfile/placeholders.hpp"
28 #include "logging/log.hpp"
29 #include "logging/logTag.hpp"
30 #include "logging/logStream.hpp"
31 #include "memory/resourceArea.hpp"
32 #include "runtime/mutexLocker.hpp"
33 #include "runtime/thread.hpp"
34 #include "utilities/hashtable.inline.hpp"
35
36 // SeenThread objects represent list of threads that are
37 // currently performing a load action on a class.
38 // For class circularity, set before loading a superclass.
39 // For bootclasssearchpath, set before calling load_instance_class.
40 // Defining must be single threaded on a class/classloader basis
41 // For DEFINE_CLASS, the head of the queue owns the
42 // define token and the rest of the threads wait to return the
43 // result the first thread gets.
44 class SeenThread: public CHeapObj<mtInternal> {
45 private:
46 JavaThread* _thread;
47 SeenThread* _stnext;
48 SeenThread* _stprev;
49 public:
50 SeenThread(JavaThread* thread) {
51 _thread = thread;
52 _stnext = NULL;
53 _stprev = NULL;
54 }
55 JavaThread* thread() const { return _thread;}
56 void set_thread(JavaThread* thread) { _thread = thread; }
57
58 SeenThread* next() const { return _stnext;}
59 void set_next(SeenThread* seen) { _stnext = seen; }
60 void set_prev(SeenThread* seen) { _stprev = seen; }
61
62 void print_action_queue(outputStream* st) {
63 SeenThread* seen = this;
64 while (seen != NULL) {
65 seen->thread()->print_value_on(st);
66 st->print(", ");
67 seen = seen->next();
68 }
69 }
70 };
71
72 SeenThread* PlaceholderEntry::actionToQueue(PlaceholderTable::classloadAction action) {
73 SeenThread* queuehead = NULL;
74 switch (action) {
75 case PlaceholderTable::LOAD_INSTANCE:
76 queuehead = _loadInstanceThreadQ;
77 break;
78 case PlaceholderTable::LOAD_SUPER:
79 queuehead = _superThreadQ;
80 break;
81 case PlaceholderTable::DEFINE_CLASS:
82 queuehead = _defineThreadQ;
83 break;
84 default: Unimplemented();
85 }
86 return queuehead;
87 }
88
89 void PlaceholderEntry::set_threadQ(SeenThread* seenthread, PlaceholderTable::classloadAction action) {
90 switch (action) {
91 case PlaceholderTable::LOAD_INSTANCE:
92 _loadInstanceThreadQ = seenthread;
93 break;
94 case PlaceholderTable::LOAD_SUPER:
95 _superThreadQ = seenthread;
96 break;
97 case PlaceholderTable::DEFINE_CLASS:
98 _defineThreadQ = seenthread;
99 break;
100 default: Unimplemented();
101 }
102 return;
103 }
104
105 // Doubly-linked list of Threads per action for class/classloader pair
106 // Class circularity support: links in thread before loading superclass
107 // bootstrap loader support: links in a thread before load_instance_class
108 // definers: use as queue of define requestors, including owner of
109 // define token. Appends for debugging of requestor order
110 void PlaceholderEntry::add_seen_thread(JavaThread* thread, PlaceholderTable::classloadAction action) {
111 assert_lock_strong(SystemDictionary_lock);
112 SeenThread* threadEntry = new SeenThread(thread);
113 SeenThread* seen = actionToQueue(action);
114
115 assert(action != PlaceholderTable::LOAD_INSTANCE || seen == NULL,
116 "Only one LOAD_INSTANCE allowed at a time");
117
118 if (seen == NULL) {
119 set_threadQ(threadEntry, action);
167 prev = seen;
168 seen = seen->next();
169 }
170 return (actionToQueue(action) == NULL);
171 }
172
173
174 // Placeholder methods
175
176 PlaceholderEntry* PlaceholderTable::new_entry(int hash, Symbol* name,
177 ClassLoaderData* loader_data,
178 Symbol* supername) {
179 PlaceholderEntry* entry = (PlaceholderEntry*)Hashtable<Symbol*, mtClass>::new_entry(hash, name);
180 // Hashtable with Symbol* literal must increment and decrement refcount.
181 name->increment_refcount();
182 entry->set_loader_data(loader_data);
183 entry->set_supername(supername);
184 entry->set_superThreadQ(NULL);
185 entry->set_loadInstanceThreadQ(NULL);
186 entry->set_defineThreadQ(NULL);
187 entry->set_definer(NULL);
188 entry->set_instance_klass(NULL);
189 return entry;
190 }
191
192 void PlaceholderTable::free_entry(PlaceholderEntry* entry) {
193 // decrement Symbol refcount here because Hashtable doesn't.
194 entry->literal()->decrement_refcount();
195 if (entry->supername() != NULL) entry->supername()->decrement_refcount();
196 BasicHashtable<mtClass>::free_entry(entry);
197 }
198
199
200 // Placeholder objects represent classes currently being loaded.
201 // All threads examining the placeholder table must hold the
202 // SystemDictionary_lock, so we don't need special precautions
203 // on store ordering here.
204 PlaceholderEntry* PlaceholderTable::add_entry(unsigned int hash,
205 Symbol* class_name, ClassLoaderData* loader_data,
206 Symbol* supername){
247 if (place_probe->hash() == hash &&
248 place_probe->equals(class_name, loader_data)) {
249 return place_probe;
250 }
251 }
252 return NULL;
253 }
254
255 Symbol* PlaceholderTable::find_entry(unsigned int hash,
256 Symbol* class_name,
257 ClassLoaderData* loader_data) {
258 PlaceholderEntry* probe = get_entry(hash, class_name, loader_data);
259 return (probe != NULL ? probe->klassname() : NULL);
260 }
261
262 static const char* action_to_string(PlaceholderTable::classloadAction action) {
263 switch (action) {
264 case PlaceholderTable::LOAD_INSTANCE: return "LOAD_INSTANCE";
265 case PlaceholderTable::LOAD_SUPER: return "LOAD_SUPER";
266 case PlaceholderTable::DEFINE_CLASS: return "DEFINE_CLASS";
267 }
268 return "";
269 }
270
271 inline void log(PlaceholderEntry* entry, const char* function, PlaceholderTable::classloadAction action) {
272 if (log_is_enabled(Debug, class, load, placeholders)) {
273 LogTarget(Debug, class, load, placeholders) lt;
274 ResourceMark rm;
275 LogStream ls(lt);
276 ls.print("%s %s ", function, action_to_string(action));
277 entry->print_entry(&ls);
278 }
279 }
280
281 // find_and_add returns probe pointer - old or new
282 // If no entry exists, add a placeholder entry
283 // If entry exists, reuse entry
284 // For both, push SeenThread for classloadAction
285 // If LOAD_SUPER, this is used for circularity detection for instanceklass loading.
286 PlaceholderEntry* PlaceholderTable::find_and_add(unsigned int hash,
312 // definer() tracks the single thread that owns define token
313 // defineThreadQ tracks waiters on defining thread's results
314 // 1st claimant creates placeholder
315 // find_and_add adds SeenThread entry for appropriate queue
316 // All claimants remove SeenThread after completing action
317 // On removal: if definer and all queues empty, remove entry
318 // Note: you can be in both placeholders and systemDictionary
319 // Therefore - must always check SD first
320 // Ignores the case where entry is not found
321 void PlaceholderTable::find_and_remove(unsigned int hash,
322 Symbol* name, ClassLoaderData* loader_data,
323 classloadAction action,
324 JavaThread* thread) {
325 assert_locked_or_safepoint(SystemDictionary_lock);
326 PlaceholderEntry *probe = get_entry(hash, name, loader_data);
327 if (probe != NULL) {
328 log(probe, "find_and_remove", action);
329 probe->remove_seen_thread(thread, action);
330 // If no other threads using this entry, and this thread is not using this entry for other states
331 if ((probe->superThreadQ() == NULL) && (probe->loadInstanceThreadQ() == NULL)
332 && (probe->defineThreadQ() == NULL) && (probe->definer() == NULL)) {
333 remove_entry(hash, name, loader_data);
334 }
335 }
336 }
337
338 PlaceholderTable::PlaceholderTable(int table_size)
339 : Hashtable<Symbol*, mtClass>(table_size, sizeof(PlaceholderEntry)) {
340 }
341
342 void PlaceholderEntry::verify() const {
343 guarantee(loader_data() != NULL, "Must have been setup.");
344 guarantee(loader_data()->class_loader() == NULL || loader_data()->class_loader()->is_instance(),
345 "checking type of _loader");
346 guarantee(instance_klass() == NULL
347 || instance_klass()->is_instance_klass(),
348 "checking type of instance_klass result");
349 }
350
351 void PlaceholderTable::verify() {
352 verify_table<PlaceholderEntry>("Placeholder Table");
367 supername()->print_value_on(st);
368 }
369 if (definer() != NULL) {
370 st->print(", definer ");
371 definer()->print_value_on(st);
372 }
373 if (instance_klass() != NULL) {
374 st->print(", InstanceKlass ");
375 instance_klass()->print_value_on(st);
376 }
377 st->cr();
378 st->print("loadInstanceThreadQ threads:");
379 loadInstanceThreadQ()->print_action_queue(st);
380 st->cr();
381 st->print("superThreadQ threads:");
382 superThreadQ()->print_action_queue(st);
383 st->cr();
384 st->print("defineThreadQ threads:");
385 defineThreadQ()->print_action_queue(st);
386 st->cr();
387 }
388
389 void PlaceholderTable::print_on(outputStream* st) const {
390 st->print_cr("Placeholder table (table_size=%d, placeholders=%d)",
391 table_size(), number_of_entries());
392 for (int pindex = 0; pindex < table_size(); pindex++) {
393 for (PlaceholderEntry* probe = bucket(pindex);
394 probe != NULL;
395 probe = probe->next()) {
396 st->print("%4d: placeholder ", pindex);
397 probe->print_entry(st);
398 }
399 }
400 }
401
402 void PlaceholderTable::print() const { return print_on(tty); }
|
24
25 #include "precompiled.hpp"
26 #include "classfile/classLoaderData.inline.hpp"
27 #include "classfile/placeholders.hpp"
28 #include "logging/log.hpp"
29 #include "logging/logTag.hpp"
30 #include "logging/logStream.hpp"
31 #include "memory/resourceArea.hpp"
32 #include "runtime/mutexLocker.hpp"
33 #include "runtime/thread.hpp"
34 #include "utilities/hashtable.inline.hpp"
35
36 // SeenThread objects represent list of threads that are
37 // currently performing a load action on a class.
38 // For class circularity, set before loading a superclass.
39 // For bootclasssearchpath, set before calling load_instance_class.
40 // Defining must be single threaded on a class/classloader basis
41 // For DEFINE_CLASS, the head of the queue owns the
42 // define token and the rest of the threads wait to return the
43 // result the first thread gets.
44 // For INLINE_FIELD, set when loading inline type fields for
45 // class circularity checking.
46 class SeenThread: public CHeapObj<mtInternal> {
47 private:
48 JavaThread* _thread;
49 SeenThread* _stnext;
50 SeenThread* _stprev;
51 public:
52 SeenThread(JavaThread* thread) {
53 _thread = thread;
54 _stnext = NULL;
55 _stprev = NULL;
56 }
57 JavaThread* thread() const { return _thread;}
58 void set_thread(JavaThread* thread) { _thread = thread; }
59
60 SeenThread* next() const { return _stnext;}
61 void set_next(SeenThread* seen) { _stnext = seen; }
62 void set_prev(SeenThread* seen) { _stprev = seen; }
63
64 void print_action_queue(outputStream* st) {
65 SeenThread* seen = this;
66 while (seen != NULL) {
67 seen->thread()->print_value_on(st);
68 st->print(", ");
69 seen = seen->next();
70 }
71 }
72 };
73
74 SeenThread* PlaceholderEntry::actionToQueue(PlaceholderTable::classloadAction action) {
75 SeenThread* queuehead = NULL;
76 switch (action) {
77 case PlaceholderTable::LOAD_INSTANCE:
78 queuehead = _loadInstanceThreadQ;
79 break;
80 case PlaceholderTable::LOAD_SUPER:
81 queuehead = _superThreadQ;
82 break;
83 case PlaceholderTable::DEFINE_CLASS:
84 queuehead = _defineThreadQ;
85 break;
86 case PlaceholderTable::PRIMITIVE_OBJECT_FIELD:
87 queuehead = _inlineTypeFieldQ;
88 break;
89 default: Unimplemented();
90 }
91 return queuehead;
92 }
93
94 void PlaceholderEntry::set_threadQ(SeenThread* seenthread, PlaceholderTable::classloadAction action) {
95 switch (action) {
96 case PlaceholderTable::LOAD_INSTANCE:
97 _loadInstanceThreadQ = seenthread;
98 break;
99 case PlaceholderTable::LOAD_SUPER:
100 _superThreadQ = seenthread;
101 break;
102 case PlaceholderTable::DEFINE_CLASS:
103 _defineThreadQ = seenthread;
104 break;
105 case PlaceholderTable::PRIMITIVE_OBJECT_FIELD:
106 _inlineTypeFieldQ = seenthread;
107 break;
108 default: Unimplemented();
109 }
110 return;
111 }
112
113 // Doubly-linked list of Threads per action for class/classloader pair
114 // Class circularity support: links in thread before loading superclass
115 // bootstrap loader support: links in a thread before load_instance_class
116 // definers: use as queue of define requestors, including owner of
117 // define token. Appends for debugging of requestor order
118 void PlaceholderEntry::add_seen_thread(JavaThread* thread, PlaceholderTable::classloadAction action) {
119 assert_lock_strong(SystemDictionary_lock);
120 SeenThread* threadEntry = new SeenThread(thread);
121 SeenThread* seen = actionToQueue(action);
122
123 assert(action != PlaceholderTable::LOAD_INSTANCE || seen == NULL,
124 "Only one LOAD_INSTANCE allowed at a time");
125
126 if (seen == NULL) {
127 set_threadQ(threadEntry, action);
175 prev = seen;
176 seen = seen->next();
177 }
178 return (actionToQueue(action) == NULL);
179 }
180
181
182 // Placeholder methods
183
184 PlaceholderEntry* PlaceholderTable::new_entry(int hash, Symbol* name,
185 ClassLoaderData* loader_data,
186 Symbol* supername) {
187 PlaceholderEntry* entry = (PlaceholderEntry*)Hashtable<Symbol*, mtClass>::new_entry(hash, name);
188 // Hashtable with Symbol* literal must increment and decrement refcount.
189 name->increment_refcount();
190 entry->set_loader_data(loader_data);
191 entry->set_supername(supername);
192 entry->set_superThreadQ(NULL);
193 entry->set_loadInstanceThreadQ(NULL);
194 entry->set_defineThreadQ(NULL);
195 entry->set_inlineTypeFieldQ(NULL);
196 entry->set_definer(NULL);
197 entry->set_instance_klass(NULL);
198 return entry;
199 }
200
201 void PlaceholderTable::free_entry(PlaceholderEntry* entry) {
202 // decrement Symbol refcount here because Hashtable doesn't.
203 entry->literal()->decrement_refcount();
204 if (entry->supername() != NULL) entry->supername()->decrement_refcount();
205 BasicHashtable<mtClass>::free_entry(entry);
206 }
207
208
209 // Placeholder objects represent classes currently being loaded.
210 // All threads examining the placeholder table must hold the
211 // SystemDictionary_lock, so we don't need special precautions
212 // on store ordering here.
213 PlaceholderEntry* PlaceholderTable::add_entry(unsigned int hash,
214 Symbol* class_name, ClassLoaderData* loader_data,
215 Symbol* supername){
256 if (place_probe->hash() == hash &&
257 place_probe->equals(class_name, loader_data)) {
258 return place_probe;
259 }
260 }
261 return NULL;
262 }
263
264 Symbol* PlaceholderTable::find_entry(unsigned int hash,
265 Symbol* class_name,
266 ClassLoaderData* loader_data) {
267 PlaceholderEntry* probe = get_entry(hash, class_name, loader_data);
268 return (probe != NULL ? probe->klassname() : NULL);
269 }
270
271 static const char* action_to_string(PlaceholderTable::classloadAction action) {
272 switch (action) {
273 case PlaceholderTable::LOAD_INSTANCE: return "LOAD_INSTANCE";
274 case PlaceholderTable::LOAD_SUPER: return "LOAD_SUPER";
275 case PlaceholderTable::DEFINE_CLASS: return "DEFINE_CLASS";
276 case PlaceholderTable::PRIMITIVE_OBJECT_FIELD: return "PRIMITIVE_OBJECT_FIELD";
277 }
278 return "";
279 }
280
281 inline void log(PlaceholderEntry* entry, const char* function, PlaceholderTable::classloadAction action) {
282 if (log_is_enabled(Debug, class, load, placeholders)) {
283 LogTarget(Debug, class, load, placeholders) lt;
284 ResourceMark rm;
285 LogStream ls(lt);
286 ls.print("%s %s ", function, action_to_string(action));
287 entry->print_entry(&ls);
288 }
289 }
290
291 // find_and_add returns probe pointer - old or new
292 // If no entry exists, add a placeholder entry
293 // If entry exists, reuse entry
294 // For both, push SeenThread for classloadAction
295 // If LOAD_SUPER, this is used for circularity detection for instanceklass loading.
296 PlaceholderEntry* PlaceholderTable::find_and_add(unsigned int hash,
322 // definer() tracks the single thread that owns define token
323 // defineThreadQ tracks waiters on defining thread's results
324 // 1st claimant creates placeholder
325 // find_and_add adds SeenThread entry for appropriate queue
326 // All claimants remove SeenThread after completing action
327 // On removal: if definer and all queues empty, remove entry
328 // Note: you can be in both placeholders and systemDictionary
329 // Therefore - must always check SD first
330 // Ignores the case where entry is not found
331 void PlaceholderTable::find_and_remove(unsigned int hash,
332 Symbol* name, ClassLoaderData* loader_data,
333 classloadAction action,
334 JavaThread* thread) {
335 assert_locked_or_safepoint(SystemDictionary_lock);
336 PlaceholderEntry *probe = get_entry(hash, name, loader_data);
337 if (probe != NULL) {
338 log(probe, "find_and_remove", action);
339 probe->remove_seen_thread(thread, action);
340 // If no other threads using this entry, and this thread is not using this entry for other states
341 if ((probe->superThreadQ() == NULL) && (probe->loadInstanceThreadQ() == NULL)
342 && (probe->defineThreadQ() == NULL) && (probe->definer() == NULL)
343 && (probe->inlineTypeFieldQ() == NULL)) {
344 remove_entry(hash, name, loader_data);
345 }
346 }
347 }
348
349 PlaceholderTable::PlaceholderTable(int table_size)
350 : Hashtable<Symbol*, mtClass>(table_size, sizeof(PlaceholderEntry)) {
351 }
352
353 void PlaceholderEntry::verify() const {
354 guarantee(loader_data() != NULL, "Must have been setup.");
355 guarantee(loader_data()->class_loader() == NULL || loader_data()->class_loader()->is_instance(),
356 "checking type of _loader");
357 guarantee(instance_klass() == NULL
358 || instance_klass()->is_instance_klass(),
359 "checking type of instance_klass result");
360 }
361
362 void PlaceholderTable::verify() {
363 verify_table<PlaceholderEntry>("Placeholder Table");
378 supername()->print_value_on(st);
379 }
380 if (definer() != NULL) {
381 st->print(", definer ");
382 definer()->print_value_on(st);
383 }
384 if (instance_klass() != NULL) {
385 st->print(", InstanceKlass ");
386 instance_klass()->print_value_on(st);
387 }
388 st->cr();
389 st->print("loadInstanceThreadQ threads:");
390 loadInstanceThreadQ()->print_action_queue(st);
391 st->cr();
392 st->print("superThreadQ threads:");
393 superThreadQ()->print_action_queue(st);
394 st->cr();
395 st->print("defineThreadQ threads:");
396 defineThreadQ()->print_action_queue(st);
397 st->cr();
398 st->print("inlineTypeFieldQ threads:");
399 inlineTypeFieldQ()->print_action_queue(st);
400 st->cr();
401 }
402
403 void PlaceholderTable::print_on(outputStream* st) const {
404 st->print_cr("Placeholder table (table_size=%d, placeholders=%d)",
405 table_size(), number_of_entries());
406 for (int pindex = 0; pindex < table_size(); pindex++) {
407 for (PlaceholderEntry* probe = bucket(pindex);
408 probe != NULL;
409 probe = probe->next()) {
410 st->print("%4d: placeholder ", pindex);
411 probe->print_entry(st);
412 }
413 }
414 }
415
416 void PlaceholderTable::print() const { return print_on(tty); }
|