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 "memory/resourceArea.hpp"
30 #include "oops/oop.inline.hpp"
31 #include "runtime/handles.inline.hpp"
32 #include "runtime/safepoint.hpp"
33 #include "utilities/hashtable.inline.hpp"
34
35 void LoaderConstraintEntry::set_loader(int i, oop p) {
36 set_loader_data(i, ClassLoaderData::class_loader_data(p));
37 }
38
39 LoaderConstraintTable::LoaderConstraintTable(int nof_buckets)
40 : Hashtable<InstanceKlass*, mtClass>(nof_buckets, sizeof(LoaderConstraintEntry)) {};
41
42
43 LoaderConstraintEntry* LoaderConstraintTable::new_entry(
44 unsigned int hash, Symbol* name,
45 InstanceKlass* klass, int num_loaders,
46 int max_loaders) {
47 LoaderConstraintEntry* entry;
48 entry = (LoaderConstraintEntry*)Hashtable<InstanceKlass*, mtClass>::new_entry(hash, klass);
72
73 while (*pp) {
74 LoaderConstraintEntry* p = *pp;
75 if (p->hash() == hash) {
76 if (p->name() == name) {
77 for (int i = p->num_loaders() - 1; i >= 0; i--) {
78 if (p->loader_data(i) == loader_data) {
79 return pp;
80 }
81 }
82 }
83 }
84 pp = p->next_addr();
85 }
86 return pp;
87 }
88
89
90 void LoaderConstraintTable::purge_loader_constraints() {
91 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
92 LogTarget(Info, class, loader, constraints) lt;
93 // Remove unloaded entries from constraint table
94 for (int index = 0; index < table_size(); index++) {
95 LoaderConstraintEntry** p = bucket_addr(index);
96 while(*p) {
97 LoaderConstraintEntry* probe = *p;
98 InstanceKlass* klass = probe->klass();
99 // Remove klass that is no longer alive
100 if (klass != NULL &&
101 klass->class_loader_data()->is_unloading()) {
102 probe->set_klass(NULL);
103 if (lt.is_enabled()) {
104 ResourceMark rm;
105 lt.print("purging class object from constraint for name %s,"
106 " loader list:",
107 probe->name()->as_C_string());
108 for (int i = 0; i < probe->num_loaders(); i++) {
109 lt.print(" [%d]: %s", i,
110 probe->loader_data(i)->loader_name());
111 }
112 }
113 }
114 // Remove entries no longer alive from loader array
115 int n = 0;
116 while (n < probe->num_loaders()) {
117 if (probe->loader_data(n)->is_unloading()) {
118 if (lt.is_enabled()) {
119 ResourceMark rm;
120 lt.print("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 (lt.is_enabled()) {
133 ResourceMark rm;
134 lt.print("new loader list:");
135 for (int i = 0; i < probe->num_loaders(); i++) {
136 lt.print(" [%d]: %s", i,
137 probe->loader_data(i)->loader_name());
138 }
139 }
140
141 continue; // current element replaced, so restart without
142 // incrementing n
143 }
144 n++;
145 }
146 // Check whether entry should be purged
147 if (probe->num_loaders() < 2) {
148 if (lt.is_enabled()) {
149 ResourceMark rm;
150 lt.print("purging complete constraint for name %s",
151 probe->name()->as_C_string());
152 }
153
154 // Purge entry
155 *p = probe->next();
156 FREE_C_HEAP_ARRAY(oop, probe->loaders());
157 free_entry(probe);
158 } else {
159 #ifdef ASSERT
160 if (probe->klass() != NULL) {
161 ClassLoaderData* loader_data =
162 probe->klass()->class_loader_data();
163 assert(!loader_data->is_unloading(), "klass should be live");
164 }
165 #endif
166 // Go to next entry
167 p = probe->next_addr();
168 }
169 }
170 }
171 }
172
173 void log_ldr_constraint_msg(Symbol* class_name, const char* reason,
174 Handle class_loader1, Handle class_loader2) {
175 LogTarget(Info, class, loader, constraints) lt;
176 if (lt.is_enabled()) {
177 ResourceMark rm;
178 lt.print("Failed to add constraint for name: %s, loader[0]: %s,"
179 " loader[1]: %s, Reason: %s",
180 class_name->as_C_string(),
181 SystemDictionary::loader_name(class_loader1()),
182 SystemDictionary::loader_name(class_loader2()),
183 reason);
184 }
185 }
186
187 bool LoaderConstraintTable::add_entry(Symbol* class_name,
188 InstanceKlass* klass1, Handle class_loader1,
189 InstanceKlass* klass2, Handle class_loader2) {
190 LogTarget(Info, class, loader, constraints) lt;
191 if (klass1 != NULL && klass2 != NULL) {
192 if (klass1 == klass2) {
193 // Same type already loaded in both places. There is no need for any constraint.
194 return true;
195 } else {
196 log_ldr_constraint_msg(class_name,
197 "The class objects presented by loader[0] and loader[1] "
198 "are different",
199 class_loader1, class_loader2);
200 return false;
201 }
202 }
203
204 InstanceKlass* klass = klass1 != NULL ? klass1 : klass2;
205 LoaderConstraintEntry** pp1 = find_loader_constraint(class_name, class_loader1);
206 if (*pp1 != NULL && (*pp1)->klass() != NULL) {
207 if (klass != NULL) {
208 if (klass != (*pp1)->klass()) {
209 log_ldr_constraint_msg(class_name,
210 "The class object presented by loader[0] does not match "
226 "the stored class object in the constraint",
227 class_loader1, class_loader2);
228 return false;
229 }
230 } else {
231 klass = (*pp2)->klass();
232 }
233 }
234
235 if (*pp1 == NULL && *pp2 == NULL) {
236 unsigned int hash = compute_hash(class_name);
237 int index = hash_to_index(hash);
238 LoaderConstraintEntry* p;
239 p = new_entry(hash, class_name, klass, 2, 2);
240 p->set_loaders(NEW_C_HEAP_ARRAY(ClassLoaderData*, 2, mtClass));
241 p->set_loader(0, class_loader1());
242 p->set_loader(1, class_loader2());
243 p->set_klass(klass);
244 p->set_next(bucket(index));
245 set_entry(index, p);
246 if (lt.is_enabled()) {
247 ResourceMark rm;
248 lt.print("adding new constraint for name: %s, loader[0]: %s,"
249 " loader[1]: %s",
250 class_name->as_C_string(),
251 SystemDictionary::loader_name(class_loader1()),
252 SystemDictionary::loader_name(class_loader2())
253 );
254 }
255 } else if (*pp1 == *pp2) {
256 /* constraint already imposed */
257 if ((*pp1)->klass() == NULL) {
258 (*pp1)->set_klass(klass);
259 if (lt.is_enabled()) {
260 ResourceMark rm;
261 lt.print("setting class object in existing constraint for"
262 " name: %s and loader %s",
263 class_name->as_C_string(),
264 SystemDictionary::loader_name(class_loader1())
265 );
266 }
267 } else {
268 assert((*pp1)->klass() == klass, "loader constraints corrupted");
269 }
270 } else if (*pp1 == NULL) {
271 extend_loader_constraint(*pp2, class_loader1, klass);
272 } else if (*pp2 == NULL) {
273 extend_loader_constraint(*pp1, class_loader2, klass);
274 } else {
275 merge_loader_constraints(pp1, pp2, klass);
276 }
277
278 return true;
279 }
280
281
282 // return true if the constraint was updated, false if the constraint is
283 // violated
284 bool LoaderConstraintTable::check_or_update(InstanceKlass* k,
285 Handle loader,
286 Symbol* name) {
287 LogTarget(Info, class, loader, constraints) lt;
288 LoaderConstraintEntry* p = *(find_loader_constraint(name, loader));
289 if (p && p->klass() != NULL && p->klass() != k) {
290 if (lt.is_enabled()) {
291 ResourceMark rm;
292 lt.print("constraint check failed for name %s, loader %s: "
293 "the presented class object differs from that stored",
294 name->as_C_string(),
295 SystemDictionary::loader_name(loader()));
296 }
297 return false;
298 } else {
299 if (p && p->klass() == NULL) {
300 p->set_klass(k);
301 if (lt.is_enabled()) {
302 ResourceMark rm;
303 lt.print("updating constraint for name %s, loader %s, "
304 "by setting class object",
305 name->as_C_string(),
306 SystemDictionary::loader_name(loader()));
307 }
308 }
309 return true;
310 }
311 }
312
313 InstanceKlass* LoaderConstraintTable::find_constrained_klass(Symbol* name,
314 Handle loader) {
315 LoaderConstraintEntry *p = *(find_loader_constraint(name, loader));
316 if (p != NULL && p->klass() != NULL) {
317 assert(p->klass()->is_instance_klass(), "sanity");
318 if (p->klass()->is_loaded()) {
319 // Only return fully loaded classes. Classes found through the
320 // constraints might still be in the process of loading.
321 return NULL;
322 }
323 return p->klass();
331 LoaderConstraintEntry *p,
332 int nfree) {
333 if (p->max_loaders() - p->num_loaders() < nfree) {
334 int n = nfree + p->num_loaders();
335 ClassLoaderData** new_loaders = NEW_C_HEAP_ARRAY(ClassLoaderData*, n, mtClass);
336 memcpy(new_loaders, p->loaders(), sizeof(ClassLoaderData*) * p->num_loaders());
337 p->set_max_loaders(n);
338 FREE_C_HEAP_ARRAY(ClassLoaderData*, p->loaders());
339 p->set_loaders(new_loaders);
340 }
341 }
342
343
344 void LoaderConstraintTable::extend_loader_constraint(LoaderConstraintEntry* p,
345 Handle loader,
346 InstanceKlass* klass) {
347 ensure_loader_constraint_capacity(p, 1);
348 int num = p->num_loaders();
349 p->set_loader(num, loader());
350 p->set_num_loaders(num + 1);
351 LogTarget(Info, class, loader, constraints) lt;
352 if (lt.is_enabled()) {
353 ResourceMark rm;
354 lt.print("extending constraint for name %s by adding loader[%d]: %s %s",
355 p->name()->as_C_string(),
356 num,
357 SystemDictionary::loader_name(loader()),
358 (p->klass() == NULL ? " and setting class object" : "")
359 );
360 }
361 if (p->klass() == NULL) {
362 p->set_klass(klass);
363 } else {
364 assert(klass == NULL || p->klass() == klass, "constraints corrupted");
365 }
366 }
367
368
369 void LoaderConstraintTable::merge_loader_constraints(
370 LoaderConstraintEntry** pp1,
371 LoaderConstraintEntry** pp2,
372 InstanceKlass* klass) {
373 // make sure *pp1 has higher capacity
374 if ((*pp1)->max_loaders() < (*pp2)->max_loaders()) {
375 LoaderConstraintEntry** tmp = pp2;
376 pp2 = pp1;
377 pp1 = tmp;
378 }
379
380 LoaderConstraintEntry* p1 = *pp1;
381 LoaderConstraintEntry* p2 = *pp2;
382
383 ensure_loader_constraint_capacity(p1, p2->num_loaders());
384
385 for (int i = 0; i < p2->num_loaders(); i++) {
386 int num = p1->num_loaders();
387 p1->set_loader_data(num, p2->loader_data(i));
388 p1->set_num_loaders(num + 1);
389 }
390
391 LogTarget(Info, class, loader, constraints) lt;
392 if (lt.is_enabled()) {
393 ResourceMark rm;
394 lt.print("merged constraints for name %s, new loader list:",
395 p1->name()->as_C_string()
396 );
397
398 for (int i = 0; i < p1->num_loaders(); i++) {
399 lt.print(" [%d]: %s", i,
400 p1->loader_data(i)->loader_name());
401 }
402 if (p1->klass() == NULL) {
403 lt.print("... and setting class object");
404 }
405 }
406
407 // p1->klass() will hold NULL if klass, p2->klass(), and old
408 // p1->klass() are all NULL. In addition, all three must have
409 // matching non-NULL values, otherwise either the constraints would
410 // have been violated, or the constraints had been corrupted (and an
411 // assertion would fail).
412 if (p2->klass() != NULL) {
413 assert(p2->klass() == klass, "constraints corrupted");
414 }
415 if (p1->klass() == NULL) {
416 p1->set_klass(klass);
417 } else {
418 assert(p1->klass() == klass, "constraints corrupted");
419 }
420
421 *pp2 = p2->next();
422 FREE_C_HEAP_ARRAY(oop, p2->loaders());
423 free_entry(p2);
|