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);
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) {
878 }
879
880 if (SystemDictionaryShared::should_be_excluded(ik)) {
881 if (log_is_enabled(Warning, aot, resolve)) {
882 ResourceMark rm;
883 log_warning(aot, resolve)("Cannot aot-resolve constants for %s because it is excluded", ik->external_name());
884 }
885 return;
886 }
887
888 if (preresolve_class) {
889 AOTConstantPoolResolver::preresolve_class_cp_entries(THREAD, ik, &preresolve_list);
890 }
891 if (preresolve_fmi) {
892 AOTConstantPoolResolver::preresolve_field_and_method_cp_entries(THREAD, ik, &preresolve_list);
893 }
894 if (preresolve_indy) {
895 AOTConstantPoolResolver::preresolve_indy_cp_entries(THREAD, ik, &preresolve_list);
896 }
897 }
|
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/cdsConfig.hpp"
30 #include "cds/classListParser.hpp"
31 #include "cds/lambdaFormInvokers.hpp"
32 #include "cds/lambdaProxyClassDictionary.hpp"
33 #include "cds/unregisteredClasses.hpp"
34 #include "classfile/classLoader.hpp"
35 #include "classfile/javaClasses.inline.hpp"
36 #include "classfile/symbolTable.hpp"
37 #include "classfile/systemDictionary.hpp"
38 #include "classfile/systemDictionaryShared.hpp"
39 #include "classfile/vmClasses.hpp"
40 #include "classfile/vmSymbols.hpp"
41 #include "interpreter/bytecode.hpp"
42 #include "interpreter/interpreterRuntime.hpp"
43 #include "interpreter/linkResolver.hpp"
44 #include "jimage.hpp"
45 #include "jvm.h"
46 #include "logging/log.hpp"
47 #include "logging/logTag.hpp"
48 #include "memory/oopFactory.hpp"
49 #include "memory/resourceArea.hpp"
50 #include "oops/constantPool.inline.hpp"
51 #include "runtime/atomicAccess.hpp"
52 #include "runtime/globals_extension.hpp"
53 #include "runtime/handles.inline.hpp"
54 #include "runtime/java.hpp"
55 #include "runtime/javaCalls.hpp"
56 #include "utilities/defaultStream.hpp"
57 #include "utilities/macros.hpp"
58 #include "utilities/utf8.hpp"
59
60 const char* ClassListParser::CONSTANT_POOL_TAG = "@cp";
61 const char* ClassListParser::LAMBDA_FORM_TAG = "@lambda-form-invoker";
62 const char* ClassListParser::LAMBDA_PROXY_TAG = "@lambda-proxy";
63 const char* ClassListParser::LOADER_NEGATIVE_CACHE_TAG = "@loader-negative-cache";
64
65 volatile Thread* ClassListParser::_parsing_thread = nullptr;
66 ClassListParser* ClassListParser::_instance = nullptr;
67
68 ClassListParser::ClassListParser(const char* file, ParseMode parse_mode) :
69 _classlist_file(file),
70 _id2klass_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE),
71 _file_input(do_open(file), /* need_close=*/true),
72 _input_stream(&_file_input),
73 _parse_mode(parse_mode) {
74 aot_log_info(aot)("Parsing %s%s", file,
75 parse_lambda_forms_invokers_only() ? " (lambda form invokers only)" : "");
76 if (!_file_input.is_open()) {
77 char reason[JVM_MAXPATHLEN];
78 os::lasterror(reason, JVM_MAXPATHLEN);
79 vm_exit_during_initialization(err_msg("Loading %s %s failed",
80 FLAG_IS_DEFAULT(AOTConfiguration) ?
81 "classlist" : "AOTConfiguration file",
82 file),
83 reason);
305 if (strcmp(_token, LAMBDA_PROXY_TAG) == 0) {
306 _indy_items->clear();
307 split_tokens_by_whitespace(offset, _indy_items);
308 if (_indy_items->length() < 2) {
309 error("Line with @ tag has too few items \"%s\" line #%zu", _token, lineno());
310 }
311 if (!parse_lambda_forms_invokers_only()) {
312 _class_name = _indy_items->at(0);
313 check_class_name(_class_name);
314 TempNewSymbol class_name_symbol = SymbolTable::new_symbol(_class_name);
315 if (_indy_items->length() > 0) {
316 // The current line is "@lambda-proxy class_name". Load the proxy class.
317 resolve_indy(THREAD, class_name_symbol);
318 }
319 }
320 } else if (strcmp(_token, LAMBDA_FORM_TAG) == 0) {
321 LambdaFormInvokers::append(os::strdup((const char*)(_line + offset), mtInternal));
322 } else if (strcmp(_token, CONSTANT_POOL_TAG) == 0) {
323 _token = _line + offset;
324 parse_constant_pool_tag();
325 } else if (strcmp(_token, LOADER_NEGATIVE_CACHE_TAG) == 0) {
326 _token = _line + offset;
327 parse_loader_negative_cache_tag();
328 } else {
329 error("Invalid @ tag at the beginning of line \"%s\" line #%zu", _token, lineno());
330 }
331 }
332
333 void ClassListParser::skip_whitespaces() {
334 while (*_token == ' ' || *_token == '\t') {
335 _token ++;
336 }
337 }
338
339 void ClassListParser::skip_non_whitespaces() {
340 while (*_token && *_token != ' ' && *_token != '\t') {
341 _token ++;
342 }
343 }
344
345 void ClassListParser::parse_int(int* value) {
346 skip_whitespaces();
347 if (sscanf(_token, "%i", value) == 1) {
883 }
884
885 if (SystemDictionaryShared::should_be_excluded(ik)) {
886 if (log_is_enabled(Warning, aot, resolve)) {
887 ResourceMark rm;
888 log_warning(aot, resolve)("Cannot aot-resolve constants for %s because it is excluded", ik->external_name());
889 }
890 return;
891 }
892
893 if (preresolve_class) {
894 AOTConstantPoolResolver::preresolve_class_cp_entries(THREAD, ik, &preresolve_list);
895 }
896 if (preresolve_fmi) {
897 AOTConstantPoolResolver::preresolve_field_and_method_cp_entries(THREAD, ik, &preresolve_list);
898 }
899 if (preresolve_indy) {
900 AOTConstantPoolResolver::preresolve_indy_cp_entries(THREAD, ik, &preresolve_list);
901 }
902 }
903
904 void ClassListParser::parse_loader_negative_cache_tag() {
905 skip_whitespaces();
906 char* loader_type = _token;
907 skip_non_whitespaces();
908 *_token = '\0';
909 _token ++;
910
911 oop loader;
912 Klass* loader_klass;
913 if (!strcmp(loader_type, "app")) {
914 loader = SystemDictionary::java_system_loader();
915 loader_klass = vmClasses::jdk_internal_loader_ClassLoaders_AppClassLoader_klass();
916 } else if (!strcmp(loader_type, "platform")) {
917 loader = SystemDictionary::java_platform_loader();
918 loader_klass = vmClasses::jdk_internal_loader_ClassLoaders_PlatformClassLoader_klass();
919 } else {
920 warning("%s: unrecognized loader type %s is ignored", LOADER_NEGATIVE_CACHE_TAG, loader_type);
921 return;
922 }
923
924 char* contents = _token;
925 skip_non_whitespaces();
926 *_token = '\0';
927 _token ++;
928
929 if (ArchiveLoaderLookupCache) {
930 TempNewSymbol method = SymbolTable::new_symbol("generateNegativeLookupCache");
931 TempNewSymbol signature = SymbolTable::new_symbol("(Ljava/lang/String;)V");
932
933 EXCEPTION_MARK;
934 HandleMark hm(THREAD);
935 JavaCallArguments args(Handle(THREAD, loader));
936 Handle contents_h = java_lang_String::create_from_str(contents, THREAD);
937 args.push_oop(contents_h);
938 JavaValue result(T_VOID);
939 JavaCalls::call_virtual(&result,
940 loader_klass,
941 method,
942 signature,
943 &args, THREAD);
944 if (HAS_PENDING_EXCEPTION) {
945 Handle exc_handle(THREAD, PENDING_EXCEPTION);
946 CLEAR_PENDING_EXCEPTION;
947
948 log_warning(cds)("Exception during BuiltinClassLoader::generateNegativeLookupCache() call for %s loader", loader_type);
949 LogStreamHandle(Debug, cds) log;
950 if (log.is_enabled()) {
951 java_lang_Throwable::print_stack_trace(exc_handle, &log);
952 }
953 }
954 }
955 }
956
|