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->is_loader_alive()) {
103 probe->set_klass(NULL);
104 if (lt.is_enabled()) {
105 ResourceMark rm;
106 lt.print("purging class object from constraint for name %s,"
107 " loader list:",
108 probe->name()->as_C_string());
109 for (int i = 0; i < probe->num_loaders(); i++) {
110 lt.print(" [%d]: %s", i,
111 probe->loader_data(i)->loader_name());
112 }
113 }
114 }
115 // Remove entries no longer alive from loader array
116 int n = 0;
117 while (n < probe->num_loaders()) {
118 if (probe->loader_data(n)->is_unloading()) {
119 if (lt.is_enabled()) {
120 ResourceMark rm;
121 lt.print("purging loader %s from constraint for name %s",
122 probe->loader_data(n)->loader_name(),
123 probe->name()->as_C_string()
124 );
125 }
126
127 // Compact array
128 int num = probe->num_loaders() - 1;
129 probe->set_num_loaders(num);
130 probe->set_loader_data(n, probe->loader_data(num));
131 probe->set_loader_data(num, NULL);
132
133 if (lt.is_enabled()) {
134 ResourceMark rm;
135 lt.print("new loader list:");
136 for (int i = 0; i < probe->num_loaders(); i++) {
137 lt.print(" [%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 (lt.is_enabled()) {
150 ResourceMark rm;
151 lt.print("purging complete constraint for name %s",
152 probe->name()->as_C_string());
153 }
154
155 // Purge entry
156 *p = probe->next();
157 FREE_C_HEAP_ARRAY(oop, probe->loaders());
158 free_entry(probe);
160 #ifdef ASSERT
161 if (probe->klass() != NULL) {
162 assert(probe->klass()->is_loader_alive(), "klass should be live");
163 }
164 #endif
165 // Go to next entry
166 p = probe->next_addr();
167 }
168 }
169 }
170 }
171
172 void log_ldr_constraint_msg(Symbol* class_name, const char* reason,
173 Handle class_loader1, Handle class_loader2) {
174 LogTarget(Info, class, loader, constraints) lt;
175 if (lt.is_enabled()) {
176 ResourceMark rm;
177 lt.print("Failed to add constraint for name: %s, loader[0]: %s,"
178 " loader[1]: %s, Reason: %s",
179 class_name->as_C_string(),
180 SystemDictionary::loader_name(class_loader1()),
181 SystemDictionary::loader_name(class_loader2()),
182 reason);
183 }
184 }
185
186 bool LoaderConstraintTable::add_entry(Symbol* class_name,
187 InstanceKlass* klass1, Handle class_loader1,
188 InstanceKlass* klass2, Handle class_loader2) {
189 LogTarget(Info, class, loader, constraints) lt;
190 if (klass1 != NULL && klass2 != NULL) {
191 if (klass1 == klass2) {
192 // Same type already loaded in both places. There is no need for any constraint.
193 return true;
194 } else {
195 log_ldr_constraint_msg(class_name,
196 "The class objects presented by loader[0] and loader[1] "
197 "are different",
198 class_loader1, class_loader2);
199 return false;
200 }
201 }
230 klass = (*pp2)->klass();
231 }
232 }
233
234 if (*pp1 == NULL && *pp2 == NULL) {
235 unsigned int hash = compute_hash(class_name);
236 int index = hash_to_index(hash);
237 LoaderConstraintEntry* p;
238 p = new_entry(hash, class_name, klass, 2, 2);
239 p->set_loaders(NEW_C_HEAP_ARRAY(ClassLoaderData*, 2, mtClass));
240 p->set_loader(0, class_loader1());
241 p->set_loader(1, class_loader2());
242 p->set_klass(klass);
243 p->set_next(bucket(index));
244 set_entry(index, p);
245 if (lt.is_enabled()) {
246 ResourceMark rm;
247 lt.print("adding new constraint for name: %s, loader[0]: %s,"
248 " loader[1]: %s",
249 class_name->as_C_string(),
250 SystemDictionary::loader_name(class_loader1()),
251 SystemDictionary::loader_name(class_loader2())
252 );
253 }
254 } else if (*pp1 == *pp2) {
255 /* constraint already imposed */
256 if ((*pp1)->klass() == NULL) {
257 (*pp1)->set_klass(klass);
258 if (lt.is_enabled()) {
259 ResourceMark rm;
260 lt.print("setting class object in existing constraint for"
261 " name: %s and loader %s",
262 class_name->as_C_string(),
263 SystemDictionary::loader_name(class_loader1())
264 );
265 }
266 } else {
267 assert((*pp1)->klass() == klass, "loader constraints corrupted");
268 }
269 } else if (*pp1 == NULL) {
270 extend_loader_constraint(*pp2, class_loader1, klass);
271 } else if (*pp2 == NULL) {
272 extend_loader_constraint(*pp1, class_loader2, klass);
273 } else {
274 merge_loader_constraints(pp1, pp2, klass);
275 }
276
277 return true;
278 }
279
280
281 // return true if the constraint was updated, false if the constraint is
282 // violated
283 bool LoaderConstraintTable::check_or_update(InstanceKlass* k,
284 Handle loader,
285 Symbol* name) {
286 LogTarget(Info, class, loader, constraints) lt;
287 LoaderConstraintEntry* p = *(find_loader_constraint(name, loader));
288 if (p && p->klass() != NULL && p->klass() != k) {
289 if (lt.is_enabled()) {
290 ResourceMark rm;
291 lt.print("constraint check failed for name %s, loader %s: "
292 "the presented class object differs from that stored",
293 name->as_C_string(),
294 SystemDictionary::loader_name(loader()));
295 }
296 return false;
297 } else {
298 if (p && p->klass() == NULL) {
299 p->set_klass(k);
300 if (lt.is_enabled()) {
301 ResourceMark rm;
302 lt.print("updating constraint for name %s, loader %s, "
303 "by setting class object",
304 name->as_C_string(),
305 SystemDictionary::loader_name(loader()));
306 }
307 }
308 return true;
309 }
310 }
311
312 InstanceKlass* LoaderConstraintTable::find_constrained_klass(Symbol* name,
313 Handle loader) {
314 LoaderConstraintEntry *p = *(find_loader_constraint(name, loader));
315 if (p != NULL && p->klass() != NULL) {
316 assert(p->klass()->is_instance_klass(), "sanity");
317 if (!p->klass()->is_loaded()) {
318 // Only return fully loaded classes. Classes found through the
319 // constraints might still be in the process of loading.
320 return NULL;
321 }
322 return p->klass();
323 }
324
325 // No constraints, or else no klass loaded yet.
336 p->set_max_loaders(n);
337 FREE_C_HEAP_ARRAY(ClassLoaderData*, p->loaders());
338 p->set_loaders(new_loaders);
339 }
340 }
341
342
343 void LoaderConstraintTable::extend_loader_constraint(LoaderConstraintEntry* p,
344 Handle loader,
345 InstanceKlass* klass) {
346 ensure_loader_constraint_capacity(p, 1);
347 int num = p->num_loaders();
348 p->set_loader(num, loader());
349 p->set_num_loaders(num + 1);
350 LogTarget(Info, class, loader, constraints) lt;
351 if (lt.is_enabled()) {
352 ResourceMark rm;
353 lt.print("extending constraint for name %s by adding loader[%d]: %s %s",
354 p->name()->as_C_string(),
355 num,
356 SystemDictionary::loader_name(loader()),
357 (p->klass() == NULL ? " and setting class object" : "")
358 );
359 }
360 if (p->klass() == NULL) {
361 p->set_klass(klass);
362 } else {
363 assert(klass == NULL || p->klass() == klass, "constraints corrupted");
364 }
365 }
366
367
368 void LoaderConstraintTable::merge_loader_constraints(
369 LoaderConstraintEntry** pp1,
370 LoaderConstraintEntry** pp2,
371 InstanceKlass* klass) {
372 // make sure *pp1 has higher capacity
373 if ((*pp1)->max_loaders() < (*pp2)->max_loaders()) {
374 LoaderConstraintEntry** tmp = pp2;
375 pp2 = pp1;
376 pp1 = tmp;
379 LoaderConstraintEntry* p1 = *pp1;
380 LoaderConstraintEntry* p2 = *pp2;
381
382 ensure_loader_constraint_capacity(p1, p2->num_loaders());
383
384 for (int i = 0; i < p2->num_loaders(); i++) {
385 int num = p1->num_loaders();
386 p1->set_loader_data(num, p2->loader_data(i));
387 p1->set_num_loaders(num + 1);
388 }
389
390 LogTarget(Info, class, loader, constraints) lt;
391 if (lt.is_enabled()) {
392 ResourceMark rm;
393 lt.print("merged constraints for name %s, new loader list:",
394 p1->name()->as_C_string()
395 );
396
397 for (int i = 0; i < p1->num_loaders(); i++) {
398 lt.print(" [%d]: %s", i,
399 p1->loader_data(i)->loader_name());
400 }
401 if (p1->klass() == NULL) {
402 lt.print("... and setting class object");
403 }
404 }
405
406 // p1->klass() will hold NULL if klass, p2->klass(), and old
407 // p1->klass() are all NULL. In addition, all three must have
408 // matching non-NULL values, otherwise either the constraints would
409 // have been violated, or the constraints had been corrupted (and an
410 // assertion would fail).
411 if (p2->klass() != NULL) {
412 assert(p2->klass() == klass, "constraints corrupted");
413 }
414 if (p1->klass() == NULL) {
415 p1->set_klass(klass);
416 } else {
417 assert(p1->klass() == klass, "constraints corrupted");
418 }
419
|
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->is_loader_alive()) {
103 probe->set_klass(NULL);
104 if (lt.is_enabled()) {
105 ResourceMark rm;
106 lt.print("purging class object from constraint for name %s,"
107 " loader list:",
108 probe->name()->as_C_string());
109 for (int i = 0; i < probe->num_loaders(); i++) {
110 lt.print(" [%d]: %s", i,
111 probe->loader_data(i)->loader_name_and_id());
112 }
113 }
114 }
115 // Remove entries no longer alive from loader array
116 int n = 0;
117 while (n < probe->num_loaders()) {
118 if (probe->loader_data(n)->is_unloading()) {
119 if (lt.is_enabled()) {
120 ResourceMark rm;
121 lt.print("purging loader %s from constraint for name %s",
122 probe->loader_data(n)->loader_name_and_id(),
123 probe->name()->as_C_string()
124 );
125 }
126
127 // Compact array
128 int num = probe->num_loaders() - 1;
129 probe->set_num_loaders(num);
130 probe->set_loader_data(n, probe->loader_data(num));
131 probe->set_loader_data(num, NULL);
132
133 if (lt.is_enabled()) {
134 ResourceMark rm;
135 lt.print("new loader list:");
136 for (int i = 0; i < probe->num_loaders(); i++) {
137 lt.print(" [%d]: %s", i,
138 probe->loader_data(i)->loader_name_and_id());
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 (lt.is_enabled()) {
150 ResourceMark rm;
151 lt.print("purging complete constraint for name %s",
152 probe->name()->as_C_string());
153 }
154
155 // Purge entry
156 *p = probe->next();
157 FREE_C_HEAP_ARRAY(oop, probe->loaders());
158 free_entry(probe);
160 #ifdef ASSERT
161 if (probe->klass() != NULL) {
162 assert(probe->klass()->is_loader_alive(), "klass should be live");
163 }
164 #endif
165 // Go to next entry
166 p = probe->next_addr();
167 }
168 }
169 }
170 }
171
172 void log_ldr_constraint_msg(Symbol* class_name, const char* reason,
173 Handle class_loader1, Handle class_loader2) {
174 LogTarget(Info, class, loader, constraints) lt;
175 if (lt.is_enabled()) {
176 ResourceMark rm;
177 lt.print("Failed to add constraint for name: %s, loader[0]: %s,"
178 " loader[1]: %s, Reason: %s",
179 class_name->as_C_string(),
180 ClassLoaderData::class_loader_data(class_loader1())->loader_name_and_id(),
181 ClassLoaderData::class_loader_data(class_loader2())->loader_name_and_id(),
182 reason);
183 }
184 }
185
186 bool LoaderConstraintTable::add_entry(Symbol* class_name,
187 InstanceKlass* klass1, Handle class_loader1,
188 InstanceKlass* klass2, Handle class_loader2) {
189 LogTarget(Info, class, loader, constraints) lt;
190 if (klass1 != NULL && klass2 != NULL) {
191 if (klass1 == klass2) {
192 // Same type already loaded in both places. There is no need for any constraint.
193 return true;
194 } else {
195 log_ldr_constraint_msg(class_name,
196 "The class objects presented by loader[0] and loader[1] "
197 "are different",
198 class_loader1, class_loader2);
199 return false;
200 }
201 }
230 klass = (*pp2)->klass();
231 }
232 }
233
234 if (*pp1 == NULL && *pp2 == NULL) {
235 unsigned int hash = compute_hash(class_name);
236 int index = hash_to_index(hash);
237 LoaderConstraintEntry* p;
238 p = new_entry(hash, class_name, klass, 2, 2);
239 p->set_loaders(NEW_C_HEAP_ARRAY(ClassLoaderData*, 2, mtClass));
240 p->set_loader(0, class_loader1());
241 p->set_loader(1, class_loader2());
242 p->set_klass(klass);
243 p->set_next(bucket(index));
244 set_entry(index, p);
245 if (lt.is_enabled()) {
246 ResourceMark rm;
247 lt.print("adding new constraint for name: %s, loader[0]: %s,"
248 " loader[1]: %s",
249 class_name->as_C_string(),
250 ClassLoaderData::class_loader_data(class_loader1())->loader_name_and_id(),
251 ClassLoaderData::class_loader_data(class_loader2())->loader_name_and_id()
252 );
253 }
254 } else if (*pp1 == *pp2) {
255 /* constraint already imposed */
256 if ((*pp1)->klass() == NULL) {
257 (*pp1)->set_klass(klass);
258 if (lt.is_enabled()) {
259 ResourceMark rm;
260 lt.print("setting class object in existing constraint for"
261 " name: %s and loader %s",
262 class_name->as_C_string(),
263 ClassLoaderData::class_loader_data(class_loader1())->loader_name_and_id()
264 );
265 }
266 } else {
267 assert((*pp1)->klass() == klass, "loader constraints corrupted");
268 }
269 } else if (*pp1 == NULL) {
270 extend_loader_constraint(*pp2, class_loader1, klass);
271 } else if (*pp2 == NULL) {
272 extend_loader_constraint(*pp1, class_loader2, klass);
273 } else {
274 merge_loader_constraints(pp1, pp2, klass);
275 }
276
277 return true;
278 }
279
280
281 // return true if the constraint was updated, false if the constraint is
282 // violated
283 bool LoaderConstraintTable::check_or_update(InstanceKlass* k,
284 Handle loader,
285 Symbol* name) {
286 LogTarget(Info, class, loader, constraints) lt;
287 LoaderConstraintEntry* p = *(find_loader_constraint(name, loader));
288 if (p && p->klass() != NULL && p->klass() != k) {
289 if (lt.is_enabled()) {
290 ResourceMark rm;
291 lt.print("constraint check failed for name %s, loader %s: "
292 "the presented class object differs from that stored",
293 name->as_C_string(),
294 ClassLoaderData::class_loader_data(loader())->loader_name_and_id());
295 }
296 return false;
297 } else {
298 if (p && p->klass() == NULL) {
299 p->set_klass(k);
300 if (lt.is_enabled()) {
301 ResourceMark rm;
302 lt.print("updating constraint for name %s, loader %s, "
303 "by setting class object",
304 name->as_C_string(),
305 ClassLoaderData::class_loader_data(loader())->loader_name_and_id());
306 }
307 }
308 return true;
309 }
310 }
311
312 InstanceKlass* LoaderConstraintTable::find_constrained_klass(Symbol* name,
313 Handle loader) {
314 LoaderConstraintEntry *p = *(find_loader_constraint(name, loader));
315 if (p != NULL && p->klass() != NULL) {
316 assert(p->klass()->is_instance_klass(), "sanity");
317 if (!p->klass()->is_loaded()) {
318 // Only return fully loaded classes. Classes found through the
319 // constraints might still be in the process of loading.
320 return NULL;
321 }
322 return p->klass();
323 }
324
325 // No constraints, or else no klass loaded yet.
336 p->set_max_loaders(n);
337 FREE_C_HEAP_ARRAY(ClassLoaderData*, p->loaders());
338 p->set_loaders(new_loaders);
339 }
340 }
341
342
343 void LoaderConstraintTable::extend_loader_constraint(LoaderConstraintEntry* p,
344 Handle loader,
345 InstanceKlass* klass) {
346 ensure_loader_constraint_capacity(p, 1);
347 int num = p->num_loaders();
348 p->set_loader(num, loader());
349 p->set_num_loaders(num + 1);
350 LogTarget(Info, class, loader, constraints) lt;
351 if (lt.is_enabled()) {
352 ResourceMark rm;
353 lt.print("extending constraint for name %s by adding loader[%d]: %s %s",
354 p->name()->as_C_string(),
355 num,
356 ClassLoaderData::class_loader_data(loader())->loader_name_and_id(),
357 (p->klass() == NULL ? " and setting class object" : "")
358 );
359 }
360 if (p->klass() == NULL) {
361 p->set_klass(klass);
362 } else {
363 assert(klass == NULL || p->klass() == klass, "constraints corrupted");
364 }
365 }
366
367
368 void LoaderConstraintTable::merge_loader_constraints(
369 LoaderConstraintEntry** pp1,
370 LoaderConstraintEntry** pp2,
371 InstanceKlass* klass) {
372 // make sure *pp1 has higher capacity
373 if ((*pp1)->max_loaders() < (*pp2)->max_loaders()) {
374 LoaderConstraintEntry** tmp = pp2;
375 pp2 = pp1;
376 pp1 = tmp;
379 LoaderConstraintEntry* p1 = *pp1;
380 LoaderConstraintEntry* p2 = *pp2;
381
382 ensure_loader_constraint_capacity(p1, p2->num_loaders());
383
384 for (int i = 0; i < p2->num_loaders(); i++) {
385 int num = p1->num_loaders();
386 p1->set_loader_data(num, p2->loader_data(i));
387 p1->set_num_loaders(num + 1);
388 }
389
390 LogTarget(Info, class, loader, constraints) lt;
391 if (lt.is_enabled()) {
392 ResourceMark rm;
393 lt.print("merged constraints for name %s, new loader list:",
394 p1->name()->as_C_string()
395 );
396
397 for (int i = 0; i < p1->num_loaders(); i++) {
398 lt.print(" [%d]: %s", i,
399 p1->loader_data(i)->loader_name_and_id());
400 }
401 if (p1->klass() == NULL) {
402 lt.print("... and setting class object");
403 }
404 }
405
406 // p1->klass() will hold NULL if klass, p2->klass(), and old
407 // p1->klass() are all NULL. In addition, all three must have
408 // matching non-NULL values, otherwise either the constraints would
409 // have been violated, or the constraints had been corrupted (and an
410 // assertion would fail).
411 if (p2->klass() != NULL) {
412 assert(p2->klass() == klass, "constraints corrupted");
413 }
414 if (p1->klass() == NULL) {
415 p1->set_klass(klass);
416 } else {
417 assert(p1->klass() == klass, "constraints corrupted");
418 }
419
|