1 /* 2 * Copyright (c) 2003, 2017, 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/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); 48 entry->set_name(name); 49 entry->set_num_loaders(num_loaders); 50 entry->set_max_loaders(max_loaders); 51 return entry; 52 } 53 54 void LoaderConstraintTable::free_entry(LoaderConstraintEntry *entry) { 55 // decrement name refcount before freeing 56 entry->name()->decrement_refcount(); 57 Hashtable<InstanceKlass*, mtClass>::free_entry(entry); 58 } 59 60 // The loaderConstraintTable must always be accessed with the 61 // SystemDictionary lock held. This is true even for readers as 62 // entries in the table could be being dynamically resized. 63 64 LoaderConstraintEntry** LoaderConstraintTable::find_loader_constraint( 65 Symbol* name, Handle loader) { 66 67 unsigned int hash = compute_hash(name); 68 int index = hash_to_index(hash); 69 LoaderConstraintEntry** pp = bucket_addr(index); 70 ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(loader()); 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 " 212 "the stored class object in the constraint", 213 class_loader1, class_loader2); 214 return false; 215 } 216 } else { 217 klass = (*pp1)->klass(); 218 } 219 } 220 221 LoaderConstraintEntry** pp2 = find_loader_constraint(class_name, class_loader2); 222 if (*pp2 != NULL && (*pp2)->klass() != NULL) { 223 if (klass != NULL) { 224 if (klass != (*pp2)->klass()) { 225 log_ldr_constraint_msg(class_name, 226 "The class object presented by loader[1] 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(); 328 } 329 330 // No constraints, or else no klass loaded yet. 331 return NULL; 332 } 333 334 void LoaderConstraintTable::ensure_loader_constraint_capacity( 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); 428 return; 429 } 430 431 432 void LoaderConstraintTable::verify(Dictionary* dictionary, 433 PlaceholderTable* placeholders) { 434 Thread *thread = Thread::current(); 435 for (int cindex = 0; cindex < _loader_constraint_size; cindex++) { 436 for (LoaderConstraintEntry* probe = bucket(cindex); 437 probe != NULL; 438 probe = probe->next()) { 439 if (probe->klass() != NULL) { 440 InstanceKlass* ik = probe->klass(); 441 guarantee(ik->name() == probe->name(), "name should match"); 442 Symbol* name = ik->name(); 443 ClassLoaderData* loader_data = ik->class_loader_data(); 444 unsigned int d_hash = dictionary->compute_hash(name, loader_data); 445 int d_index = dictionary->hash_to_index(d_hash); 446 InstanceKlass* k = dictionary->find_class(d_index, d_hash, name, loader_data); 447 if (k != NULL) { 448 // We found the class in the system dictionary, so we should 449 // make sure that the Klass* matches what we already have. 450 guarantee(k == probe->klass(), "klass should be in dictionary"); 451 } else { 452 // If we don't find the class in the system dictionary, it 453 // has to be in the placeholders table. 454 unsigned int p_hash = placeholders->compute_hash(name, loader_data); 455 int p_index = placeholders->hash_to_index(p_hash); 456 PlaceholderEntry* entry = placeholders->get_entry(p_index, p_hash, 457 name, loader_data); 458 459 // The InstanceKlass might not be on the entry, so the only 460 // thing we can check here is whether we were successful in 461 // finding the class in the placeholders table. 462 guarantee(entry != NULL, "klass should be in the placeholders"); 463 } 464 } 465 for (int n = 0; n< probe->num_loaders(); n++) { 466 assert(ClassLoaderDataGraph::contains_loader_data(probe->loader_data(n)), "The loader is missing"); 467 } 468 } 469 } 470 } 471 472 #ifndef PRODUCT 473 474 // Called with the system dictionary lock held 475 void LoaderConstraintTable::print() { 476 ResourceMark rm; 477 assert_locked_or_safepoint(SystemDictionary_lock); 478 tty->print_cr("Java loader constraints (entries=%d)", _loader_constraint_size); 479 for (int cindex = 0; cindex < _loader_constraint_size; cindex++) { 480 for (LoaderConstraintEntry* probe = bucket(cindex); 481 probe != NULL; 482 probe = probe->next()) { 483 tty->print("%4d: ", cindex); 484 probe->name()->print(); 485 tty->print(" , loaders:"); 486 for (int n = 0; n < probe->num_loaders(); n++) { 487 probe->loader_data(n)->print_value(); 488 tty->print(", "); 489 } 490 tty->cr(); 491 } 492 } 493 } 494 #endif