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