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 bool LoaderConstraintTable::add_entry(Symbol* class_name, 176 InstanceKlass* klass1, Handle class_loader1, 177 InstanceKlass* klass2, Handle class_loader2) { 178 int failure_code = 0; // encode different reasons for failing 179 180 if (klass1 != NULL && klass2 != NULL && klass1 != klass2) { 181 failure_code = 1; 182 } else { 183 InstanceKlass* klass = klass1 != NULL ? klass1 : klass2; 184 185 LoaderConstraintEntry** pp1 = find_loader_constraint(class_name, 186 class_loader1); 187 if (*pp1 != NULL && (*pp1)->klass() != NULL) { 188 if (klass != NULL) { 189 if (klass != (*pp1)->klass()) { 190 failure_code = 2; 191 } 192 } else { 193 klass = (*pp1)->klass(); 194 } 195 } 196 197 LoaderConstraintEntry** pp2 = find_loader_constraint(class_name, 198 class_loader2); 199 if (*pp2 != NULL && (*pp2)->klass() != NULL) { 200 if (klass != NULL) { 201 if (klass != (*pp2)->klass()) { 202 failure_code = 3; 203 } 204 } else { 205 klass = (*pp2)->klass(); 206 } 207 } 208 209 if (failure_code == 0) { 210 if (*pp1 == NULL && *pp2 == NULL) { 211 unsigned int hash = compute_hash(class_name); 212 int index = hash_to_index(hash); 213 LoaderConstraintEntry* p; 214 p = new_entry(hash, class_name, klass, 2, 2); 215 p->set_loaders(NEW_C_HEAP_ARRAY(ClassLoaderData*, 2, mtClass)); 216 p->set_loader(0, class_loader1()); 217 p->set_loader(1, class_loader2()); 218 p->set_klass(klass); 219 p->set_next(bucket(index)); 220 set_entry(index, p); 221 if (log_is_enabled(Info, class, loader, constraints)) { 222 ResourceMark rm; 223 outputStream* out = Log(class, loader, constraints)::info_stream(); 224 out->print_cr("adding new constraint for name: %s, loader[0]: %s," 225 " loader[1]: %s", 226 class_name->as_C_string(), 227 SystemDictionary::loader_name(class_loader1()), 228 SystemDictionary::loader_name(class_loader2()) 229 ); 230 } 231 } else if (*pp1 == *pp2) { 232 /* constraint already imposed */ 233 if ((*pp1)->klass() == NULL) { 234 (*pp1)->set_klass(klass); 235 if (log_is_enabled(Info, class, loader, constraints)) { 236 ResourceMark rm; 237 outputStream* out = Log(class, loader, constraints)::info_stream(); 238 out->print_cr("setting class object in existing constraint for" 239 " name: %s and loader %s", 240 class_name->as_C_string(), 241 SystemDictionary::loader_name(class_loader1()) 242 ); 243 } 244 } else { 245 assert((*pp1)->klass() == klass, "loader constraints corrupted"); 246 } 247 } else if (*pp1 == NULL) { 248 extend_loader_constraint(*pp2, class_loader1, klass); 249 } else if (*pp2 == NULL) { 250 extend_loader_constraint(*pp1, class_loader2, klass); 251 } else { 252 merge_loader_constraints(pp1, pp2, klass); 253 } 254 } 255 } 256 257 if (failure_code != 0 && log_is_enabled(Info, class, loader, constraints)) { 258 ResourceMark rm; 259 outputStream* out = Log(class, loader, constraints)::info_stream(); 260 const char* reason = ""; 261 switch(failure_code) { 262 case 1: reason = "the class objects presented by loader[0] and loader[1]" 263 " are different"; break; 264 case 2: reason = "the class object presented by loader[0] does not match" 265 " the stored class object in the constraint"; break; 266 case 3: reason = "the class object presented by loader[1] does not match" 267 " the stored class object in the constraint"; break; 268 default: reason = "unknown reason code"; 269 } 270 out->print_cr("failed to add constraint for name: %s, loader[0]: %s," 271 " loader[1]: %s, Reason: %s", 272 class_name->as_C_string(), 273 SystemDictionary::loader_name(class_loader1()), 274 SystemDictionary::loader_name(class_loader2()), 275 reason 276 ); 277 } 278 279 return failure_code == 0; 280 } 281 282 283 // return true if the constraint was updated, false if the constraint is 284 // violated 285 bool LoaderConstraintTable::check_or_update(InstanceKlass* k, 286 Handle loader, 287 Symbol* name) { 288 LoaderConstraintEntry* p = *(find_loader_constraint(name, loader)); 289 if (p && p->klass() != NULL && p->klass() != k) { 290 if (log_is_enabled(Info, class, loader, constraints)) { 291 ResourceMark rm; 292 outputStream* out = Log(class, loader, constraints)::info_stream(); 293 out->print_cr("constraint check failed for name %s, loader %s: " 294 "the presented class object differs from that stored", 295 name->as_C_string(), 296 SystemDictionary::loader_name(loader())); 297 } 298 return false; 299 } else { 300 if (p && p->klass() == NULL) { 301 p->set_klass(k); 302 if (log_is_enabled(Info, class, loader, constraints)) { 303 ResourceMark rm; 304 outputStream* out = Log(class, loader, constraints)::info_stream(); 305 out->print_cr("updating constraint for name %s, loader %s, " 306 "by setting class object", 307 name->as_C_string(), 308 SystemDictionary::loader_name(loader())); 309 } 310 } 311 return true; 312 } 313 } 314 315 InstanceKlass* LoaderConstraintTable::find_constrained_klass(Symbol* name, 316 Handle loader) { 317 LoaderConstraintEntry *p = *(find_loader_constraint(name, loader)); 318 if (p != NULL && p->klass() != NULL) { 319 assert(p->klass()->is_instance_klass(), "sanity"); 320 if (p->klass()->is_loaded()) { 321 // Only return fully loaded classes. Classes found through the 322 // constraints might still be in the process of loading. 323 return NULL; 324 } 325 return p->klass(); 326 } 327 328 // No constraints, or else no klass loaded yet. 329 return NULL; 330 } 331 332 void LoaderConstraintTable::ensure_loader_constraint_capacity( 333 LoaderConstraintEntry *p, 334 int nfree) { 335 if (p->max_loaders() - p->num_loaders() < nfree) { 336 int n = nfree + p->num_loaders(); 337 ClassLoaderData** new_loaders = NEW_C_HEAP_ARRAY(ClassLoaderData*, n, mtClass); 338 memcpy(new_loaders, p->loaders(), sizeof(ClassLoaderData*) * p->num_loaders()); 339 p->set_max_loaders(n); 340 FREE_C_HEAP_ARRAY(ClassLoaderData*, p->loaders()); 341 p->set_loaders(new_loaders); 342 } 343 } 344 345 346 void LoaderConstraintTable::extend_loader_constraint(LoaderConstraintEntry* p, 347 Handle loader, 348 InstanceKlass* klass) { 349 ensure_loader_constraint_capacity(p, 1); 350 int num = p->num_loaders(); 351 p->set_loader(num, loader()); 352 p->set_num_loaders(num + 1); 353 if (log_is_enabled(Info, class, loader, constraints)) { 354 ResourceMark rm; 355 outputStream* out = Log(class, loader, constraints)::info_stream(); 356 out->print_cr("extending constraint for name %s by adding loader[%d]: %s %s", 357 p->name()->as_C_string(), 358 num, 359 SystemDictionary::loader_name(loader()), 360 (p->klass() == NULL ? " and setting class object" : "") 361 ); 362 } 363 if (p->klass() == NULL) { 364 p->set_klass(klass); 365 } else { 366 assert(klass == NULL || p->klass() == klass, "constraints corrupted"); 367 } 368 } 369 370 371 void LoaderConstraintTable::merge_loader_constraints( 372 LoaderConstraintEntry** pp1, 373 LoaderConstraintEntry** pp2, 374 InstanceKlass* klass) { 375 // make sure *pp1 has higher capacity 376 if ((*pp1)->max_loaders() < (*pp2)->max_loaders()) { 377 LoaderConstraintEntry** tmp = pp2; 378 pp2 = pp1; 379 pp1 = tmp; 380 } 381 382 LoaderConstraintEntry* p1 = *pp1; 383 LoaderConstraintEntry* p2 = *pp2; 384 385 ensure_loader_constraint_capacity(p1, p2->num_loaders()); 386 387 for (int i = 0; i < p2->num_loaders(); i++) { 388 int num = p1->num_loaders(); 389 p1->set_loader_data(num, p2->loader_data(i)); 390 p1->set_num_loaders(num + 1); 391 } 392 393 if (log_is_enabled(Info, class, loader, constraints)) { 394 ResourceMark rm; 395 outputStream* out = Log(class, loader, constraints)::info_stream(); 396 out->print_cr("merged constraints for name %s, new loader list:", 397 p1->name()->as_C_string() 398 ); 399 400 for (int i = 0; i < p1->num_loaders(); i++) { 401 out->print_cr(" [%d]: %s", i, 402 p1->loader_data(i)->loader_name()); 403 } 404 if (p1->klass() == NULL) { 405 out->print_cr("... and setting class object"); 406 } 407 } 408 409 // p1->klass() will hold NULL if klass, p2->klass(), and old 410 // p1->klass() are all NULL. In addition, all three must have 411 // matching non-NULL values, otherwise either the constraints would 412 // have been violated, or the constraints had been corrupted (and an 413 // assertion would fail). 414 if (p2->klass() != NULL) { 415 assert(p2->klass() == klass, "constraints corrupted"); 416 } 417 if (p1->klass() == NULL) { 418 p1->set_klass(klass); 419 } else { 420 assert(p1->klass() == klass, "constraints corrupted"); 421 } 422 423 *pp2 = p2->next(); 424 FREE_C_HEAP_ARRAY(oop, p2->loaders()); 425 free_entry(p2); 426 return; 427 } 428 429 430 void LoaderConstraintTable::verify(Dictionary* dictionary, 431 PlaceholderTable* placeholders) { 432 Thread *thread = Thread::current(); 433 for (int cindex = 0; cindex < _loader_constraint_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 unsigned int d_hash = dictionary->compute_hash(name, loader_data); 443 int d_index = dictionary->hash_to_index(d_hash); 444 InstanceKlass* k = dictionary->find_class(d_index, d_hash, name, loader_data); 445 if (k != NULL) { 446 // We found the class in the system dictionary, so we should 447 // make sure that the Klass* matches what we already have. 448 guarantee(k == probe->klass(), "klass should be in dictionary"); 449 } else { 450 // If we don't find the class in the system dictionary, it 451 // has to be in the placeholders table. 452 unsigned int p_hash = placeholders->compute_hash(name, loader_data); 453 int p_index = placeholders->hash_to_index(p_hash); 454 PlaceholderEntry* entry = placeholders->get_entry(p_index, p_hash, 455 name, loader_data); 456 457 // The InstanceKlass might not be on the entry, so the only 458 // thing we can check here is whether we were successful in 459 // finding the class in the placeholders table. 460 guarantee(entry != NULL, "klass should be in the placeholders"); 461 } 462 } 463 for (int n = 0; n< probe->num_loaders(); n++) { 464 assert(ClassLoaderDataGraph::contains_loader_data(probe->loader_data(n)), "The loader is missing"); 465 } 466 } 467 } 468 } 469 470 #ifndef PRODUCT 471 472 // Called with the system dictionary lock held 473 void LoaderConstraintTable::print() { 474 ResourceMark rm; 475 assert_locked_or_safepoint(SystemDictionary_lock); 476 tty->print_cr("Java loader constraints (entries=%d)", _loader_constraint_size); 477 for (int cindex = 0; cindex < _loader_constraint_size; cindex++) { 478 for (LoaderConstraintEntry* probe = bucket(cindex); 479 probe != NULL; 480 probe = probe->next()) { 481 tty->print("%4d: ", cindex); 482 probe->name()->print(); 483 tty->print(" , loaders:"); 484 for (int n = 0; n < probe->num_loaders(); n++) { 485 probe->loader_data(n)->print_value(); 486 tty->print(", "); 487 } 488 tty->cr(); 489 } 490 } 491 } 492 #endif