1/*
2 * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
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/classLoaderDataGraph.hpp"
28#include "classfile/dictionary.hpp"
29#include "classfile/loaderConstraints.hpp"
30#include "logging/log.hpp"
31#include "memory/resourceArea.hpp"
32#include "oops/oop.inline.hpp"
33#include "runtime/handles.inline.hpp"
34#include "runtime/safepoint.hpp"
35#include "utilities/hashtable.inline.hpp"
36
37void LoaderConstraintEntry::set_loader(int i, oop p) {
38 set_loader_data(i, ClassLoaderData::class_loader_data(p));
39}
40
41LoaderConstraintTable::LoaderConstraintTable(int table_size)
42 : Hashtable<InstanceKlass*, mtClass>(table_size, sizeof(LoaderConstraintEntry)) {};
43
44
45LoaderConstraintEntry* LoaderConstraintTable::new_entry(
46 unsigned int hash, Symbol* name,
47 InstanceKlass* klass, int num_loaders,
48 int max_loaders) {
49 LoaderConstraintEntry* entry;
50 entry = (LoaderConstraintEntry*)Hashtable<InstanceKlass*, mtClass>::new_entry(hash, klass);
51 entry->set_name(name);
52 entry->set_num_loaders(num_loaders);
53 entry->set_max_loaders(max_loaders);
54 return entry;
55}
56
57void LoaderConstraintTable::free_entry(LoaderConstraintEntry *entry) {
58 // decrement name refcount before freeing
59 entry->name()->decrement_refcount();
60 Hashtable<InstanceKlass*, mtClass>::free_entry(entry);
61}
62
63// The loaderConstraintTable must always be accessed with the
64// SystemDictionary lock held. This is true even for readers as
65// entries in the table could be being dynamically resized.
66
67LoaderConstraintEntry** LoaderConstraintTable::find_loader_constraint(
68 Symbol* name, Handle loader) {
69 assert_lock_strong(SystemDictionary_lock);
70 unsigned int hash = compute_hash(name);
71 int index = hash_to_index(hash);
72 LoaderConstraintEntry** pp = bucket_addr(index);
73 ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(loader());
74
75 while (*pp) {
76 LoaderConstraintEntry* p = *pp;
77 if (p->hash() == hash) {
78 if (p->name() == name) {
79 for (int i = p->num_loaders() - 1; i >= 0; i--) {
80 if (p->loader_data(i) == loader_data &&
81 // skip unloaded klasses
82 (p->klass() == NULL ||
83 p->klass()->is_loader_alive())) {
84 return pp;
85 }
86 }
87 }
88 }
89 pp = p->next_addr();
90 }
91 return pp;
92}
93
94
95void LoaderConstraintTable::purge_loader_constraints() {
96 assert_locked_or_safepoint(SystemDictionary_lock);
97 LogTarget(Info, class, loader, constraints) lt;
98 // Remove unloaded entries from constraint table
99 for (int index = 0; index < table_size(); index++) {
100 LoaderConstraintEntry** p = bucket_addr(index);
101 while(*p) {
102 LoaderConstraintEntry* probe = *p;
103 InstanceKlass* klass = probe->klass();
104 // Remove klass that is no longer alive
105 if (klass != NULL &&
106 !klass->is_loader_alive()) {
107 probe->set_klass(NULL);
108 if (lt.is_enabled()) {
109 ResourceMark rm;
110 lt.print("purging class object from constraint for name %s,"
111 " loader list:",
112 probe->name()->as_C_string());
113 for (int i = 0; i < probe->num_loaders(); i++) {
114 lt.print(" [%d]: %s", i,
115 probe->loader_data(i)->loader_name_and_id());
116 }
117 }
118 }
119 // Remove entries no longer alive from loader array
120 int n = 0;
121 while (n < probe->num_loaders()) {
122 if (probe->loader_data(n)->is_unloading()) {
123 if (lt.is_enabled()) {
124 ResourceMark rm;
125 lt.print("purging loader %s from constraint for name %s",
126 probe->loader_data(n)->loader_name_and_id(),
127 probe->name()->as_C_string()
128 );
129 }
130
131 // Compact array
132 int num = probe->num_loaders() - 1;
133 probe->set_num_loaders(num);
134 probe->set_loader_data(n, probe->loader_data(num));
135 probe->set_loader_data(num, NULL);
136
137 if (lt.is_enabled()) {
138 ResourceMark rm;
139 lt.print("new loader list:");
140 for (int i = 0; i < probe->num_loaders(); i++) {
141 lt.print(" [%d]: %s", i,
142 probe->loader_data(i)->loader_name_and_id());
143 }
144 }
145
146 continue; // current element replaced, so restart without
147 // incrementing n
148 }
149 n++;
150 }
151 // Check whether entry should be purged
152 if (probe->num_loaders() < 2) {
153 if (lt.is_enabled()) {
154 ResourceMark rm;
155 lt.print("purging complete constraint for name %s",
156 probe->name()->as_C_string());
157 }
158
159 // Purge entry
160 *p = probe->next();
161 FREE_C_HEAP_ARRAY(oop, probe->loaders());
162 free_entry(probe);
163 } else {
164#ifdef ASSERT
165 if (probe->klass() != NULL) {
166 assert(probe->klass()->is_loader_alive(), "klass should be live");
167 }
168#endif
169 // Go to next entry
170 p = probe->next_addr();
171 }
172 }
173 }
174}
175
176void log_ldr_constraint_msg(Symbol* class_name, const char* reason,
177 Handle class_loader1, Handle class_loader2) {
178 LogTarget(Info, class, loader, constraints) lt;
179 if (lt.is_enabled()) {
180 ResourceMark rm;
181 lt.print("Failed to add constraint for name: %s, loader[0]: %s,"
182 " loader[1]: %s, Reason: %s",
183 class_name->as_C_string(),
184 ClassLoaderData::class_loader_data(class_loader1())->loader_name_and_id(),
185 ClassLoaderData::class_loader_data(class_loader2())->loader_name_and_id(),
186 reason);
187 }
188}
189
190bool LoaderConstraintTable::add_entry(Symbol* class_name,
191 InstanceKlass* klass1, Handle class_loader1,
192 InstanceKlass* klass2, Handle class_loader2) {
193 LogTarget(Info, class, loader, constraints) lt;
194 if (klass1 != NULL && klass2 != NULL) {
195 if (klass1 == klass2) {
196 // Same type already loaded in both places. There is no need for any constraint.
197 return true;
198 } else {
199 log_ldr_constraint_msg(class_name,
200 "The class objects presented by loader[0] and loader[1] "
201 "are different",
202 class_loader1, class_loader2);
203 return false;
204 }
205 }
206
207 InstanceKlass* klass = klass1 != NULL ? klass1 : klass2;
208 LoaderConstraintEntry** pp1 = find_loader_constraint(class_name, class_loader1);
209 if (*pp1 != NULL && (*pp1)->klass() != NULL) {
210 if (klass != NULL) {
211 if (klass != (*pp1)->klass()) {
212 log_ldr_constraint_msg(class_name,
213 "The class object presented by loader[0] does not match "
214 "the stored class object in the constraint",
215 class_loader1, class_loader2);
216 return false;
217 }
218 } else {
219 klass = (*pp1)->klass();
220 }
221 }
222
223 LoaderConstraintEntry** pp2 = find_loader_constraint(class_name, class_loader2);
224 if (*pp2 != NULL && (*pp2)->klass() != NULL) {
225 if (klass != NULL) {
226 if (klass != (*pp2)->klass()) {
227 log_ldr_constraint_msg(class_name,
228 "The class object presented by loader[1] does not match "
229 "the stored class object in the constraint",
230 class_loader1, class_loader2);
231 return false;
232 }
233 } else {
234 klass = (*pp2)->klass();
235 }
236 }
237
238 if (*pp1 == NULL && *pp2 == NULL) {
239 unsigned int hash = compute_hash(class_name);
240 int index = hash_to_index(hash);
241 LoaderConstraintEntry* p;
242 p = new_entry(hash, class_name, klass, 2, 2);
243 p->set_loaders(NEW_C_HEAP_ARRAY(ClassLoaderData*, 2, mtClass));
244 p->set_loader(0, class_loader1());
245 p->set_loader(1, class_loader2());
246 p->set_klass(klass);
247 p->set_next(bucket(index));
248 set_entry(index, p);
249 if (lt.is_enabled()) {
250 ResourceMark rm;
251 lt.print("adding new constraint for name: %s, loader[0]: %s,"
252 " loader[1]: %s",
253 class_name->as_C_string(),
254 ClassLoaderData::class_loader_data(class_loader1())->loader_name_and_id(),
255 ClassLoaderData::class_loader_data(class_loader2())->loader_name_and_id()
256 );
257 }
258 } else if (*pp1 == *pp2) {
259 /* constraint already imposed */
260 if ((*pp1)->klass() == NULL) {
261 (*pp1)->set_klass(klass);
262 if (lt.is_enabled()) {
263 ResourceMark rm;
264 lt.print("setting class object in existing constraint for"
265 " name: %s and loader %s",
266 class_name->as_C_string(),
267 ClassLoaderData::class_loader_data(class_loader1())->loader_name_and_id()
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
287bool LoaderConstraintTable::check_or_update(InstanceKlass* k,
288 Handle loader,
289 Symbol* name) {
290 LogTarget(Info, class, loader, constraints) lt;
291 LoaderConstraintEntry* p = *(find_loader_constraint(name, loader));
292 if (p && p->klass() != NULL && p->klass() != k) {
293 if (lt.is_enabled()) {
294 ResourceMark rm;
295 lt.print("constraint check failed for name %s, loader %s: "
296 "the presented class object differs from that stored",
297 name->as_C_string(),
298 ClassLoaderData::class_loader_data(loader())->loader_name_and_id());
299 }
300 return false;
301 } else {
302 if (p && p->klass() == NULL) {
303 p->set_klass(k);
304 if (lt.is_enabled()) {
305 ResourceMark rm;
306 lt.print("updating constraint for name %s, loader %s, "
307 "by setting class object",
308 name->as_C_string(),
309 ClassLoaderData::class_loader_data(loader())->loader_name_and_id());
310 }
311 }
312 return true;
313 }
314}
315
316InstanceKlass* LoaderConstraintTable::find_constrained_klass(Symbol* name,
317 Handle loader) {
318 LoaderConstraintEntry *p = *(find_loader_constraint(name, loader));
319 if (p != NULL && p->klass() != NULL) {
320 assert(p->klass()->is_instance_klass(), "sanity");
321 if (!p->klass()->is_loaded()) {
322 // Only return fully loaded classes. Classes found through the
323 // constraints might still be in the process of loading.
324 return NULL;
325 }
326 return p->klass();
327 }
328
329 // No constraints, or else no klass loaded yet.
330 return NULL;
331}
332
333void LoaderConstraintTable::ensure_loader_constraint_capacity(
334 LoaderConstraintEntry *p,
335 int nfree) {
336 if (p->max_loaders() - p->num_loaders() < nfree) {
337 int n = nfree + p->num_loaders();
338 ClassLoaderData** new_loaders = NEW_C_HEAP_ARRAY(ClassLoaderData*, n, mtClass);
339 memcpy(new_loaders, p->loaders(), sizeof(ClassLoaderData*) * p->num_loaders());
340 p->set_max_loaders(n);
341 FREE_C_HEAP_ARRAY(ClassLoaderData*, p->loaders());
342 p->set_loaders(new_loaders);
343 }
344}
345
346
347void LoaderConstraintTable::extend_loader_constraint(LoaderConstraintEntry* p,
348 Handle loader,
349 InstanceKlass* klass) {
350 ensure_loader_constraint_capacity(p, 1);
351 int num = p->num_loaders();
352 p->set_loader(num, loader());
353 p->set_num_loaders(num + 1);
354 LogTarget(Info, class, loader, constraints) lt;
355 if (lt.is_enabled()) {
356 ResourceMark rm;
357 lt.print("extending constraint for name %s by adding loader[%d]: %s %s",
358 p->name()->as_C_string(),
359 num,
360 ClassLoaderData::class_loader_data(loader())->loader_name_and_id(),
361 (p->klass() == NULL ? " and setting class object" : "")
362 );
363 }
364 if (p->klass() == NULL) {
365 p->set_klass(klass);
366 } else {
367 assert(klass == NULL || p->klass() == klass, "constraints corrupted");
368 }
369}
370
371
372void LoaderConstraintTable::merge_loader_constraints(
373 LoaderConstraintEntry** pp1,
374 LoaderConstraintEntry** pp2,
375 InstanceKlass* klass) {
376 // make sure *pp1 has higher capacity
377 if ((*pp1)->max_loaders() < (*pp2)->max_loaders()) {
378 LoaderConstraintEntry** tmp = pp2;
379 pp2 = pp1;
380 pp1 = tmp;
381 }
382
383 LoaderConstraintEntry* p1 = *pp1;
384 LoaderConstraintEntry* p2 = *pp2;
385
386 ensure_loader_constraint_capacity(p1, p2->num_loaders());
387
388 for (int i = 0; i < p2->num_loaders(); i++) {
389 int num = p1->num_loaders();
390 p1->set_loader_data(num, p2->loader_data(i));
391 p1->set_num_loaders(num + 1);
392 }
393
394 LogTarget(Info, class, loader, constraints) lt;
395 if (lt.is_enabled()) {
396 ResourceMark rm;
397 lt.print("merged constraints for name %s, new loader list:",
398 p1->name()->as_C_string()
399 );
400
401 for (int i = 0; i < p1->num_loaders(); i++) {
402 lt.print(" [%d]: %s", i,
403 p1->loader_data(i)->loader_name_and_id());
404 }
405 if (p1->klass() == NULL) {
406 lt.print("... and setting class object");
407 }
408 }
409
410 // p1->klass() will hold NULL if klass, p2->klass(), and old
411 // p1->klass() are all NULL. In addition, all three must have
412 // matching non-NULL values, otherwise either the constraints would
413 // have been violated, or the constraints had been corrupted (and an
414 // assertion would fail).
415 if (p2->klass() != NULL) {
416 assert(p2->klass() == klass, "constraints corrupted");
417 }
418 if (p1->klass() == NULL) {
419 p1->set_klass(klass);
420 } else {
421 assert(p1->klass() == klass, "constraints corrupted");
422 }
423
424 *pp2 = p2->next();
425 FREE_C_HEAP_ARRAY(oop, p2->loaders());
426 free_entry(p2);
427 return;
428}
429
430
431void LoaderConstraintTable::verify(PlaceholderTable* placeholders) {
432 Thread *thread = Thread::current();
433 for (int cindex = 0; cindex < table_size(); cindex++) {
434 for (LoaderConstraintEntry* probe = bucket(cindex);
435 probe != NULL;
436 probe = probe->next()) {
437 if (probe->klass() != NULL) {
438 InstanceKlass* ik = probe->klass();
439 guarantee(ik->name() == probe->name(), "name should match");
440 Symbol* name = ik->name();
441 ClassLoaderData* loader_data = ik->class_loader_data();
442 Dictionary* dictionary = loader_data->dictionary();
443 unsigned int d_hash = dictionary->compute_hash(name);
444 int d_index = dictionary->hash_to_index(d_hash);
445 InstanceKlass* k = dictionary->find_class(d_index, d_hash, name);
446 if (k != NULL) {
447 // We found the class in the dictionary, so we should
448 // make sure that the Klass* matches what we already have.
449 guarantee(k == probe->klass(), "klass should be in dictionary");
450 } else {
451 // If we don't find the class in the dictionary, it
452 // has to be in the placeholders table.
453 unsigned int p_hash = placeholders->compute_hash(name);
454 int p_index = placeholders->hash_to_index(p_hash);
455 PlaceholderEntry* entry = placeholders->get_entry(p_index, p_hash,
456 name, loader_data);
457
458 // The InstanceKlass might not be on the entry, so the only
459 // thing we can check here is whether we were successful in
460 // finding the class in the placeholders table.
461 guarantee(entry != NULL, "klass should be in the placeholders");
462 }
463 }
464 for (int n = 0; n< probe->num_loaders(); n++) {
465 assert(ClassLoaderDataGraph::contains_loader_data(probe->loader_data(n)), "The loader is missing");
466 }
467 }
468 }
469}
470
471// Called with the system dictionary lock held
472void LoaderConstraintTable::print_on(outputStream* st) const {
473 ResourceMark rm;
474 assert_locked_or_safepoint(SystemDictionary_lock);
475 st->print_cr("Java loader constraints (table_size=%d, constraints=%d)",
476 table_size(), number_of_entries());
477 for (int cindex = 0; cindex < table_size(); cindex++) {
478 for (LoaderConstraintEntry* probe = bucket(cindex);
479 probe != NULL;
480 probe = probe->next()) {
481 st->print("%4d: ", cindex);
482 probe->name()->print_on(st);
483 st->print(" , loaders:");
484 for (int n = 0; n < probe->num_loaders(); n++) {
485 probe->loader_data(n)->print_value_on(st);
486 st->print(", ");
487 }
488 st->cr();
489 }
490 }
491}
492