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