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