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