8193213: Make the UseAppCDS option obsolete

8182731: Odd handling of -XX:-UseAppCDS and -XX:SharedArchiveFile

Application class data sharing is enabled without -XX:+UseAppCDS. SharedArchiveFile is now a product flag.

Reviewed-by: dholmes, ihse, erikj, ccheung
This commit is contained in:
Jiangli Zhou 2018-04-30 16:59:05 -04:00
parent cdd3f0ac39
commit 20edc74068
33 changed files with 189 additions and 238 deletions

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -61,11 +61,12 @@ $(CLASSLIST_FILE): $(INTERIM_IMAGE_DIR)/bin/java$(EXE_SUFFIX) $(CLASSLIST_JAR)
$(call MakeDir, $(LINK_OPT_DIR))
$(call LogInfo, Generating $(patsubst $(OUTPUTDIR)/%, %, $@))
$(call LogInfo, Generating $(patsubst $(OUTPUTDIR)/%, %, $(JLI_TRACE_FILE)))
$(FIXPATH) $(INTERIM_IMAGE_DIR)/bin/java -XX:DumpLoadedClassList=$@ \
$(FIXPATH) $(INTERIM_IMAGE_DIR)/bin/java -XX:DumpLoadedClassList=$@.raw \
-Djava.lang.invoke.MethodHandle.TRACE_RESOLVE=true \
-cp $(SUPPORT_OUTPUTDIR)/classlist.jar \
build.tools.classlist.HelloClasslist \
$(LOG_DEBUG) 2>&1 > $(JLI_TRACE_FILE)
$(GREP) -v HelloClasslist $@.raw > $@
# The jli trace is created by the same recipe as classlist. By declaring these
# dependencies, make will correctly rebuild both jli trace and classlist

View File

@ -283,7 +283,6 @@ InstanceKlass* ClassListParser::load_class_from_source(Symbol* class_name, TRAPS
error("AppCDS custom class loaders not supported on this platform");
#endif
assert(UseAppCDS, "must be");
if (!is_super_specified()) {
error("If source location is specified, super class must be also specified");
}
@ -383,9 +382,7 @@ Klass* ClassListParser::load_current_class(TRAPS) {
} else {
// If "source:" tag is specified, all super class and super interfaces must be specified in the
// class list file.
if (UseAppCDS) {
klass = load_class_from_source(class_name_symbol, CHECK_NULL);
}
klass = load_class_from_source(class_name_symbol, CHECK_NULL);
}
if (klass != NULL && klass->is_instance_klass() && is_id_specified()) {

View File

@ -270,14 +270,6 @@ ClassFileStream* ClassPathDirEntry::open_stream(const char* name, TRAPS) {
// check if file exists
struct stat st;
if (os::stat(path, &st) == 0) {
#if INCLUDE_CDS
if (DumpSharedSpaces) {
// We have already check in ClassLoader::check_shared_classpath() that the directory is empty, so
// we should never find a file underneath it -- unless user has added a new file while we are running
// the dump, in which case let's quit!
ShouldNotReachHere();
}
#endif
// found file, open it
int file_handle = os::open(path, 0, 0);
if (file_handle != -1) {
@ -644,24 +636,6 @@ void ClassLoader::trace_class_path(const char* msg, const char* name) {
}
}
#if INCLUDE_CDS
void ClassLoader::check_shared_classpath(const char *path) {
if (strcmp(path, "") == 0) {
exit_with_path_failure("Cannot have empty path in archived classpaths", NULL);
}
struct stat st;
if (os::stat(path, &st) == 0) {
if ((st.st_mode & S_IFMT) != S_IFREG) { // is not a regular file
if (!os::dir_is_empty(path)) {
tty->print_cr("Error: non-empty directory '%s'", path);
exit_with_path_failure("CDS allows only empty directories in archived classpaths", NULL);
}
}
}
}
#endif
void ClassLoader::setup_bootstrap_search_path() {
const char* sys_class_path = Arguments::get_sysclasspath();
if (PrintSharedArchiveAndExit) {
@ -713,8 +687,6 @@ void ClassLoader::setup_app_search_path(const char *class_path) {
strncpy(path, &class_path[start], end - start);
path[end - start] = '\0';
check_shared_classpath(path);
update_class_path_entry_list(path, false, false);
while (class_path[end] == os::path_separator()[0]) {
@ -757,7 +729,6 @@ void ClassLoader::update_module_path_entry_list(const char *path, TRAPS) {
}
void ClassLoader::setup_module_search_path(const char* path, TRAPS) {
check_shared_classpath(path);
update_module_path_entry_list(path, THREAD);
}
#endif // INCLUDE_CDS
@ -886,11 +857,6 @@ void ClassLoader::setup_boot_search_path(const char *class_path) {
update_class_path_entry_list(path, false, true);
}
#if INCLUDE_CDS
if (DumpSharedSpaces) {
check_shared_classpath(path);
}
#endif
while (class_path[end] == os::path_separator()[0]) {
end++;
}
@ -1082,11 +1048,6 @@ void ClassLoader::add_to_app_classpath_entries(const char* path,
if (entry->is_jar_file()) {
ClassLoaderExt::process_jar_manifest(entry, check_for_duplicates);
} else {
if (!os::dir_is_empty(path)) {
tty->print_cr("Error: non-empty directory '%s'", path);
exit_with_path_failure("Cannot have non-empty directory in app classpaths", NULL);
}
}
#endif
}

View File

@ -422,7 +422,6 @@ class ClassLoader: AllStatic {
}
return num_entries;
}
static void check_shared_classpath(const char *path);
static void finalize_shared_paths_misc_info();
static int get_shared_paths_misc_info_size();
static void* get_shared_paths_misc_info();

View File

@ -54,8 +54,17 @@ jshort ClassLoaderExt::_app_module_paths_start_index = ClassLoaderExt::max_class
bool ClassLoaderExt::_has_app_classes = false;
bool ClassLoaderExt::_has_platform_classes = false;
void ClassLoaderExt::append_boot_classpath(ClassPathEntry* new_entry) {
#if INCLUDE_CDS
warning("Sharing is only supported for boot loader classes because bootstrap classpath has been appended");
FileMapHeaderExt* header = (FileMapHeaderExt*)FileMapInfo::current_info()->header();
header->set_has_platform_or_app_classes(false);
#endif
ClassLoader::add_to_boot_append_entries(new_entry);
}
void ClassLoaderExt::setup_app_search_path() {
assert(DumpSharedSpaces, "this function is only used with -Xshare:dump and -XX:+UseAppCDS");
assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
_app_class_paths_start_index = ClassLoader::num_boot_classpath_entries();
char* app_class_path = os::strdup(Arguments::get_appclasspath());
@ -85,8 +94,8 @@ void ClassLoaderExt::process_module_table(ModuleEntryTable* met, TRAPS) {
}
}
}
void ClassLoaderExt::setup_module_search_path(TRAPS) {
assert(DumpSharedSpaces, "this function is only used with -Xshare:dump and -XX:+UseAppCDS");
void ClassLoaderExt::setup_module_paths(TRAPS) {
assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
_app_module_paths_start_index = ClassLoader::num_boot_classpath_entries() +
ClassLoader::num_app_classpath_entries();
Handle system_class_loader (THREAD, SystemDictionary::java_system_loader());
@ -215,16 +224,8 @@ void ClassLoaderExt::process_jar_manifest(ClassPathEntry* entry,
}
void ClassLoaderExt::setup_search_paths() {
if (UseAppCDS) {
shared_paths_misc_info()->record_app_offset();
ClassLoaderExt::setup_app_search_path();
}
}
void ClassLoaderExt::setup_module_paths(TRAPS) {
if (UseAppCDS) {
ClassLoaderExt::setup_module_search_path(THREAD);
}
shared_paths_misc_info()->record_app_offset();
ClassLoaderExt::setup_app_search_path();
}
Thread* ClassLoaderExt::Context::_dump_thread = NULL;
@ -251,10 +252,8 @@ void ClassLoaderExt::record_result(ClassLoaderExt::Context *context,
}
void ClassLoaderExt::finalize_shared_paths_misc_info() {
if (UseAppCDS) {
if (!_has_app_classes) {
shared_paths_misc_info()->pop_app();
}
if (!_has_app_classes) {
shared_paths_misc_info()->pop_app();
}
}
@ -264,7 +263,7 @@ void ClassLoaderExt::finalize_shared_paths_misc_info() {
InstanceKlass* ClassLoaderExt::load_class(Symbol* name, const char* path, TRAPS) {
assert(name != NULL, "invariant");
assert(DumpSharedSpaces && UseAppCDS, "this function is only used with -Xshare:dump and -XX:+UseAppCDS");
assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
ResourceMark rm(THREAD);
const char* class_name = name->as_C_string();
@ -322,7 +321,7 @@ static GrowableArray<CachedClassPathEntry>* cached_path_entries = NULL;
ClassPathEntry* ClassLoaderExt::find_classpath_entry_from_cache(const char* path, TRAPS) {
// This is called from dump time so it's single threaded and there's no need for a lock.
assert(DumpSharedSpaces && UseAppCDS, "this function is only used with -Xshare:dump and -XX:+UseAppCDS");
assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
if (cached_path_entries == NULL) {
cached_path_entries = new (ResourceObj::C_HEAP, mtClass) GrowableArray<CachedClassPathEntry>(20, /*c heap*/ true);
}

View File

@ -95,7 +95,6 @@ private:
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 void process_module_table(ModuleEntryTable* met, TRAPS);
static void setup_module_search_path(TRAPS);
static SharedPathsMiscInfoExt* shared_paths_misc_info() {
return (SharedPathsMiscInfoExt*)_shared_paths_misc_info;
}
@ -112,15 +111,7 @@ 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 append_boot_classpath(ClassPathEntry* new_entry);
static void setup_search_paths() NOT_CDS_RETURN;
static void setup_module_paths(TRAPS) NOT_CDS_RETURN;

View File

@ -173,11 +173,9 @@ void SharedClassUtil::initialize(TRAPS) {
int size = FileMapInfo::get_number_of_shared_paths();
if (size > 0) {
SystemDictionaryShared::allocate_shared_data_arrays(size, THREAD);
if (!DumpSharedSpaces) {
FileMapHeaderExt* header = (FileMapHeaderExt*)FileMapInfo::current_info()->header();
ClassLoaderExt::init_paths_start_index(header->_app_class_paths_start_index);
ClassLoaderExt::init_app_module_paths_start_index(header->_app_module_paths_start_index);
}
FileMapHeaderExt* header = (FileMapHeaderExt*)FileMapInfo::current_info()->header();
ClassLoaderExt::init_paths_start_index(header->_app_class_paths_start_index);
ClassLoaderExt::init_app_module_paths_start_index(header->_app_module_paths_start_index);
}
}
@ -229,19 +227,20 @@ void FileMapHeaderExt::populate(FileMapInfo* mapinfo, size_t alignment) {
}
bool FileMapHeaderExt::validate() {
if (UseAppCDS) {
const char* prop = Arguments::get_property("java.system.class.loader");
if (prop != NULL) {
warning("UseAppCDS is disabled because the java.system.class.loader property is specified (value = \"%s\"). "
"To enable UseAppCDS, this property must be not be set", prop);
UseAppCDS = false;
}
}
if (!FileMapInfo::FileMapHeader::validate()) {
return false;
}
// This must be done after header validation because it might change the
// header data
const char* prop = Arguments::get_property("java.system.class.loader");
if (prop != NULL) {
warning("Archived non-system classes are disabled because the "
"java.system.class.loader property is specified (value = \"%s\"). "
"To use archived non-system classes, this property must be not be set", prop);
_has_platform_or_app_classes = false;
}
// For backwards compatibility, we don't check the verification setting
// if the archive only contains system classes.
if (_has_platform_or_app_classes &&

View File

@ -43,6 +43,10 @@ public:
FileMapHeaderExt() {
_has_platform_or_app_classes = true;
}
void set_has_platform_or_app_classes(bool v) {
_has_platform_or_app_classes = v;
}
bool has_platform_or_app_classes() { return _has_platform_or_app_classes; }
virtual void populate(FileMapInfo* mapinfo, size_t alignment);
virtual bool validate();
};

View File

@ -141,7 +141,7 @@ bool SharedPathsMiscInfo::check(jint type, const char* path) {
switch (type) {
case BOOT:
// In the future we should perform the check based on the content of the mapped archive.
if (UseAppCDS && os::file_name_strcmp(path, Arguments::get_sysclasspath()) != 0) {
if (os::file_name_strcmp(path, Arguments::get_sysclasspath()) != 0) {
return fail("[BOOT classpath mismatch, actual =", Arguments::get_sysclasspath());
}
break;

View File

@ -3059,13 +3059,9 @@ class CombineDictionariesClosure : public CLDClosure {
// During run time, we only have one shared dictionary.
void SystemDictionary::combine_shared_dictionaries() {
assert(DumpSharedSpaces, "dump time only");
// If AppCDS isn't enabled, we only dump the classes in the boot loader dictionary
// into the shared archive.
if (UseAppCDS) {
Dictionary* master_dictionary = ClassLoaderData::the_null_class_loader_data()->dictionary();
CombineDictionariesClosure cdc(master_dictionary);
ClassLoaderDataGraph::cld_do(&cdc);
}
Dictionary* master_dictionary = ClassLoaderData::the_null_class_loader_data()->dictionary();
CombineDictionariesClosure cdc(master_dictionary);
ClassLoaderDataGraph::cld_do(&cdc);
// These tables are no longer valid or necessary. Keeping them around will
// cause SystemDictionary::verify() to fail. Let's empty them.

View File

@ -360,9 +360,8 @@ Handle SystemDictionaryShared::init_security_info(Handle class_loader, InstanceK
bool SystemDictionaryShared::is_sharing_possible(ClassLoaderData* loader_data) {
oop class_loader = loader_data->class_loader();
return (class_loader == NULL ||
(UseAppCDS && (SystemDictionary::is_system_class_loader(class_loader) ||
SystemDictionary::is_platform_class_loader(class_loader)))
);
SystemDictionary::is_system_class_loader(class_loader) ||
SystemDictionary::is_platform_class_loader(class_loader));
}
// Currently AppCDS only archives classes from the run-time image, the
@ -508,57 +507,59 @@ bool SystemDictionaryShared::is_shared_class_visible_for_classloader(
//
InstanceKlass* SystemDictionaryShared::find_or_load_shared_class(
Symbol* name, Handle class_loader, TRAPS) {
if (DumpSharedSpaces) {
return NULL;
}
InstanceKlass* k = NULL;
if (shared_dictionary() != NULL &&
UseAppCDS && (SystemDictionary::is_system_class_loader(class_loader()) ||
SystemDictionary::is_platform_class_loader(class_loader()))) {
// Fix for 4474172; see evaluation for more details
class_loader = Handle(
THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader()));
ClassLoaderData *loader_data = register_loader(class_loader);
Dictionary* dictionary = loader_data->dictionary();
unsigned int d_hash = dictionary->compute_hash(name);
bool DoObjectLock = true;
if (is_parallelCapable(class_loader)) {
DoObjectLock = false;
if (UseSharedSpaces) {
FileMapHeaderExt* header = (FileMapHeaderExt*)FileMapInfo::current_info()->header();
if (!header->has_platform_or_app_classes()) {
return NULL;
}
// Make sure we are synchronized on the class loader before we proceed
//
// Note: currently, find_or_load_shared_class is called only from
// JVM_FindLoadedClass and used for PlatformClassLoader and AppClassLoader,
// which are parallel-capable loaders, so this lock is NOT taken.
Handle lockObject = compute_loader_lock_object(class_loader, THREAD);
check_loader_lock_contention(lockObject, THREAD);
ObjectLocker ol(lockObject, THREAD, DoObjectLock);
if (shared_dictionary() != NULL &&
(SystemDictionary::is_system_class_loader(class_loader()) ||
SystemDictionary::is_platform_class_loader(class_loader()))) {
// Fix for 4474172; see evaluation for more details
class_loader = Handle(
THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader()));
ClassLoaderData *loader_data = register_loader(class_loader);
Dictionary* dictionary = loader_data->dictionary();
{
MutexLocker mu(SystemDictionary_lock, THREAD);
Klass* check = find_class(d_hash, name, dictionary);
if (check != NULL) {
return InstanceKlass::cast(check);
unsigned int d_hash = dictionary->compute_hash(name);
bool DoObjectLock = true;
if (is_parallelCapable(class_loader)) {
DoObjectLock = false;
}
// Make sure we are synchronized on the class loader before we proceed
//
// Note: currently, find_or_load_shared_class is called only from
// JVM_FindLoadedClass and used for PlatformClassLoader and AppClassLoader,
// which are parallel-capable loaders, so this lock is NOT taken.
Handle lockObject = compute_loader_lock_object(class_loader, THREAD);
check_loader_lock_contention(lockObject, THREAD);
ObjectLocker ol(lockObject, THREAD, DoObjectLock);
{
MutexLocker mu(SystemDictionary_lock, THREAD);
Klass* check = find_class(d_hash, name, dictionary);
if (check != NULL) {
return InstanceKlass::cast(check);
}
}
k = load_shared_class_for_builtin_loader(name, class_loader, THREAD);
if (k != NULL) {
define_instance_class(k, CHECK_NULL);
}
}
k = load_shared_class_for_builtin_loader(name, class_loader, THREAD);
if (k != NULL) {
define_instance_class(k, CHECK_NULL);
}
}
return k;
}
InstanceKlass* SystemDictionaryShared::load_shared_class_for_builtin_loader(
Symbol* class_name, Handle class_loader, TRAPS) {
assert(UseAppCDS && shared_dictionary() != NULL, "already checked");
assert(UseSharedSpaces, "must be");
assert(shared_dictionary() != NULL, "already checked");
Klass* k = shared_dictionary()->find_class_for_builtin_loader(class_name);
if (k != NULL) {
@ -609,13 +610,13 @@ void SystemDictionaryShared::allocate_shared_data_arrays(int size, TRAPS) {
allocate_shared_jar_manifest_array(size, CHECK);
}
// This function is called for loading only UNREGISTERED classes
InstanceKlass* SystemDictionaryShared::lookup_from_stream(const Symbol* class_name,
Handle class_loader,
Handle protection_domain,
const ClassFileStream* cfs,
TRAPS) {
if (!UseAppCDS || shared_dictionary() == NULL) {
if (shared_dictionary() == NULL) {
return NULL;
}
if (class_name == NULL) { // don't do this for anonymous classes
@ -624,7 +625,6 @@ InstanceKlass* SystemDictionaryShared::lookup_from_stream(const Symbol* class_na
if (class_loader.is_null() ||
SystemDictionary::is_system_class_loader(class_loader()) ||
SystemDictionary::is_platform_class_loader(class_loader())) {
// This function is called for loading only UNREGISTERED classes.
// Do nothing for the BUILTIN loaders.
return NULL;
}
@ -686,11 +686,12 @@ InstanceKlass* SystemDictionaryShared::acquire_class_for_current_thread(
return shared_klass;
}
bool SystemDictionaryShared::add_non_builtin_klass(Symbol* name, ClassLoaderData* loader_data,
bool SystemDictionaryShared::add_non_builtin_klass(Symbol* name,
ClassLoaderData* loader_data,
InstanceKlass* k,
TRAPS) {
assert(DumpSharedSpaces, "only when dumping");
assert(UseAppCDS && boot_loader_dictionary() != NULL, "must be");
assert(boot_loader_dictionary() != NULL, "must be");
if (boot_loader_dictionary()->add_non_builtin_klass(name, loader_data, k)) {
MutexLocker mu_r(Compile_lock, THREAD); // not really necessary, but add_to_hierarchy asserts this.

View File

@ -207,10 +207,6 @@ void SharedClassPathEntry::init(const char* name, TRAPS) {
struct stat st;
if (os::stat(name, &st) == 0) {
if ((st.st_mode & S_IFMT) == S_IFDIR) {
if (!os::dir_is_empty(name)) {
ClassLoader::exit_with_path_failure(
"Cannot have non-empty directory in archived classpaths", name);
}
_is_dir = true;
} else {
_is_dir = false;
@ -232,6 +228,8 @@ void SharedClassPathEntry::init(const char* name, TRAPS) {
}
bool SharedClassPathEntry::validate(bool is_class_path) {
assert(UseSharedSpaces, "runtime only");
struct stat st;
const char* name = this->name();
bool ok = true;
@ -335,22 +333,49 @@ void FileMapInfo::allocate_shared_path_table() {
assert(i == num_entries, "number of shared path entry mismatch");
}
// This function should only be called during run time with UseSharedSpaces enabled.
bool FileMapInfo::validate_shared_path_table() {
_validating_shared_path_table = true;
void FileMapInfo::check_nonempty_dir_in_shared_path_table() {
assert(DumpSharedSpaces, "dump time only");
bool has_nonempty_dir = false;
int end = _shared_path_table_size;
if (!ClassLoaderExt::has_platform_or_app_classes()) {
// only check the boot path if no app class is loaded
end = ClassLoaderExt::app_class_paths_start_index();
}
for (int i = 0; i < end; i++) {
SharedClassPathEntry *e = shared_path(i);
if (e->is_dir()) {
const char* path = e->name();
if (!os::dir_is_empty(path)) {
tty->print_cr("Error: non-empty directory '%s'", path);
has_nonempty_dir = true;
}
}
}
if (has_nonempty_dir) {
ClassLoader::exit_with_path_failure("Cannot have non-empty directory in paths", NULL);
}
}
bool FileMapInfo::validate_shared_path_table() {
assert(UseSharedSpaces, "runtime only");
_validating_shared_path_table = true;
_shared_path_table = _header->_shared_path_table;
_shared_path_entry_size = _header->_shared_path_entry_size;
_shared_path_table_size = _header->_shared_path_table_size;
// Note: _app_module_paths_start_index may not have a valid value if the UseAppCDS flag
// wasn't enabled during dump time. Therefore, we need to use the smaller of
// _shared_path_table_size and _app_module_paths_start_index for the _app_module_paths_start_index.
FileMapHeaderExt* header = (FileMapHeaderExt*)FileMapInfo::current_info()->header();
int module_paths_start_index = (header->_app_module_paths_start_index >= _shared_path_table_size) ?
_shared_path_table_size : header->_app_module_paths_start_index;
int module_paths_start_index = header->_app_module_paths_start_index;
int count = _shared_path_table_size;
// If the shared archive contain app or platform classes, validate all entries
// in the shared path table. Otherwise, only validate the boot path entries (with
// entry index < _app_class_paths_start_index).
int count = header->has_platform_or_app_classes() ?
_shared_path_table_size : header->_app_class_paths_start_index;
for (int i=0; i<count; i++) {
if (i < module_paths_start_index) {

View File

@ -115,7 +115,7 @@ public:
int _obj_alignment; // value of ObjectAlignmentInBytes
address _narrow_oop_base; // compressed oop encoding base
int _narrow_oop_shift; // compressed oop encoding shift
bool _compact_strings; // value of CompactStrings
bool _compact_strings; // value of CompactStrings
uintx _max_heap_size; // java max heap size during dumping
Universe::NARROW_OOP_MODE _narrow_oop_mode; // compressed oop encoding mode
int _narrow_klass_shift; // save narrow klass base and shift
@ -272,6 +272,7 @@ public:
static void stop_sharing_and_unmap(const char* msg);
static void allocate_shared_path_table();
static void check_nonempty_dir_in_shared_path_table();
bool validate_shared_path_table();
static SharedClassPathEntry* shared_path(int index) {

View File

@ -454,11 +454,6 @@ static void collect_array_classes(Klass* k) {
class CollectClassesClosure : public KlassClosure {
void do_klass(Klass* k) {
if (!UseAppCDS && !k->class_loader_data()->is_the_null_class_loader_data()) {
// AppCDS is not enabled. Let's omit non-boot classes.
return;
}
if (!(k->is_instance_klass() && InstanceKlass::cast(k)->is_in_error_state())) {
if (k->is_instance_klass() && InstanceKlass::cast(k)->signers() != NULL) {
// Mark any class with signers and don't add to the _global_klass_objects
@ -1327,6 +1322,8 @@ char* VM_PopulateDumpSharedSpace::dump_read_only_tables() {
void VM_PopulateDumpSharedSpace::doit() {
Thread* THREAD = VMThread::vm_thread();
FileMapInfo::check_nonempty_dir_in_shared_path_table();
NOT_PRODUCT(SystemDictionary::verify();)
// The following guarantee is meant to ensure that no loader constraints
// exist yet, since the constraints table is not shared. This becomes

View File

@ -545,6 +545,7 @@ static SpecialFlag const special_jvm_flags[] = {
{ "SharedMiscDataSize", JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() },
{ "SharedMiscCodeSize", JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() },
{ "UseUTCFileTimestamp", JDK_Version::undefined(), JDK_Version::jdk(11), JDK_Version::jdk(12) },
{ "UseAppCDS", JDK_Version::undefined(), JDK_Version::jdk(11), JDK_Version::jdk(12) },
#ifdef TEST_VERIFY_SPECIAL_JVM_FLAGS
{ "dep > obs", JDK_Version::jdk(9), JDK_Version::jdk(8), JDK_Version::undefined() },
@ -3889,14 +3890,6 @@ jint Arguments::match_special_option_and_act(const JavaVMInitArgs* args,
vm_exit(0);
}
#endif
if (match_option(option, "-XX:+UseAppCDS")) {
JVMFlag* flag = JVMFlag::find_flag("SharedArchiveFile", 17, true, true);
if (flag->is_diagnostic()) {
flag->clear_diagnostic();
}
continue;
}
}
return JNI_OK;
}

View File

@ -2480,10 +2480,6 @@ define_pd_global(uint64_t,MaxRAM, 1ULL*G);
"Address to allocate shared memory region for class data") \
range(0, SIZE_MAX) \
\
product(bool, UseAppCDS, false, \
"Enable Application Class Data Sharing when using shared spaces") \
writeable(CommandLineOnly) \
\
product(ccstr, SharedArchiveConfigFile, NULL, \
"Data to add to the CDS archive file") \
\
@ -2589,7 +2585,7 @@ define_pd_global(uint64_t,MaxRAM, 1ULL*G);
product(ccstr, SharedClassListFile, NULL, \
"Override the default CDS class list") \
\
diagnostic(ccstr, SharedArchiveFile, NULL, \
product(ccstr, SharedArchiveFile, NULL, \
"Override the default location of the CDS archive file") \
\
product(ccstr, ExtraSharedClassListFile, NULL, \

View File

@ -53,9 +53,6 @@ public class CDSDumper {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
heapsize,
"-XX:+IgnoreUnrecognizedVMOptions",
"-XX:+UnlockCommercialFeatures",
"-XX:+UseAppCDS",
"-XX:+UnlockDiagnosticVMOptions",
"-cp", classpath,
"-XX:ExtraSharedClassListFile=" + classlist,
"-XX:SharedArchiveFile=" + archive,

View File

@ -43,9 +43,9 @@
* compiler.aot.fingerprint.Blah TEST-UNMODIFIED
* @run main compiler.aot.fingerprint.CDSRunner -cp SelfChangedCDS.jar
* -XX:+UseAOT -XX:+PrintAOT -XX:AOTLibrary=./libSelfChanged.so
* -XX:+UnlockDiagnosticVMOptions -XX:SharedArchiveFile=SelfChangedCDS.jsa
* -XX:SharedArchiveFile=SelfChangedCDS.jsa
* -XX:+IgnoreUnrecognizedVMOptions
* -Xshare:auto -XX:+UnlockCommercialFeatures -XX:+UseAppCDS -showversion
* -Xshare:auto -showversion
* -Xlog:cds -Xlog:gc+heap+coops
* -Xlog:aot+class+fingerprint=trace -Xlog:aot+class+load=trace
* compiler.aot.fingerprint.Blah TEST-UNMODIFIED
@ -59,9 +59,9 @@
* compiler.aot.fingerprint.Blah TEST-MODIFIED
* @run main compiler.aot.fingerprint.CDSRunner -cp SelfChangedCDS.jar
* -XX:+UseAOT -XX:+PrintAOT -XX:AOTLibrary=./libSelfChanged.so
* -XX:+UnlockDiagnosticVMOptions -XX:SharedArchiveFile=SelfChangedCDS.jsa
* -XX:SharedArchiveFile=SelfChangedCDS.jsa
* -XX:+IgnoreUnrecognizedVMOptions
* -Xshare:auto -XX:+UnlockCommercialFeatures -XX:+UseAppCDS -showversion
* -Xshare:auto -showversion
* -Xlog:cds -Xlog:gc+heap+coops
* -Xlog:aot+class+fingerprint=trace -Xlog:aot+class+load=trace
* compiler.aot.fingerprint.Blah TEST-MODIFIED
@ -78,9 +78,9 @@
* compiler.aot.fingerprint.Blah TEST-UNMODIFIED
* @run main compiler.aot.fingerprint.CDSRunner -Xmx512m -cp SelfChangedCDS.jar
* -XX:+UseAOT -XX:+PrintAOT -XX:AOTLibrary=./libSelfChanged.so
* -XX:+UnlockDiagnosticVMOptions -XX:SharedArchiveFile=SelfChangedCDS.jsa
* -XX:SharedArchiveFile=SelfChangedCDS.jsa
* -XX:+IgnoreUnrecognizedVMOptions
* -Xshare:auto -XX:+UnlockCommercialFeatures -XX:+UseAppCDS -showversion
* -Xshare:auto -showversion
* -Xlog:cds -Xlog:gc+heap+coops
* -Xlog:aot+class+fingerprint=trace -Xlog:aot+class+load=trace
* compiler.aot.fingerprint.Blah TEST-UNMODIFIED

View File

@ -111,6 +111,7 @@ public class BootAppendTests {
OutputAnalyzer out = CDSTestUtils.createArchiveAndCheck(
"-Xbootclasspath/a:" + bootAppendJar,
"-cp", appJar,
"-XX:SharedClassListFile=" + classlist.getPath());
// Make sure all the classes were successfully archived.
for (String archiveClass : ARCHIVE_CLASSES) {
@ -156,8 +157,10 @@ public class BootAppendTests {
.addSuffix("-Xlog:class+load=info",
APP_CLASS, BOOT_APPEND_DUPLICATE_MODULE_CLASS_NAME);
String MATCH_PATTERN = ".class.load. javax.annotation.processing.FilerException source:.*bootAppend.jar*";
OutputAnalyzer out = CDSTestUtils.runWithArchive(opts);
CDSTestUtils.checkExec(out, opts, "[class,load] javax.annotation.processing.FilerException source: jrt:/java.compiler");
out.shouldHaveExitValue(0)
.shouldNotMatch(MATCH_PATTERN);
}
}

View File

@ -42,7 +42,6 @@ public class DumpSharedDictionary {
if (args.length == 0) {
// Start this process
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-XX:+UnlockDiagnosticVMOptions",
"-XX:SharedArchiveFile=./DumpSharedDictionary.jsa",
"-Xshare:dump");
@ -52,7 +51,6 @@ public class DumpSharedDictionary {
String testjdkPath = System.getProperty("test.jdk");
pb = ProcessTools.createJavaProcessBuilder(
"-XX:+UnlockDiagnosticVMOptions",
"-XX:SharedArchiveFile=./DumpSharedDictionary.jsa",
"-Dtest.jdk=" + testjdkPath,
"-Xshare:on", "DumpSharedDictionary", "test");

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,7 +23,7 @@
/*
* @test NonBootLoaderClasses
* @summary Test to ensure platform and app classes are not being archived
* @summary Test to ensure platform and app classes are archived when specified in classlist
* @requires vm.cds
* @library /test/lib
* @modules java.base/jdk.internal.misc
@ -46,20 +46,21 @@ public class NonBootLoaderClasses {
CDSTestUtils.makeClassList(classes).getPath();
String archiveName = "NonBootLoaderClasses.jsa";
CDSOptions opts = (new CDSOptions())
.addPrefix("-XX:ExtraSharedClassListFile=" + classList)
.addPrefix("-XX:ExtraSharedClassListFile=" + classList, "-cp", "\"\"")
.setArchiveName(archiveName);
CDSTestUtils.createArchiveAndCheck(opts);
// Print the shared dictionary and inspect the output
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-cp", "\"\"",
"-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./" + archiveName,
"-XX:+PrintSharedArchiveAndExit", "-XX:+PrintSharedDictionary");
OutputAnalyzer out = CDSTestUtils.executeAndLog(pb, "print-shared-archive");
if (!CDSTestUtils.isUnableToMap(out)) {
out.shouldContain("archive is valid")
.shouldHaveExitValue(0) // Should report success in error code.
.shouldNotContain(PLATFORM_CLASS)
.shouldNotContain(APP_CLASS);
.shouldContain(PLATFORM_CLASS.replace('/', '.'))
.shouldContain(APP_CLASS.replace('/', '.'));
}
}
}

View File

@ -77,7 +77,6 @@ public class SASymbolTableTest {
// (1) Launch the attachee process
System.out.println("Starting LingeredApp");
List<String> vmOpts = Arrays.asList(
"-XX:+UnlockDiagnosticVMOptions",
"-XX:SharedArchiveFile=" + jsaName,
"-Xshare:" + flag,
"-showversion"); // so we can see "sharing" in the output

View File

@ -42,14 +42,12 @@ import jdk.test.lib.process.OutputAnalyzer;
public class SharedArchiveFile {
public static void main(String[] args) throws Exception {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true,
"-XX:+UnlockDiagnosticVMOptions",
"-XX:SharedArchiveFile=./SharedArchiveFile.jsa",
"-Xshare:dump");
OutputAnalyzer out = CDSTestUtils.executeAndLog(pb, "SharedArchiveFile");
CDSTestUtils.checkDump(out);
pb = ProcessTools.createJavaProcessBuilder(true,
"-XX:+UnlockDiagnosticVMOptions",
"-XX:SharedArchiveFile=./SharedArchiveFile.jsa",
"-Xshare:on", "-version");
out = CDSTestUtils.executeAndLog(pb, "SharedArchiveFile");

View File

@ -24,7 +24,7 @@
/*
* @test
* @summary AppCDS handling of directories in -cp
* @summary Handling of directories in -cp is based on the classlist
* @requires vm.cds
* @library /test/lib
* @run main DirClasspathTest
@ -45,10 +45,14 @@ public class DirClasspathTest {
File emptydir = new File(dir, "emptydir");
emptydir.mkdir();
/////////////////////////////////////////////////////////////////
// The classlist only contains boot class in following test cases
/////////////////////////////////////////////////////////////////
String bootClassList[] = {"java/lang/Object"};
// Empty dir in -cp: should be OK
OutputAnalyzer output;
String classList[] = {"java/lang/Object"};
output = TestCommon.dump(emptydir.getPath(), classList, "-Xlog:class+path=info");
output = TestCommon.dump(emptydir.getPath(), bootClassList, "-Xlog:class+path=info");
TestCommon.checkDump(output);
// Long path to empty dir in -cp: should be OK
@ -65,19 +69,32 @@ public class DirClasspathTest {
longDir.mkdir();
File subDir = new File(longDir, "subdir");
subDir.mkdir();
output = TestCommon.dump(subDir.getPath(), classList, "-Xlog:class+path=info");
output = TestCommon.dump(subDir.getPath(), bootClassList, "-Xlog:class+path=info");
TestCommon.checkDump(output);
// Non-empty dir in -cp: should fail
// Non-empty dir in -cp: should be OK
// <dir> is not empty because it has at least one subdirectory, i.e., <emptydir>
output = TestCommon.dump(dir.getPath(), classList, "-Xlog:class+path=info");
output.shouldNotHaveExitValue(0);
output.shouldContain("CDS allows only empty directories in archived classpaths");
output = TestCommon.dump(dir.getPath(), bootClassList, "-Xlog:class+path=info");
TestCommon.checkDump(output);
// Long path to non-empty dir in -cp: should fail
// Long path to non-empty dir in -cp: should be OK
// <dir> is not empty because it has at least one subdirectory, i.e., <emptydir>
output = TestCommon.dump(longDir.getPath(), classList, "-Xlog:class+path=info");
output = TestCommon.dump(longDir.getPath(), bootClassList, "-Xlog:class+path=info");
TestCommon.checkDump(output);
/////////////////////////////////////////////////////////////////
// The classlist contains non-boot class in following test cases
/////////////////////////////////////////////////////////////////
String appClassList[] = {"java/lang/Object", "com/sun/tools/javac/Main"};
// Non-empty dir in -cp: should report error
output = TestCommon.dump(dir.getPath(), appClassList, "-Xlog:class+path=info");
output.shouldNotHaveExitValue(0);
output.shouldContain("CDS allows only empty directories in archived classpaths");
output.shouldContain("Cannot have non-empty directory in paths");
// Long path to non-empty dir in -cp: should report error
output = TestCommon.dump(longDir.getPath(), appClassList, "-Xlog:class+path=info");
output.shouldNotHaveExitValue(0);
output.shouldContain("Cannot have non-empty directory in paths");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -92,7 +92,6 @@ public class DumpClassList {
output = TestCommon.createArchive(appJar, appClass,
"-Xbootclasspath/a:" + appendJar,
"-XX:+UnlockDiagnosticVMOptions",
"-Xlog:class+load",
"-XX:SharedClassListFile=" + classList);
TestCommon.checkDump(output)

View File

@ -94,7 +94,6 @@ public class GraalWithLimitedMetaspace {
"-XX:+EagerJVMCI",
"-cp",
TESTJAR,
"-XX:+UseAppCDS",
TESTNAME,
TEST_OUT));
@ -117,7 +116,6 @@ public class GraalWithLimitedMetaspace {
TestCommon.makeCommandLineForAppCDS(
"-cp",
TESTJAR,
"-XX:+UseAppCDS",
"-XX:SharedClassListFile=" + CLASSLIST_FILE,
"-XX:SharedArchiveFile=" + ARCHIVE_FILE,
"-Xlog:cds",

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -59,7 +59,7 @@ public class MismatchedUseAppCDS {
"-XX:-UseAppCDS",
"-XX:+UnlockDiagnosticVMOptions",
"-XX:+WhiteBoxAPI",
"CheckIfShared", "false");
"CheckIfShared", "true");
TestCommon.checkExec(output);
// (2): dump with -XX:-UseAppCDS, but run with -XX:+UseAppCDS
@ -74,7 +74,7 @@ public class MismatchedUseAppCDS {
"-XX:+UseAppCDS",
"-XX:+UnlockDiagnosticVMOptions",
"-XX:+WhiteBoxAPI",
"CheckIfShared", "false");
"CheckIfShared", "true");
TestCommon.checkExec(output);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -24,7 +24,7 @@
/*
* @test
* @summary If -Djava.system.class.loader=xxx is specified in command-line, disable UseAppCDS
* @summary If -Djava.system.class.loader=xxx is specified in command-line, disable archived non-system classes
* @requires vm.cds
* @library /test/lib
* @modules java.base/jdk.internal.misc
@ -46,7 +46,7 @@ public class SpecifySysLoaderProp {
String jarFileName = "sysloader.jar";
String appJar = TestCommon.getTestJar(jarFileName);
TestCommon.testDump(appJar, TestCommon.list("ReportMyLoader"));
String warning = "VM warning: UseAppCDS is disabled because the java.system.class.loader property is specified";
String warning = "VM warning: Archived non-system classes are disabled because the java.system.class.loader property is specified";
// (0) Baseline. Do not specify -Djava.system.class.loader
@ -70,7 +70,7 @@ public class SpecifySysLoaderProp {
});
// (2) Try to execute the archive with -Djava.system.class.loader=TestClassLoader,
// it should run, but AppCDS should be disabled
// it should run, but archived non-system classes should be disabled
TestCommon.run(
"-verbose:class",
"-cp", appJar,

View File

@ -109,18 +109,8 @@ public class TestCommon extends CDSTestUtils {
return createArchive(opts);
}
// If you use -XX:+UseAppCDS or -XX:-UseAppCDS in your JVM command-line, call this method
// to wrap the arguments. On commercial builds, -XX:+UnlockCommercialFeatures will be
// prepended to the command-line. See JDK-8193664.
public static String[] makeCommandLineForAppCDS(String... args) throws Exception {
if (BuildHelper.isCommercialBuild()) {
String[] newArgs = new String[args.length + 1];
newArgs[0] = "-XX:+UnlockCommercialFeatures";
System.arraycopy(args, 0, newArgs, 1, args.length);
return newArgs;
} else {
return args;
}
return args;
}
// Create AppCDS archive using appcds options
@ -143,7 +133,6 @@ public class TestCommon extends CDSTestUtils {
cmd.add("-Xshare:dump");
cmd.add("-Xlog:cds,cds+hashtables");
cmd.add("-XX:+UseAppCDS");
cmd.add("-XX:ExtraSharedClassListFile=" + classList.getPath());
if (opts.archiveName == null)
@ -168,7 +157,6 @@ public class TestCommon extends CDSTestUtils {
for (String p : opts.prefix) cmd.add(p);
cmd.add("-Xshare:" + opts.xShareMode);
cmd.add("-XX:+UseAppCDS");
cmd.add("-showversion");
cmd.add("-XX:SharedArchiveFile=" + getCurrentArchiveName());
cmd.add("-Dtest.timeout.factor=" + timeoutFactor);

View File

@ -243,7 +243,6 @@ public class VerifierTest implements Opcodes {
if (!dump_setting.equals(prev_dump_setting)) {
OutputAnalyzer dumpOutput = TestCommon.dump(
jar, appClasses, dump_setting,
"-XX:+UnlockDiagnosticVMOptions",
// FIXME: the following options are for working around a GC
// issue - assert failure when dumping archive with the -Xverify:all
"-Xms256m",

View File

@ -48,7 +48,6 @@ public class SharedStringsBasic {
ProcessBuilder dumpPb = ProcessTools.createJavaProcessBuilder(true,
TestCommon.makeCommandLineForAppCDS(
"-XX:+UseAppCDS",
"-cp", appJar,
"-XX:SharedArchiveConfigFile=" + sharedArchiveConfigFile,
"-XX:SharedArchiveFile=./SharedStringsBasic.jsa",
@ -61,7 +60,6 @@ public class SharedStringsBasic {
ProcessBuilder runPb = ProcessTools.createJavaProcessBuilder(true,
TestCommon.makeCommandLineForAppCDS(
"-XX:+UseAppCDS",
"-cp", appJar,
"-XX:SharedArchiveFile=./SharedStringsBasic.jsa",
"-Xshare:auto",

View File

@ -44,7 +44,6 @@ public class SysDictCrash {
ProcessBuilder dumpPb = ProcessTools.createJavaProcessBuilder(true,
TestCommon.makeCommandLineForAppCDS(
"-XX:+UseG1GC", "-XX:MaxRAMPercentage=12.5",
"-XX:+UseAppCDS",
"-cp", ".",
"-XX:SharedBaseAddress=0", "-XX:SharedArchiveFile=./SysDictCrash.jsa",
"-Xshare:dump",
@ -55,7 +54,6 @@ public class SysDictCrash {
ProcessBuilder runPb = ProcessTools.createJavaProcessBuilder(true,
TestCommon.makeCommandLineForAppCDS(
"-XX:+UseG1GC", "-XX:MaxRAMPercentage=12.5",
"-XX:+UseAppCDS",
"-XX:SharedArchiveFile=./SysDictCrash.jsa",
"-Xshare:on",
"-version"));

View File

@ -247,7 +247,6 @@ public class CDSTestUtils {
cmd.add("-Xshare:dump");
cmd.add("-Xlog:cds,cds+hashtables");
cmd.add("-XX:+UnlockDiagnosticVMOptions");
if (opts.archiveName == null)
opts.archiveName = getDefaultArchiveName();
cmd.add("-XX:SharedArchiveFile=./" + opts.archiveName);
@ -389,7 +388,6 @@ public class CDSTestUtils {
for (String p : opts.prefix) cmd.add(p);
cmd.add("-Xshare:" + opts.xShareMode);
cmd.add("-XX:+UnlockDiagnosticVMOptions");
cmd.add("-Dtest.timeout.factor=" + TestTimeoutFactor);
if (opts.archiveName == null)