8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/classLoaderData.inline.hpp"
27 #include "classfile/loaderConstraints.hpp"
28 #include "memory/resourceArea.hpp"
29 #include "oops/oop.inline.hpp"
30 #include "runtime/handles.inline.hpp"
31 #include "runtime/safepoint.hpp"
32 #include "utilities/hashtable.inline.hpp"
33
34 void LoaderConstraintEntry::set_loader(int i, oop p) {
35 set_loader_data(i, ClassLoaderData::class_loader_data(p));
36 }
37
38 LoaderConstraintTable::LoaderConstraintTable(int nof_buckets)
39 : Hashtable<InstanceKlass*, mtClass>(nof_buckets, sizeof(LoaderConstraintEntry)) {};
40
41
42 LoaderConstraintEntry* LoaderConstraintTable::new_entry(
43 unsigned int hash, Symbol* name,
44 InstanceKlass* klass, int num_loaders,
45 int max_loaders) {
46 LoaderConstraintEntry* entry;
47 entry = (LoaderConstraintEntry*)Hashtable<InstanceKlass*, mtClass>::new_entry(hash, klass);
71
72 while (*pp) {
73 LoaderConstraintEntry* p = *pp;
74 if (p->hash() == hash) {
75 if (p->name() == name) {
76 for (int i = p->num_loaders() - 1; i >= 0; i--) {
77 if (p->loader_data(i) == loader_data) {
78 return pp;
79 }
80 }
81 }
82 }
83 pp = p->next_addr();
84 }
85 return pp;
86 }
87
88
89 void LoaderConstraintTable::purge_loader_constraints() {
90 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
91 // Remove unloaded entries from constraint table
92 for (int index = 0; index < table_size(); index++) {
93 LoaderConstraintEntry** p = bucket_addr(index);
94 while(*p) {
95 LoaderConstraintEntry* probe = *p;
96 InstanceKlass* klass = probe->klass();
97 // Remove klass that is no longer alive
98 if (klass != NULL &&
99 klass->class_loader_data()->is_unloading()) {
100 probe->set_klass(NULL);
101 if (log_is_enabled(Info, class, loader, constraints)) {
102 ResourceMark rm;
103 outputStream* out = Log(class, loader, constraints)::info_stream();
104 out->print_cr("purging class object from constraint for name %s,"
105 " loader list:",
106 probe->name()->as_C_string());
107 for (int i = 0; i < probe->num_loaders(); i++) {
108 out->print_cr(" [%d]: %s", i,
109 probe->loader_data(i)->loader_name());
110 }
111 }
112 }
113 // Remove entries no longer alive from loader array
114 int n = 0;
115 while (n < probe->num_loaders()) {
116 if (probe->loader_data(n)->is_unloading()) {
117 if (log_is_enabled(Info, class, loader, constraints)) {
118 ResourceMark rm;
119 outputStream* out = Log(class, loader, constraints)::info_stream();
120 out->print_cr("purging loader %s from constraint for name %s",
121 probe->loader_data(n)->loader_name(),
122 probe->name()->as_C_string()
123 );
124 }
125
126 // Compact array
127 int num = probe->num_loaders() - 1;
128 probe->set_num_loaders(num);
129 probe->set_loader_data(n, probe->loader_data(num));
130 probe->set_loader_data(num, NULL);
131
132 if (log_is_enabled(Info, class, loader, constraints)) {
133 ResourceMark rm;
134 outputStream* out = Log(class, loader, constraints)::info_stream();
135 out->print_cr("new loader list:");
136 for (int i = 0; i < probe->num_loaders(); i++) {
137 out->print_cr(" [%d]: %s", i,
138 probe->loader_data(i)->loader_name());
139 }
140 }
141
142 continue; // current element replaced, so restart without
143 // incrementing n
144 }
145 n++;
146 }
147 // Check whether entry should be purged
148 if (probe->num_loaders() < 2) {
149 if (log_is_enabled(Info, class, loader, constraints)) {
150 ResourceMark rm;
151 outputStream* out = Log(class, loader, constraints)::info_stream();
152 out->print_cr("purging complete constraint for name %s",
153 probe->name()->as_C_string());
154 }
155
156 // Purge entry
157 *p = probe->next();
158 FREE_C_HEAP_ARRAY(oop, probe->loaders());
159 free_entry(probe);
160 } else {
161 #ifdef ASSERT
162 if (probe->klass() != NULL) {
163 ClassLoaderData* loader_data =
164 probe->klass()->class_loader_data();
165 assert(!loader_data->is_unloading(), "klass should be live");
166 }
167 #endif
168 // Go to next entry
169 p = probe->next_addr();
170 }
171 }
172 }
173 }
174
175 void log_ldr_constraint_msg(Symbol* class_name, const char* reason,
176 Handle class_loader1, Handle class_loader2) {
177 if (log_is_enabled(Info, class, loader, constraints)) {
178 ResourceMark rm;
179 outputStream* out = Log(class, loader, constraints)::info_stream();
180 out->print_cr("Failed to add constraint for name: %s, loader[0]: %s,"
181 " loader[1]: %s, Reason: %s",
182 class_name->as_C_string(),
183 SystemDictionary::loader_name(class_loader1()),
184 SystemDictionary::loader_name(class_loader2()),
185 reason);
186 }
187 }
188
189 bool LoaderConstraintTable::add_entry(Symbol* class_name,
190 InstanceKlass* klass1, Handle class_loader1,
191 InstanceKlass* klass2, Handle class_loader2) {
192 if (klass1 != NULL && klass2 != NULL) {
193 if (klass1 == klass2) {
194 // Same type already loaded in both places. There is no need for any constraint.
195 return true;
196 } else {
197 log_ldr_constraint_msg(class_name,
198 "The class objects presented by loader[0] and loader[1] "
199 "are different",
200 class_loader1, class_loader2);
201 return false;
202 }
203 }
204
205 InstanceKlass* klass = klass1 != NULL ? klass1 : klass2;
206 LoaderConstraintEntry** pp1 = find_loader_constraint(class_name, class_loader1);
207 if (*pp1 != NULL && (*pp1)->klass() != NULL) {
208 if (klass != NULL) {
209 if (klass != (*pp1)->klass()) {
210 log_ldr_constraint_msg(class_name,
211 "The class object presented by loader[0] does not match "
227 "the stored class object in the constraint",
228 class_loader1, class_loader2);
229 return false;
230 }
231 } else {
232 klass = (*pp2)->klass();
233 }
234 }
235
236 if (*pp1 == NULL && *pp2 == NULL) {
237 unsigned int hash = compute_hash(class_name);
238 int index = hash_to_index(hash);
239 LoaderConstraintEntry* p;
240 p = new_entry(hash, class_name, klass, 2, 2);
241 p->set_loaders(NEW_C_HEAP_ARRAY(ClassLoaderData*, 2, mtClass));
242 p->set_loader(0, class_loader1());
243 p->set_loader(1, class_loader2());
244 p->set_klass(klass);
245 p->set_next(bucket(index));
246 set_entry(index, p);
247 if (log_is_enabled(Info, class, loader, constraints)) {
248 ResourceMark rm;
249 outputStream* out = Log(class, loader, constraints)::info_stream();
250 out->print_cr("adding new constraint for name: %s, loader[0]: %s,"
251 " loader[1]: %s",
252 class_name->as_C_string(),
253 SystemDictionary::loader_name(class_loader1()),
254 SystemDictionary::loader_name(class_loader2())
255 );
256 }
257 } else if (*pp1 == *pp2) {
258 /* constraint already imposed */
259 if ((*pp1)->klass() == NULL) {
260 (*pp1)->set_klass(klass);
261 if (log_is_enabled(Info, class, loader, constraints)) {
262 ResourceMark rm;
263 outputStream* out = Log(class, loader, constraints)::info_stream();
264 out->print_cr("setting class object in existing constraint for"
265 " name: %s and loader %s",
266 class_name->as_C_string(),
267 SystemDictionary::loader_name(class_loader1())
268 );
269 }
270 } else {
271 assert((*pp1)->klass() == klass, "loader constraints corrupted");
272 }
273 } else if (*pp1 == NULL) {
274 extend_loader_constraint(*pp2, class_loader1, klass);
275 } else if (*pp2 == NULL) {
276 extend_loader_constraint(*pp1, class_loader2, klass);
277 } else {
278 merge_loader_constraints(pp1, pp2, klass);
279 }
280
281 return true;
282 }
283
284
285 // return true if the constraint was updated, false if the constraint is
286 // violated
287 bool LoaderConstraintTable::check_or_update(InstanceKlass* k,
288 Handle loader,
289 Symbol* name) {
290 LoaderConstraintEntry* p = *(find_loader_constraint(name, loader));
291 if (p && p->klass() != NULL && p->klass() != k) {
292 if (log_is_enabled(Info, class, loader, constraints)) {
293 ResourceMark rm;
294 outputStream* out = Log(class, loader, constraints)::info_stream();
295 out->print_cr("constraint check failed for name %s, loader %s: "
296 "the presented class object differs from that stored",
297 name->as_C_string(),
298 SystemDictionary::loader_name(loader()));
299 }
300 return false;
301 } else {
302 if (p && p->klass() == NULL) {
303 p->set_klass(k);
304 if (log_is_enabled(Info, class, loader, constraints)) {
305 ResourceMark rm;
306 outputStream* out = Log(class, loader, constraints)::info_stream();
307 out->print_cr("updating constraint for name %s, loader %s, "
308 "by setting class object",
309 name->as_C_string(),
310 SystemDictionary::loader_name(loader()));
311 }
312 }
313 return true;
314 }
315 }
316
317 InstanceKlass* LoaderConstraintTable::find_constrained_klass(Symbol* name,
318 Handle loader) {
319 LoaderConstraintEntry *p = *(find_loader_constraint(name, loader));
320 if (p != NULL && p->klass() != NULL) {
321 assert(p->klass()->is_instance_klass(), "sanity");
322 if (p->klass()->is_loaded()) {
323 // Only return fully loaded classes. Classes found through the
324 // constraints might still be in the process of loading.
325 return NULL;
326 }
327 return p->klass();
335 LoaderConstraintEntry *p,
336 int nfree) {
337 if (p->max_loaders() - p->num_loaders() < nfree) {
338 int n = nfree + p->num_loaders();
339 ClassLoaderData** new_loaders = NEW_C_HEAP_ARRAY(ClassLoaderData*, n, mtClass);
340 memcpy(new_loaders, p->loaders(), sizeof(ClassLoaderData*) * p->num_loaders());
341 p->set_max_loaders(n);
342 FREE_C_HEAP_ARRAY(ClassLoaderData*, p->loaders());
343 p->set_loaders(new_loaders);
344 }
345 }
346
347
348 void LoaderConstraintTable::extend_loader_constraint(LoaderConstraintEntry* p,
349 Handle loader,
350 InstanceKlass* klass) {
351 ensure_loader_constraint_capacity(p, 1);
352 int num = p->num_loaders();
353 p->set_loader(num, loader());
354 p->set_num_loaders(num + 1);
355 if (log_is_enabled(Info, class, loader, constraints)) {
356 ResourceMark rm;
357 outputStream* out = Log(class, loader, constraints)::info_stream();
358 out->print_cr("extending constraint for name %s by adding loader[%d]: %s %s",
359 p->name()->as_C_string(),
360 num,
361 SystemDictionary::loader_name(loader()),
362 (p->klass() == NULL ? " and setting class object" : "")
363 );
364 }
365 if (p->klass() == NULL) {
366 p->set_klass(klass);
367 } else {
368 assert(klass == NULL || p->klass() == klass, "constraints corrupted");
369 }
370 }
371
372
373 void LoaderConstraintTable::merge_loader_constraints(
374 LoaderConstraintEntry** pp1,
375 LoaderConstraintEntry** pp2,
376 InstanceKlass* klass) {
377 // make sure *pp1 has higher capacity
378 if ((*pp1)->max_loaders() < (*pp2)->max_loaders()) {
379 LoaderConstraintEntry** tmp = pp2;
380 pp2 = pp1;
381 pp1 = tmp;
382 }
383
384 LoaderConstraintEntry* p1 = *pp1;
385 LoaderConstraintEntry* p2 = *pp2;
386
387 ensure_loader_constraint_capacity(p1, p2->num_loaders());
388
389 for (int i = 0; i < p2->num_loaders(); i++) {
390 int num = p1->num_loaders();
391 p1->set_loader_data(num, p2->loader_data(i));
392 p1->set_num_loaders(num + 1);
393 }
394
395 if (log_is_enabled(Info, class, loader, constraints)) {
396 ResourceMark rm;
397 outputStream* out = Log(class, loader, constraints)::info_stream();
398 out->print_cr("merged constraints for name %s, new loader list:",
399 p1->name()->as_C_string()
400 );
401
402 for (int i = 0; i < p1->num_loaders(); i++) {
403 out->print_cr(" [%d]: %s", i,
404 p1->loader_data(i)->loader_name());
405 }
406 if (p1->klass() == NULL) {
407 out->print_cr("... and setting class object");
408 }
409 }
410
411 // p1->klass() will hold NULL if klass, p2->klass(), and old
412 // p1->klass() are all NULL. In addition, all three must have
413 // matching non-NULL values, otherwise either the constraints would
414 // have been violated, or the constraints had been corrupted (and an
415 // assertion would fail).
416 if (p2->klass() != NULL) {
417 assert(p2->klass() == klass, "constraints corrupted");
418 }
419 if (p1->klass() == NULL) {
420 p1->set_klass(klass);
421 } else {
422 assert(p1->klass() == klass, "constraints corrupted");
423 }
424
425 *pp2 = p2->next();
426 FREE_C_HEAP_ARRAY(oop, p2->loaders());
427 free_entry(p2);
|
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/classLoaderData.inline.hpp"
27 #include "classfile/loaderConstraints.hpp"
28 #include "logging/log.hpp"
29 #include "logging/logStream.hpp"
30 #include "memory/resourceArea.hpp"
31 #include "oops/oop.inline.hpp"
32 #include "runtime/handles.inline.hpp"
33 #include "runtime/safepoint.hpp"
34 #include "utilities/hashtable.inline.hpp"
35
36 void LoaderConstraintEntry::set_loader(int i, oop p) {
37 set_loader_data(i, ClassLoaderData::class_loader_data(p));
38 }
39
40 LoaderConstraintTable::LoaderConstraintTable(int nof_buckets)
41 : Hashtable<InstanceKlass*, mtClass>(nof_buckets, sizeof(LoaderConstraintEntry)) {};
42
43
44 LoaderConstraintEntry* LoaderConstraintTable::new_entry(
45 unsigned int hash, Symbol* name,
46 InstanceKlass* klass, int num_loaders,
47 int max_loaders) {
48 LoaderConstraintEntry* entry;
49 entry = (LoaderConstraintEntry*)Hashtable<InstanceKlass*, mtClass>::new_entry(hash, klass);
73
74 while (*pp) {
75 LoaderConstraintEntry* p = *pp;
76 if (p->hash() == hash) {
77 if (p->name() == name) {
78 for (int i = p->num_loaders() - 1; i >= 0; i--) {
79 if (p->loader_data(i) == loader_data) {
80 return pp;
81 }
82 }
83 }
84 }
85 pp = p->next_addr();
86 }
87 return pp;
88 }
89
90
91 void LoaderConstraintTable::purge_loader_constraints() {
92 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
93 LogTarget(Info, class, loader, constraints) lt;
94 // Remove unloaded entries from constraint table
95 for (int index = 0; index < table_size(); index++) {
96 LoaderConstraintEntry** p = bucket_addr(index);
97 while(*p) {
98 LoaderConstraintEntry* probe = *p;
99 InstanceKlass* klass = probe->klass();
100 // Remove klass that is no longer alive
101 if (klass != NULL &&
102 klass->class_loader_data()->is_unloading()) {
103 probe->set_klass(NULL);
104 if (lt.is_enabled()) {
105 ResourceMark rm;
106 LogStream ls(lt);
107 ls.print_cr("purging class object from constraint for name %s,"
108 " loader list:",
109 probe->name()->as_C_string());
110 for (int i = 0; i < probe->num_loaders(); i++) {
111 ls.print_cr(" [%d]: %s", i,
112 probe->loader_data(i)->loader_name());
113 }
114 }
115 }
116 // Remove entries no longer alive from loader array
117 int n = 0;
118 while (n < probe->num_loaders()) {
119 if (probe->loader_data(n)->is_unloading()) {
120 if (lt.is_enabled()) {
121 ResourceMark rm;
122 LogStream ls(lt);
123 ls.print_cr("purging loader %s from constraint for name %s",
124 probe->loader_data(n)->loader_name(),
125 probe->name()->as_C_string()
126 );
127 }
128
129 // Compact array
130 int num = probe->num_loaders() - 1;
131 probe->set_num_loaders(num);
132 probe->set_loader_data(n, probe->loader_data(num));
133 probe->set_loader_data(num, NULL);
134
135 if (lt.is_enabled()) {
136 ResourceMark rm;
137 LogStream ls(lt);
138 ls.print_cr("new loader list:");
139 for (int i = 0; i < probe->num_loaders(); i++) {
140 ls.print_cr(" [%d]: %s", i,
141 probe->loader_data(i)->loader_name());
142 }
143 }
144
145 continue; // current element replaced, so restart without
146 // incrementing n
147 }
148 n++;
149 }
150 // Check whether entry should be purged
151 if (probe->num_loaders() < 2) {
152 if (lt.is_enabled()) {
153 ResourceMark rm;
154 LogStream(lt).print_cr("purging complete constraint for name %s",
155 probe->name()->as_C_string());
156 }
157
158 // Purge entry
159 *p = probe->next();
160 FREE_C_HEAP_ARRAY(oop, probe->loaders());
161 free_entry(probe);
162 } else {
163 #ifdef ASSERT
164 if (probe->klass() != NULL) {
165 ClassLoaderData* loader_data =
166 probe->klass()->class_loader_data();
167 assert(!loader_data->is_unloading(), "klass should be live");
168 }
169 #endif
170 // Go to next entry
171 p = probe->next_addr();
172 }
173 }
174 }
175 }
176
177 void log_ldr_constraint_msg(Symbol* class_name, const char* reason,
178 Handle class_loader1, Handle class_loader2) {
179 LogTarget(Info, class, loader, constraints) lt;
180 if (lt.is_enabled()) {
181 ResourceMark rm;
182 lt.print("Failed to add constraint for name: %s, loader[0]: %s,"
183 " loader[1]: %s, Reason: %s",
184 class_name->as_C_string(),
185 SystemDictionary::loader_name(class_loader1()),
186 SystemDictionary::loader_name(class_loader2()),
187 reason);
188 }
189 }
190
191 bool LoaderConstraintTable::add_entry(Symbol* class_name,
192 InstanceKlass* klass1, Handle class_loader1,
193 InstanceKlass* klass2, Handle class_loader2) {
194 LogTarget(Info, class, loader, constraints) lt;
195 if (klass1 != NULL && klass2 != NULL) {
196 if (klass1 == klass2) {
197 // Same type already loaded in both places. There is no need for any constraint.
198 return true;
199 } else {
200 log_ldr_constraint_msg(class_name,
201 "The class objects presented by loader[0] and loader[1] "
202 "are different",
203 class_loader1, class_loader2);
204 return false;
205 }
206 }
207
208 InstanceKlass* klass = klass1 != NULL ? klass1 : klass2;
209 LoaderConstraintEntry** pp1 = find_loader_constraint(class_name, class_loader1);
210 if (*pp1 != NULL && (*pp1)->klass() != NULL) {
211 if (klass != NULL) {
212 if (klass != (*pp1)->klass()) {
213 log_ldr_constraint_msg(class_name,
214 "The class object presented by loader[0] does not match "
230 "the stored class object in the constraint",
231 class_loader1, class_loader2);
232 return false;
233 }
234 } else {
235 klass = (*pp2)->klass();
236 }
237 }
238
239 if (*pp1 == NULL && *pp2 == NULL) {
240 unsigned int hash = compute_hash(class_name);
241 int index = hash_to_index(hash);
242 LoaderConstraintEntry* p;
243 p = new_entry(hash, class_name, klass, 2, 2);
244 p->set_loaders(NEW_C_HEAP_ARRAY(ClassLoaderData*, 2, mtClass));
245 p->set_loader(0, class_loader1());
246 p->set_loader(1, class_loader2());
247 p->set_klass(klass);
248 p->set_next(bucket(index));
249 set_entry(index, p);
250 if (lt.is_enabled()) {
251 ResourceMark rm;
252 LogStream ls(lt);
253 ls.print_cr("adding new constraint for name: %s, loader[0]: %s,"
254 " loader[1]: %s",
255 class_name->as_C_string(),
256 SystemDictionary::loader_name(class_loader1()),
257 SystemDictionary::loader_name(class_loader2())
258 );
259 }
260 } else if (*pp1 == *pp2) {
261 /* constraint already imposed */
262 if ((*pp1)->klass() == NULL) {
263 (*pp1)->set_klass(klass);
264 if (lt.is_enabled()) {
265 ResourceMark rm;
266 LogStream ls(lt);
267 ls.print_cr("setting class object in existing constraint for"
268 " name: %s and loader %s",
269 class_name->as_C_string(),
270 SystemDictionary::loader_name(class_loader1())
271 );
272 }
273 } else {
274 assert((*pp1)->klass() == klass, "loader constraints corrupted");
275 }
276 } else if (*pp1 == NULL) {
277 extend_loader_constraint(*pp2, class_loader1, klass);
278 } else if (*pp2 == NULL) {
279 extend_loader_constraint(*pp1, class_loader2, klass);
280 } else {
281 merge_loader_constraints(pp1, pp2, klass);
282 }
283
284 return true;
285 }
286
287
288 // return true if the constraint was updated, false if the constraint is
289 // violated
290 bool LoaderConstraintTable::check_or_update(InstanceKlass* k,
291 Handle loader,
292 Symbol* name) {
293 LogTarget(Info, class, loader, constraints) lt;
294 LoaderConstraintEntry* p = *(find_loader_constraint(name, loader));
295 if (p && p->klass() != NULL && p->klass() != k) {
296 if (lt.is_enabled()) {
297 ResourceMark rm;
298 LogStream ls(lt);
299 ls.print_cr("constraint check failed for name %s, loader %s: "
300 "the presented class object differs from that stored",
301 name->as_C_string(),
302 SystemDictionary::loader_name(loader()));
303 }
304 return false;
305 } else {
306 if (p && p->klass() == NULL) {
307 p->set_klass(k);
308 if (lt.is_enabled()) {
309 ResourceMark rm;
310 LogStream ls(lt);
311 ls.print_cr("updating constraint for name %s, loader %s, "
312 "by setting class object",
313 name->as_C_string(),
314 SystemDictionary::loader_name(loader()));
315 }
316 }
317 return true;
318 }
319 }
320
321 InstanceKlass* LoaderConstraintTable::find_constrained_klass(Symbol* name,
322 Handle loader) {
323 LoaderConstraintEntry *p = *(find_loader_constraint(name, loader));
324 if (p != NULL && p->klass() != NULL) {
325 assert(p->klass()->is_instance_klass(), "sanity");
326 if (p->klass()->is_loaded()) {
327 // Only return fully loaded classes. Classes found through the
328 // constraints might still be in the process of loading.
329 return NULL;
330 }
331 return p->klass();
339 LoaderConstraintEntry *p,
340 int nfree) {
341 if (p->max_loaders() - p->num_loaders() < nfree) {
342 int n = nfree + p->num_loaders();
343 ClassLoaderData** new_loaders = NEW_C_HEAP_ARRAY(ClassLoaderData*, n, mtClass);
344 memcpy(new_loaders, p->loaders(), sizeof(ClassLoaderData*) * p->num_loaders());
345 p->set_max_loaders(n);
346 FREE_C_HEAP_ARRAY(ClassLoaderData*, p->loaders());
347 p->set_loaders(new_loaders);
348 }
349 }
350
351
352 void LoaderConstraintTable::extend_loader_constraint(LoaderConstraintEntry* p,
353 Handle loader,
354 InstanceKlass* klass) {
355 ensure_loader_constraint_capacity(p, 1);
356 int num = p->num_loaders();
357 p->set_loader(num, loader());
358 p->set_num_loaders(num + 1);
359 LogTarget(Info, class, loader, constraints) lt;
360 if (lt.is_enabled()) {
361 ResourceMark rm;
362 LogStream ls(lt);
363 ls.print_cr("extending constraint for name %s by adding loader[%d]: %s %s",
364 p->name()->as_C_string(),
365 num,
366 SystemDictionary::loader_name(loader()),
367 (p->klass() == NULL ? " and setting class object" : "")
368 );
369 }
370 if (p->klass() == NULL) {
371 p->set_klass(klass);
372 } else {
373 assert(klass == NULL || p->klass() == klass, "constraints corrupted");
374 }
375 }
376
377
378 void LoaderConstraintTable::merge_loader_constraints(
379 LoaderConstraintEntry** pp1,
380 LoaderConstraintEntry** pp2,
381 InstanceKlass* klass) {
382 // make sure *pp1 has higher capacity
383 if ((*pp1)->max_loaders() < (*pp2)->max_loaders()) {
384 LoaderConstraintEntry** tmp = pp2;
385 pp2 = pp1;
386 pp1 = tmp;
387 }
388
389 LoaderConstraintEntry* p1 = *pp1;
390 LoaderConstraintEntry* p2 = *pp2;
391
392 ensure_loader_constraint_capacity(p1, p2->num_loaders());
393
394 for (int i = 0; i < p2->num_loaders(); i++) {
395 int num = p1->num_loaders();
396 p1->set_loader_data(num, p2->loader_data(i));
397 p1->set_num_loaders(num + 1);
398 }
399
400 LogTarget(Info, class, loader, constraints) lt;
401 if (lt.is_enabled()) {
402 ResourceMark rm;
403 LogStream ls(lt);
404 ls.print_cr("merged constraints for name %s, new loader list:",
405 p1->name()->as_C_string()
406 );
407
408 for (int i = 0; i < p1->num_loaders(); i++) {
409 ls.print_cr(" [%d]: %s", i,
410 p1->loader_data(i)->loader_name());
411 }
412 if (p1->klass() == NULL) {
413 ls.print_cr("... and setting class object");
414 }
415 }
416
417 // p1->klass() will hold NULL if klass, p2->klass(), and old
418 // p1->klass() are all NULL. In addition, all three must have
419 // matching non-NULL values, otherwise either the constraints would
420 // have been violated, or the constraints had been corrupted (and an
421 // assertion would fail).
422 if (p2->klass() != NULL) {
423 assert(p2->klass() == klass, "constraints corrupted");
424 }
425 if (p1->klass() == NULL) {
426 p1->set_klass(klass);
427 } else {
428 assert(p1->klass() == klass, "constraints corrupted");
429 }
430
431 *pp2 = p2->next();
432 FREE_C_HEAP_ARRAY(oop, p2->loaders());
433 free_entry(p2);
|