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 
  57 const char* ClassListParser::CLASS_REFLECTION_DATA_TAG = "@class-reflection-data";
  58 const char* ClassListParser::CONSTANT_POOL_TAG = "@cp";
  59 const char* ClassListParser::DYNAMIC_PROXY_TAG = "@dynamic-proxy";
  60 const char* ClassListParser::LAMBDA_FORM_TAG = "@lambda-form-invoker";
  61 const char* ClassListParser::LAMBDA_PROXY_TAG = "@lambda-proxy";
  62 const char* ClassListParser::LOADER_NEGATIVE_CACHE_TAG = "@loader-negative-cache";
  63 const char* ClassListParser::ARRAY_TAG = "@array";
  64 
  65 volatile Thread* ClassListParser::_parsing_thread = nullptr;
  66 ClassListParser* ClassListParser::_instance = nullptr;
  67 
  68 ClassListParser::ClassListParser(const char* file, ParseMode parse_mode) :
  69     _id2klass_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE), _line_reader() {
  70   log_info(cds)("Parsing %s%s", file,
  71                 (parse_mode == _parse_lambda_forms_invokers_only) ? " (lambda form invokers only)" : "");
  72   _classlist_file = file;
  73   _file = nullptr;
  74   // Use os::open() because neither fopen() nor os::fopen()
  75   // can handle long path name on Windows.
  76   int fd = os::open(file, O_RDONLY, S_IREAD);
  77   if (fd != -1) {
  78     // Obtain a File* from the file descriptor so that fgets()
  79     // can be used in parse_one_line()
  80     _file = os::fdopen(fd, "r");
  81   }
  82   if (_file == nullptr) {
  83     char errmsg[JVM_MAXPATHLEN];
  84     os::lasterror(errmsg, JVM_MAXPATHLEN);
  85     vm_exit_during_initialization("Loading classlist failed", errmsg);
  86   }
  87   _line_reader.init(_file);
  88   _line_no = 0;
  89   _token = _line = nullptr;
  90   _interfaces = new (mtClass) GrowableArray<int>(10, mtClass);
  91   _indy_items = new (mtClass) GrowableArray<const char*>(9, mtClass);
  92   _parse_mode = parse_mode;
  93 
  94   // _instance should only be accessed by the thread that created _instance.
  95   assert(_instance == nullptr, "must be singleton");
  96   _instance = this;
  97   Atomic::store(&_parsing_thread, Thread::current());
  98 }
  99 
 100 bool ClassListParser::is_parsing_thread() {
 101   return Atomic::load(&_parsing_thread) == Thread::current();
 102 }
 103 
 104 ClassListParser::~ClassListParser() {
 105   if (_file != nullptr) {
 106     fclose(_file);
 107   }
 108   Atomic::store(&_parsing_thread, (Thread*)nullptr);
 109   delete _indy_items;
 110   delete _interfaces;
 111   _instance = nullptr;
 112 }
 113 
 114 int ClassListParser::parse(TRAPS) {
 115   int class_count = 0;
 116 
 117   while (parse_one_line()) {
 118     if (lambda_form_line()) {
 119       // The current line is "@lambda-form-invoker ...". It has been recorded in LambdaFormInvokers,
 120       // and will be processed later.
 121       continue;
 122     }
 123     if (_constant_pool_line) {
 124       continue;
 125     }
 126     if (_class_reflection_data_line) {
 127       continue;
 128     }
 129     if (_loader_negative_cache_line) {
 130       continue;
 131     }
 132     if (_parse_mode == _parse_lambda_forms_invokers_only) {
 133       continue;
 134     }
 135 
 136     TempNewSymbol class_name_symbol = SymbolTable::new_symbol(_class_name);
 137     if (_indy_items->length() > 0) {
 138       // The current line is "@lambda-proxy class_name". Load the proxy class.
 139       resolve_indy(THREAD, class_name_symbol);
 140       class_count++;
 141       continue;
 142     }
 143 
 144     Klass* klass = load_current_class(class_name_symbol, THREAD);
 145     if (HAS_PENDING_EXCEPTION) {
 146       if (PENDING_EXCEPTION->is_a(vmClasses::OutOfMemoryError_klass())) {
 147         // If we have run out of memory, don't try to load the rest of the classes in
 148         // the classlist. Throw an exception, which will terminate the dumping process.
 149         return 0; // THROW
 150       }
 151 
 152       ResourceMark rm(THREAD);
 153       char* ex_msg = (char*)"";
 154       oop message = java_lang_Throwable::message(PENDING_EXCEPTION);
 155       if (message != nullptr) {
 156         ex_msg = java_lang_String::as_utf8_string(message);
 157       }
 158       log_warning(cds)("%s: %s", PENDING_EXCEPTION->klass()->external_name(), ex_msg);
 159       // We might have an invalid class name or an bad class. Warn about it
 160       // and keep going to the next line.
 161       CLEAR_PENDING_EXCEPTION;
 162       log_warning(cds)("Preload Warning: Cannot find %s", _class_name);
 163       continue;
 164     }
 165 
 166     assert(klass != nullptr, "sanity");
 167     if (log_is_enabled(Trace, cds)) {
 168       ResourceMark rm(THREAD);
 169       log_trace(cds)("Shared spaces preloaded: %s", klass->external_name());
 170     }
 171 
 172     if (klass->is_instance_klass()) {
 173       InstanceKlass* ik = InstanceKlass::cast(klass);
 174 
 175       // Link the class to cause the bytecodes to be rewritten and the
 176       // cpcache to be created. The linking is done as soon as classes
 177       // are loaded in order that the related data structures (klass and
 178       // cpCache) are located together.
 179       MetaspaceShared::try_link_class(THREAD, ik);
 180     }
 181 
 182     class_count++;
 183   }
 184 
 185   return class_count;
 186 }
 187 
 188 bool ClassListParser::parse_one_line() {
 189   for (;;) {
 190     _line = _line_reader.read_line();
 191     if (_line == nullptr) {
 192       if (_line_reader.is_oom()) {
 193         // Don't try to print the input line that we already know is too long.
 194         _line_len = 0;
 195         error("Input line too long"); // will exit JVM
 196       }
 197       return false;
 198     }
 199     ++ _line_no;




 200     if (*_line == '#') { // comment
 201       continue;
 202     }
 203 
 204     {
 205       int len = (int)strlen(_line);
 206       int i;
 207       // Replace \t\r\n\f with ' '
 208       for (i=0; i<len; i++) {
 209         if (_line[i] == '\t' || _line[i] == '\r' || _line[i] == '\n' || _line[i] == '\f') {
 210           _line[i] = ' ';
 211         }
 212       }
 213 
 214       // Remove trailing newline/space
 215       while (len > 0) {
 216         if (_line[len-1] == ' ') {
 217           _line[len-1] = '\0';
 218           len --;
 219         } else {
 220           break;
 221         }
 222       }
 223       _line_len = len;
 224     }
 225 
 226     // valid line
 227     break;
 228   }
 229 
 230   _class_name = _line;
 231   _id = _unspecified;
 232   _super = _unspecified;
 233   _interfaces->clear();
 234   _source = nullptr;
 235   _interfaces_specified = false;
 236   _indy_items->clear();
 237   _lambda_form_line = false;
 238   _constant_pool_line = false;
 239   _class_reflection_data_line = false;
 240   _loader_negative_cache_line = false;
 241 
 242   if (_line[0] == '@') {
 243     return parse_at_tags();
 244   }
 245 
 246   if ((_token = strchr(_line, ' ')) == nullptr) {
 247     // No optional arguments are specified.
 248     return true;
 249   }
 250 
 251   // Mark the end of the name, and go to the next input char
 252   *_token++ = '\0';
 253 
 254   while (*_token) {
 255     skip_whitespaces();
 256 
 257     if (parse_uint_option("id:", &_id)) {
 258       continue;
 259     } else if (parse_uint_option("super:", &_super)) {
 260       check_already_loaded("Super class", _super);
 261       continue;
 262     } else if (skip_token("interfaces:")) {
 263       int i;
 264       while (try_parse_uint(&i)) {
 265         check_already_loaded("Interface", i);
 266         _interfaces->append(i);
 267       }
 268     } else if (skip_token("source:")) {
 269       skip_whitespaces();
 270       _source = _token;
 271       char* s = strchr(_token, ' ');
 272       if (s == nullptr) {
 273         break; // end of input line
 274       } else {
 275         *s = '\0'; // mark the end of _source
 276         _token = s+1;
 277       }
 278     } else {
 279       error("Unknown input");
 280     }
 281   }
 282 
 283   // if src is specified
 284   //     id super interfaces must all be specified
 285   //     loader may be specified
 286   // else
 287   //     # the class is loaded from classpath
 288   //     id may be specified
 289   //     super, interfaces, loader must not be specified
 290   return true;
 291 }
 292 
 293 void ClassListParser::split_tokens_by_whitespace(int offset) {
 294   int start = offset;
 295   int end;
 296   bool done = false;
 297   while (!done) {
 298     while (_line[start] == ' ' || _line[start] == '\t') start++;
 299     end = start;
 300     while (_line[end] && _line[end] != ' ' && _line[end] != '\t') end++;
 301     if (_line[end] == '\0') {
 302       done = true;
 303     } else {
 304       _line[end] = '\0';
 305     }
 306     _indy_items->append(_line + start);
 307     start = ++end;
 308   }
 309 }
 310 
 311 int ClassListParser::split_at_tag_from_line() {
 312   _token = _line;
 313   char* ptr;
 314   if ((ptr = strchr(_line, ' ')) == nullptr) {
 315     error("Too few items following the @ tag \"%s\" line #%d", _line, _line_no);
 316     return 0;
 317   }
 318   *ptr++ = '\0';
 319   while (*ptr == ' ' || *ptr == '\t') ptr++;
 320   return (int)(ptr - _line);
 321 }
 322 
 323 bool ClassListParser::parse_at_tags() {
 324   assert(_line[0] == '@', "must be");
 325   int offset;
 326   if ((offset = split_at_tag_from_line()) == 0) {
 327     return false;
 328   }
 329 
 330   if (strcmp(_token, LAMBDA_PROXY_TAG) == 0) {
 331     split_tokens_by_whitespace(offset);
 332     if (_indy_items->length() < 2) {
 333       error("Line with @ tag has too few items \"%s\" line #%d", _token, _line_no);
 334       return false;
 335     }
 336     // set the class name
 337     _class_name = _indy_items->at(0);
 338     return true;
 339   } else if (strcmp(_token, LAMBDA_FORM_TAG) == 0) {
 340     LambdaFormInvokers::append(os::strdup((const char*)(_line + offset), mtInternal));
 341     _lambda_form_line = true;
 342     return true;
 343   } else if (strcmp(_token, CONSTANT_POOL_TAG) == 0) {
 344     _token = _line + offset;
 345     _constant_pool_line = true;
 346     parse_constant_pool_tag();
 347     return true;
 348   } else if (strcmp(_token, ARRAY_TAG) == 0) {
 349     _token = _line + offset;
 350     _constant_pool_line = true;
 351     parse_array_dimension_tag();
 352     return true;
 353   } else if (strcmp(_token, CLASS_REFLECTION_DATA_TAG) == 0) {
 354     _token = _line + offset;
 355     _class_reflection_data_line = true;
 356     parse_class_reflection_data_tag();
 357     return true;
 358   } else if (strcmp(_token, DYNAMIC_PROXY_TAG) == 0) {
 359     _token = _line + offset;
 360     _constant_pool_line = true;
 361     parse_dynamic_proxy_tag();
 362     return true;
 363   } else if (strcmp(_token, LOADER_NEGATIVE_CACHE_TAG) == 0) {
 364     _token = _line + offset;
 365     _loader_negative_cache_line = true;
 366     parse_loader_negative_cache_tag();
 367     return true;
 368   } else {
 369     error("Invalid @ tag at the beginning of line \"%s\" line #%d", _token, _line_no);
 370     return false;
 371   }
 372 }
 373 
 374 void ClassListParser::skip_whitespaces() {
 375   while (*_token == ' ' || *_token == '\t') {
 376     _token ++;
 377   }
 378 }
 379 
 380 void ClassListParser::skip_non_whitespaces() {
 381   while (*_token && *_token != ' ' && *_token != '\t') {
 382     _token ++;
 383   }
 384 }
 385 
 386 void ClassListParser::parse_int(int* value) {
 387   skip_whitespaces();
 388   if (sscanf(_token, "%i", value) == 1) {
 389     skip_non_whitespaces();
 390   } else {
 391     error("Error: expected integer");
 392   }
 393 }
 394 
 395 void ClassListParser::parse_uint(int* value) {
 396   parse_int(value);
 397   if (*value < 0) {
 398     error("Error: negative integers not allowed (%d)", *value);
 399   }
 400 }
 401 
 402 bool ClassListParser::try_parse_uint(int* value) {
 403   skip_whitespaces();
 404   if (sscanf(_token, "%i", value) == 1) {
 405     skip_non_whitespaces();
 406     return true;
 407   }
 408   return false;
 409 }
 410 
 411 bool ClassListParser::skip_token(const char* option_name) {
 412   size_t len = strlen(option_name);
 413   if (strncmp(_token, option_name, len) == 0) {
 414     _token += len;
 415     return true;
 416   } else {
 417     return false;
 418   }
 419 }
 420 
 421 bool ClassListParser::parse_int_option(const char* option_name, int* value) {
 422   if (skip_token(option_name)) {
 423     if (*value != _unspecified) {
 424       error("%s specified twice", option_name);
 425     } else {
 426       parse_int(value);
 427       return true;
 428     }
 429   }
 430   return false;
 431 }
 432 
 433 bool ClassListParser::parse_uint_option(const char* option_name, int* value) {
 434   if (skip_token(option_name)) {
 435     if (*value != _unspecified) {
 436       error("%s specified twice", option_name);
 437     } else {
 438       parse_uint(value);
 439       return true;
 440     }
 441   }
 442   return false;
 443 }
 444 
 445 void ClassListParser::print_specified_interfaces() {
 446   const int n = _interfaces->length();
 447   jio_fprintf(defaultStream::error_stream(), "Currently specified interfaces[%d] = {\n", n);
 448   for (int i=0; i<n; i++) {
 449     InstanceKlass* k = lookup_class_by_id(_interfaces->at(i));
 450     jio_fprintf(defaultStream::error_stream(), "  %4d = %s\n", _interfaces->at(i), k->name()->as_klass_external_name());
 451   }
 452   jio_fprintf(defaultStream::error_stream(), "}\n");
 453 }
 454 
 455 void ClassListParser::print_actual_interfaces(InstanceKlass* ik) {
 456   int n = ik->local_interfaces()->length();
 457   jio_fprintf(defaultStream::error_stream(), "Actual interfaces[%d] = {\n", n);
 458   for (int i = 0; i < n; i++) {
 459     InstanceKlass* e = ik->local_interfaces()->at(i);
 460     jio_fprintf(defaultStream::error_stream(), "  %s\n", e->name()->as_klass_external_name());
 461   }
 462   jio_fprintf(defaultStream::error_stream(), "}\n");
 463 }
 464 
 465 void ClassListParser::print_diagnostic_info(outputStream* st, const char* msg, ...) {
 466   va_list ap;
 467   va_start(ap, msg);
 468   print_diagnostic_info(st, msg, ap);
 469   va_end(ap);
 470 }
 471 
 472 void ClassListParser::print_diagnostic_info(outputStream* st, const char* msg, va_list ap) {
 473   int error_index = pointer_delta_as_int(_token, _line);
 474   if (error_index >= _line_len) {
 475     error_index = _line_len - 1;
 476   }
 477   if (error_index < 0) {
 478     error_index = 0;
 479   }
 480 
 481   st->print("An error has occurred while processing class list file %s %d:%d.\n",
 482             _classlist_file, _line_no, (error_index + 1));
 483   st->vprint(msg, ap);

 484 
 485   if (_line_len <= 0) {
 486     st->print("\n");
 487   } else {
 488     st->print(":\n");
 489     for (int i=0; i<_line_len; i++) {
 490       char c = _line[i];
 491       if (c == '\0') {
 492         st->print("%s", " ");
 493       } else {
 494         st->print("%c", c);
 495       }
 496     }
 497     st->print("\n");
 498     for (int i=0; i<error_index; i++) {
 499       st->print("%s", " ");
 500     }
 501     st->print("^\n");
 502   }
 503 }
 504 
 505 void ClassListParser::error(const char* msg, ...) {
 506   va_list ap;
 507   va_start(ap, msg);
 508   LogTarget(Error, cds) lt;
 509   LogStream ls(lt);
 510   print_diagnostic_info(&ls, msg, ap);
 511   vm_exit_during_initialization("class list format error.", nullptr);
 512   va_end(ap);
 513 }
 514 
 515 void ClassListParser::constant_pool_resolution_warning(const char* msg, ...) {
 516   va_list ap;
 517   va_start(ap, msg);
 518   LogTarget(Warning, cds, resolve) lt;
 519   LogStream ls(lt);
 520   print_diagnostic_info(&ls, msg, ap);
 521   ls.print("Your classlist may be out of sync with the JDK or the application.");
 522   va_end(ap);
 523 }
 524 
 525 // This function is used for loading classes for customized class loaders
 526 // during archive dumping.
 527 InstanceKlass* ClassListParser::load_class_from_source(Symbol* class_name, TRAPS) {
 528 #if !(defined(_LP64) && (defined(LINUX) || defined(__APPLE__) || defined(_WINDOWS)))
 529   // The only supported platforms are: (1) Linux/64-bit and (2) Solaris/64-bit and
 530   // (3) MacOSX/64-bit and (4) Windowss/64-bit
 531   // This #if condition should be in sync with the areCustomLoadersSupportedForCDS
 532   // method in test/lib/jdk/test/lib/Platform.java.
 533   error("AppCDS custom class loaders not supported on this platform");
 534 #endif
 535 
 536   if (!is_super_specified()) {
 537     error("If source location is specified, super class must be also specified");
 538   }
 539   if (!is_id_specified()) {
 540     error("If source location is specified, id must be also specified");
 541   }
 542   if (strncmp(_class_name, "java/", 5) == 0) {
 543     log_info(cds)("Prohibited package for non-bootstrap classes: %s.class from %s",
 544           _class_name, _source);
 545     THROW_NULL(vmSymbols::java_lang_ClassNotFoundException());
 546   }
 547 
 548   InstanceKlass* k = UnregisteredClasses::load_class(class_name, _source, CHECK_NULL);
 549   if (k->local_interfaces()->length() != _interfaces->length()) {
 550     print_specified_interfaces();
 551     print_actual_interfaces(k);
 552     error("The number of interfaces (%d) specified in class list does not match the class file (%d)",
 553           _interfaces->length(), k->local_interfaces()->length());
 554   }
 555 
 556   assert(k->is_shared_unregistered_class(), "must be");
 557 
 558   bool added = SystemDictionaryShared::add_unregistered_class(THREAD, k);
 559   if (!added) {
 560     // We allow only a single unregistered class for each unique name.
 561     error("Duplicated class %s", _class_name);
 562   }
 563 
 564   return k;
 565 }
 566 
 567 void ClassListParser::populate_cds_indy_info(const constantPoolHandle &pool, int cp_index, CDSIndyInfo* cii, TRAPS) {
 568   // Caller needs to allocate ResourceMark.
 569   int type_index = pool->bootstrap_name_and_type_ref_index_at(cp_index);
 570   int name_index = pool->name_ref_index_at(type_index);
 571   cii->add_item(pool->symbol_at(name_index)->as_C_string());
 572   int sig_index = pool->signature_ref_index_at(type_index);
 573   cii->add_item(pool->symbol_at(sig_index)->as_C_string());
 574   int argc = pool->bootstrap_argument_count_at(cp_index);
 575   if (argc > 0) {
 576     for (int arg_i = 0; arg_i < argc; arg_i++) {
 577       int arg = pool->bootstrap_argument_index_at(cp_index, arg_i);
 578       jbyte tag = pool->tag_at(arg).value();
 579       if (tag == JVM_CONSTANT_MethodType) {
 580         cii->add_item(pool->method_type_signature_at(arg)->as_C_string());
 581       } else if (tag == JVM_CONSTANT_MethodHandle) {
 582         cii->add_ref_kind(pool->method_handle_ref_kind_at(arg));
 583         int callee_index = pool->method_handle_klass_index_at(arg);
 584         Klass* callee = pool->klass_at(callee_index, CHECK);
 585         cii->add_item(callee->name()->as_C_string());
 586         cii->add_item(pool->method_handle_name_ref_at(arg)->as_C_string());
 587         cii->add_item(pool->method_handle_signature_ref_at(arg)->as_C_string());
 588       } else {
 589         ShouldNotReachHere();
 590       }
 591     }
 592   }
 593 }
 594 
 595 bool ClassListParser::is_matching_cp_entry(const constantPoolHandle &pool, int cp_index, TRAPS) {
 596   ResourceMark rm(THREAD);
 597   CDSIndyInfo cii;
 598   populate_cds_indy_info(pool, cp_index, &cii, CHECK_0);
 599   GrowableArray<const char*>* items = cii.items();
 600   int indy_info_offset = 1;
 601   if (_indy_items->length() - indy_info_offset != items->length()) {
 602     return false;
 603   }
 604   for (int i = 0; i < items->length(); i++) {
 605     if (strcmp(_indy_items->at(i + indy_info_offset), items->at(i)) != 0) {
 606       return false;
 607     }
 608   }
 609   return true;
 610 }
 611 
 612 void ClassListParser::resolve_indy(JavaThread* current, Symbol* class_name_symbol) {
 613   ExceptionMark em(current);
 614   JavaThread* THREAD = current; // For exception macros.
 615   ClassListParser::resolve_indy_impl(class_name_symbol, THREAD);
 616   if (HAS_PENDING_EXCEPTION) {
 617     ResourceMark rm(current);
 618     char* ex_msg = (char*)"";
 619     oop message = java_lang_Throwable::message(PENDING_EXCEPTION);
 620     if (message != nullptr) {
 621       ex_msg = java_lang_String::as_utf8_string(message);
 622     }
 623     log_warning(cds)("resolve_indy for class %s has encountered exception: %s %s",
 624                      class_name_symbol->as_C_string(),
 625                      PENDING_EXCEPTION->klass()->external_name(),
 626                      ex_msg);
 627     CLEAR_PENDING_EXCEPTION;
 628   }
 629 }
 630 
 631 void ClassListParser::resolve_indy_impl(Symbol* class_name_symbol, TRAPS) {
 632   Handle class_loader(THREAD, SystemDictionary::java_system_loader());
 633   Handle protection_domain;
 634   Klass* klass = SystemDictionary::resolve_or_fail(class_name_symbol, class_loader, protection_domain, true, CHECK);
 635   if (klass->is_instance_klass()) {
 636     InstanceKlass* ik = InstanceKlass::cast(klass);
 637     MetaspaceShared::try_link_class(THREAD, ik);
 638     if (!ik->is_linked()) {
 639       // Verification of ik has failed
 640       return;
 641     }
 642 
 643     ConstantPool* cp = ik->constants();
 644     ConstantPoolCache* cpcache = cp->cache();
 645     bool found = false;
 646     for (int indy_index = 0; indy_index < cpcache->resolved_indy_entries_length(); indy_index++) {
 647       int pool_index = cpcache->resolved_indy_entry_at(indy_index)->constant_pool_index();
 648       constantPoolHandle pool(THREAD, cp);
 649       BootstrapInfo bootstrap_specifier(pool, pool_index, indy_index);
 650       Handle bsm = bootstrap_specifier.resolve_bsm(CHECK);
 651       if (!SystemDictionaryShared::is_supported_invokedynamic(&bootstrap_specifier)) {
 652         log_debug(cds, lambda)("is_supported_invokedynamic check failed for cp_index %d", pool_index);
 653         continue;
 654       }
 655       bool matched = is_matching_cp_entry(pool, pool_index, CHECK);
 656       if (matched) {
 657         found = true;
 658         CallInfo info;
 659         bool is_done = bootstrap_specifier.resolve_previously_linked_invokedynamic(info, CHECK);
 660         if (!is_done) {
 661           // resolve it
 662           Handle recv;
 663           LinkResolver::resolve_invoke(info,
 664                                        recv,
 665                                        pool,
 666                                        ConstantPool::encode_invokedynamic_index(indy_index),
 667                                        Bytecodes::_invokedynamic, CHECK);
 668           break;
 669         }
 670         cpcache->set_dynamic_call(info, indy_index);
 671       }
 672     }
 673     if (!found) {
 674       ResourceMark rm(THREAD);
 675       log_warning(cds)("No invoke dynamic constant pool entry can be found for class %s. The classlist is probably out-of-date.",
 676                      class_name_symbol->as_C_string());
 677     }
 678   }
 679 }
 680 
 681 Klass* ClassListParser::load_current_class(Symbol* class_name_symbol, TRAPS) {
 682   Klass* klass;
 683   if (!is_loading_from_source()) {
 684     // Load classes for the boot/platform/app loaders only.
 685     if (is_super_specified()) {
 686       error("If source location is not specified, super class must not be specified");
 687     }
 688     if (are_interfaces_specified()) {
 689       error("If source location is not specified, interface(s) must not be specified");
 690     }
 691 
 692     if (Signature::is_array(class_name_symbol)) {
 693       // array classes are not supported in class list.
 694       THROW_NULL(vmSymbols::java_lang_ClassNotFoundException());
 695     }
 696 
 697     JavaValue result(T_OBJECT);
 698     // Call java_system_loader().loadClass() directly, which will
 699     // delegate to the correct loader (boot, platform or app) depending on
 700     // the package name.
 701 
 702     // ClassLoader.loadClass() wants external class name format, i.e., convert '/' chars to '.'
 703     Handle ext_class_name = java_lang_String::externalize_classname(class_name_symbol, CHECK_NULL);
 704     Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());
 705 
 706     JavaCalls::call_virtual(&result,
 707                             loader, //SystemDictionary::java_system_loader(),
 708                             vmClasses::ClassLoader_klass(),
 709                             vmSymbols::loadClass_name(),
 710                             vmSymbols::string_class_signature(),
 711                             ext_class_name,
 712                             CHECK_NULL);
 713 
 714     assert(result.get_type() == T_OBJECT, "just checking");
 715     oop obj = result.get_oop();
 716     assert(obj != nullptr, "jdk.internal.loader.BuiltinClassLoader::loadClass never returns null");
 717     klass = java_lang_Class::as_Klass(obj);
 718   } else {
 719     // If "source:" tag is specified, all super class and super interfaces must be specified in the
 720     // class list file.
 721     klass = load_class_from_source(class_name_symbol, CHECK_NULL);
 722   }
 723 
 724   assert(klass != nullptr, "exception should have been thrown");
 725   assert(klass->is_instance_klass(), "array classes should have been filtered out");
 726 
 727   if (is_id_specified()) {
 728     InstanceKlass* ik = InstanceKlass::cast(klass);
 729     int id = this->id();
 730     SystemDictionaryShared::update_shared_entry(ik, id);
 731     bool created;
 732     id2klass_table()->put_if_absent(id, ik, &created);
 733     if (!created) {
 734       error("Duplicated ID %d for class %s", id, _class_name);
 735     }
 736     if (id2klass_table()->maybe_grow()) {
 737       log_info(cds, hashtables)("Expanded id2klass_table() to %d", id2klass_table()->table_size());
 738     }
 739   }
 740 
 741   return klass;
 742 }
 743 
 744 bool ClassListParser::is_loading_from_source() {
 745   return (_source != nullptr);
 746 }
 747 
 748 InstanceKlass* ClassListParser::lookup_class_by_id(int id) {
 749   InstanceKlass** klass_ptr = id2klass_table()->get(id);
 750   if (klass_ptr == nullptr) {
 751     error("Class ID %d has not been defined", id);
 752   }
 753   assert(*klass_ptr != nullptr, "must be");
 754   return *klass_ptr;
 755 }
 756 
 757 
 758 InstanceKlass* ClassListParser::lookup_super_for_current_class(Symbol* super_name) {
 759   if (!is_loading_from_source()) {
 760     return nullptr;
 761   }
 762 
 763   InstanceKlass* k = lookup_class_by_id(super());
 764   if (super_name != k->name()) {
 765     error("The specified super class %s (id %d) does not match actual super class %s",
 766           k->name()->as_klass_external_name(), super(),
 767           super_name->as_klass_external_name());
 768   }
 769   return k;
 770 }
 771 
 772 InstanceKlass* ClassListParser::lookup_interface_for_current_class(Symbol* interface_name) {
 773   if (!is_loading_from_source()) {
 774     return nullptr;
 775   }
 776 
 777   const int n = _interfaces->length();
 778   if (n == 0) {
 779     error("Class %s implements the interface %s, but no interface has been specified in the input line",
 780           _class_name, interface_name->as_klass_external_name());
 781     ShouldNotReachHere();
 782   }
 783 
 784   int i;
 785   for (i=0; i<n; i++) {
 786     InstanceKlass* k = lookup_class_by_id(_interfaces->at(i));
 787     if (interface_name == k->name()) {
 788       return k;
 789     }
 790   }
 791 
 792   // interface_name is not specified by the "interfaces:" keyword.
 793   print_specified_interfaces();
 794   error("The interface %s implemented by class %s does not match any of the specified interface IDs",
 795         interface_name->as_klass_external_name(), _class_name);
 796   ShouldNotReachHere();
 797   return nullptr;
 798 }
 799 
 800 InstanceKlass* ClassListParser::find_builtin_class_helper(JavaThread* current, Symbol* class_name_symbol, oop class_loader_oop) {
 801   Handle class_loader(current, class_loader_oop);
 802   Handle protection_domain;
 803   return SystemDictionary::find_instance_klass(current, class_name_symbol, class_loader, protection_domain);
 804 }
 805 
 806 InstanceKlass* ClassListParser::find_builtin_class(JavaThread* current, const char* class_name) {
 807   TempNewSymbol class_name_symbol = SymbolTable::new_symbol(class_name);
 808   InstanceKlass* ik;
 809 
 810   if ( (ik = find_builtin_class_helper(current, class_name_symbol, nullptr)) != nullptr
 811     || (ik = find_builtin_class_helper(current, class_name_symbol, SystemDictionary::java_platform_loader())) != nullptr
 812     || (ik = find_builtin_class_helper(current, class_name_symbol, SystemDictionary::java_system_loader())) != nullptr) {
 813     return ik;
 814   } else {
 815     return nullptr;
 816   }
 817 }
 818 
 819 void ClassListParser::parse_array_dimension_tag() {
 820   if (_parse_mode == _parse_lambda_forms_invokers_only) {
 821     return;
 822   }
 823 
 824   skip_whitespaces();
 825   char* class_name = _token;
 826   skip_non_whitespaces();
 827   *_token = '\0';
 828   _token ++;
 829 
 830   skip_whitespaces();
 831   int dim;
 832   parse_uint(&dim);
 833 
 834   JavaThread* THREAD = JavaThread::current();
 835   InstanceKlass* ik = find_builtin_class(THREAD, class_name);
 836   if (ik == nullptr) {
 837     _token = class_name;
 838     if (strstr(class_name, "/$Proxy") != nullptr ||
 839         strstr(class_name, "MethodHandle$Species_") != nullptr) {
 840       // ignore -- TODO: we should filter these out in classListWriter.cpp
 841     } else {
 842       constant_pool_resolution_warning("class %s is not (yet) loaded by one of the built-in loaders", class_name);
 843     }
 844     return;
 845   }
 846 
 847   if (dim > 0) {
 848     ik->array_klass(dim, THREAD);
 849     if (HAS_PENDING_EXCEPTION) {
 850       error("Array klass allocation failed: %s %d", _class_name, dim);
 851     }
 852   }
 853 }
 854 
 855 void ClassListParser::parse_constant_pool_tag() {
 856   if (_parse_mode == _parse_lambda_forms_invokers_only) {
 857     return;
 858   }
 859 
 860   JavaThread* THREAD = JavaThread::current();
 861   skip_whitespaces();
 862   char* class_name = _token;
 863   skip_non_whitespaces();
 864   *_token = '\0';
 865   _token ++;
 866 
 867   InstanceKlass* ik = find_builtin_class(THREAD, class_name);
 868   if (ik == nullptr) {
 869     _token = class_name;
 870     if (strstr(class_name, "/$Proxy") != nullptr ||
 871         strstr(class_name, "MethodHandle$Species_") != nullptr) {
 872       // ignore -- TODO: we should filter these out in classListWriter.cpp
 873     } else {
 874       constant_pool_resolution_warning("class %s is not (yet) loaded by one of the built-in loaders", class_name);
 875     }
 876     return;
 877   }
 878 
 879   ResourceMark rm(THREAD);
 880   constantPoolHandle cp(THREAD, ik->constants());
 881   GrowableArray<bool> preresolve_list(cp->length(), cp->length(), false);
 882   bool preresolve_class = false;
 883   bool preresolve_fmi = false;
 884   bool preresolve_indy = false;
 885   
 886   while (*_token) {
 887     int cp_index;
 888     skip_whitespaces();
 889     parse_uint(&cp_index);
 890     if (cp_index < 1 || cp_index >= cp->length()) {
 891       constant_pool_resolution_warning("Invalid constant pool index %d", cp_index);
 892       return;
 893     } else {
 894       preresolve_list.at_put(cp_index, true);
 895     }
 896     constantTag cp_tag = cp->tag_at(cp_index);
 897     switch (cp_tag.value()) {
 898     case JVM_CONSTANT_UnresolvedClass:
 899       preresolve_class = true;
 900       break;
 901     case JVM_CONSTANT_UnresolvedClassInError:
 902     case JVM_CONSTANT_Class:
 903       // ignore
 904       break;
 905     case JVM_CONSTANT_Fieldref:
 906     case JVM_CONSTANT_Methodref:
 907     case JVM_CONSTANT_InterfaceMethodref:
 908       preresolve_fmi = true;
 909       break;
 910     case JVM_CONSTANT_InvokeDynamic:
 911       preresolve_indy = true;
 912       break;
 913     default:
 914       constant_pool_resolution_warning("Unsupported constant pool index %d: %s (type=%d)",
 915                                        cp_index, cp_tag.internal_name(), cp_tag.value());
 916       return;
 917     }
 918   }
 919 
 920   if (preresolve_class) {
 921     ClassPrelinker::preresolve_class_cp_entries(THREAD, ik, &preresolve_list);
 922   }
 923   if (preresolve_fmi) {
 924 // FIXME: too coarse; doesn't cover resolution of Class entries
 925 //    JavaThread::NoJavaCodeMark no_java_code(THREAD); // ensure no clinits are exectued
 926     ClassPrelinker::preresolve_field_and_method_cp_entries(THREAD, ik, &preresolve_list);
 927   }
 928   if (preresolve_indy) {
 929     ClassPrelinker::preresolve_indy_cp_entries(THREAD, ik, &preresolve_list);
 930   }
 931 }
 932 
 933 void ClassListParser::parse_class_reflection_data_tag() {
 934   if (_parse_mode == _parse_lambda_forms_invokers_only) {
 935     return;
 936   }
 937 
 938   JavaThread* THREAD = JavaThread::current();
 939   skip_whitespaces();
 940   char* class_name = _token;
 941   skip_non_whitespaces();
 942   *_token = '\0';
 943   _token ++;
 944 
 945   InstanceKlass* ik = find_builtin_class(THREAD, class_name);
 946   if (ik == nullptr) {
 947     _token = class_name;
 948     if (strstr(class_name, "/$Proxy") != nullptr ||
 949         strstr(class_name, "MethodHandle$Species_") != nullptr) {
 950       // ignore -- TODO: we should filter these out in classListWriter.cpp
 951     } else {
 952       warning("%s: class not found: %s", CLASS_REFLECTION_DATA_TAG, class_name);
 953     }
 954     return;
 955   }
 956 
 957   ResourceMark rm(THREAD);
 958 
 959   int rd_flags = _unspecified;
 960   while (*_token) {
 961     skip_whitespaces();
 962     if (rd_flags != _unspecified) {
 963       error("rd_flags specified twice");
 964       return;
 965     }
 966     parse_uint(&rd_flags);
 967   }
 968   if (rd_flags == _unspecified) {
 969     error("no rd_flags specified");
 970     return;
 971   }
 972 
 973   if (ArchiveReflectionData) {
 974     ClassPrelinker::generate_reflection_data(THREAD, ik, rd_flags);
 975   }
 976 }
 977 
 978 oop ClassListParser::loader_from_type(const char* loader_type) {
 979   oop loader;
 980   if (!ArchiveUtils::builtin_loader_from_type(loader_type, &loader)) {
 981     error("Unknown loader %s", loader_type);
 982   }
 983   return loader;
 984 }
 985 
 986 void ClassListParser::parse_dynamic_proxy_tag() {
 987   if (_parse_mode == _parse_lambda_forms_invokers_only) {
 988     return;
 989   }
 990 
 991   skip_whitespaces();
 992   char* loader_type = _token;
 993   skip_non_whitespaces();
 994   *_token = '\0';
 995   _token ++;
 996 
 997   skip_whitespaces();
 998   char* proxy_name_str = _token;
 999   skip_non_whitespaces();
1000   *_token = '\0';
1001   _token ++;
1002 
1003   skip_whitespaces();
1004   int access_flags;
1005   parse_uint(&access_flags);
1006 
1007   skip_whitespaces();
1008   int num_intfs;
1009   parse_uint(&num_intfs);
1010 
1011   JavaThread* THREAD = JavaThread::current();
1012   Handle loader(THREAD, loader_from_type(loader_type));
1013   Handle proxy_name(THREAD, java_lang_String::create_oop_from_str(proxy_name_str, THREAD));
1014   if (HAS_PENDING_EXCEPTION) {
1015     error("Out of memory");
1016   }
1017 
1018   objArrayHandle interfaces(THREAD, oopFactory::new_objArray(vmClasses::Class_klass(), num_intfs, THREAD));
1019   if (HAS_PENDING_EXCEPTION) {
1020     error("Out of memory");
1021   }
1022 
1023   for (int i = 0; i < num_intfs; i++) {
1024     skip_whitespaces();
1025     char* intf_name = _token;
1026     skip_non_whitespaces();
1027     *_token = '\0';
1028     _token ++;
1029 
1030     InstanceKlass* ik = find_builtin_class(THREAD, intf_name);
1031     if (ik != nullptr) {
1032       interfaces()->obj_at_put(i, ik->java_mirror());
1033     } else {
1034       error("Unknown class %s", intf_name);
1035     }
1036   }
1037 
1038   if (strncmp("jdk.proxy", proxy_name_str, 9) != 0) {
1039     return;
1040   }
1041 
1042   ClassPrelinker::define_dynamic_proxy_class(loader, proxy_name, interfaces, access_flags, THREAD);
1043   if (HAS_PENDING_EXCEPTION) {
1044     PENDING_EXCEPTION->print_on(tty);
1045     error("defineProxyClassForCDS failed");
1046   }
1047 }
1048 
1049 void ClassListParser::parse_loader_negative_cache_tag() {
1050   skip_whitespaces();
1051   char* loader_type = _token;
1052   skip_non_whitespaces();
1053   *_token = '\0';
1054   _token ++;
1055 
1056   oop loader;
1057   Klass* loader_klass;
1058   if (!strcmp(loader_type, "app")) {
1059     loader = SystemDictionary::java_system_loader();
1060     loader_klass = vmClasses::jdk_internal_loader_ClassLoaders_AppClassLoader_klass();
1061   } else if (!strcmp(loader_type, "platform")) {
1062     loader = SystemDictionary::java_platform_loader();
1063     loader_klass = vmClasses::jdk_internal_loader_ClassLoaders_PlatformClassLoader_klass();
1064   } else {
1065     warning("%s: unrecognized loader type %s is ignored", LOADER_NEGATIVE_CACHE_TAG, loader_type);
1066     return;
1067   }
1068 
1069   char* contents = _token;
1070   skip_non_whitespaces();
1071   *_token = '\0';
1072   _token ++;
1073 
1074   if (ArchiveLoaderLookupCache) {
1075     TempNewSymbol method = SymbolTable::new_symbol("generateNegativeLookupCache");
1076     TempNewSymbol signature = SymbolTable::new_symbol("(Ljava/lang/String;)V");
1077 
1078     EXCEPTION_MARK;
1079     HandleMark hm(THREAD);
1080     JavaCallArguments args(Handle(THREAD, loader));
1081     Handle contents_h = java_lang_String::create_from_str(contents, THREAD);
1082     args.push_oop(contents_h);
1083     JavaValue result(T_VOID);
1084     JavaCalls::call_virtual(&result,
1085                             loader_klass,
1086                             method,
1087                             signature,
1088                             &args, THREAD);
1089     if (HAS_PENDING_EXCEPTION) {
1090       Handle exc_handle(THREAD, PENDING_EXCEPTION);
1091       CLEAR_PENDING_EXCEPTION;
1092 
1093       log_warning(cds)("Exception during BuiltinClassLoader::generateNegativeLookupCache() call for %s loader", loader_type);
1094       LogStreamHandle(Debug, cds) log;
1095       if (log.is_enabled()) {
1096         java_lang_Throwable::print_stack_trace(exc_handle, &log);
1097       }
1098     }
1099   }
1100 }
--- EOF ---