8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "cds/aotConstantPoolResolver.hpp"
27 #include "cds/archiveUtils.hpp"
28 #include "cds/classListParser.hpp"
29 #include "cds/lambdaFormInvokers.hpp"
30 #include "cds/metaspaceShared.hpp"
31 #include "cds/unregisteredClasses.hpp"
32 #include "classfile/classLoaderExt.hpp"
33 #include "classfile/javaClasses.inline.hpp"
34 #include "classfile/symbolTable.hpp"
35 #include "classfile/systemDictionary.hpp"
36 #include "classfile/systemDictionaryShared.hpp"
37 #include "classfile/vmClasses.hpp"
38 #include "classfile/vmSymbols.hpp"
39 #include "interpreter/bytecode.hpp"
40 #include "interpreter/bytecodeStream.hpp"
41 #include "interpreter/linkResolver.hpp"
42 #include "jimage.hpp"
43 #include "jvm.h"
44 #include "logging/log.hpp"
45 #include "logging/logTag.hpp"
46 #include "memory/resourceArea.hpp"
47 #include "oops/constantPool.inline.hpp"
48 #include "runtime/atomic.hpp"
49 #include "runtime/globals_extension.hpp"
50 #include "runtime/handles.inline.hpp"
51 #include "runtime/java.hpp"
52 #include "runtime/javaCalls.hpp"
53 #include "utilities/defaultStream.hpp"
54 #include "utilities/macros.hpp"
55 #include "utilities/utf8.hpp"
56
57 const char* ClassListParser::CONSTANT_POOL_TAG = "@cp";
58 const char* ClassListParser::LAMBDA_FORM_TAG = "@lambda-form-invoker";
59 const char* ClassListParser::LAMBDA_PROXY_TAG = "@lambda-proxy";
60
61 volatile Thread* ClassListParser::_parsing_thread = nullptr;
62 ClassListParser* ClassListParser::_instance = nullptr;
63
64 ClassListParser::ClassListParser(const char* file, ParseMode parse_mode) :
65 _classlist_file(file),
66 _id2klass_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE),
67 _file_input(do_open(file), /* need_close=*/true),
68 _input_stream(&_file_input),
69 _parse_mode(parse_mode) {
70 log_info(cds)("Parsing %s%s", file,
71 parse_lambda_forms_invokers_only() ? " (lambda form invokers only)" : "");
72 if (!_file_input.is_open()) {
73 char reason[JVM_MAXPATHLEN];
74 os::lasterror(reason, JVM_MAXPATHLEN);
75 vm_exit_during_initialization(err_msg("Loading %s %s failed",
76 FLAG_IS_DEFAULT(AOTConfiguration) ?
77 "classlist" : "AOTConfiguration file",
78 file),
79 reason);
295 if (strcmp(_token, LAMBDA_PROXY_TAG) == 0) {
296 _indy_items->clear();
297 split_tokens_by_whitespace(offset, _indy_items);
298 if (_indy_items->length() < 2) {
299 error("Line with @ tag has too few items \"%s\" line #%zu", _token, lineno());
300 }
301 if (!parse_lambda_forms_invokers_only()) {
302 _class_name = _indy_items->at(0);
303 check_class_name(_class_name);
304 TempNewSymbol class_name_symbol = SymbolTable::new_symbol(_class_name);
305 if (_indy_items->length() > 0) {
306 // The current line is "@lambda-proxy class_name". Load the proxy class.
307 resolve_indy(THREAD, class_name_symbol);
308 }
309 }
310 } else if (strcmp(_token, LAMBDA_FORM_TAG) == 0) {
311 LambdaFormInvokers::append(os::strdup((const char*)(_line + offset), mtInternal));
312 } else if (strcmp(_token, CONSTANT_POOL_TAG) == 0) {
313 _token = _line + offset;
314 parse_constant_pool_tag();
315 } else {
316 error("Invalid @ tag at the beginning of line \"%s\" line #%zu", _token, lineno());
317 }
318 }
319
320 void ClassListParser::skip_whitespaces() {
321 while (*_token == ' ' || *_token == '\t') {
322 _token ++;
323 }
324 }
325
326 void ClassListParser::skip_non_whitespaces() {
327 while (*_token && *_token != ' ' && *_token != '\t') {
328 _token ++;
329 }
330 }
331
332 void ClassListParser::parse_int(int* value) {
333 skip_whitespaces();
334 if (sscanf(_token, "%i", value) == 1) {
779 }
780
781 InstanceKlass* ClassListParser::find_builtin_class_helper(JavaThread* current, Symbol* class_name_symbol, oop class_loader_oop) {
782 Handle class_loader(current, class_loader_oop);
783 return SystemDictionary::find_instance_klass(current, class_name_symbol, class_loader);
784 }
785
786 InstanceKlass* ClassListParser::find_builtin_class(JavaThread* current, const char* class_name) {
787 TempNewSymbol class_name_symbol = SymbolTable::new_symbol(class_name);
788 InstanceKlass* ik;
789
790 if ( (ik = find_builtin_class_helper(current, class_name_symbol, nullptr)) != nullptr
791 || (ik = find_builtin_class_helper(current, class_name_symbol, SystemDictionary::java_platform_loader())) != nullptr
792 || (ik = find_builtin_class_helper(current, class_name_symbol, SystemDictionary::java_system_loader())) != nullptr) {
793 return ik;
794 } else {
795 return nullptr;
796 }
797 }
798
799 void ClassListParser::parse_constant_pool_tag() {
800 if (parse_lambda_forms_invokers_only()) {
801 return;
802 }
803
804 JavaThread* THREAD = JavaThread::current();
805 skip_whitespaces();
806 char* class_name = _token;
807 skip_non_whitespaces();
808 *_token = '\0';
809 _token ++;
810
811 InstanceKlass* ik = find_builtin_class(THREAD, class_name);
812 if (ik == nullptr) {
813 _token = class_name;
814 if (strstr(class_name, "/$Proxy") != nullptr ||
815 strstr(class_name, "MethodHandle$Species_") != nullptr) {
816 // ignore -- TODO: we should filter these out in classListWriter.cpp
817 } else {
818 constant_pool_resolution_warning("class %s is not (yet) loaded by one of the built-in loaders", class_name);
848 break;
849 case JVM_CONSTANT_Fieldref:
850 case JVM_CONSTANT_Methodref:
851 case JVM_CONSTANT_InterfaceMethodref:
852 preresolve_fmi = true;
853 break;
854 case JVM_CONSTANT_InvokeDynamic:
855 preresolve_indy = true;
856 break;
857 default:
858 constant_pool_resolution_warning("Unsupported constant pool index %d: %s (type=%d)",
859 cp_index, cp_tag.internal_name(), cp_tag.value());
860 return;
861 }
862 }
863
864 if (preresolve_class) {
865 AOTConstantPoolResolver::preresolve_class_cp_entries(THREAD, ik, &preresolve_list);
866 }
867 if (preresolve_fmi) {
868 AOTConstantPoolResolver::preresolve_field_and_method_cp_entries(THREAD, ik, &preresolve_list);
869 }
870 if (preresolve_indy) {
871 AOTConstantPoolResolver::preresolve_indy_cp_entries(THREAD, ik, &preresolve_list);
872 }
873 }
|
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "cds/aotConstantPoolResolver.hpp"
27 #include "cds/archiveUtils.hpp"
28 #include "cds/cdsConfig.hpp"
29 #include "cds/classListParser.hpp"
30 #include "cds/lambdaFormInvokers.hpp"
31 #include "cds/metaspaceShared.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/interpreterRuntime.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 "oops/cpCache.inline.hpp"
51 #include "runtime/atomic.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::CLASS_REFLECTION_DATA_TAG = "@class-reflection-data";
61 const char* ClassListParser::CONSTANT_POOL_TAG = "@cp";
62 const char* ClassListParser::DYNAMIC_PROXY_TAG = "@dynamic-proxy";
63 const char* ClassListParser::LAMBDA_FORM_TAG = "@lambda-form-invoker";
64 const char* ClassListParser::LAMBDA_PROXY_TAG = "@lambda-proxy";
65 const char* ClassListParser::LOADER_NEGATIVE_CACHE_TAG = "@loader-negative-cache";
66 const char* ClassListParser::ARRAY_TAG = "@array";
67
68 volatile Thread* ClassListParser::_parsing_thread = nullptr;
69 ClassListParser* ClassListParser::_instance = nullptr;
70
71 ClassListParser::ClassListParser(const char* file, ParseMode parse_mode) :
72 _classlist_file(file),
73 _id2klass_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE),
74 _file_input(do_open(file), /* need_close=*/true),
75 _input_stream(&_file_input),
76 _parse_mode(parse_mode) {
77 log_info(cds)("Parsing %s%s", file,
78 parse_lambda_forms_invokers_only() ? " (lambda form invokers only)" : "");
79 if (!_file_input.is_open()) {
80 char reason[JVM_MAXPATHLEN];
81 os::lasterror(reason, JVM_MAXPATHLEN);
82 vm_exit_during_initialization(err_msg("Loading %s %s failed",
83 FLAG_IS_DEFAULT(AOTConfiguration) ?
84 "classlist" : "AOTConfiguration file",
85 file),
86 reason);
302 if (strcmp(_token, LAMBDA_PROXY_TAG) == 0) {
303 _indy_items->clear();
304 split_tokens_by_whitespace(offset, _indy_items);
305 if (_indy_items->length() < 2) {
306 error("Line with @ tag has too few items \"%s\" line #%zu", _token, lineno());
307 }
308 if (!parse_lambda_forms_invokers_only()) {
309 _class_name = _indy_items->at(0);
310 check_class_name(_class_name);
311 TempNewSymbol class_name_symbol = SymbolTable::new_symbol(_class_name);
312 if (_indy_items->length() > 0) {
313 // The current line is "@lambda-proxy class_name". Load the proxy class.
314 resolve_indy(THREAD, class_name_symbol);
315 }
316 }
317 } else if (strcmp(_token, LAMBDA_FORM_TAG) == 0) {
318 LambdaFormInvokers::append(os::strdup((const char*)(_line + offset), mtInternal));
319 } else if (strcmp(_token, CONSTANT_POOL_TAG) == 0) {
320 _token = _line + offset;
321 parse_constant_pool_tag();
322 } else if (strcmp(_token, ARRAY_TAG) == 0) {
323 _token = _line + offset;
324 parse_array_dimension_tag();
325 } else if (strcmp(_token, CLASS_REFLECTION_DATA_TAG) == 0) {
326 _token = _line + offset;
327 parse_class_reflection_data_tag();
328 } else if (strcmp(_token, DYNAMIC_PROXY_TAG) == 0) {
329 _token = _line + offset;
330 parse_dynamic_proxy_tag();
331 } else if (strcmp(_token, LOADER_NEGATIVE_CACHE_TAG) == 0) {
332 _token = _line + offset;
333 parse_loader_negative_cache_tag();
334 } else {
335 error("Invalid @ tag at the beginning of line \"%s\" line #%zu", _token, lineno());
336 }
337 }
338
339 void ClassListParser::skip_whitespaces() {
340 while (*_token == ' ' || *_token == '\t') {
341 _token ++;
342 }
343 }
344
345 void ClassListParser::skip_non_whitespaces() {
346 while (*_token && *_token != ' ' && *_token != '\t') {
347 _token ++;
348 }
349 }
350
351 void ClassListParser::parse_int(int* value) {
352 skip_whitespaces();
353 if (sscanf(_token, "%i", value) == 1) {
798 }
799
800 InstanceKlass* ClassListParser::find_builtin_class_helper(JavaThread* current, Symbol* class_name_symbol, oop class_loader_oop) {
801 Handle class_loader(current, class_loader_oop);
802 return SystemDictionary::find_instance_klass(current, class_name_symbol, class_loader);
803 }
804
805 InstanceKlass* ClassListParser::find_builtin_class(JavaThread* current, const char* class_name) {
806 TempNewSymbol class_name_symbol = SymbolTable::new_symbol(class_name);
807 InstanceKlass* ik;
808
809 if ( (ik = find_builtin_class_helper(current, class_name_symbol, nullptr)) != nullptr
810 || (ik = find_builtin_class_helper(current, class_name_symbol, SystemDictionary::java_platform_loader())) != nullptr
811 || (ik = find_builtin_class_helper(current, class_name_symbol, SystemDictionary::java_system_loader())) != nullptr) {
812 return ik;
813 } else {
814 return nullptr;
815 }
816 }
817
818 void ClassListParser::parse_array_dimension_tag() {
819 if (parse_lambda_forms_invokers_only()) {
820 return;
821 }
822
823 skip_whitespaces();
824 char* class_name = _token;
825 skip_non_whitespaces();
826 *_token = '\0';
827 _token ++;
828
829 skip_whitespaces();
830 int dim;
831 parse_uint(&dim);
832
833 JavaThread* THREAD = JavaThread::current();
834 InstanceKlass* ik = find_builtin_class(THREAD, class_name);
835 if (ik == nullptr) {
836 _token = class_name;
837 if (strstr(class_name, "/$Proxy") != nullptr ||
838 strstr(class_name, "MethodHandle$Species_") != nullptr) {
839 // ignore -- TODO: we should filter these out in classListWriter.cpp
840 } else {
841 constant_pool_resolution_warning("class %s is not (yet) loaded by one of the built-in loaders", class_name);
842 }
843 return;
844 }
845
846 if (dim > 0) {
847 ik->array_klass(dim, THREAD);
848 if (HAS_PENDING_EXCEPTION) {
849 error("Array klass allocation failed: %s %d", _class_name, dim);
850 }
851 }
852 }
853
854 void ClassListParser::parse_constant_pool_tag() {
855 if (parse_lambda_forms_invokers_only()) {
856 return;
857 }
858
859 JavaThread* THREAD = JavaThread::current();
860 skip_whitespaces();
861 char* class_name = _token;
862 skip_non_whitespaces();
863 *_token = '\0';
864 _token ++;
865
866 InstanceKlass* ik = find_builtin_class(THREAD, class_name);
867 if (ik == nullptr) {
868 _token = class_name;
869 if (strstr(class_name, "/$Proxy") != nullptr ||
870 strstr(class_name, "MethodHandle$Species_") != nullptr) {
871 // ignore -- TODO: we should filter these out in classListWriter.cpp
872 } else {
873 constant_pool_resolution_warning("class %s is not (yet) loaded by one of the built-in loaders", class_name);
903 break;
904 case JVM_CONSTANT_Fieldref:
905 case JVM_CONSTANT_Methodref:
906 case JVM_CONSTANT_InterfaceMethodref:
907 preresolve_fmi = true;
908 break;
909 case JVM_CONSTANT_InvokeDynamic:
910 preresolve_indy = true;
911 break;
912 default:
913 constant_pool_resolution_warning("Unsupported constant pool index %d: %s (type=%d)",
914 cp_index, cp_tag.internal_name(), cp_tag.value());
915 return;
916 }
917 }
918
919 if (preresolve_class) {
920 AOTConstantPoolResolver::preresolve_class_cp_entries(THREAD, ik, &preresolve_list);
921 }
922 if (preresolve_fmi) {
923 // FIXME: too coarse; doesn't cover resolution of Class entries
924 // JavaThread::NoJavaCodeMark no_java_code(THREAD); // ensure no clinits are exectued
925 AOTConstantPoolResolver::preresolve_field_and_method_cp_entries(THREAD, ik, &preresolve_list);
926 }
927 if (preresolve_indy) {
928 AOTConstantPoolResolver::preresolve_indy_cp_entries(THREAD, ik, &preresolve_list);
929 }
930 }
931
932 void ClassListParser::parse_class_reflection_data_tag() {
933 if (parse_lambda_forms_invokers_only()) {
934 return;
935 }
936
937 JavaThread* THREAD = JavaThread::current();
938 skip_whitespaces();
939 char* class_name = _token;
940 skip_non_whitespaces();
941 *_token = '\0';
942 _token ++;
943
944 InstanceKlass* ik = find_builtin_class(THREAD, class_name);
945 if (ik == nullptr) {
946 _token = class_name;
947 if (strstr(class_name, "/$Proxy") != nullptr ||
948 strstr(class_name, "MethodHandle$Species_") != nullptr) {
949 // ignore -- TODO: we should filter these out in classListWriter.cpp
950 } else {
951 warning("%s: class not found: %s", CLASS_REFLECTION_DATA_TAG, class_name);
952 }
953 return;
954 }
955
956 ResourceMark rm(THREAD);
957
958 int rd_flags = _unspecified;
959 while (*_token) {
960 skip_whitespaces();
961 if (rd_flags != _unspecified) {
962 error("rd_flags specified twice");
963 return;
964 }
965 parse_uint(&rd_flags);
966 }
967 if (rd_flags == _unspecified) {
968 error("no rd_flags specified");
969 return;
970 }
971
972 if (CDSConfig::is_dumping_reflection_data()) {
973 AOTConstantPoolResolver::generate_reflection_data(THREAD, ik, rd_flags);
974 }
975 }
976
977 oop ClassListParser::loader_from_type(const char* loader_type) {
978 oop loader;
979 if (!ArchiveUtils::builtin_loader_from_type(loader_type, &loader)) {
980 error("Unknown loader %s", loader_type);
981 }
982 return loader;
983 }
984
985 void ClassListParser::parse_dynamic_proxy_tag() {
986 if (parse_lambda_forms_invokers_only()) {
987 return;
988 }
989
990 skip_whitespaces();
991 char* loader_type = _token;
992 skip_non_whitespaces();
993 *_token = '\0';
994 _token ++;
995
996 skip_whitespaces();
997 char* proxy_name_str = _token;
998 skip_non_whitespaces();
999 *_token = '\0';
1000 _token ++;
1001
1002 skip_whitespaces();
1003 int access_flags;
1004 parse_uint(&access_flags);
1005
1006 skip_whitespaces();
1007 int num_intfs;
1008 parse_uint(&num_intfs);
1009
1010 JavaThread* THREAD = JavaThread::current();
1011 Handle loader(THREAD, loader_from_type(loader_type));
1012 Handle proxy_name(THREAD, java_lang_String::create_oop_from_str(proxy_name_str, THREAD));
1013 if (HAS_PENDING_EXCEPTION) {
1014 error("Out of memory");
1015 }
1016
1017 objArrayHandle interfaces(THREAD, oopFactory::new_objArray(vmClasses::Class_klass(), num_intfs, THREAD));
1018 if (HAS_PENDING_EXCEPTION) {
1019 error("Out of memory");
1020 }
1021
1022 for (int i = 0; i < num_intfs; i++) {
1023 skip_whitespaces();
1024 char* intf_name = _token;
1025 skip_non_whitespaces();
1026 *_token = '\0';
1027 _token ++;
1028
1029 InstanceKlass* ik = find_builtin_class(THREAD, intf_name);
1030 if (ik != nullptr) {
1031 interfaces()->obj_at_put(i, ik->java_mirror());
1032 } else {
1033 error("Unknown class %s", intf_name);
1034 }
1035 }
1036
1037 if (strncmp("jdk.proxy", proxy_name_str, 9) != 0) {
1038 return;
1039 }
1040
1041 AOTConstantPoolResolver::define_dynamic_proxy_class(loader, proxy_name, interfaces, access_flags, THREAD);
1042 if (HAS_PENDING_EXCEPTION) {
1043 PENDING_EXCEPTION->print_on(tty);
1044 error("defineProxyClassForCDS failed");
1045 }
1046 }
1047
1048 void ClassListParser::parse_loader_negative_cache_tag() {
1049 skip_whitespaces();
1050 char* loader_type = _token;
1051 skip_non_whitespaces();
1052 *_token = '\0';
1053 _token ++;
1054
1055 oop loader;
1056 Klass* loader_klass;
1057 if (!strcmp(loader_type, "app")) {
1058 loader = SystemDictionary::java_system_loader();
1059 loader_klass = vmClasses::jdk_internal_loader_ClassLoaders_AppClassLoader_klass();
1060 } else if (!strcmp(loader_type, "platform")) {
1061 loader = SystemDictionary::java_platform_loader();
1062 loader_klass = vmClasses::jdk_internal_loader_ClassLoaders_PlatformClassLoader_klass();
1063 } else {
1064 warning("%s: unrecognized loader type %s is ignored", LOADER_NEGATIVE_CACHE_TAG, loader_type);
1065 return;
1066 }
1067
1068 char* contents = _token;
1069 skip_non_whitespaces();
1070 *_token = '\0';
1071 _token ++;
1072
1073 if (ArchiveLoaderLookupCache) {
1074 TempNewSymbol method = SymbolTable::new_symbol("generateNegativeLookupCache");
1075 TempNewSymbol signature = SymbolTable::new_symbol("(Ljava/lang/String;)V");
1076
1077 EXCEPTION_MARK;
1078 HandleMark hm(THREAD);
1079 JavaCallArguments args(Handle(THREAD, loader));
1080 Handle contents_h = java_lang_String::create_from_str(contents, THREAD);
1081 args.push_oop(contents_h);
1082 JavaValue result(T_VOID);
1083 JavaCalls::call_virtual(&result,
1084 loader_klass,
1085 method,
1086 signature,
1087 &args, THREAD);
1088 if (HAS_PENDING_EXCEPTION) {
1089 Handle exc_handle(THREAD, PENDING_EXCEPTION);
1090 CLEAR_PENDING_EXCEPTION;
1091
1092 log_warning(cds)("Exception during BuiltinClassLoader::generateNegativeLookupCache() call for %s loader", loader_type);
1093 LogStreamHandle(Debug, cds) log;
1094 if (log.is_enabled()) {
1095 java_lang_Throwable::print_stack_trace(exc_handle, &log);
1096 }
1097 }
1098 }
1099 }
1100
|