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