--- old/src/hotspot/share/classfile/classLoaderExt.hpp 2017-11-27 12:10:45.638183389 -0800 +++ new/src/hotspot/share/classfile/classLoaderExt.hpp 2017-11-27 12:10:45.246168280 -0800 @@ -26,65 +26,152 @@ #define SHARE_VM_CLASSFILE_CLASSLOADEREXT_HPP #include "classfile/classLoader.hpp" -#include "classfile/systemDictionary.hpp" -#include "oops/instanceKlass.hpp" -#include "runtime/handles.hpp" +#include "utilities/macros.hpp" -class ClassListParser; +CDS_ONLY(class SharedPathsMiscInfoExt;) +CDS_ONLY(class ClassListParser;) class ClassLoaderExt: public ClassLoader { // AllStatic public: - + enum SomeConstants { + max_classpath_index = 0x7fff + }; + // ClassLoaderExt::Context -- + // + // This is used by DumpSharedSpaces only - it enforces the same classloader + // delegation model as would be in run-time. I.e., + // + classes defined by the NULL class loader cannot load classes in the PLATFORM or APP paths. + // + classes defined by the PLATFORM class loader cannot load classes in the APP paths. class Context { + static Thread* _dump_thread; + const char* _class_name; const char* _file_name; public: + const char* class_name() { + return _class_name; + } + const char* file_name() { + return _file_name; + } + Context(const char* class_name, const char* file_name, TRAPS) { + _class_name = class_name; _file_name = file_name; +#if INCLUDE_CDS + if (!DumpSharedSpaces && !UseSharedSpaces) { + // Must not modify _app_paths_start_index if we're not using CDS. + assert(_app_paths_start_index == ClassLoaderExt::max_classpath_index, "must be"); + } +#endif } bool check(const ClassFileStream* stream, const int classpath_index) { - return true; + CDS_ONLY(return ClassLoaderExt::check(this, stream, classpath_index);) + NOT_CDS(return true;) } bool should_verify(int classpath_index) { - return false; + CDS_ONLY(return (classpath_index >= _app_paths_start_index);) + NOT_CDS(return false;) } void record_result(Symbol* class_name, const s2 classpath_index, - InstanceKlass* result, TRAPS) { + InstanceKlass* result, + TRAPS) { #if INCLUDE_CDS - assert(DumpSharedSpaces, "Sanity"); - oop loader = result->class_loader(); - s2 classloader_type = ClassLoader::BOOT_LOADER; - if (SystemDictionary::is_system_class_loader(loader)) { - classloader_type = ClassLoader::APP_LOADER; - ClassLoaderExt::set_has_app_classes(); - } else if (SystemDictionary::is_platform_class_loader(loader)) { - classloader_type = ClassLoader::PLATFORM_LOADER; - ClassLoaderExt::set_has_platform_classes(); + ClassLoaderExt::record_result(this, class_name, classpath_index, result, THREAD); +#endif + } + + ~Context() { +#if INCLUDE_CDS + if (!DumpSharedSpaces && !UseSharedSpaces) { + // Must not modify app_paths_start_index if we're not using CDS. + assert(_app_paths_start_index == ClassLoaderExt::max_classpath_index, "must be"); } - result->set_shared_classpath_index(classpath_index); - result->set_class_loader_type(classloader_type); #endif } - }; + }; // end ClassLoaderExt::Context + +private: +#if INCLUDE_CDS + static char* get_class_path_attr(const char* jar_path, char* manifest, jint manifest_size); + static void setup_app_search_path(); // Only when -Xshare:dump + static SharedPathsMiscInfoExt* shared_paths_misc_info() { + return (SharedPathsMiscInfoExt*)_shared_paths_misc_info; + } + static jshort _app_paths_start_index; // index of first app JAR in shared classpath entry table + static bool _has_app_classes; + static bool _has_platform_classes; +#endif + +public: + CDS_ONLY(static void process_jar_manifest(ClassPathEntry* entry, bool check_for_duplicates);) + // Called by JVMTI code to add boot classpath static void append_boot_classpath(ClassPathEntry* new_entry) { +#if INCLUDE_CDS + if (UseAppCDS) { + warning("UseAppCDS is disabled because bootstrap classpath has been appended"); + UseAppCDS = false; + } +#endif ClassLoader::add_to_boot_append_entries(new_entry); } - static void setup_search_paths() {} - static bool is_boot_classpath(int classpath_index) { - return true; - } - static Klass* load_one_class(ClassListParser* parser, TRAPS); + + static void setup_search_paths() NOT_CDS_RETURN; + #if INCLUDE_CDS - static void set_has_app_classes() {} - static void set_has_platform_classes() {} +private: + static char* read_manifest(ClassPathEntry* entry, jint *manifest_size, bool clean_text, TRAPS); + static ClassPathEntry* find_classpath_entry_from_cache(const char* path, TRAPS); + +public: static char* read_manifest(ClassPathEntry* entry, jint *manifest_size, TRAPS) { - return NULL; + // Remove all the new-line continuations (which wrap long lines at 72 characters, see + // http://docs.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#JAR%20Manifest), so + // that the manifest is easier to parse. + return read_manifest(entry, manifest_size, true, THREAD); + } + static char* read_raw_manifest(ClassPathEntry* entry, jint *manifest_size, TRAPS) { + // Do not remove new-line continuations, so we can easily pass it as an argument to + // java.util.jar.Manifest.getManifest() at run-time. + return read_manifest(entry, manifest_size, false, THREAD); + } + + static void finalize_shared_paths_misc_info(); + + static jshort app_paths_start_index() { return _app_paths_start_index; } + + static void init_paths_start_index(jshort app_start) { + _app_paths_start_index = app_start; + } + + static bool is_boot_classpath(int classpath_index) { + return classpath_index < _app_paths_start_index; + } + + static bool has_platform_or_app_classes() { + return _has_app_classes || _has_platform_classes; + } + + static bool check(class ClassLoaderExt::Context *context, + const ClassFileStream* stream, + const int classpath_index); + + static void record_result(class ClassLoaderExt::Context *context, + Symbol* class_name, + const s2 classpath_index, + InstanceKlass* result, TRAPS); + static InstanceKlass* load_class(Symbol* h_name, const char* path, TRAPS); + static Klass* load_one_class(ClassListParser* parser, TRAPS); + static void set_has_app_classes() { + _has_app_classes = true; + } + static void set_has_platform_classes() { + _has_platform_classes = true; } - static void process_jar_manifest(ClassPathEntry* entry, bool check_for_duplicates) {} #endif };