1 /* 2 * Copyright (c) 2015, 2025, 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 "cds/aotConstantPoolResolver.hpp" 26 #include "cds/aotLogging.hpp" 27 #include "cds/archiveUtils.hpp" 28 #include "cds/classListParser.hpp" 29 #include "cds/lambdaFormInvokers.hpp" 30 #include "cds/lambdaProxyClassDictionary.hpp" 31 #include "cds/metaspaceShared.hpp" 32 #include "cds/unregisteredClasses.hpp" 33 #include "classfile/classLoaderExt.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/bytecodeStream.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 "runtime/atomic.hpp" 51 #include "runtime/globals_extension.hpp" 52 #include "runtime/handles.inline.hpp" 53 #include "runtime/java.hpp" 54 #include "runtime/javaCalls.hpp" 55 #include "utilities/defaultStream.hpp" 56 #include "utilities/macros.hpp" 57 #include "utilities/utf8.hpp" 58 59 const char* ClassListParser::CONSTANT_POOL_TAG = "@cp"; 60 const char* ClassListParser::LAMBDA_FORM_TAG = "@lambda-form-invoker"; 61 const char* ClassListParser::LAMBDA_PROXY_TAG = "@lambda-proxy"; 62 63 volatile Thread* ClassListParser::_parsing_thread = nullptr; 64 ClassListParser* ClassListParser::_instance = nullptr; 65 66 ClassListParser::ClassListParser(const char* file, ParseMode parse_mode) : 67 _classlist_file(file), 68 _id2klass_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE), 69 _file_input(do_open(file), /* need_close=*/true), 70 _input_stream(&_file_input), 71 _parse_mode(parse_mode) { 72 aot_log_info(aot)("Parsing %s%s", file, 73 parse_lambda_forms_invokers_only() ? " (lambda form invokers only)" : ""); 74 if (!_file_input.is_open()) { 75 char reason[JVM_MAXPATHLEN]; 76 os::lasterror(reason, JVM_MAXPATHLEN); 77 vm_exit_during_initialization(err_msg("Loading %s %s failed", 78 FLAG_IS_DEFAULT(AOTConfiguration) ? 79 "classlist" : "AOTConfiguration file", 80 file), 81 reason); 82 } 83 _token = _line = nullptr; 84 _interfaces = new (mtClass) GrowableArray<int>(10, mtClass); 85 _indy_items = new (mtClass) GrowableArray<const char*>(9, mtClass); 86 87 // _instance should only be accessed by the thread that created _instance. 88 assert(_instance == nullptr, "must be singleton"); 89 _instance = this; 90 Atomic::store(&_parsing_thread, Thread::current()); 91 } 92 93 FILE* ClassListParser::do_open(const char* file) { 94 // Use os::open() because neither fopen() nor os::fopen() 95 // can handle long path name on Windows. (See JDK-8216184) 96 int fd = os::open(file, O_RDONLY, S_IREAD); 97 FILE* fp = nullptr; 98 if (fd != -1) { 99 // Obtain a FILE* from the file descriptor so that _input_stream 100 // can be used in ClassListParser::parse() 101 fp = os::fdopen(fd, "r"); 102 } 103 return fp; 104 } 105 106 bool ClassListParser::is_parsing_thread() { 107 return Atomic::load(&_parsing_thread) == Thread::current(); 108 } 109 110 ClassListParser::~ClassListParser() { 111 Atomic::store(&_parsing_thread, (Thread*)nullptr); 112 delete _indy_items; 113 delete _interfaces; 114 _instance = nullptr; 115 } 116 117 void ClassListParser::parse_classlist(const char* classlist_path, ParseMode parse_mode, TRAPS) { 118 UnregisteredClasses::initialize(CHECK); 119 ClassListParser parser(classlist_path, parse_mode); 120 parser.parse(THREAD); 121 } 122 123 void ClassListParser::parse(TRAPS) { 124 for (; !_input_stream.done(); _input_stream.next()) { 125 _line = _input_stream.current_line(); 126 clean_up_input_line(); 127 128 // Each line in the classlist can be one of three forms: 129 if (_line[0] == '#') { 130 // A comment; ignore it 131 } else if (_line[0] == '@') { 132 // @xxx - a tag like @lambda-proxy, to be parsed by parse_at_tags() 133 parse_at_tags(CHECK); 134 } else { 135 // A class name, followed by optional attributes. E.g. 136 // java/lang/String 137 // java/lang/Object id: 1 138 // my/pkg/TestClass id: 5 super: 1 interfaces: 3 4 source: foo.jar 139 parse_class_name_and_attributes(CHECK); 140 } 141 } 142 } 143 144 void ClassListParser::parse_class_name_and_attributes(TRAPS) { 145 read_class_name_and_attributes(); 146 147 if (parse_lambda_forms_invokers_only()) { 148 return; 149 } 150 151 check_class_name(_class_name); 152 TempNewSymbol class_name_symbol = SymbolTable::new_symbol(_class_name); 153 Klass* klass = load_current_class(class_name_symbol, THREAD); 154 if (HAS_PENDING_EXCEPTION) { 155 if (PENDING_EXCEPTION->is_a(vmClasses::OutOfMemoryError_klass())) { 156 // If we have run out of memory, don't try to load the rest of the classes in 157 // the classlist. Throw an exception, which will terminate the dumping process. 158 return; // THROW 159 } 160 161 ResourceMark rm(THREAD); 162 char* ex_msg = (char*)""; 163 oop message = java_lang_Throwable::message(PENDING_EXCEPTION); 164 if (message != nullptr) { 165 ex_msg = java_lang_String::as_utf8_string(message); 166 } 167 aot_log_warning(aot)("%s: %s", PENDING_EXCEPTION->klass()->external_name(), ex_msg); 168 // We might have an invalid class name or an bad class. Warn about it 169 // and keep going to the next line. 170 CLEAR_PENDING_EXCEPTION; 171 aot_log_warning(aot)("Preload Warning: Cannot find %s", _class_name); 172 return; 173 } 174 175 assert(klass != nullptr, "sanity"); 176 if (aot_log_is_enabled(Trace, aot)) { 177 ResourceMark rm(THREAD); 178 log_trace(aot)("Shared spaces preloaded: %s", klass->external_name()); 179 } 180 181 if (klass->is_instance_klass()) { 182 InstanceKlass* ik = InstanceKlass::cast(klass); 183 184 // Link the class to cause the bytecodes to be rewritten and the 185 // cpcache to be created. The linking is done as soon as classes 186 // are loaded in order that the related data structures (klass and 187 // cpCache) are located together. 188 MetaspaceShared::try_link_class(THREAD, ik); 189 } 190 } 191 192 void ClassListParser::clean_up_input_line() { 193 int len = (int)strlen(_line); 194 int i; 195 // Replace \t\r\n\f with ' ' 196 for (i=0; i<len; i++) { 197 if (_line[i] == '\t' || _line[i] == '\r' || _line[i] == '\n' || _line[i] == '\f') { 198 _line[i] = ' '; 199 } 200 } 201 202 // Remove trailing newline/space 203 while (len > 0) { 204 if (_line[len-1] == ' ') { 205 _line[len-1] = '\0'; 206 len --; 207 } else { 208 break; 209 } 210 } 211 _line_len = len; 212 } 213 214 void ClassListParser::read_class_name_and_attributes() { 215 _class_name = _line; 216 _id = _unspecified; 217 _super = _unspecified; 218 _interfaces->clear(); 219 _source = nullptr; 220 _interfaces_specified = false; 221 222 if ((_token = strchr(_line, ' ')) == nullptr) { 223 // No optional attributes are specified. 224 return; 225 } 226 227 // Mark the end of the name, and go to the next input char 228 *_token++ = '\0'; 229 230 while (*_token) { 231 skip_whitespaces(); 232 233 if (parse_uint_option("id:", &_id)) { 234 continue; 235 } else if (parse_uint_option("super:", &_super)) { 236 check_already_loaded("Super class", _super); 237 continue; 238 } else if (skip_token("interfaces:")) { 239 int i; 240 while (try_parse_uint(&i)) { 241 check_already_loaded("Interface", i); 242 _interfaces->append(i); 243 } 244 } else if (skip_token("source:")) { 245 skip_whitespaces(); 246 _source = _token; 247 char* s = strchr(_token, ' '); 248 if (s == nullptr) { 249 break; // end of input line 250 } else { 251 *s = '\0'; // mark the end of _source 252 _token = s+1; 253 } 254 } else { 255 error("Unknown input"); 256 } 257 } 258 259 // if src is specified 260 // id super interfaces must all be specified 261 // loader may be specified 262 // else 263 // # the class is loaded from classpath 264 // id may be specified 265 // super, interfaces, loader must not be specified 266 } 267 268 void ClassListParser::split_tokens_by_whitespace(int offset, GrowableArray<const char*>* items) { 269 int start = offset; 270 int end; 271 bool done = false; 272 while (!done) { 273 while (_line[start] == ' ' || _line[start] == '\t') start++; 274 end = start; 275 while (_line[end] && _line[end] != ' ' && _line[end] != '\t') end++; 276 if (_line[end] == '\0') { 277 done = true; 278 } else { 279 _line[end] = '\0'; 280 } 281 items->append(_line + start); 282 start = ++end; 283 } 284 } 285 286 int ClassListParser::split_at_tag_from_line() { 287 _token = _line; 288 char* ptr; 289 if ((ptr = strchr(_line, ' ')) == nullptr) { 290 error("Too few items following the @ tag \"%s\" line #%zu", _line, lineno()); 291 return 0; 292 } 293 *ptr++ = '\0'; 294 while (*ptr == ' ' || *ptr == '\t') ptr++; 295 return (int)(ptr - _line); 296 } 297 298 void ClassListParser::parse_at_tags(TRAPS) { 299 assert(_line[0] == '@', "must be"); 300 int offset = split_at_tag_from_line(); 301 assert(offset > 0, "would have exited VM"); 302 303 if (strcmp(_token, LAMBDA_PROXY_TAG) == 0) { 304 _indy_items->clear(); 305 split_tokens_by_whitespace(offset, _indy_items); 306 if (_indy_items->length() < 2) { 307 error("Line with @ tag has too few items \"%s\" line #%zu", _token, lineno()); 308 } 309 if (!parse_lambda_forms_invokers_only()) { 310 _class_name = _indy_items->at(0); 311 check_class_name(_class_name); 312 TempNewSymbol class_name_symbol = SymbolTable::new_symbol(_class_name); 313 if (_indy_items->length() > 0) { 314 // The current line is "@lambda-proxy class_name". Load the proxy class. 315 resolve_indy(THREAD, class_name_symbol); 316 } 317 } 318 } else if (strcmp(_token, LAMBDA_FORM_TAG) == 0) { 319 LambdaFormInvokers::append(os::strdup((const char*)(_line + offset), mtInternal)); 320 } else if (strcmp(_token, CONSTANT_POOL_TAG) == 0) { 321 _token = _line + offset; 322 parse_constant_pool_tag(); 323 } else { 324 error("Invalid @ tag at the beginning of line \"%s\" line #%zu", _token, lineno()); 325 } 326 } 327 328 void ClassListParser::skip_whitespaces() { 329 while (*_token == ' ' || *_token == '\t') { 330 _token ++; 331 } 332 } 333 334 void ClassListParser::skip_non_whitespaces() { 335 while (*_token && *_token != ' ' && *_token != '\t') { 336 _token ++; 337 } 338 } 339 340 void ClassListParser::parse_int(int* value) { 341 skip_whitespaces(); 342 if (sscanf(_token, "%i", value) == 1) { 343 skip_non_whitespaces(); 344 } else { 345 error("Error: expected integer"); 346 } 347 } 348 349 void ClassListParser::parse_uint(int* value) { 350 parse_int(value); 351 if (*value < 0) { 352 error("Error: negative integers not allowed (%d)", *value); 353 } 354 } 355 356 bool ClassListParser::try_parse_uint(int* value) { 357 skip_whitespaces(); 358 if (sscanf(_token, "%i", value) == 1) { 359 skip_non_whitespaces(); 360 return true; 361 } 362 return false; 363 } 364 365 bool ClassListParser::skip_token(const char* option_name) { 366 size_t len = strlen(option_name); 367 if (strncmp(_token, option_name, len) == 0) { 368 _token += len; 369 return true; 370 } else { 371 return false; 372 } 373 } 374 375 bool ClassListParser::parse_int_option(const char* option_name, int* value) { 376 if (skip_token(option_name)) { 377 if (*value != _unspecified) { 378 error("%s specified twice", option_name); 379 } else { 380 parse_int(value); 381 return true; 382 } 383 } 384 return false; 385 } 386 387 bool ClassListParser::parse_uint_option(const char* option_name, int* value) { 388 if (skip_token(option_name)) { 389 if (*value != _unspecified) { 390 error("%s specified twice", option_name); 391 } else { 392 parse_uint(value); 393 return true; 394 } 395 } 396 return false; 397 } 398 399 GrowableArray<InstanceKlass *> ClassListParser::get_specified_interfaces() { 400 const int n = _interfaces->length(); 401 GrowableArray<InstanceKlass *> specified_interfaces(n); 402 for (int i = 0; i < n; i++) { 403 specified_interfaces.append(lookup_class_by_id(_interfaces->at(i))); 404 } 405 return specified_interfaces; 406 } 407 408 void ClassListParser::print_specified_interfaces() { 409 const int n = _interfaces->length(); 410 jio_fprintf(defaultStream::error_stream(), "Currently specified interfaces[%d] = {\n", n); 411 for (int i=0; i<n; i++) { 412 InstanceKlass* k = lookup_class_by_id(_interfaces->at(i)); 413 jio_fprintf(defaultStream::error_stream(), " %4d = %s\n", _interfaces->at(i), k->name()->as_klass_external_name()); 414 } 415 jio_fprintf(defaultStream::error_stream(), "}\n"); 416 } 417 418 void ClassListParser::print_actual_interfaces(InstanceKlass* ik) { 419 int n = ik->local_interfaces()->length(); 420 jio_fprintf(defaultStream::error_stream(), "Actual interfaces[%d] = {\n", n); 421 for (int i = 0; i < n; i++) { 422 InstanceKlass* e = ik->local_interfaces()->at(i); 423 jio_fprintf(defaultStream::error_stream(), " %s\n", e->name()->as_klass_external_name()); 424 } 425 jio_fprintf(defaultStream::error_stream(), "}\n"); 426 } 427 428 void ClassListParser::print_diagnostic_info(outputStream* st, const char* msg, ...) { 429 va_list ap; 430 va_start(ap, msg); 431 print_diagnostic_info(st, msg, ap); 432 va_end(ap); 433 } 434 435 void ClassListParser::print_diagnostic_info(outputStream* st, const char* msg, va_list ap) { 436 int error_index = pointer_delta_as_int(_token, _line); 437 if (error_index >= _line_len) { 438 error_index = _line_len - 1; 439 } 440 if (error_index < 0) { 441 error_index = 0; 442 } 443 444 st->print("An error has occurred while processing class list file %s %zu:%d.\n", 445 _classlist_file, lineno(), (error_index + 1)); 446 st->vprint(msg, ap); 447 448 if (_line_len <= 0) { 449 st->print("\n"); 450 } else { 451 st->print(":\n"); 452 for (int i=0; i<_line_len; i++) { 453 char c = _line[i]; 454 if (c == '\0') { 455 st->print("%s", " "); 456 } else { 457 st->print("%c", c); 458 } 459 } 460 st->print("\n"); 461 for (int i=0; i<error_index; i++) { 462 st->print("%s", " "); 463 } 464 st->print("^\n"); 465 } 466 } 467 468 void ClassListParser::error(const char* msg, ...) { 469 va_list ap; 470 va_start(ap, msg); 471 fileStream fs(defaultStream::error_stream()); 472 //TODO: we should write to UL/error instead, but that requires fixing some tests cases. 473 //LogTarget(Error, cds) lt; 474 //LogStream ls(lt); 475 print_diagnostic_info(&fs, msg, ap); 476 va_end(ap); 477 vm_exit_during_initialization("class list format error.", nullptr); 478 } 479 480 void ClassListParser::check_class_name(const char* class_name) { 481 const char* err = nullptr; 482 size_t len = strlen(class_name); 483 if (len > (size_t)Symbol::max_length()) { 484 err = "class name too long"; 485 } else { 486 assert(Symbol::max_length() < INT_MAX && len < INT_MAX, "must be"); 487 if (!UTF8::is_legal_utf8((const unsigned char*)class_name, len, /*version_leq_47*/false)) { 488 err = "class name is not valid UTF8"; 489 } 490 } 491 if (err != nullptr) { 492 jio_fprintf(defaultStream::error_stream(), 493 "An error has occurred while processing class list file %s:%zu %s\n", 494 _classlist_file, lineno(), err); 495 vm_exit_during_initialization("class list format error.", nullptr); 496 } 497 } 498 499 void ClassListParser::constant_pool_resolution_warning(const char* msg, ...) { 500 va_list ap; 501 va_start(ap, msg); 502 LogTarget(Warning, aot, resolve) lt; 503 LogStream ls(lt); 504 print_diagnostic_info(&ls, msg, ap); 505 ls.print("Your classlist may be out of sync with the JDK or the application."); 506 va_end(ap); 507 } 508 509 // If an unregistered class U is specified to have a registered supertype S1 510 // named SN but an unregistered class S2 also named SN has already been loaded 511 // S2 will be incorrectly used as the supertype of U instead of S1 due to 512 // limitations in the loading mechanism of unregistered classes. 513 void ClassListParser::check_supertype_obstruction(int specified_supertype_id, const InstanceKlass* specified_supertype, TRAPS) { 514 if (specified_supertype->defined_by_other_loaders()) { 515 return; // Only registered supertypes can be obstructed 516 } 517 const InstanceKlass* obstructor = SystemDictionaryShared::get_unregistered_class(specified_supertype->name()); 518 if (obstructor == nullptr) { 519 return; // No unregistered types with the same name have been loaded, i.e. no obstruction 520 } 521 // 'specified_supertype' is S1, 'obstructor' is S2 from the explanation above 522 ResourceMark rm; 523 THROW_MSG(vmSymbols::java_lang_UnsupportedOperationException(), 524 err_msg("%s (id %d) has super-type %s (id %d) obstructed by another class with the same name", 525 _class_name, _id, specified_supertype->external_name(), specified_supertype_id)); 526 } 527 528 // This function is used for loading classes for customized class loaders 529 // during archive dumping. 530 InstanceKlass* ClassListParser::load_class_from_source(Symbol* class_name, TRAPS) { 531 #if !(defined(_LP64) && (defined(LINUX) || defined(__APPLE__) || defined(_WINDOWS))) 532 // The only supported platforms are: (1) Linux/64-bit and (2) Solaris/64-bit and 533 // (3) MacOSX/64-bit and (4) Windowss/64-bit 534 // This #if condition should be in sync with the areCustomLoadersSupportedForCDS 535 // method in test/lib/jdk/test/lib/Platform.java. 536 error("AppCDS custom class loaders not supported on this platform"); 537 #endif 538 539 if (!is_super_specified()) { 540 error("If source location is specified, super class must be also specified"); 541 } 542 if (!is_id_specified()) { 543 error("If source location is specified, id must be also specified"); 544 } 545 if (strncmp(_class_name, "java/", 5) == 0) { 546 aot_log_info(aot)("Prohibited package for non-bootstrap classes: %s.class from %s", 547 _class_name, _source); 548 THROW_NULL(vmSymbols::java_lang_ClassNotFoundException()); 549 } 550 551 ResourceMark rm; 552 InstanceKlass* specified_super = lookup_class_by_id(_super); 553 GrowableArray<InstanceKlass*> specified_interfaces = get_specified_interfaces(); 554 // Obstruction must be checked before the class loading attempt because it may 555 // cause class loading errors (JVMS 5.3.5.3-5.3.5.4) 556 check_supertype_obstruction(_super, specified_super, CHECK_NULL); 557 for (int i = 0; i < _interfaces->length(); i++) { 558 check_supertype_obstruction(_interfaces->at(i), specified_interfaces.at(i), CHECK_NULL); 559 } 560 561 const char* source_path = ClassLoader::uri_to_path(_source); 562 InstanceKlass* k = UnregisteredClasses::load_class(class_name, source_path, CHECK_NULL); 563 564 if (k->java_super() != specified_super) { 565 error("The specified super class %s (id %d) does not match actual super class %s", 566 specified_super->external_name(), _super, 567 k->java_super()->external_name()); 568 } 569 if (k->local_interfaces()->length() != _interfaces->length()) { 570 print_specified_interfaces(); 571 print_actual_interfaces(k); 572 error("The number of interfaces (%d) specified in class list does not match the class file (%d)", 573 _interfaces->length(), k->local_interfaces()->length()); 574 } 575 for (int i = 0; i < _interfaces->length(); i++) { 576 InstanceKlass* specified_interface = specified_interfaces.at(i); 577 if (!k->local_interfaces()->contains(specified_interface)) { 578 print_specified_interfaces(); 579 print_actual_interfaces(k); 580 error("Specified interface %s (id %d) is not directly implemented", 581 specified_interface->external_name(), _interfaces->at(i)); 582 } 583 } 584 585 assert(k->defined_by_other_loaders(), "must be"); 586 587 bool added = SystemDictionaryShared::add_unregistered_class(THREAD, k); 588 if (!added) { 589 // We allow only a single unregistered class for each unique name. 590 error("Duplicated class %s", _class_name); 591 } 592 593 return k; 594 } 595 596 void ClassListParser::populate_cds_indy_info(const constantPoolHandle &pool, int cp_index, CDSIndyInfo* cii, TRAPS) { 597 // Caller needs to allocate ResourceMark. 598 int type_index = pool->bootstrap_name_and_type_ref_index_at(cp_index); 599 int name_index = pool->name_ref_index_at(type_index); 600 cii->add_item(pool->symbol_at(name_index)->as_C_string()); 601 int sig_index = pool->signature_ref_index_at(type_index); 602 cii->add_item(pool->symbol_at(sig_index)->as_C_string()); 603 int argc = pool->bootstrap_argument_count_at(cp_index); 604 if (argc > 0) { 605 for (int arg_i = 0; arg_i < argc; arg_i++) { 606 int arg = pool->bootstrap_argument_index_at(cp_index, arg_i); 607 jbyte tag = pool->tag_at(arg).value(); 608 if (tag == JVM_CONSTANT_MethodType) { 609 cii->add_item(pool->method_type_signature_at(arg)->as_C_string()); 610 } else if (tag == JVM_CONSTANT_MethodHandle) { 611 cii->add_ref_kind(pool->method_handle_ref_kind_at(arg)); 612 int callee_index = pool->method_handle_klass_index_at(arg); 613 Klass* callee = pool->klass_at(callee_index, CHECK); 614 cii->add_item(callee->name()->as_C_string()); 615 cii->add_item(pool->method_handle_name_ref_at(arg)->as_C_string()); 616 cii->add_item(pool->method_handle_signature_ref_at(arg)->as_C_string()); 617 } else { 618 ShouldNotReachHere(); 619 } 620 } 621 } 622 } 623 624 bool ClassListParser::is_matching_cp_entry(const constantPoolHandle &pool, int cp_index, TRAPS) { 625 ResourceMark rm(THREAD); 626 CDSIndyInfo cii; 627 populate_cds_indy_info(pool, cp_index, &cii, CHECK_0); 628 GrowableArray<const char*>* items = cii.items(); 629 int indy_info_offset = 1; 630 if (_indy_items->length() - indy_info_offset != items->length()) { 631 return false; 632 } 633 for (int i = 0; i < items->length(); i++) { 634 if (strcmp(_indy_items->at(i + indy_info_offset), items->at(i)) != 0) { 635 return false; 636 } 637 } 638 return true; 639 } 640 641 void ClassListParser::resolve_indy(JavaThread* current, Symbol* class_name_symbol) { 642 ExceptionMark em(current); 643 JavaThread* THREAD = current; // For exception macros. 644 ClassListParser::resolve_indy_impl(class_name_symbol, THREAD); 645 if (HAS_PENDING_EXCEPTION) { 646 ResourceMark rm(current); 647 char* ex_msg = (char*)""; 648 oop message = java_lang_Throwable::message(PENDING_EXCEPTION); 649 if (message != nullptr) { 650 ex_msg = java_lang_String::as_utf8_string(message); 651 } 652 aot_log_warning(aot)("resolve_indy for class %s has encountered exception: %s %s", 653 class_name_symbol->as_C_string(), 654 PENDING_EXCEPTION->klass()->external_name(), 655 ex_msg); 656 CLEAR_PENDING_EXCEPTION; 657 } 658 } 659 660 void ClassListParser::resolve_indy_impl(Symbol* class_name_symbol, TRAPS) { 661 if (CDSConfig::is_dumping_method_handles()) { 662 // The CP entry for the invokedynamic instruction will be resolved. 663 // No need to do the following. 664 return; 665 } 666 667 // This is an older CDS optimization: 668 // We store a pre-generated version of the lambda proxy class in the AOT cache, 669 // which will be loaded via JVM_LookupLambdaProxyClassFromArchive(). 670 // This eliminate dynamic class generation of the proxy class, but we still need to 671 // resolve the CP entry for the invokedynamic instruction, which may result in 672 // generation of LambdaForm classes. 673 Handle class_loader(THREAD, SystemDictionary::java_system_loader()); 674 Klass* klass = SystemDictionary::resolve_or_fail(class_name_symbol, class_loader, true, CHECK); 675 if (klass->is_instance_klass()) { 676 InstanceKlass* ik = InstanceKlass::cast(klass); 677 MetaspaceShared::try_link_class(THREAD, ik); 678 if (!ik->is_linked()) { 679 // Verification of ik has failed 680 return; 681 } 682 683 ConstantPool* cp = ik->constants(); 684 ConstantPoolCache* cpcache = cp->cache(); 685 bool found = false; 686 for (int indy_index = 0; indy_index < cpcache->resolved_indy_entries_length(); indy_index++) { 687 int pool_index = cpcache->resolved_indy_entry_at(indy_index)->constant_pool_index(); 688 constantPoolHandle pool(THREAD, cp); 689 BootstrapInfo bootstrap_specifier(pool, pool_index, indy_index); 690 Handle bsm = bootstrap_specifier.resolve_bsm(CHECK); 691 if (!LambdaProxyClassDictionary::is_supported_invokedynamic(&bootstrap_specifier)) { 692 log_debug(aot, lambda)("is_supported_invokedynamic check failed for cp_index %d", pool_index); 693 continue; 694 } 695 bool matched = is_matching_cp_entry(pool, pool_index, CHECK); 696 if (matched) { 697 found = true; 698 CallInfo info; 699 bool is_done = bootstrap_specifier.resolve_previously_linked_invokedynamic(info, CHECK); 700 if (!is_done) { 701 // resolve it 702 Handle recv; 703 LinkResolver::resolve_invoke(info, 704 recv, 705 pool, 706 indy_index, 707 Bytecodes::_invokedynamic, CHECK); 708 break; 709 } 710 cpcache->set_dynamic_call(info, indy_index); 711 } 712 } 713 if (!found) { 714 ResourceMark rm(THREAD); 715 aot_log_warning(aot)("No invoke dynamic constant pool entry can be found for class %s. The classlist is probably out-of-date.", 716 class_name_symbol->as_C_string()); 717 } 718 } 719 } 720 721 Klass* ClassListParser::load_current_class(Symbol* class_name_symbol, TRAPS) { 722 Klass* klass; 723 if (!is_loading_from_source()) { 724 // Load classes for the boot/platform/app loaders only. 725 if (is_super_specified()) { 726 error("If source location is not specified, super class must not be specified"); 727 } 728 if (are_interfaces_specified()) { 729 error("If source location is not specified, interface(s) must not be specified"); 730 } 731 732 if (Signature::is_array(class_name_symbol)) { 733 // array classes are not supported in class list. 734 THROW_NULL(vmSymbols::java_lang_ClassNotFoundException()); 735 } 736 737 JavaValue result(T_OBJECT); 738 // Call java_system_loader().loadClass() directly, which will 739 // delegate to the correct loader (boot, platform or app) depending on 740 // the package name. 741 742 // ClassLoader.loadClass() wants external class name format, i.e., convert '/' chars to '.' 743 Handle ext_class_name = java_lang_String::externalize_classname(class_name_symbol, CHECK_NULL); 744 Handle loader = Handle(THREAD, SystemDictionary::java_system_loader()); 745 746 JavaCalls::call_virtual(&result, 747 loader, //SystemDictionary::java_system_loader(), 748 vmClasses::ClassLoader_klass(), 749 vmSymbols::loadClass_name(), 750 vmSymbols::string_class_signature(), 751 ext_class_name, 752 CHECK_NULL); 753 754 assert(result.get_type() == T_OBJECT, "just checking"); 755 oop obj = result.get_oop(); 756 assert(obj != nullptr, "jdk.internal.loader.BuiltinClassLoader::loadClass never returns null"); 757 klass = java_lang_Class::as_Klass(obj); 758 } else { 759 // If "source:" tag is specified, all super class and super interfaces must be specified in the 760 // class list file. 761 klass = load_class_from_source(class_name_symbol, CHECK_NULL); 762 } 763 764 assert(klass != nullptr, "exception should have been thrown"); 765 assert(klass->is_instance_klass(), "array classes should have been filtered out"); 766 767 if (is_id_specified()) { 768 InstanceKlass* ik = InstanceKlass::cast(klass); 769 int id = this->id(); 770 SystemDictionaryShared::update_shared_entry(ik, id); 771 bool created; 772 id2klass_table()->put_if_absent(id, ik, &created); 773 if (!created) { 774 error("Duplicated ID %d for class %s", id, _class_name); 775 } 776 if (id2klass_table()->maybe_grow()) { 777 log_info(aot, hashtables)("Expanded id2klass_table() to %d", id2klass_table()->table_size()); 778 } 779 } 780 781 return klass; 782 } 783 784 bool ClassListParser::is_loading_from_source() { 785 return (_source != nullptr); 786 } 787 788 InstanceKlass* ClassListParser::lookup_class_by_id(int id) { 789 InstanceKlass** klass_ptr = id2klass_table()->get(id); 790 if (klass_ptr == nullptr) { 791 error("Class ID %d has not been defined", id); 792 } 793 assert(*klass_ptr != nullptr, "must be"); 794 return *klass_ptr; 795 } 796 797 InstanceKlass* ClassListParser::find_builtin_class_helper(JavaThread* current, Symbol* class_name_symbol, oop class_loader_oop) { 798 Handle class_loader(current, class_loader_oop); 799 return SystemDictionary::find_instance_klass(current, class_name_symbol, class_loader); 800 } 801 802 InstanceKlass* ClassListParser::find_builtin_class(JavaThread* current, const char* class_name) { 803 TempNewSymbol class_name_symbol = SymbolTable::new_symbol(class_name); 804 InstanceKlass* ik; 805 806 if ( (ik = find_builtin_class_helper(current, class_name_symbol, nullptr)) != nullptr 807 || (ik = find_builtin_class_helper(current, class_name_symbol, SystemDictionary::java_platform_loader())) != nullptr 808 || (ik = find_builtin_class_helper(current, class_name_symbol, SystemDictionary::java_system_loader())) != nullptr) { 809 return ik; 810 } else { 811 return nullptr; 812 } 813 } 814 815 void ClassListParser::parse_constant_pool_tag() { 816 if (parse_lambda_forms_invokers_only()) { 817 return; 818 } 819 820 JavaThread* THREAD = JavaThread::current(); 821 skip_whitespaces(); 822 char* class_name = _token; 823 skip_non_whitespaces(); 824 *_token = '\0'; 825 _token ++; 826 827 InstanceKlass* ik = find_builtin_class(THREAD, class_name); 828 if (ik == nullptr) { 829 _token = class_name; 830 if (strstr(class_name, "/$Proxy") != nullptr || 831 strstr(class_name, "MethodHandle$Species_") != nullptr) { 832 // ignore -- TODO: we should filter these out in classListWriter.cpp 833 } else { 834 constant_pool_resolution_warning("class %s is not (yet) loaded by one of the built-in loaders", class_name); 835 } 836 return; 837 } 838 839 ResourceMark rm(THREAD); 840 constantPoolHandle cp(THREAD, ik->constants()); 841 GrowableArray<bool> preresolve_list(cp->length(), cp->length(), false); 842 bool preresolve_class = false; 843 bool preresolve_fmi = false; 844 bool preresolve_indy = false; 845 846 while (*_token) { 847 int cp_index; 848 skip_whitespaces(); 849 parse_uint(&cp_index); 850 if (cp_index < 1 || cp_index >= cp->length()) { 851 constant_pool_resolution_warning("Invalid constant pool index %d", cp_index); 852 return; 853 } else { 854 preresolve_list.at_put(cp_index, true); 855 } 856 constantTag cp_tag = cp->tag_at(cp_index); 857 switch (cp_tag.value()) { 858 case JVM_CONSTANT_UnresolvedClass: 859 preresolve_class = true; 860 break; 861 case JVM_CONSTANT_UnresolvedClassInError: 862 case JVM_CONSTANT_Class: 863 // ignore 864 break; 865 case JVM_CONSTANT_Fieldref: 866 case JVM_CONSTANT_Methodref: 867 case JVM_CONSTANT_InterfaceMethodref: 868 preresolve_fmi = true; 869 break; 870 case JVM_CONSTANT_InvokeDynamic: 871 preresolve_indy = true; 872 break; 873 default: 874 constant_pool_resolution_warning("Unsupported constant pool index %d: %s (type=%d)", 875 cp_index, cp_tag.internal_name(), cp_tag.value()); 876 return; 877 } 878 } 879 880 if (SystemDictionaryShared::should_be_excluded(ik)) { 881 if (log_is_enabled(Warning, aot, resolve)) { 882 ResourceMark rm; 883 log_warning(aot, resolve)("Cannot aot-resolve constants for %s because it is excluded", ik->external_name()); 884 } 885 return; 886 } 887 888 if (preresolve_class) { 889 AOTConstantPoolResolver::preresolve_class_cp_entries(THREAD, ik, &preresolve_list); 890 } 891 if (preresolve_fmi) { 892 AOTConstantPoolResolver::preresolve_field_and_method_cp_entries(THREAD, ik, &preresolve_list); 893 } 894 if (preresolve_indy) { 895 AOTConstantPoolResolver::preresolve_indy_cp_entries(THREAD, ik, &preresolve_list); 896 } 897 }