57 void add_entry(int index, unsigned int hash, Symbol* name,
58 ClassLoaderData* loader_data, bool havesupername, Symbol* supername);
59
60 // This returns a Symbol* to match type for SystemDictionary
61 Symbol* find_entry(int index, unsigned int hash,
62 Symbol* name, ClassLoaderData* loader_data);
63
64 PlaceholderEntry* get_entry(int index, unsigned int hash,
65 Symbol* name, ClassLoaderData* loader_data);
66
67 // caller to create a placeholder entry must enumerate an action
68 // caller claims ownership of that action
69 // For parallel classloading:
70 // multiple LOAD_INSTANCE threads can proceed in parallel
71 // multiple LOAD_SUPER threads can proceed in parallel
72 // LOAD_SUPER needed to check for class circularity
73 // DEFINE_CLASS: ultimately define class must be single threaded
74 // on a class/classloader basis
75 // so the head of that queue owns the token
76 // and the rest of the threads return the result the first thread gets
77 enum classloadAction {
78 LOAD_INSTANCE = 1, // calling load_instance_class
79 LOAD_SUPER = 2, // loading superclass for this class
80 DEFINE_CLASS = 3 // find_or_define class
81 };
82
83 // find_and_add returns probe pointer - old or new
84 // If no entry exists, add a placeholder entry and push SeenThread for classloadAction
85 // If entry exists, reuse entry and push SeenThread for classloadAction
86 PlaceholderEntry* find_and_add(int index, unsigned int hash,
87 Symbol* name, ClassLoaderData* loader_data,
88 classloadAction action, Symbol* supername,
89 Thread* thread);
90
91 void remove_entry(int index, unsigned int hash,
92 Symbol* name, ClassLoaderData* loader_data);
93
94 // find_and_remove first removes SeenThread for classloadAction
95 // If all queues are empty and definer is null, remove the PlacheholderEntry completely
96 void find_and_remove(int index, unsigned int hash,
97 Symbol* name, ClassLoaderData* loader_data,
98 classloadAction action, Thread* thread);
99
100 void print_on(outputStream* st) const;
101 void verify();
102 };
103
104 // SeenThread objects represent list of threads that are
105 // currently performing a load action on a class.
106 // For class circularity, set before loading a superclass.
107 // For bootclasssearchpath, set before calling load_instance_class.
108 // Defining must be single threaded on a class/classloader basis
109 // For DEFINE_CLASS, the head of the queue owns the
110 // define token and the rest of the threads wait to return the
111 // result the first thread gets.
112 class SeenThread: public CHeapObj<mtInternal> {
113 private:
114 Thread *_thread;
115 SeenThread* _stnext;
116 SeenThread* _stprev;
117 public:
118 SeenThread(Thread *thread) {
119 _thread = thread;
120 _stnext = NULL;
121 _stprev = NULL;
122 }
123 Thread* thread() const { return _thread;}
124 void set_thread(Thread *thread) { _thread = thread; }
125
126 SeenThread* next() const { return _stnext;}
127 void set_next(SeenThread *seen) { _stnext = seen; }
128 void set_prev(SeenThread *seen) { _stprev = seen; }
129
130 void print_action_queue(outputStream* st) {
131 SeenThread* seen = this;
143 // on store ordering here.
144 // The system dictionary is the only user of this class.
145
146 class PlaceholderEntry : public HashtableEntry<Symbol*, mtClass> {
147
148 private:
149 ClassLoaderData* _loader_data; // initiating loader
150 bool _havesupername; // distinguish between null supername, and unknown
151 Symbol* _supername;
152 Thread* _definer; // owner of define token
153 InstanceKlass* _instanceKlass; // InstanceKlass from successful define
154 SeenThread* _superThreadQ; // doubly-linked queue of Threads loading a superclass for this class
155 SeenThread* _loadInstanceThreadQ; // loadInstance thread
156 // can be multiple threads if classloader object lock broken by application
157 // or if classloader supports parallel classloading
158
159 SeenThread* _defineThreadQ; // queue of Threads trying to define this class
160 // including _definer
161 // _definer owns token
162 // queue waits for and returns results from _definer
163
164 public:
165 // Simple accessors, used only by SystemDictionary
166 Symbol* klassname() const { return literal(); }
167
168 ClassLoaderData* loader_data() const { return _loader_data; }
169 void set_loader_data(ClassLoaderData* loader_data) { _loader_data = loader_data; }
170
171 bool havesupername() const { return _havesupername; }
172 void set_havesupername(bool havesupername) { _havesupername = havesupername; }
173
174 Symbol* supername() const { return _supername; }
175 void set_supername(Symbol* supername) {
176 _supername = supername;
177 if (_supername != NULL) _supername->increment_refcount();
178 }
179
180 Thread* definer() const {return _definer; }
181 void set_definer(Thread* definer) { _definer = definer; }
182
183 InstanceKlass* instance_klass() const {return _instanceKlass; }
184 void set_instance_klass(InstanceKlass* ik) { _instanceKlass = ik; }
185
186 SeenThread* superThreadQ() const { return _superThreadQ; }
187 void set_superThreadQ(SeenThread* SeenThread) { _superThreadQ = SeenThread; }
188
189 SeenThread* loadInstanceThreadQ() const { return _loadInstanceThreadQ; }
190 void set_loadInstanceThreadQ(SeenThread* SeenThread) { _loadInstanceThreadQ = SeenThread; }
191
192 SeenThread* defineThreadQ() const { return _defineThreadQ; }
193 void set_defineThreadQ(SeenThread* SeenThread) { _defineThreadQ = SeenThread; }
194
195 PlaceholderEntry* next() const {
196 return (PlaceholderEntry*)HashtableEntry<Symbol*, mtClass>::next();
197 }
198
199 PlaceholderEntry** next_addr() {
200 return (PlaceholderEntry**)HashtableEntry<Symbol*, mtClass>::next_addr();
201 }
202
203 // Test for equality
204 // Entries are unique for class/classloader name pair
205 bool equals(Symbol* class_name, ClassLoaderData* loader) const {
206 return (klassname() == class_name && loader_data() == loader);
207 }
208
209 SeenThread* actionToQueue(PlaceholderTable::classloadAction action) {
210 SeenThread* queuehead = NULL;
211 switch (action) {
212 case PlaceholderTable::LOAD_INSTANCE:
213 queuehead = _loadInstanceThreadQ;
214 break;
215 case PlaceholderTable::LOAD_SUPER:
216 queuehead = _superThreadQ;
217 break;
218 case PlaceholderTable::DEFINE_CLASS:
219 queuehead = _defineThreadQ;
220 break;
221 default: Unimplemented();
222 }
223 return queuehead;
224 }
225
226 void set_threadQ(SeenThread* seenthread, PlaceholderTable::classloadAction action) {
227 switch (action) {
228 case PlaceholderTable::LOAD_INSTANCE:
229 _loadInstanceThreadQ = seenthread;
230 break;
231 case PlaceholderTable::LOAD_SUPER:
232 _superThreadQ = seenthread;
233 break;
234 case PlaceholderTable::DEFINE_CLASS:
235 _defineThreadQ = seenthread;
236 break;
237 default: Unimplemented();
238 }
239 return;
240 }
241
242 bool super_load_in_progress() {
243 return (_superThreadQ != NULL);
244 }
245
246 bool instance_load_in_progress() {
247 return (_loadInstanceThreadQ != NULL);
248 }
249
250 bool define_class_in_progress() {
251 return (_defineThreadQ != NULL);
252 }
253
254 // Doubly-linked list of Threads per action for class/classloader pair
255 // Class circularity support: links in thread before loading superclass
256 // bootstrapsearchpath support: links in a thread before load_instance_class
257 // definers: use as queue of define requestors, including owner of
258 // define token. Appends for debugging of requestor order
259 void add_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) {
260 assert_lock_strong(SystemDictionary_lock);
261 SeenThread* threadEntry = new SeenThread(thread);
262 SeenThread* seen = actionToQueue(action);
263
264 if (seen == NULL) {
265 set_threadQ(threadEntry, action);
266 return;
267 }
268 SeenThread* next;
269 while ((next = seen->next()) != NULL) {
270 seen = next;
271 }
|
57 void add_entry(int index, unsigned int hash, Symbol* name,
58 ClassLoaderData* loader_data, bool havesupername, Symbol* supername);
59
60 // This returns a Symbol* to match type for SystemDictionary
61 Symbol* find_entry(int index, unsigned int hash,
62 Symbol* name, ClassLoaderData* loader_data);
63
64 PlaceholderEntry* get_entry(int index, unsigned int hash,
65 Symbol* name, ClassLoaderData* loader_data);
66
67 // caller to create a placeholder entry must enumerate an action
68 // caller claims ownership of that action
69 // For parallel classloading:
70 // multiple LOAD_INSTANCE threads can proceed in parallel
71 // multiple LOAD_SUPER threads can proceed in parallel
72 // LOAD_SUPER needed to check for class circularity
73 // DEFINE_CLASS: ultimately define class must be single threaded
74 // on a class/classloader basis
75 // so the head of that queue owns the token
76 // and the rest of the threads return the result the first thread gets
77 // FLATTENABLE_FIELD: needed to check for value type flattenable fields circularity
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 FLATTENABLE_FIELD = 4 // flattenable value type fields
83 };
84
85 // find_and_add returns probe pointer - old or new
86 // If no entry exists, add a placeholder entry and push SeenThread for classloadAction
87 // If entry exists, reuse entry and push SeenThread for classloadAction
88 PlaceholderEntry* find_and_add(int index, unsigned int hash,
89 Symbol* name, ClassLoaderData* loader_data,
90 classloadAction action, Symbol* supername,
91 Thread* thread);
92
93 void remove_entry(int index, unsigned int hash,
94 Symbol* name, ClassLoaderData* loader_data);
95
96 // find_and_remove first removes SeenThread for classloadAction
97 // If all queues are empty and definer is null, remove the PlacheholderEntry completely
98 void find_and_remove(int index, unsigned int hash,
99 Symbol* name, ClassLoaderData* loader_data,
100 classloadAction action, Thread* thread);
101
102 void print_on(outputStream* st) const;
103 void verify();
104 };
105
106 // SeenThread objects represent list of threads that are
107 // currently performing a load action on a class.
108 // For class circularity, set before loading a superclass.
109 // For bootclasssearchpath, set before calling load_instance_class.
110 // Defining must be single threaded on a class/classloader basis
111 // For DEFINE_CLASS, the head of the queue owns the
112 // define token and the rest of the threads wait to return the
113 // result the first thread gets.
114 // For FLATTENABLE_FIELD, set when loading value type fields for
115 // class circularity checking.
116 class SeenThread: public CHeapObj<mtInternal> {
117 private:
118 Thread *_thread;
119 SeenThread* _stnext;
120 SeenThread* _stprev;
121 public:
122 SeenThread(Thread *thread) {
123 _thread = thread;
124 _stnext = NULL;
125 _stprev = NULL;
126 }
127 Thread* thread() const { return _thread;}
128 void set_thread(Thread *thread) { _thread = thread; }
129
130 SeenThread* next() const { return _stnext;}
131 void set_next(SeenThread *seen) { _stnext = seen; }
132 void set_prev(SeenThread *seen) { _stprev = seen; }
133
134 void print_action_queue(outputStream* st) {
135 SeenThread* seen = this;
147 // on store ordering here.
148 // The system dictionary is the only user of this class.
149
150 class PlaceholderEntry : public HashtableEntry<Symbol*, mtClass> {
151
152 private:
153 ClassLoaderData* _loader_data; // initiating loader
154 bool _havesupername; // distinguish between null supername, and unknown
155 Symbol* _supername;
156 Thread* _definer; // owner of define token
157 InstanceKlass* _instanceKlass; // InstanceKlass from successful define
158 SeenThread* _superThreadQ; // doubly-linked queue of Threads loading a superclass for this class
159 SeenThread* _loadInstanceThreadQ; // loadInstance thread
160 // can be multiple threads if classloader object lock broken by application
161 // or if classloader supports parallel classloading
162
163 SeenThread* _defineThreadQ; // queue of Threads trying to define this class
164 // including _definer
165 // _definer owns token
166 // queue waits for and returns results from _definer
167 SeenThread* _flattenableFieldQ; // queue of value types for circularity checking
168
169 public:
170 // Simple accessors, used only by SystemDictionary
171 Symbol* klassname() const { return literal(); }
172
173 ClassLoaderData* loader_data() const { return _loader_data; }
174 void set_loader_data(ClassLoaderData* loader_data) { _loader_data = loader_data; }
175
176 bool havesupername() const { return _havesupername; }
177 void set_havesupername(bool havesupername) { _havesupername = havesupername; }
178
179 Symbol* supername() const { return _supername; }
180 void set_supername(Symbol* supername) {
181 _supername = supername;
182 if (_supername != NULL) _supername->increment_refcount();
183 }
184
185 Thread* definer() const {return _definer; }
186 void set_definer(Thread* definer) { _definer = definer; }
187
188 InstanceKlass* instance_klass() const {return _instanceKlass; }
189 void set_instance_klass(InstanceKlass* ik) { _instanceKlass = ik; }
190
191 SeenThread* superThreadQ() const { return _superThreadQ; }
192 void set_superThreadQ(SeenThread* SeenThread) { _superThreadQ = SeenThread; }
193
194 SeenThread* loadInstanceThreadQ() const { return _loadInstanceThreadQ; }
195 void set_loadInstanceThreadQ(SeenThread* SeenThread) { _loadInstanceThreadQ = SeenThread; }
196
197 SeenThread* defineThreadQ() const { return _defineThreadQ; }
198 void set_defineThreadQ(SeenThread* SeenThread) { _defineThreadQ = SeenThread; }
199
200 SeenThread* flattenableFieldQ() const { return _flattenableFieldQ; }
201 void set_flattenableFieldQ(SeenThread* SeenThread) { _flattenableFieldQ = SeenThread; }
202
203 PlaceholderEntry* next() const {
204 return (PlaceholderEntry*)HashtableEntry<Symbol*, mtClass>::next();
205 }
206
207 PlaceholderEntry** next_addr() {
208 return (PlaceholderEntry**)HashtableEntry<Symbol*, mtClass>::next_addr();
209 }
210
211 // Test for equality
212 // Entries are unique for class/classloader name pair
213 bool equals(Symbol* class_name, ClassLoaderData* loader) const {
214 return (klassname() == class_name && loader_data() == loader);
215 }
216
217 SeenThread* actionToQueue(PlaceholderTable::classloadAction action) {
218 SeenThread* queuehead = NULL;
219 switch (action) {
220 case PlaceholderTable::LOAD_INSTANCE:
221 queuehead = _loadInstanceThreadQ;
222 break;
223 case PlaceholderTable::LOAD_SUPER:
224 queuehead = _superThreadQ;
225 break;
226 case PlaceholderTable::DEFINE_CLASS:
227 queuehead = _defineThreadQ;
228 break;
229 case PlaceholderTable::FLATTENABLE_FIELD:
230 queuehead = _flattenableFieldQ;
231 break;
232 default: Unimplemented();
233 }
234 return queuehead;
235 }
236
237 void set_threadQ(SeenThread* seenthread, PlaceholderTable::classloadAction action) {
238 switch (action) {
239 case PlaceholderTable::LOAD_INSTANCE:
240 _loadInstanceThreadQ = seenthread;
241 break;
242 case PlaceholderTable::LOAD_SUPER:
243 _superThreadQ = seenthread;
244 break;
245 case PlaceholderTable::DEFINE_CLASS:
246 _defineThreadQ = seenthread;
247 break;
248 case PlaceholderTable::FLATTENABLE_FIELD:
249 _flattenableFieldQ = seenthread;
250 break;
251 default: Unimplemented();
252 }
253 return;
254 }
255
256 bool super_load_in_progress() {
257 return (_superThreadQ != NULL);
258 }
259
260 bool instance_load_in_progress() {
261 return (_loadInstanceThreadQ != NULL);
262 }
263
264 bool define_class_in_progress() {
265 return (_defineThreadQ != NULL);
266 }
267
268 bool flattenable_field_in_progress() {
269 return (_flattenableFieldQ != NULL);
270 }
271
272 // Doubly-linked list of Threads per action for class/classloader pair
273 // Class circularity support: links in thread before loading superclass
274 // bootstrapsearchpath support: links in a thread before load_instance_class
275 // definers: use as queue of define requestors, including owner of
276 // define token. Appends for debugging of requestor order
277 void add_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) {
278 assert_lock_strong(SystemDictionary_lock);
279 SeenThread* threadEntry = new SeenThread(thread);
280 SeenThread* seen = actionToQueue(action);
281
282 if (seen == NULL) {
283 set_threadQ(threadEntry, action);
284 return;
285 }
286 SeenThread* next;
287 while ((next = seen->next()) != NULL) {
288 seen = next;
289 }
|