56 ClassLoaderData* loader_data,
57 Symbol* supername);
58
59 // This returns a Symbol* to match type for SystemDictionary
60 Symbol* find_entry(unsigned int hash,
61 Symbol* name, ClassLoaderData* loader_data);
62
63 PlaceholderEntry* get_entry(unsigned int hash,
64 Symbol* name, ClassLoaderData* loader_data);
65
66 // caller to create a placeholder entry must enumerate an action
67 // caller claims ownership of that action
68 // For parallel classloading:
69 // multiple LOAD_INSTANCE threads can proceed in parallel
70 // multiple LOAD_SUPER threads can proceed in parallel
71 // LOAD_SUPER needed to check for class circularity
72 // DEFINE_CLASS: ultimately define class must be single threaded
73 // on a class/classloader basis
74 // so the head of that queue owns the token
75 // and the rest of the threads return the result the first thread gets
76 enum classloadAction {
77 LOAD_INSTANCE = 1, // calling load_instance_class
78 LOAD_SUPER = 2, // loading superclass for this class
79 DEFINE_CLASS = 3 // find_or_define class
80 };
81
82 // find_and_add returns probe pointer - old or new
83 // If no entry exists, add a placeholder entry and push SeenThread for classloadAction
84 // If entry exists, reuse entry and push SeenThread for classloadAction
85 PlaceholderEntry* find_and_add(unsigned int hash,
86 Symbol* name, ClassLoaderData* loader_data,
87 classloadAction action, Symbol* supername,
88 JavaThread* thread);
89
90 void remove_entry(unsigned int hash,
91 Symbol* name, ClassLoaderData* loader_data);
92
93 // find_and_remove first removes SeenThread for classloadAction
94 // If all queues are empty and definer is null, remove the PlacheholderEntry completely
95 void find_and_remove(unsigned int hash,
96 Symbol* name, ClassLoaderData* loader_data,
97 classloadAction action, JavaThread* thread);
98
99 void print_on(outputStream* st) const;
110 // The system dictionary is the only user of this class.
111
112 class PlaceholderEntry : public HashtableEntry<Symbol*, mtClass> {
113
114 friend class PlaceholderTable;
115
116 private:
117 ClassLoaderData* _loader_data; // initiating loader
118 Symbol* _supername;
119 JavaThread* _definer; // owner of define token
120 InstanceKlass* _instanceKlass; // InstanceKlass from successful define
121 SeenThread* _superThreadQ; // doubly-linked queue of Threads loading a superclass for this class
122 SeenThread* _loadInstanceThreadQ; // loadInstance thread
123 // This can't be multiple threads since class loading waits for
124 // this token to be removed.
125
126 SeenThread* _defineThreadQ; // queue of Threads trying to define this class
127 // including _definer
128 // _definer owns token
129 // queue waits for and returns results from _definer
130
131 SeenThread* actionToQueue(PlaceholderTable::classloadAction action);
132 void set_threadQ(SeenThread* seenthread, PlaceholderTable::classloadAction action);
133 void add_seen_thread(JavaThread* thread, PlaceholderTable::classloadAction action);
134 bool remove_seen_thread(JavaThread* thread, PlaceholderTable::classloadAction action);
135
136 public:
137 // Simple accessors, used only by SystemDictionary
138 Symbol* klassname() const { return literal(); }
139
140 ClassLoaderData* loader_data() const { return _loader_data; }
141 void set_loader_data(ClassLoaderData* loader_data) { _loader_data = loader_data; }
142
143 Symbol* supername() const { return _supername; }
144 void set_supername(Symbol* supername) {
145 _supername = supername;
146 if (_supername != NULL) _supername->increment_refcount();
147 }
148
149 JavaThread* definer() const {return _definer; }
150 void set_definer(JavaThread* definer) { _definer = definer; }
151
152 InstanceKlass* instance_klass() const {return _instanceKlass; }
153 void set_instance_klass(InstanceKlass* ik) { _instanceKlass = ik; }
154
155 SeenThread* superThreadQ() const { return _superThreadQ; }
156 void set_superThreadQ(SeenThread* SeenThread) { _superThreadQ = SeenThread; }
157
158 SeenThread* loadInstanceThreadQ() const { return _loadInstanceThreadQ; }
159 void set_loadInstanceThreadQ(SeenThread* SeenThread) { _loadInstanceThreadQ = SeenThread; }
160
161 SeenThread* defineThreadQ() const { return _defineThreadQ; }
162 void set_defineThreadQ(SeenThread* SeenThread) { _defineThreadQ = SeenThread; }
163
164 PlaceholderEntry* next() const {
165 return (PlaceholderEntry*)HashtableEntry<Symbol*, mtClass>::next();
166 }
167
168 PlaceholderEntry** next_addr() {
169 return (PlaceholderEntry**)HashtableEntry<Symbol*, mtClass>::next_addr();
170 }
171
172 // Test for equality
173 // Entries are unique for class/classloader name pair
174 bool equals(Symbol* class_name, ClassLoaderData* loader) const {
175 return (klassname() == class_name && loader_data() == loader);
176 }
177
178 bool super_load_in_progress() {
179 return (_superThreadQ != NULL);
180 }
181
182 bool instance_load_in_progress() {
183 return (_loadInstanceThreadQ != NULL);
184 }
185
186 bool define_class_in_progress() {
187 return (_defineThreadQ != NULL);
188 }
189
190 // Used for ClassCircularityError checking
191 bool check_seen_thread(JavaThread* thread, PlaceholderTable::classloadAction action);
192
193 // Print method doesn't append a cr
194 void print_entry(outputStream* st) const;
195 void verify() const;
196 };
197
198 #endif // SHARE_CLASSFILE_PLACEHOLDERS_HPP
|
56 ClassLoaderData* loader_data,
57 Symbol* supername);
58
59 // This returns a Symbol* to match type for SystemDictionary
60 Symbol* find_entry(unsigned int hash,
61 Symbol* name, ClassLoaderData* loader_data);
62
63 PlaceholderEntry* get_entry(unsigned int hash,
64 Symbol* name, ClassLoaderData* loader_data);
65
66 // caller to create a placeholder entry must enumerate an action
67 // caller claims ownership of that action
68 // For parallel classloading:
69 // multiple LOAD_INSTANCE threads can proceed in parallel
70 // multiple LOAD_SUPER threads can proceed in parallel
71 // LOAD_SUPER needed to check for class circularity
72 // DEFINE_CLASS: ultimately define class must be single threaded
73 // on a class/classloader basis
74 // so the head of that queue owns the token
75 // and the rest of the threads return the result the first thread gets
76 // PRIMITIVE_OBJECT_FIELD: needed to check for inline type fields circularity
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 PRIMITIVE_OBJECT_FIELD = 4 // primitive object fields
82 };
83
84 // find_and_add returns probe pointer - old or new
85 // If no entry exists, add a placeholder entry and push SeenThread for classloadAction
86 // If entry exists, reuse entry and push SeenThread for classloadAction
87 PlaceholderEntry* find_and_add(unsigned int hash,
88 Symbol* name, ClassLoaderData* loader_data,
89 classloadAction action, Symbol* supername,
90 JavaThread* thread);
91
92 void remove_entry(unsigned int hash,
93 Symbol* name, ClassLoaderData* loader_data);
94
95 // find_and_remove first removes SeenThread for classloadAction
96 // If all queues are empty and definer is null, remove the PlacheholderEntry completely
97 void find_and_remove(unsigned int hash,
98 Symbol* name, ClassLoaderData* loader_data,
99 classloadAction action, JavaThread* thread);
100
101 void print_on(outputStream* st) const;
112 // The system dictionary is the only user of this class.
113
114 class PlaceholderEntry : public HashtableEntry<Symbol*, mtClass> {
115
116 friend class PlaceholderTable;
117
118 private:
119 ClassLoaderData* _loader_data; // initiating loader
120 Symbol* _supername;
121 JavaThread* _definer; // owner of define token
122 InstanceKlass* _instanceKlass; // InstanceKlass from successful define
123 SeenThread* _superThreadQ; // doubly-linked queue of Threads loading a superclass for this class
124 SeenThread* _loadInstanceThreadQ; // loadInstance thread
125 // This can't be multiple threads since class loading waits for
126 // this token to be removed.
127
128 SeenThread* _defineThreadQ; // queue of Threads trying to define this class
129 // including _definer
130 // _definer owns token
131 // queue waits for and returns results from _definer
132 SeenThread* _inlineTypeFieldQ; // queue of inline types for circularity checking
133
134 SeenThread* actionToQueue(PlaceholderTable::classloadAction action);
135 void set_threadQ(SeenThread* seenthread, PlaceholderTable::classloadAction action);
136 void add_seen_thread(JavaThread* thread, PlaceholderTable::classloadAction action);
137 bool remove_seen_thread(JavaThread* thread, PlaceholderTable::classloadAction action);
138
139 public:
140 // Simple accessors, used only by SystemDictionary
141 Symbol* klassname() const { return literal(); }
142
143 ClassLoaderData* loader_data() const { return _loader_data; }
144 void set_loader_data(ClassLoaderData* loader_data) { _loader_data = loader_data; }
145
146 Symbol* supername() const { return _supername; }
147 void set_supername(Symbol* supername) {
148 _supername = supername;
149 if (_supername != NULL) _supername->increment_refcount();
150 }
151
152 JavaThread* definer() const {return _definer; }
153 void set_definer(JavaThread* definer) { _definer = definer; }
154
155 InstanceKlass* instance_klass() const {return _instanceKlass; }
156 void set_instance_klass(InstanceKlass* ik) { _instanceKlass = ik; }
157
158 SeenThread* superThreadQ() const { return _superThreadQ; }
159 void set_superThreadQ(SeenThread* SeenThread) { _superThreadQ = SeenThread; }
160
161 SeenThread* loadInstanceThreadQ() const { return _loadInstanceThreadQ; }
162 void set_loadInstanceThreadQ(SeenThread* SeenThread) { _loadInstanceThreadQ = SeenThread; }
163
164 SeenThread* defineThreadQ() const { return _defineThreadQ; }
165 void set_defineThreadQ(SeenThread* SeenThread) { _defineThreadQ = SeenThread; }
166
167 SeenThread* inlineTypeFieldQ() const { return _inlineTypeFieldQ; }
168 void set_inlineTypeFieldQ(SeenThread* SeenThread) { _inlineTypeFieldQ = SeenThread; }
169
170 PlaceholderEntry* next() const {
171 return (PlaceholderEntry*)HashtableEntry<Symbol*, mtClass>::next();
172 }
173
174 PlaceholderEntry** next_addr() {
175 return (PlaceholderEntry**)HashtableEntry<Symbol*, mtClass>::next_addr();
176 }
177
178 // Test for equality
179 // Entries are unique for class/classloader name pair
180 bool equals(Symbol* class_name, ClassLoaderData* loader) const {
181 return (klassname() == class_name && loader_data() == loader);
182 }
183
184 bool super_load_in_progress() {
185 return (_superThreadQ != NULL);
186 }
187
188 bool instance_load_in_progress() {
189 return (_loadInstanceThreadQ != NULL);
190 }
191
192 bool define_class_in_progress() {
193 return (_defineThreadQ != NULL);
194 }
195
196 bool inline_type_field_in_progress() {
197 return (_inlineTypeFieldQ != NULL);
198 }
199
200 // Used for ClassCircularityError checking
201 bool check_seen_thread(JavaThread* thread, PlaceholderTable::classloadAction action);
202
203 // Print method doesn't append a cr
204 void print_entry(outputStream* st) const;
205 void verify() const;
206 };
207
208 #endif // SHARE_CLASSFILE_PLACEHOLDERS_HPP
|