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/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/resourceArea.hpp"
 46 #include "oops/constantPool.inline.hpp"
 47 #include "runtime/atomic.hpp"
 48 #include "runtime/handles.inline.hpp"
 49 #include "runtime/java.hpp"
 50 #include "runtime/javaCalls.hpp"
 51 #include "utilities/defaultStream.hpp"
 52 #include "utilities/macros.hpp"
 53 #include "utilities/utf8.hpp"
 54 
 55 volatile Thread* ClassListParser::_parsing_thread = nullptr;
 56 ClassListParser* ClassListParser::_instance = nullptr;
 57 
 58 ClassListParser::ClassListParser(const char* file, ParseMode parse_mode) :
 59     _classlist_file(file),
 60     _id2klass_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE),
 61     _file_input(do_open(file), /* need_close=*/true),
 62     _input_stream(&_file_input),
 63     _parse_mode(parse_mode) {
 64   log_info(cds)("Parsing %s%s", file,
 65                 parse_lambda_forms_invokers_only() ? " (lambda form invokers only)" : "");
 66   if (!_file_input.is_open()) {
 67     char errmsg[JVM_MAXPATHLEN];
 68     os::lasterror(errmsg, JVM_MAXPATHLEN);
 69     vm_exit_during_initialization("Loading classlist failed", errmsg);
 70   }
 71   _token = _line = nullptr;
 72   _interfaces = new (mtClass) GrowableArray<int>(10, mtClass);
 73   _indy_items = new (mtClass) GrowableArray<const char*>(9, mtClass);
 74 
 75   // _instance should only be accessed by the thread that created _instance.
 76   assert(_instance == nullptr, "must be singleton");
 77   _instance = this;
 78   Atomic::store(&_parsing_thread, Thread::current());
 79 }
 80 
 81 FILE* ClassListParser::do_open(const char* file) {
 82   // Use os::open() because neither fopen() nor os::fopen()
 83   // can handle long path name on Windows. (See JDK-8216184)
 84   int fd = os::open(file, O_RDONLY, S_IREAD);
 85   FILE* fp = nullptr;
 86   if (fd != -1) {
 87     // Obtain a FILE* from the file descriptor so that _input_stream
 88     // can be used in ClassListParser::parse()
 89     fp = os::fdopen(fd, "r");
 90   }
 91   return fp;
 92 }
 93 
 94 bool ClassListParser::is_parsing_thread() {
 95   return Atomic::load(&_parsing_thread) == Thread::current();
 96 }
 97 
 98 ClassListParser::~ClassListParser() {
 99   Atomic::store(&_parsing_thread, (Thread*)nullptr);
100   delete _indy_items;
101   delete _interfaces;
102   _instance = nullptr;
103 }
104 
105 void ClassListParser::parse(TRAPS) {
106   for (; !_input_stream.done(); _input_stream.next()) {
107     _line = _input_stream.current_line();
108     clean_up_input_line();
109 
110     // Each line in the classlist can be one of three forms:
111     if (_line[0] == '#') {
112       // A comment; ignore it
113     } else if (_line[0] == '@') {
114       // @xxx - a tag like @lambda-proxy, to be parsed by parse_at_tags()
115       parse_at_tags(CHECK);
116     } else {
117       // A class name, followed by optional attributes. E.g.
118       //   java/lang/String
119       //   java/lang/Object id: 1
120       //   my/pkg/TestClass id: 5 super: 1 interfaces: 3 4 source: foo.jar
121       parse_class_name_and_attributes(CHECK);
122     }
123   }
124 }
125 
126 void ClassListParser::parse_class_name_and_attributes(TRAPS) {
127   read_class_name_and_attributes();
128 
129   if (parse_lambda_forms_invokers_only()) {
130     return;
131   }
132 
133   check_class_name(_class_name);
134   TempNewSymbol class_name_symbol = SymbolTable::new_symbol(_class_name);
135   Klass* klass = load_current_class(class_name_symbol, THREAD);
136   if (HAS_PENDING_EXCEPTION) {
137     if (PENDING_EXCEPTION->is_a(vmClasses::OutOfMemoryError_klass())) {
138       // If we have run out of memory, don't try to load the rest of the classes in
139       // the classlist. Throw an exception, which will terminate the dumping process.
140       return; // THROW
141     }
142 
143     ResourceMark rm(THREAD);
144     char* ex_msg = (char*)"";
145     oop message = java_lang_Throwable::message(PENDING_EXCEPTION);
146     if (message != nullptr) {
147       ex_msg = java_lang_String::as_utf8_string(message);
148     }
149     log_warning(cds)("%s: %s", PENDING_EXCEPTION->klass()->external_name(), ex_msg);
150     // We might have an invalid class name or an bad class. Warn about it
151     // and keep going to the next line.
152     CLEAR_PENDING_EXCEPTION;
153     log_warning(cds)("Preload Warning: Cannot find %s", _class_name);
154     return;
155   }
156 
157   assert(klass != nullptr, "sanity");
158   if (log_is_enabled(Trace, cds)) {
159     ResourceMark rm(THREAD);
160     log_trace(cds)("Shared spaces preloaded: %s", klass->external_name());
161   }
162 
163   if (klass->is_instance_klass()) {
164     InstanceKlass* ik = InstanceKlass::cast(klass);
165 
166     // Link the class to cause the bytecodes to be rewritten and the
167     // cpcache to be created. The linking is done as soon as classes
168     // are loaded in order that the related data structures (klass and
169     // cpCache) are located together.
170     MetaspaceShared::try_link_class(THREAD, ik);
171   }
172 }
173 
174 void ClassListParser::clean_up_input_line() {
175   int len = (int)strlen(_line);
176   int i;
177   // Replace \t\r\n\f with ' '
178   for (i=0; i<len; i++) {
179     if (_line[i] == '\t' || _line[i] == '\r' || _line[i] == '\n' || _line[i] == '\f') {
180       _line[i] = ' ';
181     }
182   }
183 
184   // Remove trailing newline/space
185   while (len > 0) {
186     if (_line[len-1] == ' ') {
187       _line[len-1] = '\0';
188       len --;
189     } else {
190       break;
191     }
192   }
193   _line_len = len;
194 }
195 
196 void ClassListParser::read_class_name_and_attributes() {
197   _class_name = _line;
198   _id = _unspecified;
199   _super = _unspecified;
200   _interfaces->clear();
201   _source = nullptr;
202   _interfaces_specified = false;
203 
204   if ((_token = strchr(_line, ' ')) == nullptr) {
205     // No optional attributes are specified.
206     return;
207   }
208 
209   // Mark the end of the name, and go to the next input char
210   *_token++ = '\0';
211 
212   while (*_token) {
213     skip_whitespaces();
214 
215     if (parse_uint_option("id:", &_id)) {
216       continue;
217     } else if (parse_uint_option("super:", &_super)) {
218       check_already_loaded("Super class", _super);
219       continue;
220     } else if (skip_token("interfaces:")) {
221       int i;
222       while (try_parse_uint(&i)) {
223         check_already_loaded("Interface", i);
224         _interfaces->append(i);
225       }
226     } else if (skip_token("source:")) {
227       skip_whitespaces();
228       _source = _token;
229       char* s = strchr(_token, ' ');
230       if (s == nullptr) {
231         break; // end of input line
232       } else {
233         *s = '\0'; // mark the end of _source
234         _token = s+1;
235       }
236     } else {
237       error("Unknown input");
238     }
239   }
240 
241   // if src is specified
242   //     id super interfaces must all be specified
243   //     loader may be specified
244   // else
245   //     # the class is loaded from classpath
246   //     id may be specified
247   //     super, interfaces, loader must not be specified
248 }
249 
250 void ClassListParser::split_tokens_by_whitespace(int offset, GrowableArray<const char*>* items) {
251   int start = offset;
252   int end;
253   bool done = false;
254   while (!done) {
255     while (_line[start] == ' ' || _line[start] == '\t') start++;
256     end = start;
257     while (_line[end] && _line[end] != ' ' && _line[end] != '\t') end++;
258     if (_line[end] == '\0') {
259       done = true;
260     } else {
261       _line[end] = '\0';
262     }
263     items->append(_line + start);
264     start = ++end;
265   }
266 }
267 
268 int ClassListParser::split_at_tag_from_line() {
269   _token = _line;
270   char* ptr;
271   if ((ptr = strchr(_line, ' ')) == nullptr) {
272     error("Too few items following the @ tag \"%s\" line #%zu", _line, lineno());
273     return 0;
274   }
275   *ptr++ = '\0';
276   while (*ptr == ' ' || *ptr == '\t') ptr++;
277   return (int)(ptr - _line);
278 }
279 
280 void ClassListParser::parse_at_tags(TRAPS) {
281   assert(_line[0] == '@', "must be");
282   int offset = split_at_tag_from_line();
283   assert(offset > 0, "would have exited VM");
284 
285   if (strcmp(_token, LAMBDA_PROXY_TAG) == 0) {
286     _indy_items->clear();
287     split_tokens_by_whitespace(offset, _indy_items);
288     if (_indy_items->length() < 2) {
289       error("Line with @ tag has too few items \"%s\" line #%zu", _token, lineno());
290     }
291     if (!parse_lambda_forms_invokers_only()) {
292       _class_name = _indy_items->at(0);
293       check_class_name(_class_name);
294       TempNewSymbol class_name_symbol = SymbolTable::new_symbol(_class_name);
295       if (_indy_items->length() > 0) {
296         // The current line is "@lambda-proxy class_name". Load the proxy class.
297         resolve_indy(THREAD, class_name_symbol);
298       }
299     }
300   } else if (strcmp(_token, LAMBDA_FORM_TAG) == 0) {
301     LambdaFormInvokers::append(os::strdup((const char*)(_line + offset), mtInternal));
302   } else {
303     error("Invalid @ tag at the beginning of line \"%s\" line #%zu", _token, lineno());
304   }
305 }
306 
307 void ClassListParser::skip_whitespaces() {
308   while (*_token == ' ' || *_token == '\t') {
309     _token ++;
310   }
311 }
312 
313 void ClassListParser::skip_non_whitespaces() {
314   while (*_token && *_token != ' ' && *_token != '\t') {
315     _token ++;
316   }
317 }
318 
319 void ClassListParser::parse_int(int* value) {
320   skip_whitespaces();
321   if (sscanf(_token, "%i", value) == 1) {
322     skip_non_whitespaces();
323   } else {
324     error("Error: expected integer");
325   }
326 }
327 
328 void ClassListParser::parse_uint(int* value) {
329   parse_int(value);
330   if (*value < 0) {
331     error("Error: negative integers not allowed (%d)", *value);
332   }
333 }
334 
335 bool ClassListParser::try_parse_uint(int* value) {
336   skip_whitespaces();
337   if (sscanf(_token, "%i", value) == 1) {
338     skip_non_whitespaces();
339     return true;
340   }
341   return false;
342 }
343 
344 bool ClassListParser::skip_token(const char* option_name) {
345   size_t len = strlen(option_name);
346   if (strncmp(_token, option_name, len) == 0) {
347     _token += len;
348     return true;
349   } else {
350     return false;
351   }
352 }
353 
354 bool ClassListParser::parse_int_option(const char* option_name, int* value) {
355   if (skip_token(option_name)) {
356     if (*value != _unspecified) {
357       error("%s specified twice", option_name);
358     } else {
359       parse_int(value);
360       return true;
361     }
362   }
363   return false;
364 }
365 
366 bool ClassListParser::parse_uint_option(const char* option_name, int* value) {
367   if (skip_token(option_name)) {
368     if (*value != _unspecified) {
369       error("%s specified twice", option_name);
370     } else {
371       parse_uint(value);
372       return true;
373     }
374   }
375   return false;
376 }
377 
378 void ClassListParser::print_specified_interfaces() {
379   const int n = _interfaces->length();
380   jio_fprintf(defaultStream::error_stream(), "Currently specified interfaces[%d] = {\n", n);
381   for (int i=0; i<n; i++) {
382     InstanceKlass* k = lookup_class_by_id(_interfaces->at(i));
383     jio_fprintf(defaultStream::error_stream(), "  %4d = %s\n", _interfaces->at(i), k->name()->as_klass_external_name());
384   }
385   jio_fprintf(defaultStream::error_stream(), "}\n");
386 }
387 
388 void ClassListParser::print_actual_interfaces(InstanceKlass* ik) {
389   int n = ik->local_interfaces()->length();
390   jio_fprintf(defaultStream::error_stream(), "Actual interfaces[%d] = {\n", n);
391   for (int i = 0; i < n; i++) {
392     InstanceKlass* e = ik->local_interfaces()->at(i);
393     jio_fprintf(defaultStream::error_stream(), "  %s\n", e->name()->as_klass_external_name());
394   }
395   jio_fprintf(defaultStream::error_stream(), "}\n");
396 }
397 
398 void ClassListParser::error(const char* msg, ...) {
399   va_list ap;
400   va_start(ap, msg);
401   int error_index = pointer_delta_as_int(_token, _line);
402   if (error_index >= _line_len) {
403     error_index = _line_len - 1;
404   }
405   if (error_index < 0) {
406     error_index = 0;
407   }
408 
409   jio_fprintf(defaultStream::error_stream(),
410               "An error has occurred while processing class list file %s %zu:%d.\n",
411               _classlist_file, lineno(), (error_index + 1));
412   jio_vfprintf(defaultStream::error_stream(), msg, ap);
413 
414   if (_line_len <= 0) {
415     jio_fprintf(defaultStream::error_stream(), "\n");
416   } else {
417     jio_fprintf(defaultStream::error_stream(), ":\n");
418     for (int i=0; i<_line_len; i++) {
419       char c = _line[i];
420       if (c == '\0') {
421         jio_fprintf(defaultStream::error_stream(), "%s", " ");
422       } else {
423         jio_fprintf(defaultStream::error_stream(), "%c", c);
424       }
425     }
426     jio_fprintf(defaultStream::error_stream(), "\n");
427     for (int i=0; i<error_index; i++) {
428       jio_fprintf(defaultStream::error_stream(), "%s", " ");
429     }
430     jio_fprintf(defaultStream::error_stream(), "^\n");
431   }
432   va_end(ap);
433 
434   vm_exit_during_initialization("class list format error.", nullptr);
435 }
436 
437 void ClassListParser::check_class_name(const char* class_name) {
438   const char* err = nullptr;
439   size_t len = strlen(class_name);
440   if (len > (size_t)Symbol::max_length()) {
441     err = "class name too long";
442   } else {
443     assert(Symbol::max_length() < INT_MAX && len < INT_MAX, "must be");
444     if (!UTF8::is_legal_utf8((const unsigned char*)class_name, (int)len, /*version_leq_47*/false)) {
445       err = "class name is not valid UTF8";
446     }
447   }
448   if (err != nullptr) {
449     jio_fprintf(defaultStream::error_stream(),
450               "An error has occurred while processing class list file %s:%zu %s\n",
451               _classlist_file, lineno(), err);
452     vm_exit_during_initialization("class list format error.", nullptr);
453   }
454 }
455 
456 // This function is used for loading classes for customized class loaders
457 // during archive dumping.
458 InstanceKlass* ClassListParser::load_class_from_source(Symbol* class_name, TRAPS) {
459 #if !(defined(_LP64) && (defined(LINUX) || defined(__APPLE__) || defined(_WINDOWS)))
460   // The only supported platforms are: (1) Linux/64-bit and (2) Solaris/64-bit and
461   // (3) MacOSX/64-bit and (4) Windowss/64-bit
462   // This #if condition should be in sync with the areCustomLoadersSupportedForCDS
463   // method in test/lib/jdk/test/lib/Platform.java.
464   error("AppCDS custom class loaders not supported on this platform");
465 #endif
466 
467   if (!is_super_specified()) {
468     error("If source location is specified, super class must be also specified");
469   }
470   if (!is_id_specified()) {
471     error("If source location is specified, id must be also specified");
472   }
473   if (strncmp(_class_name, "java/", 5) == 0) {
474     log_info(cds)("Prohibited package for non-bootstrap classes: %s.class from %s",
475           _class_name, _source);
476     THROW_NULL(vmSymbols::java_lang_ClassNotFoundException());
477   }
478 
479   InstanceKlass* k = UnregisteredClasses::load_class(class_name, _source, CHECK_NULL);
480   const int actual_num_interfaces = k->local_interfaces()->length();
481   const int specified_num_interfaces = _interfaces->length(); // specified in classlist
482   int expected_num_interfaces = actual_num_interfaces;
483 
484   if (specified_num_interfaces != expected_num_interfaces) {
485     print_specified_interfaces();
486     print_actual_interfaces(k);
487     error("The number of interfaces (%d) specified in class list does not match the class file (%d)",
488           specified_num_interfaces, expected_num_interfaces);
489   }
490 
491   assert(k->is_shared_unregistered_class(), "must be");
492 
493   bool added = SystemDictionaryShared::add_unregistered_class(THREAD, k);
494   if (!added) {
495     // We allow only a single unregistered class for each unique name.
496     error("Duplicated class %s", _class_name);
497   }
498 
499   return k;
500 }
501 
502 void ClassListParser::populate_cds_indy_info(const constantPoolHandle &pool, int cp_index, CDSIndyInfo* cii, TRAPS) {
503   // Caller needs to allocate ResourceMark.
504   int type_index = pool->bootstrap_name_and_type_ref_index_at(cp_index);
505   int name_index = pool->name_ref_index_at(type_index);
506   cii->add_item(pool->symbol_at(name_index)->as_C_string());
507   int sig_index = pool->signature_ref_index_at(type_index);
508   cii->add_item(pool->symbol_at(sig_index)->as_C_string());
509   int argc = pool->bootstrap_argument_count_at(cp_index);
510   if (argc > 0) {
511     for (int arg_i = 0; arg_i < argc; arg_i++) {
512       int arg = pool->bootstrap_argument_index_at(cp_index, arg_i);
513       jbyte tag = pool->tag_at(arg).value();
514       if (tag == JVM_CONSTANT_MethodType) {
515         cii->add_item(pool->method_type_signature_at(arg)->as_C_string());
516       } else if (tag == JVM_CONSTANT_MethodHandle) {
517         cii->add_ref_kind(pool->method_handle_ref_kind_at(arg));
518         int callee_index = pool->method_handle_klass_index_at(arg);
519         Klass* callee = pool->klass_at(callee_index, CHECK);
520         cii->add_item(callee->name()->as_C_string());
521         cii->add_item(pool->method_handle_name_ref_at(arg)->as_C_string());
522         cii->add_item(pool->method_handle_signature_ref_at(arg)->as_C_string());
523       } else {
524         ShouldNotReachHere();
525       }
526     }
527   }
528 }
529 
530 bool ClassListParser::is_matching_cp_entry(const constantPoolHandle &pool, int cp_index, TRAPS) {
531   ResourceMark rm(THREAD);
532   CDSIndyInfo cii;
533   populate_cds_indy_info(pool, cp_index, &cii, CHECK_0);
534   GrowableArray<const char*>* items = cii.items();
535   int indy_info_offset = 1;
536   if (_indy_items->length() - indy_info_offset != items->length()) {
537     return false;
538   }
539   for (int i = 0; i < items->length(); i++) {
540     if (strcmp(_indy_items->at(i + indy_info_offset), items->at(i)) != 0) {
541       return false;
542     }
543   }
544   return true;
545 }
546 
547 void ClassListParser::resolve_indy(JavaThread* current, Symbol* class_name_symbol) {
548   ExceptionMark em(current);
549   JavaThread* THREAD = current; // For exception macros.
550   ClassListParser::resolve_indy_impl(class_name_symbol, THREAD);
551   if (HAS_PENDING_EXCEPTION) {
552     ResourceMark rm(current);
553     char* ex_msg = (char*)"";
554     oop message = java_lang_Throwable::message(PENDING_EXCEPTION);
555     if (message != nullptr) {
556       ex_msg = java_lang_String::as_utf8_string(message);
557     }
558     log_warning(cds)("resolve_indy for class %s has encountered exception: %s %s",
559                      class_name_symbol->as_C_string(),
560                      PENDING_EXCEPTION->klass()->external_name(),
561                      ex_msg);
562     CLEAR_PENDING_EXCEPTION;
563   }
564 }
565 
566 void ClassListParser::resolve_indy_impl(Symbol* class_name_symbol, TRAPS) {
567   Handle class_loader(THREAD, SystemDictionary::java_system_loader());
568   Handle protection_domain;
569   Klass* klass = SystemDictionary::resolve_or_fail(class_name_symbol, class_loader, protection_domain, true, CHECK);
570   if (klass->is_instance_klass()) {
571     InstanceKlass* ik = InstanceKlass::cast(klass);
572     MetaspaceShared::try_link_class(THREAD, ik);
573     if (!ik->is_linked()) {
574       // Verification of ik has failed
575       return;
576     }
577 
578     ConstantPool* cp = ik->constants();
579     ConstantPoolCache* cpcache = cp->cache();
580     bool found = false;
581     for (int indy_index = 0; indy_index < cpcache->resolved_indy_entries_length(); indy_index++) {
582       int pool_index = cpcache->resolved_indy_entry_at(indy_index)->constant_pool_index();
583       constantPoolHandle pool(THREAD, cp);
584       BootstrapInfo bootstrap_specifier(pool, pool_index, indy_index);
585       Handle bsm = bootstrap_specifier.resolve_bsm(CHECK);
586       if (!SystemDictionaryShared::is_supported_invokedynamic(&bootstrap_specifier)) {
587         log_debug(cds, lambda)("is_supported_invokedynamic check failed for cp_index %d", pool_index);
588         continue;
589       }
590       bool matched = is_matching_cp_entry(pool, pool_index, CHECK);
591       if (matched) {
592         found = true;
593         CallInfo info;
594         bool is_done = bootstrap_specifier.resolve_previously_linked_invokedynamic(info, CHECK);
595         if (!is_done) {
596           // resolve it
597           Handle recv;
598           LinkResolver::resolve_invoke(info,
599                                        recv,
600                                        pool,
601                                        indy_index,
602                                        Bytecodes::_invokedynamic, CHECK);
603           break;
604         }
605         cpcache->set_dynamic_call(info, indy_index);
606       }
607     }
608     if (!found) {
609       ResourceMark rm(THREAD);
610       log_warning(cds)("No invoke dynamic constant pool entry can be found for class %s. The classlist is probably out-of-date.",
611                      class_name_symbol->as_C_string());
612     }
613   }
614 }
615 
616 Klass* ClassListParser::load_current_class(Symbol* class_name_symbol, TRAPS) {
617   Klass* klass;
618   if (!is_loading_from_source()) {
619     // Load classes for the boot/platform/app loaders only.
620     if (is_super_specified()) {
621       error("If source location is not specified, super class must not be specified");
622     }
623     if (are_interfaces_specified()) {
624       error("If source location is not specified, interface(s) must not be specified");
625     }
626 
627     if (Signature::is_array(class_name_symbol)) {
628       // array classes are not supported in class list.
629       THROW_NULL(vmSymbols::java_lang_ClassNotFoundException());
630     }
631 
632     JavaValue result(T_OBJECT);
633     // Call java_system_loader().loadClass() directly, which will
634     // delegate to the correct loader (boot, platform or app) depending on
635     // the package name.
636 
637     // ClassLoader.loadClass() wants external class name format, i.e., convert '/' chars to '.'
638     Handle ext_class_name = java_lang_String::externalize_classname(class_name_symbol, CHECK_NULL);
639     Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());
640 
641     JavaCalls::call_virtual(&result,
642                             loader, //SystemDictionary::java_system_loader(),
643                             vmClasses::ClassLoader_klass(),
644                             vmSymbols::loadClass_name(),
645                             vmSymbols::string_class_signature(),
646                             ext_class_name,
647                             CHECK_NULL);
648 
649     assert(result.get_type() == T_OBJECT, "just checking");
650     oop obj = result.get_oop();
651     assert(obj != nullptr, "jdk.internal.loader.BuiltinClassLoader::loadClass never returns null");
652     klass = java_lang_Class::as_Klass(obj);
653   } else {
654     // If "source:" tag is specified, all super class and super interfaces must be specified in the
655     // class list file.
656     klass = load_class_from_source(class_name_symbol, CHECK_NULL);
657   }
658 
659   assert(klass != nullptr, "exception should have been thrown");
660   assert(klass->is_instance_klass(), "array classes should have been filtered out");
661 
662   if (is_id_specified()) {
663     InstanceKlass* ik = InstanceKlass::cast(klass);
664     int id = this->id();
665     SystemDictionaryShared::update_shared_entry(ik, id);
666     bool created;
667     id2klass_table()->put_if_absent(id, ik, &created);
668     if (!created) {
669       error("Duplicated ID %d for class %s", id, _class_name);
670     }
671     if (id2klass_table()->maybe_grow()) {
672       log_info(cds, hashtables)("Expanded id2klass_table() to %d", id2klass_table()->table_size());
673     }
674   }
675 
676   return klass;
677 }
678 
679 bool ClassListParser::is_loading_from_source() {
680   return (_source != nullptr);
681 }
682 
683 InstanceKlass* ClassListParser::lookup_class_by_id(int id) {
684   InstanceKlass** klass_ptr = id2klass_table()->get(id);
685   if (klass_ptr == nullptr) {
686     error("Class ID %d has not been defined", id);
687   }
688   assert(*klass_ptr != nullptr, "must be");
689   return *klass_ptr;
690 }
691 
692 
693 InstanceKlass* ClassListParser::lookup_super_for_current_class(Symbol* super_name) {
694   if (!is_loading_from_source()) {
695     return nullptr;
696   }
697 
698   InstanceKlass* k = lookup_class_by_id(super());
699   if (super_name != k->name()) {
700     error("The specified super class %s (id %d) does not match actual super class %s",
701           k->name()->as_klass_external_name(), super(),
702           super_name->as_klass_external_name());
703   }
704   return k;
705 }
706 
707 InstanceKlass* ClassListParser::lookup_interface_for_current_class(Symbol* interface_name) {
708   if (!is_loading_from_source()) {
709     return nullptr;
710   }
711 
712   const int n = _interfaces->length();
713   if (n == 0) {
714     error("Class %s implements the interface %s, but no interface has been specified in the input line",
715           _class_name, interface_name->as_klass_external_name());
716     ShouldNotReachHere();
717   }
718 
719   int i;
720   for (i=0; i<n; i++) {
721     InstanceKlass* k = lookup_class_by_id(_interfaces->at(i));
722     if (interface_name == k->name()) {
723       return k;
724     }
725   }
726 
727   // interface_name is not specified by the "interfaces:" keyword.
728   print_specified_interfaces();
729   error("The interface %s implemented by class %s does not match any of the specified interface IDs",
730         interface_name->as_klass_external_name(), _class_name);
731   ShouldNotReachHere();
732   return nullptr;
733 }