< prev index next >

src/hotspot/share/cds/classListParser.cpp

Print this page

  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 
< prev index next >