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