1 /* 2 * Copyright (c) 2015, 2024, 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 "cds/aotConstantPoolResolver.hpp" 27 #include "cds/archiveUtils.hpp" 28 #include "cds/cdsConfig.hpp" 29 #include "cds/classListParser.hpp" 30 #include "cds/lambdaFormInvokers.hpp" 31 #include "cds/metaspaceShared.hpp" 32 #include "cds/unregisteredClasses.hpp" 33 #include "classfile/classLoader.hpp" 34 #include "classfile/javaClasses.inline.hpp" 35 #include "classfile/symbolTable.hpp" 36 #include "classfile/systemDictionary.hpp" 37 #include "classfile/systemDictionaryShared.hpp" 38 #include "classfile/vmClasses.hpp" 39 #include "classfile/vmSymbols.hpp" 40 #include "interpreter/bytecode.hpp" 41 #include "interpreter/interpreterRuntime.hpp" 42 #include "interpreter/linkResolver.hpp" 43 #include "jimage.hpp" 44 #include "jvm.h" 45 #include "logging/log.hpp" 46 #include "logging/logTag.hpp" 47 #include "memory/oopFactory.hpp" 48 #include "memory/resourceArea.hpp" 49 #include "oops/constantPool.inline.hpp" 50 #include "oops/cpCache.inline.hpp" 51 #include "runtime/atomic.hpp" 52 #include "runtime/globals_extension.hpp" 53 #include "runtime/handles.inline.hpp" 54 #include "runtime/java.hpp" 55 #include "runtime/javaCalls.hpp" 56 #include "utilities/defaultStream.hpp" 57 #include "utilities/macros.hpp" 58 #include "utilities/utf8.hpp" 59 60 const char* ClassListParser::CLASS_REFLECTION_DATA_TAG = "@class-reflection-data"; 61 const char* ClassListParser::CONSTANT_POOL_TAG = "@cp"; 62 const char* ClassListParser::DYNAMIC_PROXY_TAG = "@dynamic-proxy"; 63 const char* ClassListParser::LAMBDA_FORM_TAG = "@lambda-form-invoker"; 64 const char* ClassListParser::LAMBDA_PROXY_TAG = "@lambda-proxy"; 65 const char* ClassListParser::LOADER_NEGATIVE_CACHE_TAG = "@loader-negative-cache"; 66 const char* ClassListParser::ARRAY_TAG = "@array"; 67 68 volatile Thread* ClassListParser::_parsing_thread = nullptr; 69 ClassListParser* ClassListParser::_instance = nullptr; 70 71 ClassListParser::ClassListParser(const char* file, ParseMode parse_mode) : 72 _classlist_file(file), 73 _id2klass_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE), 74 _file_input(do_open(file), /* need_close=*/true), 75 _input_stream(&_file_input), 76 _parse_mode(parse_mode) { 77 log_info(cds)("Parsing %s%s", file, 78 parse_lambda_forms_invokers_only() ? " (lambda form invokers only)" : ""); 79 if (!_file_input.is_open()) { 80 char reason[JVM_MAXPATHLEN]; 81 os::lasterror(reason, JVM_MAXPATHLEN); 82 vm_exit_during_initialization(err_msg("Loading %s %s failed", 83 FLAG_IS_DEFAULT(AOTConfiguration) ? 84 "classlist" : "AOTConfiguration file", 85 file), 86 reason); 87 } 88 _token = _line = nullptr; 89 _interfaces = new (mtClass) GrowableArray<int>(10, mtClass); 90 _indy_items = new (mtClass) GrowableArray<const char*>(9, mtClass); 91 92 // _instance should only be accessed by the thread that created _instance. 93 assert(_instance == nullptr, "must be singleton"); 94 _instance = this; 95 Atomic::store(&_parsing_thread, Thread::current()); 96 } 97 98 FILE* ClassListParser::do_open(const char* file) { 99 // Use os::open() because neither fopen() nor os::fopen() 100 // can handle long path name on Windows. (See JDK-8216184) 101 int fd = os::open(file, O_RDONLY, S_IREAD); 102 FILE* fp = nullptr; 103 if (fd != -1) { 104 // Obtain a FILE* from the file descriptor so that _input_stream 105 // can be used in ClassListParser::parse() 106 fp = os::fdopen(fd, "r"); 107 } 108 return fp; 109 } 110 111 bool ClassListParser::is_parsing_thread() { 112 return Atomic::load(&_parsing_thread) == Thread::current(); 113 } 114 115 ClassListParser::~ClassListParser() { 116 Atomic::store(&_parsing_thread, (Thread*)nullptr); 117 delete _indy_items; 118 delete _interfaces; 119 _instance = nullptr; 120 } 121 122 void ClassListParser::parse(TRAPS) { 123 for (; !_input_stream.done(); _input_stream.next()) { 124 _line = _input_stream.current_line(); 125 clean_up_input_line(); 126 127 // Each line in the classlist can be one of three forms: 128 if (_line[0] == '#') { 129 // A comment; ignore it 130 } else if (_line[0] == '@') { 131 // @xxx - a tag like @lambda-proxy, to be parsed by parse_at_tags() 132 parse_at_tags(CHECK); 133 } else { 134 // A class name, followed by optional attributes. E.g. 135 // java/lang/String 136 // java/lang/Object id: 1 137 // my/pkg/TestClass id: 5 super: 1 interfaces: 3 4 source: foo.jar 138 parse_class_name_and_attributes(CHECK); 139 } 140 } 141 } 142 143 void ClassListParser::parse_class_name_and_attributes(TRAPS) { 144 read_class_name_and_attributes(); 145 146 if (parse_lambda_forms_invokers_only()) { 147 return; 148 } 149 150 check_class_name(_class_name); 151 TempNewSymbol class_name_symbol = SymbolTable::new_symbol(_class_name); 152 Klass* klass = load_current_class(class_name_symbol, THREAD); 153 if (HAS_PENDING_EXCEPTION) { 154 if (PENDING_EXCEPTION->is_a(vmClasses::OutOfMemoryError_klass())) { 155 // If we have run out of memory, don't try to load the rest of the classes in 156 // the classlist. Throw an exception, which will terminate the dumping process. 157 return; // THROW 158 } 159 160 ResourceMark rm(THREAD); 161 char* ex_msg = (char*)""; 162 oop message = java_lang_Throwable::message(PENDING_EXCEPTION); 163 if (message != nullptr) { 164 ex_msg = java_lang_String::as_utf8_string(message); 165 } 166 log_warning(cds)("%s: %s", PENDING_EXCEPTION->klass()->external_name(), ex_msg); 167 // We might have an invalid class name or an bad class. Warn about it 168 // and keep going to the next line. 169 CLEAR_PENDING_EXCEPTION; 170 log_warning(cds)("Preload Warning: Cannot find %s", _class_name); 171 return; 172 } 173 174 assert(klass != nullptr, "sanity"); 175 if (log_is_enabled(Trace, cds)) { 176 ResourceMark rm(THREAD); 177 log_trace(cds)("Shared spaces preloaded: %s", klass->external_name()); 178 } 179 180 if (klass->is_instance_klass()) { 181 InstanceKlass* ik = InstanceKlass::cast(klass); 182 183 // Link the class to cause the bytecodes to be rewritten and the 184 // cpcache to be created. The linking is done as soon as classes 185 // are loaded in order that the related data structures (klass and 186 // cpCache) are located together. 187 MetaspaceShared::try_link_class(THREAD, ik); 188 } 189 } 190 191 void ClassListParser::clean_up_input_line() { 192 int len = (int)strlen(_line); 193 int i; 194 // Replace \t\r\n\f with ' ' 195 for (i=0; i<len; i++) { 196 if (_line[i] == '\t' || _line[i] == '\r' || _line[i] == '\n' || _line[i] == '\f') { 197 _line[i] = ' '; 198 } 199 } 200 201 // Remove trailing newline/space 202 while (len > 0) { 203 if (_line[len-1] == ' ') { 204 _line[len-1] = '\0'; 205 len --; 206 } else { 207 break; 208 } 209 } 210 _line_len = len; 211 } 212 213 void ClassListParser::read_class_name_and_attributes() { 214 _class_name = _line; 215 _id = _unspecified; 216 _super = _unspecified; 217 _interfaces->clear(); 218 _source = nullptr; 219 _interfaces_specified = false; 220 221 if ((_token = strchr(_line, ' ')) == nullptr) { 222 // No optional attributes are specified. 223 return; 224 } 225 226 // Mark the end of the name, and go to the next input char 227 *_token++ = '\0'; 228 229 while (*_token) { 230 skip_whitespaces(); 231 232 if (parse_uint_option("id:", &_id)) { 233 continue; 234 } else if (parse_uint_option("super:", &_super)) { 235 check_already_loaded("Super class", _super); 236 continue; 237 } else if (skip_token("interfaces:")) { 238 int i; 239 while (try_parse_uint(&i)) { 240 check_already_loaded("Interface", i); 241 _interfaces->append(i); 242 } 243 } else if (skip_token("source:")) { 244 skip_whitespaces(); 245 _source = _token; 246 char* s = strchr(_token, ' '); 247 if (s == nullptr) { 248 break; // end of input line 249 } else { 250 *s = '\0'; // mark the end of _source 251 _token = s+1; 252 } 253 } else { 254 error("Unknown input"); 255 } 256 } 257 258 // if src is specified 259 // id super interfaces must all be specified 260 // loader may be specified 261 // else 262 // # the class is loaded from classpath 263 // id may be specified 264 // super, interfaces, loader must not be specified 265 } 266 267 void ClassListParser::split_tokens_by_whitespace(int offset, GrowableArray<const char*>* items) { 268 int start = offset; 269 int end; 270 bool done = false; 271 while (!done) { 272 while (_line[start] == ' ' || _line[start] == '\t') start++; 273 end = start; 274 while (_line[end] && _line[end] != ' ' && _line[end] != '\t') end++; 275 if (_line[end] == '\0') { 276 done = true; 277 } else { 278 _line[end] = '\0'; 279 } 280 items->append(_line + start); 281 start = ++end; 282 } 283 } 284 285 int ClassListParser::split_at_tag_from_line() { 286 _token = _line; 287 char* ptr; 288 if ((ptr = strchr(_line, ' ')) == nullptr) { 289 error("Too few items following the @ tag \"%s\" line #%zu", _line, lineno()); 290 return 0; 291 } 292 *ptr++ = '\0'; 293 while (*ptr == ' ' || *ptr == '\t') ptr++; 294 return (int)(ptr - _line); 295 } 296 297 void ClassListParser::parse_at_tags(TRAPS) { 298 assert(_line[0] == '@', "must be"); 299 int offset = split_at_tag_from_line(); 300 assert(offset > 0, "would have exited VM"); 301 302 if (strcmp(_token, LAMBDA_PROXY_TAG) == 0) { 303 _indy_items->clear(); 304 split_tokens_by_whitespace(offset, _indy_items); 305 if (_indy_items->length() < 2) { 306 error("Line with @ tag has too few items \"%s\" line #%zu", _token, lineno()); 307 } 308 if (!parse_lambda_forms_invokers_only()) { 309 _class_name = _indy_items->at(0); 310 check_class_name(_class_name); 311 TempNewSymbol class_name_symbol = SymbolTable::new_symbol(_class_name); 312 if (_indy_items->length() > 0) { 313 // The current line is "@lambda-proxy class_name". Load the proxy class. 314 resolve_indy(THREAD, class_name_symbol); 315 } 316 } 317 } else if (strcmp(_token, LAMBDA_FORM_TAG) == 0) { 318 LambdaFormInvokers::append(os::strdup((const char*)(_line + offset), mtInternal)); 319 } else if (strcmp(_token, CONSTANT_POOL_TAG) == 0) { 320 _token = _line + offset; 321 parse_constant_pool_tag(); 322 } else if (strcmp(_token, ARRAY_TAG) == 0) { 323 _token = _line + offset; 324 parse_array_dimension_tag(); 325 } else if (strcmp(_token, CLASS_REFLECTION_DATA_TAG) == 0) { 326 _token = _line + offset; 327 parse_class_reflection_data_tag(); 328 } else if (strcmp(_token, DYNAMIC_PROXY_TAG) == 0) { 329 _token = _line + offset; 330 parse_dynamic_proxy_tag(); 331 } else if (strcmp(_token, LOADER_NEGATIVE_CACHE_TAG) == 0) { 332 _token = _line + offset; 333 parse_loader_negative_cache_tag(); 334 } else { 335 error("Invalid @ tag at the beginning of line \"%s\" line #%zu", _token, lineno()); 336 } 337 } 338 339 void ClassListParser::skip_whitespaces() { 340 while (*_token == ' ' || *_token == '\t') { 341 _token ++; 342 } 343 } 344 345 void ClassListParser::skip_non_whitespaces() { 346 while (*_token && *_token != ' ' && *_token != '\t') { 347 _token ++; 348 } 349 } 350 351 void ClassListParser::parse_int(int* value) { 352 skip_whitespaces(); 353 if (sscanf(_token, "%i", value) == 1) { 354 skip_non_whitespaces(); 355 } else { 356 error("Error: expected integer"); 357 } 358 } 359 360 void ClassListParser::parse_uint(int* value) { 361 parse_int(value); 362 if (*value < 0) { 363 error("Error: negative integers not allowed (%d)", *value); 364 } 365 } 366 367 bool ClassListParser::try_parse_uint(int* value) { 368 skip_whitespaces(); 369 if (sscanf(_token, "%i", value) == 1) { 370 skip_non_whitespaces(); 371 return true; 372 } 373 return false; 374 } 375 376 bool ClassListParser::skip_token(const char* option_name) { 377 size_t len = strlen(option_name); 378 if (strncmp(_token, option_name, len) == 0) { 379 _token += len; 380 return true; 381 } else { 382 return false; 383 } 384 } 385 386 bool ClassListParser::parse_int_option(const char* option_name, int* value) { 387 if (skip_token(option_name)) { 388 if (*value != _unspecified) { 389 error("%s specified twice", option_name); 390 } else { 391 parse_int(value); 392 return true; 393 } 394 } 395 return false; 396 } 397 398 bool ClassListParser::parse_uint_option(const char* option_name, int* value) { 399 if (skip_token(option_name)) { 400 if (*value != _unspecified) { 401 error("%s specified twice", option_name); 402 } else { 403 parse_uint(value); 404 return true; 405 } 406 } 407 return false; 408 } 409 410 void ClassListParser::print_specified_interfaces() { 411 const int n = _interfaces->length(); 412 jio_fprintf(defaultStream::error_stream(), "Currently specified interfaces[%d] = {\n", n); 413 for (int i=0; i<n; i++) { 414 InstanceKlass* k = lookup_class_by_id(_interfaces->at(i)); 415 jio_fprintf(defaultStream::error_stream(), " %4d = %s\n", _interfaces->at(i), k->name()->as_klass_external_name()); 416 } 417 jio_fprintf(defaultStream::error_stream(), "}\n"); 418 } 419 420 void ClassListParser::print_actual_interfaces(InstanceKlass* ik) { 421 int n = ik->local_interfaces()->length(); 422 jio_fprintf(defaultStream::error_stream(), "Actual interfaces[%d] = {\n", n); 423 for (int i = 0; i < n; i++) { 424 InstanceKlass* e = ik->local_interfaces()->at(i); 425 jio_fprintf(defaultStream::error_stream(), " %s\n", e->name()->as_klass_external_name()); 426 } 427 jio_fprintf(defaultStream::error_stream(), "}\n"); 428 } 429 430 void ClassListParser::print_diagnostic_info(outputStream* st, const char* msg, ...) { 431 va_list ap; 432 va_start(ap, msg); 433 print_diagnostic_info(st, msg, ap); 434 va_end(ap); 435 } 436 437 void ClassListParser::print_diagnostic_info(outputStream* st, const char* msg, va_list ap) { 438 int error_index = pointer_delta_as_int(_token, _line); 439 if (error_index >= _line_len) { 440 error_index = _line_len - 1; 441 } 442 if (error_index < 0) { 443 error_index = 0; 444 } 445 446 jio_fprintf(defaultStream::error_stream(), 447 "An error has occurred while processing class list file %s %zu:%d.\n", 448 _classlist_file, lineno(), (error_index + 1)); 449 jio_vfprintf(defaultStream::error_stream(), msg, ap); 450 451 if (_line_len <= 0) { 452 st->print("\n"); 453 } else { 454 st->print(":\n"); 455 for (int i=0; i<_line_len; i++) { 456 char c = _line[i]; 457 if (c == '\0') { 458 st->print("%s", " "); 459 } else { 460 st->print("%c", c); 461 } 462 } 463 st->print("\n"); 464 for (int i=0; i<error_index; i++) { 465 st->print("%s", " "); 466 } 467 st->print("^\n"); 468 } 469 } 470 471 void ClassListParser::error(const char* msg, ...) { 472 va_list ap; 473 va_start(ap, msg); 474 fileStream fs(defaultStream::error_stream()); 475 //TODO: we should write to UL/error instead, but that requires fixing some tests cases. 476 //LogTarget(Error, cds) lt; 477 //LogStream ls(lt); 478 print_diagnostic_info(&fs, msg, ap); 479 va_end(ap); 480 vm_exit_during_initialization("class list format error.", nullptr); 481 } 482 483 void ClassListParser::check_class_name(const char* class_name) { 484 const char* err = nullptr; 485 size_t len = strlen(class_name); 486 if (len > (size_t)Symbol::max_length()) { 487 err = "class name too long"; 488 } else { 489 assert(Symbol::max_length() < INT_MAX && len < INT_MAX, "must be"); 490 if (!UTF8::is_legal_utf8((const unsigned char*)class_name, len, /*version_leq_47*/false)) { 491 err = "class name is not valid UTF8"; 492 } 493 } 494 if (err != nullptr) { 495 jio_fprintf(defaultStream::error_stream(), 496 "An error has occurred while processing class list file %s:%zu %s\n", 497 _classlist_file, lineno(), err); 498 vm_exit_during_initialization("class list format error.", nullptr); 499 } 500 } 501 502 void ClassListParser::constant_pool_resolution_warning(const char* msg, ...) { 503 va_list ap; 504 va_start(ap, msg); 505 LogTarget(Warning, cds, resolve) lt; 506 LogStream ls(lt); 507 print_diagnostic_info(&ls, msg, ap); 508 ls.print("Your classlist may be out of sync with the JDK or the application."); 509 va_end(ap); 510 } 511 512 // This function is used for loading classes for customized class loaders 513 // during archive dumping. 514 InstanceKlass* ClassListParser::load_class_from_source(Symbol* class_name, TRAPS) { 515 #if !(defined(_LP64) && (defined(LINUX) || defined(__APPLE__) || defined(_WINDOWS))) 516 // The only supported platforms are: (1) Linux/64-bit and (2) Solaris/64-bit and 517 // (3) MacOSX/64-bit and (4) Windowss/64-bit 518 // This #if condition should be in sync with the areCustomLoadersSupportedForCDS 519 // method in test/lib/jdk/test/lib/Platform.java. 520 error("AppCDS custom class loaders not supported on this platform"); 521 #endif 522 523 if (!is_super_specified()) { 524 error("If source location is specified, super class must be also specified"); 525 } 526 if (!is_id_specified()) { 527 error("If source location is specified, id must be also specified"); 528 } 529 if (strncmp(_class_name, "java/", 5) == 0) { 530 log_info(cds)("Prohibited package for non-bootstrap classes: %s.class from %s", 531 _class_name, _source); 532 THROW_NULL(vmSymbols::java_lang_ClassNotFoundException()); 533 } 534 535 ResourceMark rm; 536 char * source_path = os::strdup_check_oom(ClassLoader::uri_to_path(_source)); 537 InstanceKlass* k = UnregisteredClasses::load_class(class_name, source_path, CHECK_NULL); 538 if (k->local_interfaces()->length() != _interfaces->length()) { 539 print_specified_interfaces(); 540 print_actual_interfaces(k); 541 error("The number of interfaces (%d) specified in class list does not match the class file (%d)", 542 _interfaces->length(), k->local_interfaces()->length()); 543 } 544 545 assert(k->is_shared_unregistered_class(), "must be"); 546 547 bool added = SystemDictionaryShared::add_unregistered_class(THREAD, k); 548 if (!added) { 549 // We allow only a single unregistered class for each unique name. 550 error("Duplicated class %s", _class_name); 551 } 552 553 return k; 554 } 555 556 void ClassListParser::populate_cds_indy_info(const constantPoolHandle &pool, int cp_index, CDSIndyInfo* cii, TRAPS) { 557 // Caller needs to allocate ResourceMark. 558 int type_index = pool->bootstrap_name_and_type_ref_index_at(cp_index); 559 int name_index = pool->name_ref_index_at(type_index); 560 cii->add_item(pool->symbol_at(name_index)->as_C_string()); 561 int sig_index = pool->signature_ref_index_at(type_index); 562 cii->add_item(pool->symbol_at(sig_index)->as_C_string()); 563 int argc = pool->bootstrap_argument_count_at(cp_index); 564 if (argc > 0) { 565 for (int arg_i = 0; arg_i < argc; arg_i++) { 566 int arg = pool->bootstrap_argument_index_at(cp_index, arg_i); 567 jbyte tag = pool->tag_at(arg).value(); 568 if (tag == JVM_CONSTANT_MethodType) { 569 cii->add_item(pool->method_type_signature_at(arg)->as_C_string()); 570 } else if (tag == JVM_CONSTANT_MethodHandle) { 571 cii->add_ref_kind(pool->method_handle_ref_kind_at(arg)); 572 int callee_index = pool->method_handle_klass_index_at(arg); 573 Klass* callee = pool->klass_at(callee_index, CHECK); 574 cii->add_item(callee->name()->as_C_string()); 575 cii->add_item(pool->method_handle_name_ref_at(arg)->as_C_string()); 576 cii->add_item(pool->method_handle_signature_ref_at(arg)->as_C_string()); 577 } else { 578 ShouldNotReachHere(); 579 } 580 } 581 } 582 } 583 584 bool ClassListParser::is_matching_cp_entry(const constantPoolHandle &pool, int cp_index, TRAPS) { 585 ResourceMark rm(THREAD); 586 CDSIndyInfo cii; 587 populate_cds_indy_info(pool, cp_index, &cii, CHECK_0); 588 GrowableArray<const char*>* items = cii.items(); 589 int indy_info_offset = 1; 590 if (_indy_items->length() - indy_info_offset != items->length()) { 591 return false; 592 } 593 for (int i = 0; i < items->length(); i++) { 594 if (strcmp(_indy_items->at(i + indy_info_offset), items->at(i)) != 0) { 595 return false; 596 } 597 } 598 return true; 599 } 600 601 void ClassListParser::resolve_indy(JavaThread* current, Symbol* class_name_symbol) { 602 ExceptionMark em(current); 603 JavaThread* THREAD = current; // For exception macros. 604 ClassListParser::resolve_indy_impl(class_name_symbol, THREAD); 605 if (HAS_PENDING_EXCEPTION) { 606 ResourceMark rm(current); 607 char* ex_msg = (char*)""; 608 oop message = java_lang_Throwable::message(PENDING_EXCEPTION); 609 if (message != nullptr) { 610 ex_msg = java_lang_String::as_utf8_string(message); 611 } 612 log_warning(cds)("resolve_indy for class %s has encountered exception: %s %s", 613 class_name_symbol->as_C_string(), 614 PENDING_EXCEPTION->klass()->external_name(), 615 ex_msg); 616 CLEAR_PENDING_EXCEPTION; 617 } 618 } 619 620 void ClassListParser::resolve_indy_impl(Symbol* class_name_symbol, TRAPS) { 621 Handle class_loader(THREAD, SystemDictionary::java_system_loader()); 622 Handle protection_domain; 623 Klass* klass = SystemDictionary::resolve_or_fail(class_name_symbol, class_loader, protection_domain, true, CHECK); 624 if (klass->is_instance_klass()) { 625 InstanceKlass* ik = InstanceKlass::cast(klass); 626 MetaspaceShared::try_link_class(THREAD, ik); 627 if (!ik->is_linked()) { 628 // Verification of ik has failed 629 return; 630 } 631 632 ConstantPool* cp = ik->constants(); 633 ConstantPoolCache* cpcache = cp->cache(); 634 bool found = false; 635 for (int indy_index = 0; indy_index < cpcache->resolved_indy_entries_length(); indy_index++) { 636 int pool_index = cpcache->resolved_indy_entry_at(indy_index)->constant_pool_index(); 637 constantPoolHandle pool(THREAD, cp); 638 BootstrapInfo bootstrap_specifier(pool, pool_index, indy_index); 639 Handle bsm = bootstrap_specifier.resolve_bsm(CHECK); 640 if (!SystemDictionaryShared::is_supported_invokedynamic(&bootstrap_specifier)) { 641 log_debug(cds, lambda)("is_supported_invokedynamic check failed for cp_index %d", pool_index); 642 continue; 643 } 644 bool matched = is_matching_cp_entry(pool, pool_index, CHECK); 645 if (matched) { 646 found = true; 647 CallInfo info; 648 bool is_done = bootstrap_specifier.resolve_previously_linked_invokedynamic(info, CHECK); 649 if (!is_done) { 650 // resolve it 651 Handle recv; 652 LinkResolver::resolve_invoke(info, 653 recv, 654 pool, 655 indy_index, 656 Bytecodes::_invokedynamic, CHECK); 657 break; 658 } 659 cpcache->set_dynamic_call(info, indy_index); 660 } 661 } 662 if (!found) { 663 ResourceMark rm(THREAD); 664 log_warning(cds)("No invoke dynamic constant pool entry can be found for class %s. The classlist is probably out-of-date.", 665 class_name_symbol->as_C_string()); 666 } 667 } 668 } 669 670 Klass* ClassListParser::load_current_class(Symbol* class_name_symbol, TRAPS) { 671 Klass* klass; 672 if (!is_loading_from_source()) { 673 // Load classes for the boot/platform/app loaders only. 674 if (is_super_specified()) { 675 error("If source location is not specified, super class must not be specified"); 676 } 677 if (are_interfaces_specified()) { 678 error("If source location is not specified, interface(s) must not be specified"); 679 } 680 681 if (Signature::is_array(class_name_symbol)) { 682 // array classes are not supported in class list. 683 THROW_NULL(vmSymbols::java_lang_ClassNotFoundException()); 684 } 685 686 JavaValue result(T_OBJECT); 687 // Call java_system_loader().loadClass() directly, which will 688 // delegate to the correct loader (boot, platform or app) depending on 689 // the package name. 690 691 // ClassLoader.loadClass() wants external class name format, i.e., convert '/' chars to '.' 692 Handle ext_class_name = java_lang_String::externalize_classname(class_name_symbol, CHECK_NULL); 693 Handle loader = Handle(THREAD, SystemDictionary::java_system_loader()); 694 695 JavaCalls::call_virtual(&result, 696 loader, //SystemDictionary::java_system_loader(), 697 vmClasses::ClassLoader_klass(), 698 vmSymbols::loadClass_name(), 699 vmSymbols::string_class_signature(), 700 ext_class_name, 701 CHECK_NULL); 702 703 assert(result.get_type() == T_OBJECT, "just checking"); 704 oop obj = result.get_oop(); 705 assert(obj != nullptr, "jdk.internal.loader.BuiltinClassLoader::loadClass never returns null"); 706 klass = java_lang_Class::as_Klass(obj); 707 } else { 708 // If "source:" tag is specified, all super class and super interfaces must be specified in the 709 // class list file. 710 klass = load_class_from_source(class_name_symbol, CHECK_NULL); 711 } 712 713 assert(klass != nullptr, "exception should have been thrown"); 714 assert(klass->is_instance_klass(), "array classes should have been filtered out"); 715 716 if (is_id_specified()) { 717 InstanceKlass* ik = InstanceKlass::cast(klass); 718 int id = this->id(); 719 SystemDictionaryShared::update_shared_entry(ik, id); 720 bool created; 721 id2klass_table()->put_if_absent(id, ik, &created); 722 if (!created) { 723 error("Duplicated ID %d for class %s", id, _class_name); 724 } 725 if (id2klass_table()->maybe_grow()) { 726 log_info(cds, hashtables)("Expanded id2klass_table() to %d", id2klass_table()->table_size()); 727 } 728 } 729 730 return klass; 731 } 732 733 bool ClassListParser::is_loading_from_source() { 734 return (_source != nullptr); 735 } 736 737 InstanceKlass* ClassListParser::lookup_class_by_id(int id) { 738 InstanceKlass** klass_ptr = id2klass_table()->get(id); 739 if (klass_ptr == nullptr) { 740 error("Class ID %d has not been defined", id); 741 } 742 assert(*klass_ptr != nullptr, "must be"); 743 return *klass_ptr; 744 } 745 746 747 InstanceKlass* ClassListParser::lookup_super_for_current_class(Symbol* super_name) { 748 if (!is_loading_from_source()) { 749 return nullptr; 750 } 751 752 InstanceKlass* k = lookup_class_by_id(super()); 753 if (super_name != k->name()) { 754 error("The specified super class %s (id %d) does not match actual super class %s", 755 k->name()->as_klass_external_name(), super(), 756 super_name->as_klass_external_name()); 757 } 758 return k; 759 } 760 761 InstanceKlass* ClassListParser::lookup_interface_for_current_class(Symbol* interface_name) { 762 if (!is_loading_from_source()) { 763 return nullptr; 764 } 765 766 const int n = _interfaces->length(); 767 if (n == 0) { 768 error("Class %s implements the interface %s, but no interface has been specified in the input line", 769 _class_name, interface_name->as_klass_external_name()); 770 ShouldNotReachHere(); 771 } 772 773 int i; 774 for (i=0; i<n; i++) { 775 InstanceKlass* k = lookup_class_by_id(_interfaces->at(i)); 776 if (interface_name == k->name()) { 777 return k; 778 } 779 } 780 781 // interface_name is not specified by the "interfaces:" keyword. 782 print_specified_interfaces(); 783 error("The interface %s implemented by class %s does not match any of the specified interface IDs", 784 interface_name->as_klass_external_name(), _class_name); 785 ShouldNotReachHere(); 786 return nullptr; 787 } 788 789 InstanceKlass* ClassListParser::find_builtin_class_helper(JavaThread* current, Symbol* class_name_symbol, oop class_loader_oop) { 790 Handle class_loader(current, class_loader_oop); 791 Handle protection_domain; 792 return SystemDictionary::find_instance_klass(current, class_name_symbol, class_loader, protection_domain); 793 } 794 795 InstanceKlass* ClassListParser::find_builtin_class(JavaThread* current, const char* class_name) { 796 TempNewSymbol class_name_symbol = SymbolTable::new_symbol(class_name); 797 InstanceKlass* ik; 798 799 if ( (ik = find_builtin_class_helper(current, class_name_symbol, nullptr)) != nullptr 800 || (ik = find_builtin_class_helper(current, class_name_symbol, SystemDictionary::java_platform_loader())) != nullptr 801 || (ik = find_builtin_class_helper(current, class_name_symbol, SystemDictionary::java_system_loader())) != nullptr) { 802 return ik; 803 } else { 804 return nullptr; 805 } 806 } 807 808 void ClassListParser::parse_array_dimension_tag() { 809 if (parse_lambda_forms_invokers_only()) { 810 return; 811 } 812 813 skip_whitespaces(); 814 char* class_name = _token; 815 skip_non_whitespaces(); 816 *_token = '\0'; 817 _token ++; 818 819 skip_whitespaces(); 820 int dim; 821 parse_uint(&dim); 822 823 JavaThread* THREAD = JavaThread::current(); 824 InstanceKlass* ik = find_builtin_class(THREAD, class_name); 825 if (ik == nullptr) { 826 _token = class_name; 827 if (strstr(class_name, "/$Proxy") != nullptr || 828 strstr(class_name, "MethodHandle$Species_") != nullptr) { 829 // ignore -- TODO: we should filter these out in classListWriter.cpp 830 } else { 831 constant_pool_resolution_warning("class %s is not (yet) loaded by one of the built-in loaders", class_name); 832 } 833 return; 834 } 835 836 if (dim > 0) { 837 ik->array_klass(dim, THREAD); 838 if (HAS_PENDING_EXCEPTION) { 839 error("Array klass allocation failed: %s %d", _class_name, dim); 840 } 841 } 842 } 843 844 void ClassListParser::parse_constant_pool_tag() { 845 if (parse_lambda_forms_invokers_only()) { 846 return; 847 } 848 849 JavaThread* THREAD = JavaThread::current(); 850 skip_whitespaces(); 851 char* class_name = _token; 852 skip_non_whitespaces(); 853 *_token = '\0'; 854 _token ++; 855 856 InstanceKlass* ik = find_builtin_class(THREAD, class_name); 857 if (ik == nullptr) { 858 _token = class_name; 859 if (strstr(class_name, "/$Proxy") != nullptr || 860 strstr(class_name, "MethodHandle$Species_") != nullptr) { 861 // ignore -- TODO: we should filter these out in classListWriter.cpp 862 } else { 863 constant_pool_resolution_warning("class %s is not (yet) loaded by one of the built-in loaders", class_name); 864 } 865 return; 866 } 867 868 ResourceMark rm(THREAD); 869 constantPoolHandle cp(THREAD, ik->constants()); 870 GrowableArray<bool> preresolve_list(cp->length(), cp->length(), false); 871 bool preresolve_class = false; 872 bool preresolve_fmi = false; 873 bool preresolve_indy = false; 874 875 while (*_token) { 876 int cp_index; 877 skip_whitespaces(); 878 parse_uint(&cp_index); 879 if (cp_index < 1 || cp_index >= cp->length()) { 880 constant_pool_resolution_warning("Invalid constant pool index %d", cp_index); 881 return; 882 } else { 883 preresolve_list.at_put(cp_index, true); 884 } 885 constantTag cp_tag = cp->tag_at(cp_index); 886 switch (cp_tag.value()) { 887 case JVM_CONSTANT_UnresolvedClass: 888 preresolve_class = true; 889 break; 890 case JVM_CONSTANT_UnresolvedClassInError: 891 case JVM_CONSTANT_Class: 892 // ignore 893 break; 894 case JVM_CONSTANT_Fieldref: 895 case JVM_CONSTANT_Methodref: 896 case JVM_CONSTANT_InterfaceMethodref: 897 preresolve_fmi = true; 898 break; 899 case JVM_CONSTANT_InvokeDynamic: 900 preresolve_indy = true; 901 break; 902 default: 903 constant_pool_resolution_warning("Unsupported constant pool index %d: %s (type=%d)", 904 cp_index, cp_tag.internal_name(), cp_tag.value()); 905 return; 906 } 907 } 908 909 if (preresolve_class) { 910 AOTConstantPoolResolver::preresolve_class_cp_entries(THREAD, ik, &preresolve_list); 911 } 912 if (preresolve_fmi) { 913 // FIXME: too coarse; doesn't cover resolution of Class entries 914 // JavaThread::NoJavaCodeMark no_java_code(THREAD); // ensure no clinits are exectued 915 AOTConstantPoolResolver::preresolve_field_and_method_cp_entries(THREAD, ik, &preresolve_list); 916 } 917 if (preresolve_indy) { 918 AOTConstantPoolResolver::preresolve_indy_cp_entries(THREAD, ik, &preresolve_list); 919 } 920 } 921 922 void ClassListParser::parse_class_reflection_data_tag() { 923 if (parse_lambda_forms_invokers_only()) { 924 return; 925 } 926 927 JavaThread* THREAD = JavaThread::current(); 928 skip_whitespaces(); 929 char* class_name = _token; 930 skip_non_whitespaces(); 931 *_token = '\0'; 932 _token ++; 933 934 InstanceKlass* ik = find_builtin_class(THREAD, class_name); 935 if (ik == nullptr) { 936 _token = class_name; 937 if (strstr(class_name, "/$Proxy") != nullptr || 938 strstr(class_name, "MethodHandle$Species_") != nullptr) { 939 // ignore -- TODO: we should filter these out in classListWriter.cpp 940 } else { 941 warning("%s: class not found: %s", CLASS_REFLECTION_DATA_TAG, class_name); 942 } 943 return; 944 } 945 946 ResourceMark rm(THREAD); 947 948 int rd_flags = _unspecified; 949 while (*_token) { 950 skip_whitespaces(); 951 if (rd_flags != _unspecified) { 952 error("rd_flags specified twice"); 953 return; 954 } 955 parse_uint(&rd_flags); 956 } 957 if (rd_flags == _unspecified) { 958 error("no rd_flags specified"); 959 return; 960 } 961 962 if (CDSConfig::is_dumping_reflection_data()) { 963 AOTConstantPoolResolver::generate_reflection_data(THREAD, ik, rd_flags); 964 } 965 } 966 967 oop ClassListParser::loader_from_type(const char* loader_type) { 968 oop loader; 969 if (!ArchiveUtils::builtin_loader_from_type(loader_type, &loader)) { 970 error("Unknown loader %s", loader_type); 971 } 972 return loader; 973 } 974 975 void ClassListParser::parse_dynamic_proxy_tag() { 976 if (parse_lambda_forms_invokers_only()) { 977 return; 978 } 979 980 skip_whitespaces(); 981 char* loader_type = _token; 982 skip_non_whitespaces(); 983 *_token = '\0'; 984 _token ++; 985 986 skip_whitespaces(); 987 char* proxy_name_str = _token; 988 skip_non_whitespaces(); 989 *_token = '\0'; 990 _token ++; 991 992 skip_whitespaces(); 993 int access_flags; 994 parse_uint(&access_flags); 995 996 skip_whitespaces(); 997 int num_intfs; 998 parse_uint(&num_intfs); 999 1000 JavaThread* THREAD = JavaThread::current(); 1001 Handle loader(THREAD, loader_from_type(loader_type)); 1002 Handle proxy_name(THREAD, java_lang_String::create_oop_from_str(proxy_name_str, THREAD)); 1003 if (HAS_PENDING_EXCEPTION) { 1004 error("Out of memory"); 1005 } 1006 1007 objArrayHandle interfaces(THREAD, oopFactory::new_objArray(vmClasses::Class_klass(), num_intfs, THREAD)); 1008 if (HAS_PENDING_EXCEPTION) { 1009 error("Out of memory"); 1010 } 1011 1012 for (int i = 0; i < num_intfs; i++) { 1013 skip_whitespaces(); 1014 char* intf_name = _token; 1015 skip_non_whitespaces(); 1016 *_token = '\0'; 1017 _token ++; 1018 1019 InstanceKlass* ik = find_builtin_class(THREAD, intf_name); 1020 if (ik != nullptr) { 1021 interfaces()->obj_at_put(i, ik->java_mirror()); 1022 } else { 1023 error("Unknown class %s", intf_name); 1024 } 1025 } 1026 1027 if (strncmp("jdk.proxy", proxy_name_str, 9) != 0) { 1028 return; 1029 } 1030 1031 AOTConstantPoolResolver::define_dynamic_proxy_class(loader, proxy_name, interfaces, access_flags, THREAD); 1032 if (HAS_PENDING_EXCEPTION) { 1033 PENDING_EXCEPTION->print_on(tty); 1034 error("defineProxyClassForCDS failed"); 1035 } 1036 } 1037 1038 void ClassListParser::parse_loader_negative_cache_tag() { 1039 skip_whitespaces(); 1040 char* loader_type = _token; 1041 skip_non_whitespaces(); 1042 *_token = '\0'; 1043 _token ++; 1044 1045 oop loader; 1046 Klass* loader_klass; 1047 if (!strcmp(loader_type, "app")) { 1048 loader = SystemDictionary::java_system_loader(); 1049 loader_klass = vmClasses::jdk_internal_loader_ClassLoaders_AppClassLoader_klass(); 1050 } else if (!strcmp(loader_type, "platform")) { 1051 loader = SystemDictionary::java_platform_loader(); 1052 loader_klass = vmClasses::jdk_internal_loader_ClassLoaders_PlatformClassLoader_klass(); 1053 } else { 1054 warning("%s: unrecognized loader type %s is ignored", LOADER_NEGATIVE_CACHE_TAG, loader_type); 1055 return; 1056 } 1057 1058 char* contents = _token; 1059 skip_non_whitespaces(); 1060 *_token = '\0'; 1061 _token ++; 1062 1063 if (ArchiveLoaderLookupCache) { 1064 TempNewSymbol method = SymbolTable::new_symbol("generateNegativeLookupCache"); 1065 TempNewSymbol signature = SymbolTable::new_symbol("(Ljava/lang/String;)V"); 1066 1067 EXCEPTION_MARK; 1068 HandleMark hm(THREAD); 1069 JavaCallArguments args(Handle(THREAD, loader)); 1070 Handle contents_h = java_lang_String::create_from_str(contents, THREAD); 1071 args.push_oop(contents_h); 1072 JavaValue result(T_VOID); 1073 JavaCalls::call_virtual(&result, 1074 loader_klass, 1075 method, 1076 signature, 1077 &args, THREAD); 1078 if (HAS_PENDING_EXCEPTION) { 1079 Handle exc_handle(THREAD, PENDING_EXCEPTION); 1080 CLEAR_PENDING_EXCEPTION; 1081 1082 log_warning(cds)("Exception during BuiltinClassLoader::generateNegativeLookupCache() call for %s loader", loader_type); 1083 LogStreamHandle(Debug, cds) log; 1084 if (log.is_enabled()) { 1085 java_lang_Throwable::print_stack_trace(exc_handle, &log); 1086 } 1087 } 1088 } 1089 } 1090