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