1 /*
  2  * Copyright (c) 2015, 2021, 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/hashtable.inline.hpp"
 53 #include "utilities/macros.hpp"
 54 
 55 volatile Thread* ClassListParser::_parsing_thread = NULL;
 56 ClassListParser* ClassListParser::_instance = NULL;
 57 
 58 ClassListParser::ClassListParser(const char* file) : _id2klass_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE) {
 59   _classlist_file = file;
 60   _file = NULL;
 61   // Use os::open() because neither fopen() nor os::fopen()
 62   // can handle long path name on Windows.
 63   int fd = os::open(file, O_RDONLY, S_IREAD);
 64   if (fd != -1) {
 65     // Obtain a File* from the file descriptor so that fgets()
 66     // can be used in parse_one_line()
 67     _file = os::open(fd, "r");
 68   }
 69   if (_file == NULL) {
 70     char errmsg[JVM_MAXPATHLEN];
 71     os::lasterror(errmsg, JVM_MAXPATHLEN);
 72     vm_exit_during_initialization("Loading classlist failed", errmsg);
 73   }
 74   _line_no = 0;
 75   _interfaces = new (ResourceObj::C_HEAP, mtClass) GrowableArray<int>(10, mtClass);
 76   _indy_items = new (ResourceObj::C_HEAP, mtClass) GrowableArray<const char*>(9, mtClass);
 77 
 78   // _instance should only be accessed by the thread that created _instance.
 79   assert(_instance == NULL, "must be singleton");
 80   _instance = this;
 81   Atomic::store(&_parsing_thread, Thread::current());
 82 }
 83 
 84 bool ClassListParser::is_parsing_thread() {
 85   return Atomic::load(&_parsing_thread) == Thread::current();
 86 }
 87 
 88 ClassListParser::~ClassListParser() {
 89   if (_file != NULL) {
 90     fclose(_file);
 91   }
 92   Atomic::store(&_parsing_thread, (Thread*)NULL);
 93   delete _indy_items;
 94   delete _interfaces;
 95   _instance = NULL;
 96 }
 97 
 98 int ClassListParser::parse(TRAPS) {
 99   int class_count = 0;
100 
101   while (parse_one_line()) {
102     if (lambda_form_line()) {
103       // The current line is "@lambda-form-invoker ...". It has been recorded in LambdaFormInvokers,
104       // and will be processed later.
105       continue;
106     }
107 
108     TempNewSymbol class_name_symbol = SymbolTable::new_symbol(_class_name);
109     if (_indy_items->length() > 0) {
110       // The current line is "@lambda-proxy class_name". Load the proxy class.
111       resolve_indy(THREAD, class_name_symbol);
112       class_count++;
113       continue;
114     }
115 
116     Klass* klass = load_current_class(class_name_symbol, THREAD);
117     if (HAS_PENDING_EXCEPTION) {
118       if (PENDING_EXCEPTION->is_a(vmClasses::OutOfMemoryError_klass())) {
119         // If we have run out of memory, don't try to load the rest of the classes in
120         // the classlist. Throw an exception, which will terminate the dumping process.
121         return 0; // THROW
122       }
123 
124       ResourceMark rm(THREAD);
125       char* ex_msg = (char*)"";
126       oop message = java_lang_Throwable::message(PENDING_EXCEPTION);
127       if (message != NULL) {
128         ex_msg = java_lang_String::as_utf8_string(message);
129       }
130       log_warning(cds)("%s: %s", PENDING_EXCEPTION->klass()->external_name(), ex_msg);
131       // We might have an invalid class name or an bad class. Warn about it
132       // and keep going to the next line.
133       CLEAR_PENDING_EXCEPTION;
134       log_warning(cds)("Preload Warning: Cannot find %s", _class_name);
135       continue;
136     }
137 
138     assert(klass != NULL, "sanity");
139     if (log_is_enabled(Trace, cds)) {
140       ResourceMark rm(THREAD);
141       log_trace(cds)("Shared spaces preloaded: %s", klass->external_name());
142     }
143 
144     if (klass->is_instance_klass()) {
145       InstanceKlass* ik = InstanceKlass::cast(klass);
146 
147       // Link the class to cause the bytecodes to be rewritten and the
148       // cpcache to be created. The linking is done as soon as classes
149       // are loaded in order that the related data structures (klass and
150       // cpCache) are located together.
151       MetaspaceShared::try_link_class(THREAD, ik);
152     }
153 
154     class_count++;
155   }
156 
157   return class_count;
158 }
159 
160 bool ClassListParser::parse_one_line() {
161   for (;;) {
162     if (fgets(_line, sizeof(_line), _file) == NULL) {
163       return false;
164     }
165     ++ _line_no;
166     _line_len = (int)strlen(_line);
167     if (_line_len > _max_allowed_line_len) {
168       error("input line too long (must be no longer than %d chars)", _max_allowed_line_len);
169     }
170     if (*_line == '#') { // comment
171       continue;
172     }
173 
174     {
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     // valid line
197     break;
198   }
199 
200   _class_name = _line;
201   _id = _unspecified;
202   _super = _unspecified;
203   _interfaces->clear();
204   _source = NULL;
205   _interfaces_specified = false;
206   _indy_items->clear();
207   _lambda_form_line = false;
208 
209   if (_line[0] == '@') {
210     return parse_at_tags();
211   }
212 
213   if ((_token = strchr(_line, ' ')) == NULL) {
214     // No optional arguments are specified.
215     return true;
216   }
217 
218   // Mark the end of the name, and go to the next input char
219   *_token++ = '\0';
220 
221   while (*_token) {
222     skip_whitespaces();
223 
224     if (parse_uint_option("id:", &_id)) {
225       continue;
226     } else if (parse_uint_option("super:", &_super)) {
227       check_already_loaded("Super class", _super);
228       continue;
229     } else if (skip_token("interfaces:")) {
230       int i;
231       while (try_parse_uint(&i)) {
232         check_already_loaded("Interface", i);
233         _interfaces->append(i);
234       }
235     } else if (skip_token("source:")) {
236       skip_whitespaces();
237       _source = _token;
238       char* s = strchr(_token, ' ');
239       if (s == NULL) {
240         break; // end of input line
241       } else {
242         *s = '\0'; // mark the end of _source
243         _token = s+1;
244       }
245     } else {
246       error("Unknown input");
247     }
248   }
249 
250   // if src is specified
251   //     id super interfaces must all be specified
252   //     loader may be specified
253   // else
254   //     # the class is loaded from classpath
255   //     id may be specified
256   //     super, interfaces, loader must not be specified
257   return true;
258 }
259 
260 void ClassListParser::split_tokens_by_whitespace(int offset) {
261   int start = offset;
262   int end;
263   bool done = false;
264   while (!done) {
265     while (_line[start] == ' ' || _line[start] == '\t') start++;
266     end = start;
267     while (_line[end] && _line[end] != ' ' && _line[end] != '\t') end++;
268     if (_line[end] == '\0') {
269       done = true;
270     } else {
271       _line[end] = '\0';
272     }
273     _indy_items->append(_line + start);
274     start = ++end;
275   }
276 }
277 
278 int ClassListParser::split_at_tag_from_line() {
279   _token = _line;
280   char* ptr;
281   if ((ptr = strchr(_line, ' ')) == NULL) {
282     error("Too few items following the @ tag \"%s\" line #%d", _line, _line_no);
283     return 0;
284   }
285   *ptr++ = '\0';
286   while (*ptr == ' ' || *ptr == '\t') ptr++;
287   return (int)(ptr - _line);
288 }
289 
290 bool ClassListParser::parse_at_tags() {
291   assert(_line[0] == '@', "must be");
292   int offset;
293   if ((offset = split_at_tag_from_line()) == 0) {
294     return false;
295   }
296 
297   if (strcmp(_token, LAMBDA_PROXY_TAG) == 0) {
298     split_tokens_by_whitespace(offset);
299     if (_indy_items->length() < 2) {
300       error("Line with @ tag has too few items \"%s\" line #%d", _token, _line_no);
301       return false;
302     }
303     // set the class name
304     _class_name = _indy_items->at(0);
305     return true;
306   } else if (strcmp(_token, LAMBDA_FORM_TAG) == 0) {
307     LambdaFormInvokers::append(os::strdup((const char*)(_line + offset), mtInternal));
308     _lambda_form_line = true;
309     return true;
310   } else {
311     error("Invalid @ tag at the beginning of line \"%s\" line #%d", _token, _line_no);
312     return false;
313   }
314 }
315 
316 void ClassListParser::skip_whitespaces() {
317   while (*_token == ' ' || *_token == '\t') {
318     _token ++;
319   }
320 }
321 
322 void ClassListParser::skip_non_whitespaces() {
323   while (*_token && *_token != ' ' && *_token != '\t') {
324     _token ++;
325   }
326 }
327 
328 void ClassListParser::parse_int(int* value) {
329   skip_whitespaces();
330   if (sscanf(_token, "%i", value) == 1) {
331     skip_non_whitespaces();
332   } else {
333     error("Error: expected integer");
334   }
335 }
336 
337 void ClassListParser::parse_uint(int* value) {
338   parse_int(value);
339   if (*value < 0) {
340     error("Error: negative integers not allowed (%d)", *value);
341   }
342 }
343 
344 bool ClassListParser::try_parse_uint(int* value) {
345   skip_whitespaces();
346   if (sscanf(_token, "%i", value) == 1) {
347     skip_non_whitespaces();
348     return true;
349   }
350   return false;
351 }
352 
353 bool ClassListParser::skip_token(const char* option_name) {
354   size_t len = strlen(option_name);
355   if (strncmp(_token, option_name, len) == 0) {
356     _token += len;
357     return true;
358   } else {
359     return false;
360   }
361 }
362 
363 bool ClassListParser::parse_int_option(const char* option_name, int* value) {
364   if (skip_token(option_name)) {
365     if (*value != _unspecified) {
366       error("%s specified twice", option_name);
367     } else {
368       parse_int(value);
369       return true;
370     }
371   }
372   return false;
373 }
374 
375 bool ClassListParser::parse_uint_option(const char* option_name, int* value) {
376   if (skip_token(option_name)) {
377     if (*value != _unspecified) {
378       error("%s specified twice", option_name);
379     } else {
380       parse_uint(value);
381       return true;
382     }
383   }
384   return false;
385 }
386 
387 void ClassListParser::print_specified_interfaces() {
388   const int n = _interfaces->length();
389   jio_fprintf(defaultStream::error_stream(), "Currently specified interfaces[%d] = {\n", n);
390   for (int i=0; i<n; i++) {
391     InstanceKlass* k = lookup_class_by_id(_interfaces->at(i));
392     jio_fprintf(defaultStream::error_stream(), "  %4d = %s\n", _interfaces->at(i), k->name()->as_klass_external_name());
393   }
394   jio_fprintf(defaultStream::error_stream(), "}\n");
395 }
396 
397 void ClassListParser::print_actual_interfaces(InstanceKlass* ik) {
398   int n = ik->local_interfaces()->length();
399   jio_fprintf(defaultStream::error_stream(), "Actual interfaces[%d] = {\n", n);
400   for (int i = 0; i < n; i++) {
401     InstanceKlass* e = ik->local_interfaces()->at(i);
402     jio_fprintf(defaultStream::error_stream(), "  %s\n", e->name()->as_klass_external_name());
403   }
404   jio_fprintf(defaultStream::error_stream(), "}\n");
405 }
406 
407 void ClassListParser::error(const char* msg, ...) {
408   va_list ap;
409   va_start(ap, msg);
410   int error_index = _token - _line;
411   if (error_index >= _line_len) {
412     error_index = _line_len - 1;
413   }
414   if (error_index < 0) {
415     error_index = 0;
416   }
417 
418   jio_fprintf(defaultStream::error_stream(),
419               "An error has occurred while processing class list file %s %d:%d.\n",
420               _classlist_file, _line_no, (error_index + 1));
421   jio_vfprintf(defaultStream::error_stream(), msg, ap);
422 
423   if (_line_len <= 0) {
424     jio_fprintf(defaultStream::error_stream(), "\n");
425   } else {
426     jio_fprintf(defaultStream::error_stream(), ":\n");
427     for (int i=0; i<_line_len; i++) {
428       char c = _line[i];
429       if (c == '\0') {
430         jio_fprintf(defaultStream::error_stream(), "%s", " ");
431       } else {
432         jio_fprintf(defaultStream::error_stream(), "%c", c);
433       }
434     }
435     jio_fprintf(defaultStream::error_stream(), "\n");
436     for (int i=0; i<error_index; i++) {
437       jio_fprintf(defaultStream::error_stream(), "%s", " ");
438     }
439     jio_fprintf(defaultStream::error_stream(), "^\n");
440   }
441 
442   vm_exit_during_initialization("class list format error.", NULL);
443   va_end(ap);
444 }
445 
446 // This function is used for loading classes for customized class loaders
447 // during archive dumping.
448 InstanceKlass* ClassListParser::load_class_from_source(Symbol* class_name, TRAPS) {
449 #if !(defined(_LP64) && (defined(LINUX) || defined(__APPLE__) || defined(_WINDOWS)))
450   // The only supported platforms are: (1) Linux/64-bit and (2) Solaris/64-bit and
451   // (3) MacOSX/64-bit and (4) Windowss/64-bit
452   // This #if condition should be in sync with the areCustomLoadersSupportedForCDS
453   // method in test/lib/jdk/test/lib/Platform.java.
454   error("AppCDS custom class loaders not supported on this platform");
455 #endif
456 
457   if (!is_super_specified()) {
458     error("If source location is specified, super class must be also specified");
459   }
460   if (!is_id_specified()) {
461     error("If source location is specified, id must be also specified");
462   }
463   if (strncmp(_class_name, "java/", 5) == 0) {
464     log_info(cds)("Prohibited package for non-bootstrap classes: %s.class from %s",
465           _class_name, _source);
466     THROW_NULL(vmSymbols::java_lang_ClassNotFoundException());
467   }
468 
469   InstanceKlass* k = UnregisteredClasses::load_class(class_name, _source, CHECK_NULL);
470   if (k->local_interfaces()->length() != _interfaces->length()) {






































471     print_specified_interfaces();
472     print_actual_interfaces(k);
473     error("The number of interfaces (%d) specified in class list does not match the class file (%d)",
474           _interfaces->length(), k->local_interfaces()->length());
475   }
476 
477   assert(k->is_shared_unregistered_class(), "must be");
478 
479   bool added = SystemDictionaryShared::add_unregistered_class(THREAD, k);
480   if (!added) {
481     // We allow only a single unregistered class for each unique name.
482     error("Duplicated class %s", _class_name);
483   }
484 
485   return k;
486 }
487 
488 void ClassListParser::populate_cds_indy_info(const constantPoolHandle &pool, int cp_index, CDSIndyInfo* cii, TRAPS) {
489   // Caller needs to allocate ResourceMark.
490   int type_index = pool->bootstrap_name_and_type_ref_index_at(cp_index);
491   int name_index = pool->name_ref_index_at(type_index);
492   cii->add_item(pool->symbol_at(name_index)->as_C_string());
493   int sig_index = pool->signature_ref_index_at(type_index);
494   cii->add_item(pool->symbol_at(sig_index)->as_C_string());
495   int argc = pool->bootstrap_argument_count_at(cp_index);
496   if (argc > 0) {
497     for (int arg_i = 0; arg_i < argc; arg_i++) {
498       int arg = pool->bootstrap_argument_index_at(cp_index, arg_i);
499       jbyte tag = pool->tag_at(arg).value();
500       if (tag == JVM_CONSTANT_MethodType) {
501         cii->add_item(pool->method_type_signature_at(arg)->as_C_string());
502       } else if (tag == JVM_CONSTANT_MethodHandle) {
503         cii->add_ref_kind(pool->method_handle_ref_kind_at(arg));
504         int callee_index = pool->method_handle_klass_index_at(arg);
505         Klass* callee = pool->klass_at(callee_index, CHECK);
506         cii->add_item(callee->name()->as_C_string());
507         cii->add_item(pool->method_handle_name_ref_at(arg)->as_C_string());
508         cii->add_item(pool->method_handle_signature_ref_at(arg)->as_C_string());
509       } else {
510         ShouldNotReachHere();
511       }
512     }
513   }
514 }
515 
516 bool ClassListParser::is_matching_cp_entry(const constantPoolHandle &pool, int cp_index, TRAPS) {
517   ResourceMark rm(THREAD);
518   CDSIndyInfo cii;
519   populate_cds_indy_info(pool, cp_index, &cii, CHECK_0);
520   GrowableArray<const char*>* items = cii.items();
521   int indy_info_offset = 1;
522   if (_indy_items->length() - indy_info_offset != items->length()) {
523     return false;
524   }
525   for (int i = 0; i < items->length(); i++) {
526     if (strcmp(_indy_items->at(i + indy_info_offset), items->at(i)) != 0) {
527       return false;
528     }
529   }
530   return true;
531 }
532 
533 void ClassListParser::resolve_indy(JavaThread* current, Symbol* class_name_symbol) {
534   ExceptionMark em(current);
535   JavaThread* THREAD = current; // For exception macros.
536   ClassListParser::resolve_indy_impl(class_name_symbol, THREAD);
537   if (HAS_PENDING_EXCEPTION) {
538     ResourceMark rm(current);
539     char* ex_msg = (char*)"";
540     oop message = java_lang_Throwable::message(PENDING_EXCEPTION);
541     if (message != NULL) {
542       ex_msg = java_lang_String::as_utf8_string(message);
543     }
544     log_warning(cds)("resolve_indy for class %s has encountered exception: %s %s",
545                      class_name_symbol->as_C_string(),
546                      PENDING_EXCEPTION->klass()->external_name(),
547                      ex_msg);
548     CLEAR_PENDING_EXCEPTION;
549   }
550 }
551 
552 void ClassListParser::resolve_indy_impl(Symbol* class_name_symbol, TRAPS) {
553   Handle class_loader(THREAD, SystemDictionary::java_system_loader());
554   Handle protection_domain;
555   Klass* klass = SystemDictionary::resolve_or_fail(class_name_symbol, class_loader, protection_domain, true, CHECK);
556   if (klass->is_instance_klass()) {
557     InstanceKlass* ik = InstanceKlass::cast(klass);
558     MetaspaceShared::try_link_class(THREAD, ik);
559     if (!ik->is_linked()) {
560       // Verification of ik has failed
561       return;
562     }
563 
564     ConstantPool* cp = ik->constants();
565     ConstantPoolCache* cpcache = cp->cache();
566     bool found = false;
567     for (int cpcindex = 0; cpcindex < cpcache->length(); cpcindex ++) {
568       int indy_index = ConstantPool::encode_invokedynamic_index(cpcindex);
569       ConstantPoolCacheEntry* cpce = cpcache->entry_at(cpcindex);
570       int pool_index = cpce->constant_pool_index();
571       constantPoolHandle pool(THREAD, cp);
572       if (pool->tag_at(pool_index).is_invoke_dynamic()) {
573         BootstrapInfo bootstrap_specifier(pool, pool_index, indy_index);
574         Handle bsm = bootstrap_specifier.resolve_bsm(CHECK);
575         if (!SystemDictionaryShared::is_supported_invokedynamic(&bootstrap_specifier)) {
576           log_debug(cds, lambda)("is_supported_invokedynamic check failed for cp_index %d", pool_index);
577           continue;
578         }
579         bool matched = is_matching_cp_entry(pool, pool_index, CHECK);
580         if (matched) {
581           found = true;
582           CallInfo info;
583           bool is_done = bootstrap_specifier.resolve_previously_linked_invokedynamic(info, CHECK);
584           if (!is_done) {
585             // resolve it
586             Handle recv;
587             LinkResolver::resolve_invoke(info, recv, pool, indy_index, Bytecodes::_invokedynamic, CHECK);
588             break;
589           }
590           cpce->set_dynamic_call(pool, info);
591         }
592       }
593     }
594     if (!found) {
595       ResourceMark rm(THREAD);
596       log_warning(cds)("No invoke dynamic constant pool entry can be found for class %s. The classlist is probably out-of-date.",
597                      class_name_symbol->as_C_string());
598     }
599   }
600 }
601 
602 Klass* ClassListParser::load_current_class(Symbol* class_name_symbol, TRAPS) {
603   Klass* klass;
604   if (!is_loading_from_source()) {
605     // Load classes for the boot/platform/app loaders only.
606     if (is_super_specified()) {
607       error("If source location is not specified, super class must not be specified");
608     }
609     if (are_interfaces_specified()) {
610       error("If source location is not specified, interface(s) must not be specified");
611     }
612 
613     if (Signature::is_array(class_name_symbol)) {
614       // array classes are not supported in class list.
615       THROW_NULL(vmSymbols::java_lang_ClassNotFoundException());
616     }
617 
618     JavaValue result(T_OBJECT);
619     // Call java_system_loader().loadClass() directly, which will
620     // delegate to the correct loader (boot, platform or app) depending on
621     // the package name.
622 
623     // ClassLoader.loadClass() wants external class name format, i.e., convert '/' chars to '.'
624     Handle ext_class_name = java_lang_String::externalize_classname(class_name_symbol, CHECK_NULL);
625     Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());
626 
627     JavaCalls::call_virtual(&result,
628                             loader, //SystemDictionary::java_system_loader(),
629                             vmClasses::ClassLoader_klass(),
630                             vmSymbols::loadClass_name(),
631                             vmSymbols::string_class_signature(),
632                             ext_class_name,
633                             CHECK_NULL);
634 
635     assert(result.get_type() == T_OBJECT, "just checking");
636     oop obj = result.get_oop();
637     assert(obj != NULL, "jdk.internal.loader.BuiltinClassLoader::loadClass never returns null");
638     klass = java_lang_Class::as_Klass(obj);
639   } else {
640     // If "source:" tag is specified, all super class and super interfaces must be specified in the
641     // class list file.
642     klass = load_class_from_source(class_name_symbol, CHECK_NULL);
643   }
644 
645   assert(klass != NULL, "exception should have been thrown");
646   assert(klass->is_instance_klass(), "array classes should have been filtered out");
647 
648   if (is_id_specified()) {
649     InstanceKlass* ik = InstanceKlass::cast(klass);
650     int id = this->id();
651     SystemDictionaryShared::update_shared_entry(ik, id);
652     bool created;
653     id2klass_table()->put_if_absent(id, ik, &created);
654     if (!created) {
655       error("Duplicated ID %d for class %s", id, _class_name);
656     }
657     if (id2klass_table()->maybe_grow()) {
658       log_info(cds, hashtables)("Expanded id2klass_table() to %d", id2klass_table()->table_size());
659     }
660   }
661 
662   return klass;
663 }
664 
665 bool ClassListParser::is_loading_from_source() {
666   return (_source != NULL);
667 }
668 
669 InstanceKlass* ClassListParser::lookup_class_by_id(int id) {
670   InstanceKlass** klass_ptr = id2klass_table()->get(id);
671   if (klass_ptr == NULL) {
672     error("Class ID %d has not been defined", id);
673   }
674   assert(*klass_ptr != NULL, "must be");
675   return *klass_ptr;
676 }
677 
678 
679 InstanceKlass* ClassListParser::lookup_super_for_current_class(Symbol* super_name) {
680   if (!is_loading_from_source()) {
681     return NULL;
682   }
683 
684   InstanceKlass* k = lookup_class_by_id(super());
685   if (super_name != k->name()) {
686     error("The specified super class %s (id %d) does not match actual super class %s",
687           k->name()->as_klass_external_name(), super(),
688           super_name->as_klass_external_name());
689   }
690   return k;
691 }
692 
693 InstanceKlass* ClassListParser::lookup_interface_for_current_class(Symbol* interface_name) {
694   if (!is_loading_from_source()) {
695     return NULL;
696   }
697 











698   const int n = _interfaces->length();
699   if (n == 0) {
700     error("Class %s implements the interface %s, but no interface has been specified in the input line",
701           _class_name, interface_name->as_klass_external_name());
702     ShouldNotReachHere();
703   }
704 
705   int i;
706   for (i=0; i<n; i++) {
707     InstanceKlass* k = lookup_class_by_id(_interfaces->at(i));
708     if (interface_name == k->name()) {
709       return k;
710     }
711   }
712 
713   // interface_name is not specified by the "interfaces:" keyword.
714   print_specified_interfaces();
715   error("The interface %s implemented by class %s does not match any of the specified interface IDs",
716         interface_name->as_klass_external_name(), _class_name);
717   ShouldNotReachHere();
718   return NULL;
719 }
--- EOF ---