44 return (k1._name == k2._name && k1._loader_data == k2._loader_data);
45 }
46 static unsigned hash(PlaceholderKey const& k) {
47 return (unsigned) k._name->identity_hash() ^ (int)((intptr_t)k._loader_data >> 3);
48 }
49 void print_on(outputStream* st) const;
50 };
51
52 const int _placeholder_table_size = 503; // Does this really have to be prime?
53 ResourceHashtable<PlaceholderKey, PlaceholderEntry, _placeholder_table_size, AnyObj::C_HEAP, mtClass,
54 PlaceholderKey::hash, PlaceholderKey::equals> _placeholders;
55
56 // SeenThread objects represent list of threads that are
57 // currently performing a load action on a class.
58 // For class circularity, set before loading a superclass.
59 // For bootclasssearchpath, set before calling load_instance_class.
60 // Defining must be single threaded on a class/classloader basis
61 // For DEFINE_CLASS, the head of the queue owns the
62 // define token and the rest of the threads wait to return the
63 // result the first thread gets.
64 class SeenThread: public CHeapObj<mtInternal> {
65 private:
66 JavaThread* _thread;
67 SeenThread* _stnext;
68 SeenThread* _stprev;
69 public:
70 SeenThread(JavaThread* thread) {
71 _thread = thread;
72 _stnext = NULL;
73 _stprev = NULL;
74 }
75 JavaThread* thread() const { return _thread;}
76 void set_thread(JavaThread* thread) { _thread = thread; }
77
78 SeenThread* next() const { return _stnext;}
79 void set_next(SeenThread* seen) { _stnext = seen; }
80 void set_prev(SeenThread* seen) { _stprev = seen; }
81
82 void print_action_queue(outputStream* st) {
83 SeenThread* seen = this;
84 while (seen != NULL) {
85 seen->thread()->print_value_on(st);
86 st->print(", ");
87 seen = seen->next();
88 }
89 }
90 };
91
92 SeenThread* PlaceholderEntry::actionToQueue(PlaceholderTable::classloadAction action) {
93 SeenThread* queuehead = NULL;
94 switch (action) {
95 case PlaceholderTable::LOAD_INSTANCE:
96 queuehead = _loadInstanceThreadQ;
97 break;
98 case PlaceholderTable::LOAD_SUPER:
99 queuehead = _superThreadQ;
100 break;
101 case PlaceholderTable::DEFINE_CLASS:
102 queuehead = _defineThreadQ;
103 break;
104 default: Unimplemented();
105 }
106 return queuehead;
107 }
108
109 void PlaceholderEntry::set_threadQ(SeenThread* seenthread, PlaceholderTable::classloadAction action) {
110 switch (action) {
111 case PlaceholderTable::LOAD_INSTANCE:
112 _loadInstanceThreadQ = seenthread;
113 break;
114 case PlaceholderTable::LOAD_SUPER:
115 _superThreadQ = seenthread;
116 break;
117 case PlaceholderTable::DEFINE_CLASS:
118 _defineThreadQ = seenthread;
119 break;
120 default: Unimplemented();
121 }
122 return;
123 }
124
125 // Doubly-linked list of Threads per action for class/classloader pair
126 // Class circularity support: links in thread before loading superclass
127 // bootstrap loader support: links in a thread before load_instance_class
128 // definers: use as queue of define requestors, including owner of
129 // define token. Appends for debugging of requestor order
130 void PlaceholderEntry::add_seen_thread(JavaThread* thread, PlaceholderTable::classloadAction action) {
131 assert_lock_strong(SystemDictionary_lock);
132 SeenThread* threadEntry = new SeenThread(thread);
133 SeenThread* seen = actionToQueue(action);
134
135 assert(action != PlaceholderTable::LOAD_INSTANCE || !EnableWaitForParallelLoad || seen == NULL,
136 "Only one LOAD_INSTANCE allowed at a time");
137
138 if (seen == NULL) {
139 set_threadQ(threadEntry, action);
214 // Remove a placeholder object.
215 void remove_entry(Symbol* class_name, ClassLoaderData* loader_data) {
216 assert_locked_or_safepoint(SystemDictionary_lock);
217
218 PlaceholderKey key(class_name, loader_data);
219 _placeholders.remove(key);
220 }
221
222
223 PlaceholderEntry* PlaceholderTable::get_entry(Symbol* class_name, ClassLoaderData* loader_data) {
224 assert_locked_or_safepoint(SystemDictionary_lock);
225 PlaceholderKey key(class_name, loader_data);
226 return _placeholders.get(key);
227 }
228
229 static const char* action_to_string(PlaceholderTable::classloadAction action) {
230 switch (action) {
231 case PlaceholderTable::LOAD_INSTANCE: return "LOAD_INSTANCE";
232 case PlaceholderTable::LOAD_SUPER: return "LOAD_SUPER";
233 case PlaceholderTable::DEFINE_CLASS: return "DEFINE_CLASS";
234 }
235 return "";
236 }
237
238 inline void log(Symbol* name, PlaceholderEntry* entry, const char* function, PlaceholderTable::classloadAction action) {
239 if (log_is_enabled(Debug, class, load, placeholders)) {
240 LogTarget(Debug, class, load, placeholders) lt;
241 ResourceMark rm;
242 LogStream ls(lt);
243 ls.print("entry %s : %s %s ", name->as_C_string(), function, action_to_string(action));
244 entry->print_on(&ls);
245 }
246 }
247
248 // find_and_add returns probe pointer - old or new
249 // If no entry exists, add a placeholder entry
250 // If entry exists, reuse entry
251 // For both, push SeenThread for classloadAction
252 // If LOAD_SUPER, this is used for circularity detection for instanceklass loading.
253 PlaceholderEntry* PlaceholderTable::find_and_add(Symbol* name,
277 // loadInstanceThreadQ tracks load_instance_class calls
278 // definer() tracks the single thread that owns define token
279 // defineThreadQ tracks waiters on defining thread's results
280 // 1st claimant creates placeholder
281 // find_and_add adds SeenThread entry for appropriate queue
282 // All claimants remove SeenThread after completing action
283 // On removal: if definer and all queues empty, remove entry
284 // Note: you can be in both placeholders and systemDictionary
285 // Therefore - must always check SD first
286 // Ignores the case where entry is not found
287 void PlaceholderTable::find_and_remove(Symbol* name, ClassLoaderData* loader_data,
288 classloadAction action,
289 JavaThread* thread) {
290 assert_locked_or_safepoint(SystemDictionary_lock);
291 PlaceholderEntry* probe = get_entry(name, loader_data);
292 if (probe != NULL) {
293 log(name, probe, "find_and_remove", action);
294 probe->remove_seen_thread(thread, action);
295 // If no other threads using this entry, and this thread is not using this entry for other states
296 if ((probe->superThreadQ() == NULL) && (probe->loadInstanceThreadQ() == NULL)
297 && (probe->defineThreadQ() == NULL) && (probe->definer() == NULL)) {
298 probe->clear_supername();
299 remove_entry(name, loader_data);
300 }
301 }
302 }
303
304 void PlaceholderKey::print_on(outputStream* st) const {
305 _name->print_value_on(st);
306 st->print(", loader ");
307 _loader_data->print_value_on(st);
308 }
309
310 void PlaceholderEntry::print_on(outputStream* st) const {
311 if (supername() != NULL) {
312 st->print(", supername ");
313 supername()->print_value_on(st);
314 }
315 if (definer() != NULL) {
316 st->print(", definer ");
317 definer()->print_value_on(st);
318 }
319 if (instance_klass() != NULL) {
320 st->print(", InstanceKlass ");
321 instance_klass()->print_value_on(st);
322 }
323 st->cr();
324 st->print("loadInstanceThreadQ threads:");
325 loadInstanceThreadQ()->print_action_queue(st);
326 st->cr();
327 st->print("superThreadQ threads:");
328 superThreadQ()->print_action_queue(st);
329 st->cr();
330 st->print("defineThreadQ threads:");
331 defineThreadQ()->print_action_queue(st);
332 st->cr();
333 }
334
335 void PlaceholderTable::print_on(outputStream* st) {
336 auto printer = [&] (PlaceholderKey& key, PlaceholderEntry& entry) {
337 st->print("placeholder ");
338 key.print_on(st);
339 entry.print_on(st);
340 return true;
341 };
342 st->print_cr("Placeholder table (table_size=%d, placeholders=%d)",
343 _placeholders.table_size(), _placeholders.number_of_entries());
344 _placeholders.iterate(printer);
345 }
346
347 void PlaceholderTable::print() { return print_on(tty); }
|
44 return (k1._name == k2._name && k1._loader_data == k2._loader_data);
45 }
46 static unsigned hash(PlaceholderKey const& k) {
47 return (unsigned) k._name->identity_hash() ^ (int)((intptr_t)k._loader_data >> 3);
48 }
49 void print_on(outputStream* st) const;
50 };
51
52 const int _placeholder_table_size = 503; // Does this really have to be prime?
53 ResourceHashtable<PlaceholderKey, PlaceholderEntry, _placeholder_table_size, AnyObj::C_HEAP, mtClass,
54 PlaceholderKey::hash, PlaceholderKey::equals> _placeholders;
55
56 // SeenThread objects represent list of threads that are
57 // currently performing a load action on a class.
58 // For class circularity, set before loading a superclass.
59 // For bootclasssearchpath, set before calling load_instance_class.
60 // Defining must be single threaded on a class/classloader basis
61 // For DEFINE_CLASS, the head of the queue owns the
62 // define token and the rest of the threads wait to return the
63 // result the first thread gets.
64 // For INLINE_FIELD, set when loading inline type fields for
65 // class circularity checking.
66 class SeenThread: public CHeapObj<mtInternal> {
67 private:
68 JavaThread* _thread;
69 SeenThread* _stnext;
70 SeenThread* _stprev;
71 public:
72 SeenThread(JavaThread* thread) {
73 _thread = thread;
74 _stnext = NULL;
75 _stprev = NULL;
76 }
77 JavaThread* thread() const { return _thread;}
78 void set_thread(JavaThread* thread) { _thread = thread; }
79
80 SeenThread* next() const { return _stnext;}
81 void set_next(SeenThread* seen) { _stnext = seen; }
82 void set_prev(SeenThread* seen) { _stprev = seen; }
83
84 void print_action_queue(outputStream* st) {
85 SeenThread* seen = this;
86 while (seen != NULL) {
87 seen->thread()->print_value_on(st);
88 st->print(", ");
89 seen = seen->next();
90 }
91 }
92 };
93
94 SeenThread* PlaceholderEntry::actionToQueue(PlaceholderTable::classloadAction action) {
95 SeenThread* queuehead = NULL;
96 switch (action) {
97 case PlaceholderTable::LOAD_INSTANCE:
98 queuehead = _loadInstanceThreadQ;
99 break;
100 case PlaceholderTable::LOAD_SUPER:
101 queuehead = _superThreadQ;
102 break;
103 case PlaceholderTable::DEFINE_CLASS:
104 queuehead = _defineThreadQ;
105 break;
106 case PlaceholderTable::PRIMITIVE_OBJECT_FIELD:
107 queuehead = _inlineTypeFieldQ;
108 break;
109 default: Unimplemented();
110 }
111 return queuehead;
112 }
113
114 void PlaceholderEntry::set_threadQ(SeenThread* seenthread, PlaceholderTable::classloadAction action) {
115 switch (action) {
116 case PlaceholderTable::LOAD_INSTANCE:
117 _loadInstanceThreadQ = seenthread;
118 break;
119 case PlaceholderTable::LOAD_SUPER:
120 _superThreadQ = seenthread;
121 break;
122 case PlaceholderTable::DEFINE_CLASS:
123 _defineThreadQ = seenthread;
124 break;
125 case PlaceholderTable::PRIMITIVE_OBJECT_FIELD:
126 _inlineTypeFieldQ = seenthread;
127 break;
128 default: Unimplemented();
129 }
130 return;
131 }
132
133 // Doubly-linked list of Threads per action for class/classloader pair
134 // Class circularity support: links in thread before loading superclass
135 // bootstrap loader support: links in a thread before load_instance_class
136 // definers: use as queue of define requestors, including owner of
137 // define token. Appends for debugging of requestor order
138 void PlaceholderEntry::add_seen_thread(JavaThread* thread, PlaceholderTable::classloadAction action) {
139 assert_lock_strong(SystemDictionary_lock);
140 SeenThread* threadEntry = new SeenThread(thread);
141 SeenThread* seen = actionToQueue(action);
142
143 assert(action != PlaceholderTable::LOAD_INSTANCE || !EnableWaitForParallelLoad || seen == NULL,
144 "Only one LOAD_INSTANCE allowed at a time");
145
146 if (seen == NULL) {
147 set_threadQ(threadEntry, action);
222 // Remove a placeholder object.
223 void remove_entry(Symbol* class_name, ClassLoaderData* loader_data) {
224 assert_locked_or_safepoint(SystemDictionary_lock);
225
226 PlaceholderKey key(class_name, loader_data);
227 _placeholders.remove(key);
228 }
229
230
231 PlaceholderEntry* PlaceholderTable::get_entry(Symbol* class_name, ClassLoaderData* loader_data) {
232 assert_locked_or_safepoint(SystemDictionary_lock);
233 PlaceholderKey key(class_name, loader_data);
234 return _placeholders.get(key);
235 }
236
237 static const char* action_to_string(PlaceholderTable::classloadAction action) {
238 switch (action) {
239 case PlaceholderTable::LOAD_INSTANCE: return "LOAD_INSTANCE";
240 case PlaceholderTable::LOAD_SUPER: return "LOAD_SUPER";
241 case PlaceholderTable::DEFINE_CLASS: return "DEFINE_CLASS";
242 case PlaceholderTable::PRIMITIVE_OBJECT_FIELD: return "PRIMITIVE_OBJECT_FIELD";
243 }
244 return "";
245 }
246
247 inline void log(Symbol* name, PlaceholderEntry* entry, const char* function, PlaceholderTable::classloadAction action) {
248 if (log_is_enabled(Debug, class, load, placeholders)) {
249 LogTarget(Debug, class, load, placeholders) lt;
250 ResourceMark rm;
251 LogStream ls(lt);
252 ls.print("entry %s : %s %s ", name->as_C_string(), function, action_to_string(action));
253 entry->print_on(&ls);
254 }
255 }
256
257 // find_and_add returns probe pointer - old or new
258 // If no entry exists, add a placeholder entry
259 // If entry exists, reuse entry
260 // For both, push SeenThread for classloadAction
261 // If LOAD_SUPER, this is used for circularity detection for instanceklass loading.
262 PlaceholderEntry* PlaceholderTable::find_and_add(Symbol* name,
286 // loadInstanceThreadQ tracks load_instance_class calls
287 // definer() tracks the single thread that owns define token
288 // defineThreadQ tracks waiters on defining thread's results
289 // 1st claimant creates placeholder
290 // find_and_add adds SeenThread entry for appropriate queue
291 // All claimants remove SeenThread after completing action
292 // On removal: if definer and all queues empty, remove entry
293 // Note: you can be in both placeholders and systemDictionary
294 // Therefore - must always check SD first
295 // Ignores the case where entry is not found
296 void PlaceholderTable::find_and_remove(Symbol* name, ClassLoaderData* loader_data,
297 classloadAction action,
298 JavaThread* thread) {
299 assert_locked_or_safepoint(SystemDictionary_lock);
300 PlaceholderEntry* probe = get_entry(name, loader_data);
301 if (probe != NULL) {
302 log(name, probe, "find_and_remove", action);
303 probe->remove_seen_thread(thread, action);
304 // If no other threads using this entry, and this thread is not using this entry for other states
305 if ((probe->superThreadQ() == NULL) && (probe->loadInstanceThreadQ() == NULL)
306 && (probe->defineThreadQ() == NULL) && (probe->definer() == NULL)
307 && (probe->inlineTypeFieldQ() == NULL)) {
308 probe->clear_supername();
309 remove_entry(name, loader_data);
310 }
311 }
312 }
313
314 void PlaceholderKey::print_on(outputStream* st) const {
315 _name->print_value_on(st);
316 st->print(", loader ");
317 _loader_data->print_value_on(st);
318 }
319
320 void PlaceholderEntry::print_on(outputStream* st) const {
321 if (supername() != NULL) {
322 st->print(", supername ");
323 supername()->print_value_on(st);
324 }
325 if (definer() != NULL) {
326 st->print(", definer ");
327 definer()->print_value_on(st);
328 }
329 if (instance_klass() != NULL) {
330 st->print(", InstanceKlass ");
331 instance_klass()->print_value_on(st);
332 }
333 st->cr();
334 st->print("loadInstanceThreadQ threads:");
335 loadInstanceThreadQ()->print_action_queue(st);
336 st->cr();
337 st->print("superThreadQ threads:");
338 superThreadQ()->print_action_queue(st);
339 st->cr();
340 st->print("defineThreadQ threads:");
341 defineThreadQ()->print_action_queue(st);
342 st->cr();
343 st->print("inlineTypeFieldQ threads:");
344 inlineTypeFieldQ()->print_action_queue(st);
345 st->cr();
346 }
347
348 void PlaceholderTable::print_on(outputStream* st) {
349 auto printer = [&] (PlaceholderKey& key, PlaceholderEntry& entry) {
350 st->print("placeholder ");
351 key.print_on(st);
352 entry.print_on(st);
353 return true;
354 };
355 st->print_cr("Placeholder table (table_size=%d, placeholders=%d)",
356 _placeholders.table_size(), _placeholders.number_of_entries());
357 _placeholders.iterate(printer);
358 }
359
360 void PlaceholderTable::print() { return print_on(tty); }
|