8197954: Remove unnecessary intermediary APIs from AppCDS implementation
Reviewed-by: jiangli, ccheung
--- a/src/hotspot/share/classfile/classListParser.cpp Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/classfile/classListParser.cpp Thu Apr 26 13:40:58 2018 -0700
@@ -27,7 +27,6 @@
#include "jimage.hpp"
#include "classfile/classListParser.hpp"
#include "classfile/classLoaderExt.hpp"
-#include "classfile/sharedClassUtil.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/systemDictionaryShared.hpp"
--- a/src/hotspot/share/classfile/classLoader.cpp Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/classfile/classLoader.cpp Thu Apr 26 13:40:58 2018 -0700
@@ -72,7 +72,6 @@
#include "utilities/hashtable.inline.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_CDS
-#include "classfile/sharedClassUtil.hpp"
#include "classfile/sharedPathsMiscInfo.hpp"
#endif
@@ -660,7 +659,7 @@
}
bool ClassLoader::check_shared_paths_misc_info(void *buf, int size) {
- SharedPathsMiscInfo* checker = SharedClassUtil::allocate_shared_paths_misc_info((char*)buf, size);
+ SharedPathsMiscInfo* checker = new SharedPathsMiscInfo((char*)buf, size);
bool result = checker->check();
delete checker;
return result;
@@ -1406,8 +1405,6 @@
name->utf8_length());
assert(file_name != NULL, "invariant");
- ClassLoaderExt::Context context(class_name, file_name, THREAD);
-
// Lookup stream for parsing .class file
ClassFileStream* stream = NULL;
s2 classpath_index = 0;
@@ -1480,7 +1477,7 @@
return NULL;
}
- stream->set_verify(context.should_verify(classpath_index));
+ stream->set_verify(ClassLoaderExt::should_verify(classpath_index));
ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
Handle protection_domain;
@@ -1628,8 +1625,7 @@
ik->name()->utf8_length());
assert(file_name != NULL, "invariant");
- ClassLoaderExt::Context context(class_name, file_name, CATCH);
- context.record_result(ik->name(), classpath_index, ik, THREAD);
+ ClassLoaderExt::record_result(classpath_index, ik, THREAD);
}
#endif // INCLUDE_CDS
@@ -1699,7 +1695,7 @@
#if INCLUDE_CDS
// initialize search path
if (DumpSharedSpaces) {
- _shared_paths_misc_info = SharedClassUtil::allocate_shared_paths_misc_info();
+ _shared_paths_misc_info = new SharedPathsMiscInfo();
}
#endif
setup_bootstrap_search_path();
--- a/src/hotspot/share/classfile/classLoader.hpp Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/classfile/classLoader.hpp Thu Apr 26 13:40:58 2018 -0700
@@ -426,8 +426,6 @@
static int get_shared_paths_misc_info_size();
static void* get_shared_paths_misc_info();
static bool check_shared_paths_misc_info(void* info, int size);
- static int get_module_paths_misc_info_size();
- static void* get_module_paths_misc_info();
static void exit_with_path_failure(const char* error, const char* message);
static char* skip_uri_protocol(char* source);
static void record_result(InstanceKlass* ik, const ClassFileStream* stream, TRAPS);
--- a/src/hotspot/share/classfile/classLoaderExt.cpp Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/classfile/classLoaderExt.cpp Thu Apr 26 13:40:58 2018 -0700
@@ -31,7 +31,6 @@
#include "classfile/classLoaderData.inline.hpp"
#include "classfile/klassFactory.hpp"
#include "classfile/modules.hpp"
-#include "classfile/sharedClassUtil.hpp"
#include "classfile/sharedPathsMiscInfo.hpp"
#include "classfile/systemDictionaryShared.hpp"
#include "classfile/vmSymbols.hpp"
@@ -57,8 +56,7 @@
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);
+ FileMapInfo::current_info()->header()->set_has_platform_or_app_classes(false);
#endif
ClassLoader::add_to_boot_append_entries(new_entry);
}
@@ -228,11 +226,7 @@
ClassLoaderExt::setup_app_search_path();
}
-Thread* ClassLoaderExt::Context::_dump_thread = NULL;
-
-void ClassLoaderExt::record_result(ClassLoaderExt::Context *context,
- Symbol* class_name,
- const s2 classpath_index,
+void ClassLoaderExt::record_result(const s2 classpath_index,
InstanceKlass* result,
TRAPS) {
assert(DumpSharedSpaces, "Sanity");
--- a/src/hotspot/share/classfile/classLoaderExt.hpp Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/classfile/classLoaderExt.hpp Thu Apr 26 13:40:58 2018 -0700
@@ -29,74 +29,21 @@
#include "classfile/moduleEntry.hpp"
#include "utilities/macros.hpp"
-CDS_ONLY(class SharedPathsMiscInfoExt;)
-CDS_ONLY(class ClassListParser;)
+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_class_paths_start_index if we're not using CDS.
- assert(_app_class_paths_start_index == ClassLoaderExt::max_classpath_index, "must be");
- }
-#endif
- }
-
- bool should_verify(int classpath_index) {
- CDS_ONLY(return (classpath_index >= _app_class_paths_start_index);)
- NOT_CDS(return false;)
- }
-
- void record_result(Symbol* class_name,
- const s2 classpath_index,
- InstanceKlass* result,
- TRAPS) {
-#if INCLUDE_CDS
- ClassLoaderExt::record_result(this, class_name, classpath_index, result, THREAD);
-#endif
- }
-
- ~Context() {
-#if INCLUDE_CDS
- if (!DumpSharedSpaces && !UseSharedSpaces) {
- // Must not modify app_class_paths_start_index if we're not using CDS.
- assert(_app_class_paths_start_index == ClassLoaderExt::max_classpath_index, "must be");
- }
-#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 void process_module_table(ModuleEntryTable* met, TRAPS);
- static SharedPathsMiscInfoExt* shared_paths_misc_info() {
- return (SharedPathsMiscInfoExt*)_shared_paths_misc_info;
+ static SharedPathsMiscInfo* shared_paths_misc_info() {
+ return (SharedPathsMiscInfo*)_shared_paths_misc_info;
}
// index of first app JAR in shared classpath entry table
static jshort _app_class_paths_start_index;
@@ -110,6 +57,10 @@
public:
CDS_ONLY(static void process_jar_manifest(ClassPathEntry* entry, bool check_for_duplicates);)
+ static bool should_verify(int classpath_index) {
+ CDS_ONLY(return (classpath_index >= _app_class_paths_start_index);)
+ NOT_CDS(return false;)
+ }
// Called by JVMTI code to add boot classpath
static void append_boot_classpath(ClassPathEntry* new_entry);
@@ -156,9 +107,7 @@
return _has_app_classes || _has_platform_classes;
}
- static void record_result(class ClassLoaderExt::Context *context,
- Symbol* class_name,
- const s2 classpath_index,
+ static void record_result(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);
--- a/src/hotspot/share/classfile/dictionary.cpp Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/classfile/dictionary.cpp Thu Apr 26 13:40:58 2018 -0700
@@ -24,7 +24,6 @@
#include "precompiled.hpp"
#include "classfile/classLoaderData.inline.hpp"
-#include "classfile/sharedClassUtil.hpp"
#include "classfile/dictionary.inline.hpp"
#include "classfile/protectionDomainCache.hpp"
#include "classfile/systemDictionary.hpp"
--- a/src/hotspot/share/classfile/klassFactory.cpp Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/classfile/klassFactory.cpp Thu Apr 26 13:40:58 2018 -0700
@@ -29,7 +29,7 @@
#include "classfile/classLoaderData.hpp"
#include "classfile/classLoaderData.inline.hpp"
#include "classfile/klassFactory.hpp"
-#include "classfile/sharedClassUtil.hpp"
+#include "memory/filemap.hpp"
#include "memory/metaspaceShared.hpp"
#include "memory/resourceArea.hpp"
#include "prims/jvmtiEnvBase.hpp"
--- a/src/hotspot/share/classfile/sharedClassUtil.cpp Mon May 07 20:42:36 2018 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,255 +0,0 @@
-/*
- * 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "classfile/classLoader.hpp"
-#include "classfile/classLoaderExt.hpp"
-#include "classfile/dictionary.hpp"
-#include "classfile/javaClasses.hpp"
-#include "classfile/sharedClassUtil.hpp"
-#include "classfile/stringTable.hpp"
-#include "classfile/symbolTable.hpp"
-#include "classfile/systemDictionary.hpp"
-#include "classfile/systemDictionaryShared.hpp"
-#include "memory/filemap.hpp"
-#include "memory/metadataFactory.hpp"
-#include "memory/resourceArea.hpp"
-#include "oops/instanceKlass.hpp"
-#include "runtime/arguments.hpp"
-#include "runtime/java.hpp"
-#include "runtime/os.inline.hpp"
-
-class ManifestStream: public ResourceObj {
- private:
- u1* _buffer_start; // Buffer bottom
- u1* _buffer_end; // Buffer top (one past last element)
- u1* _current; // Current buffer position
-
- public:
- // Constructor
- ManifestStream(u1* buffer, int length) : _buffer_start(buffer),
- _current(buffer) {
- _buffer_end = buffer + length;
- }
-
- static bool is_attr(u1* attr, const char* name) {
- return strncmp((const char*)attr, name, strlen(name)) == 0;
- }
-
- static char* copy_attr(u1* value, size_t len) {
- char* buf = NEW_RESOURCE_ARRAY(char, len + 1);
- strncpy(buf, (char*)value, len);
- buf[len] = 0;
- return buf;
- }
-
- // The return value indicates if the JAR is signed or not
- bool check_is_signed() {
- u1* attr = _current;
- bool isSigned = false;
- while (_current < _buffer_end) {
- if (*_current == '\n') {
- *_current = '\0';
- u1* value = (u1*)strchr((char*)attr, ':');
- if (value != NULL) {
- assert(*(value+1) == ' ', "Unrecognized format" );
- if (strstr((char*)attr, "-Digest") != NULL) {
- isSigned = true;
- break;
- }
- }
- *_current = '\n'; // restore
- attr = _current + 1;
- }
- _current ++;
- }
- return isSigned;
- }
-};
-
-void SharedPathsMiscInfoExt::print_path(outputStream* out, int type, const char* path) {
- switch(type) {
- case APP:
- ClassLoader::trace_class_path("Expecting -Djava.class.path=", path);
- break;
- case MODULE:
- ClassLoader::trace_class_path("Checking module path: ", path);
- break;
- default:
- SharedPathsMiscInfo::print_path(out, type, path);
- }
-}
-
-bool SharedPathsMiscInfoExt::check(jint type, const char* path) {
-
- switch (type) {
- case APP:
- {
- // Prefix is OK: E.g., dump with -cp foo.jar, but run with -cp foo.jar:bar.jar
- size_t len = strlen(path);
- const char *appcp = Arguments::get_appclasspath();
- assert(appcp != NULL, "NULL app classpath");
- size_t appcp_len = strlen(appcp);
- if (appcp_len < len) {
- return fail("Run time APP classpath is shorter than the one at dump time: ", appcp);
- }
- ResourceMark rm;
- char* tmp_path;
- if (len == appcp_len) {
- tmp_path = (char*)appcp;
- } else {
- tmp_path = NEW_RESOURCE_ARRAY(char, len + 1);
- strncpy(tmp_path, appcp, len);
- tmp_path[len] = 0;
- }
- if (os::file_name_strcmp(path, tmp_path) != 0) {
- return fail("[APP classpath mismatch, actual: -Djava.class.path=", appcp);
- }
- if (appcp[len] != '\0' && appcp[len] != os::path_separator()[0]) {
- return fail("Dump time APP classpath is not a proper prefix of run time APP classpath: ", appcp);
- }
- }
- break;
- default:
- return SharedPathsMiscInfo::check(type, path);
- }
-
- return true;
-}
-
-void SharedClassUtil::update_shared_classpath(ClassPathEntry *cpe, SharedClassPathEntry* e, TRAPS) {
- ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
- SharedClassPathEntryExt* ent = (SharedClassPathEntryExt*)e;
- ResourceMark rm(THREAD);
- jint manifest_size;
- bool isSigned;
-
- if (cpe->is_jar_file()) {
- char* manifest = ClassLoaderExt::read_manifest(cpe, &manifest_size, CHECK);
- if (manifest != NULL) {
- ManifestStream* stream = new ManifestStream((u1*)manifest,
- manifest_size);
- isSigned = stream->check_is_signed();
- if (isSigned) {
- ent->_is_signed = true;
- } else {
- // Copy the manifest into the shared archive
- manifest = ClassLoaderExt::read_raw_manifest(cpe, &manifest_size, CHECK);
- Array<u1>* buf = MetadataFactory::new_array<u1>(loader_data,
- manifest_size,
- THREAD);
- char* p = (char*)(buf->data());
- memcpy(p, manifest, manifest_size);
- ent->set_manifest(buf);
- ent->_is_signed = false;
- }
- }
- }
-}
-
-void SharedClassUtil::initialize(TRAPS) {
- if (UseSharedSpaces) {
- int size = FileMapInfo::get_number_of_shared_paths();
- if (size > 0) {
- SystemDictionaryShared::allocate_shared_data_arrays(size, THREAD);
- 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);
- }
- }
-
- if (DumpSharedSpaces) {
- if (SharedArchiveConfigFile) {
- read_extra_data(SharedArchiveConfigFile, THREAD);
- }
- }
-}
-
-void SharedClassUtil::read_extra_data(const char* filename, TRAPS) {
- HashtableTextDump reader(filename);
- reader.check_version("VERSION: 1.0");
-
- while (reader.remain() > 0) {
- int utf8_length;
- int prefix_type = reader.scan_prefix(&utf8_length);
- ResourceMark rm(THREAD);
- char* utf8_buffer = NEW_RESOURCE_ARRAY(char, utf8_length);
- reader.get_utf8(utf8_buffer, utf8_length);
-
- if (prefix_type == HashtableTextDump::SymbolPrefix) {
- SymbolTable::new_symbol(utf8_buffer, utf8_length, THREAD);
- } else{
- assert(prefix_type == HashtableTextDump::StringPrefix, "Sanity");
- utf8_buffer[utf8_length] = '\0';
- oop s = StringTable::intern(utf8_buffer, THREAD);
- }
- }
-}
-
-bool SharedClassUtil::is_classpath_entry_signed(int classpath_index) {
- assert(classpath_index >= 0, "Sanity");
- SharedClassPathEntryExt* ent = (SharedClassPathEntryExt*)
- FileMapInfo::shared_path(classpath_index);
- return ent->_is_signed;
-}
-
-void FileMapHeaderExt::populate(FileMapInfo* mapinfo, size_t alignment) {
- FileMapInfo::FileMapHeader::populate(mapinfo, alignment);
-
- ClassLoaderExt::finalize_shared_paths_misc_info();
- _app_class_paths_start_index = ClassLoaderExt::app_class_paths_start_index();
- _app_module_paths_start_index = ClassLoaderExt::app_module_paths_start_index();
-
- _verify_local = BytecodeVerificationLocal;
- _verify_remote = BytecodeVerificationRemote;
- _has_platform_or_app_classes = ClassLoaderExt::has_platform_or_app_classes();
-}
-
-bool FileMapHeaderExt::validate() {
- 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 &&
- ((!_verify_local && BytecodeVerificationLocal) ||
- (!_verify_remote && BytecodeVerificationRemote))) {
- FileMapInfo::fail_continue("The shared archive file was created with less restrictive "
- "verification setting than the current setting.");
- return false;
- }
-
- return true;
-}
--- a/src/hotspot/share/classfile/sharedClassUtil.hpp Mon May 07 20:42:36 2018 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,141 +0,0 @@
-/*
- * 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_CLASSFILE_SHAREDCLASSUTIL_HPP
-#define SHARE_VM_CLASSFILE_SHAREDCLASSUTIL_HPP
-
-#include "classfile/sharedPathsMiscInfo.hpp"
-#include "memory/filemap.hpp"
-#include "classfile/classLoaderExt.hpp"
-#include "classfile/dictionary.hpp"
-#include "classfile/systemDictionaryShared.hpp"
-#include "oops/klass.hpp"
-
-class FileMapHeaderExt: public FileMapInfo::FileMapHeader {
-public:
- jshort _app_class_paths_start_index; // Index of first app classpath entry
- jshort _app_module_paths_start_index; // Index of first module path entry
- bool _verify_local; // BytecodeVerificationLocal setting
- bool _verify_remote; // BytecodeVerificationRemote setting
- bool _has_platform_or_app_classes; // Archive contains app classes
-
- 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();
-};
-
-// In addition to SharedPathsMiscInfo, the following information is also stored
-//
-//
-// + The value of Arguments::get_appclasspath() used during dumping.
-//
-class SharedPathsMiscInfoExt : public SharedPathsMiscInfo {
-private:
- int _app_offset;
-public:
- enum {
- APP = 5,
- MODULE = 6
- };
-
- virtual const char* type_name(int type) {
- switch (type) {
- case APP: return "APP";
- case MODULE: return "MODULE";
- default: return SharedPathsMiscInfo::type_name(type);
- }
- }
-
- virtual void print_path(outputStream* out, int type, const char* path);
-
- SharedPathsMiscInfoExt() : SharedPathsMiscInfo() {
- _app_offset = 0;
- }
- SharedPathsMiscInfoExt(char* buf, int size) : SharedPathsMiscInfo(buf, size) {
- _app_offset = 0;
- }
-
- virtual bool check(jint type, const char* path);
-
- void add_app_classpath(const char* path) {
- add_path(path, APP);
- }
-
- void record_app_offset() {
- _app_offset = get_used_bytes();
- }
- void pop_app() {
- _cur_ptr = _buf_start + _app_offset;
- write_jint(0);
- }
-};
-
-class SharedClassPathEntryExt: public SharedClassPathEntry {
-public:
- //Maniest attributes
- bool _is_signed;
- void set_manifest(Array<u1>* manifest) {
- _manifest = manifest;
- }
-};
-
-class SharedClassUtil : AllStatic {
-public:
- static SharedPathsMiscInfo* allocate_shared_paths_misc_info() {
- return new SharedPathsMiscInfoExt();
- }
-
- static SharedPathsMiscInfo* allocate_shared_paths_misc_info(char* buf, int size) {
- return new SharedPathsMiscInfoExt(buf, size);
- }
-
- static FileMapInfo::FileMapHeader* allocate_file_map_header() {
- return new FileMapHeaderExt();
- }
-
- static size_t file_map_header_size() {
- return sizeof(FileMapHeaderExt);
- }
-
- static size_t shared_class_path_entry_size() {
- return sizeof(SharedClassPathEntryExt);
- }
-
- static void update_shared_classpath(ClassPathEntry *cpe, SharedClassPathEntry* ent, TRAPS);
- static void initialize(TRAPS);
-
-private:
- static void read_extra_data(const char* filename, TRAPS);
-
-public:
- static bool is_classpath_entry_signed(int classpath_index);
-};
-
-#endif // SHARE_VM_CLASSFILE_SHAREDCLASSUTIL_HPP
--- a/src/hotspot/share/classfile/sharedPathsMiscInfo.cpp Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/classfile/sharedPathsMiscInfo.cpp Thu Apr 26 13:40:58 2018 -0700
@@ -24,7 +24,6 @@
#include "precompiled.hpp"
#include "classfile/classLoader.hpp"
-#include "classfile/classLoaderData.inline.hpp"
#include "classfile/sharedPathsMiscInfo.hpp"
#include "logging/log.hpp"
#include "logging/logStream.hpp"
@@ -36,6 +35,7 @@
#include "utilities/ostream.hpp"
SharedPathsMiscInfo::SharedPathsMiscInfo() {
+ _app_offset = 0;
_buf_size = INITIAL_BUF_SIZE;
_cur_ptr = _buf_start = NEW_C_HEAP_ARRAY(char, _buf_size, mtClass);
_allocated = true;
@@ -89,12 +89,15 @@
void SharedPathsMiscInfo::print_path(outputStream* out, int type, const char* path) {
switch (type) {
- case BOOT:
+ case BOOT_PATH:
out->print("Expecting BOOT path=%s", path);
break;
case NON_EXIST:
out->print("Expecting that %s does not exist", path);
break;
+ case APP_PATH:
+ ClassLoader::trace_class_path("Expecting -Djava.class.path=", path);
+ break;
default:
ShouldNotReachHere();
}
@@ -139,7 +142,7 @@
bool SharedPathsMiscInfo::check(jint type, const char* path) {
switch (type) {
- case BOOT:
+ case BOOT_PATH:
// In the future we should perform the check based on the content of the mapped archive.
if (os::file_name_strcmp(path, Arguments::get_sysclasspath()) != 0) {
return fail("[BOOT classpath mismatch, actual =", Arguments::get_sysclasspath());
@@ -155,6 +158,33 @@
}
}
break;
+ case APP_PATH:
+ {
+ // Prefix is OK: E.g., dump with -cp foo.jar, but run with -cp foo.jar:bar.jar
+ size_t len = strlen(path);
+ const char *appcp = Arguments::get_appclasspath();
+ assert(appcp != NULL, "NULL app classpath");
+ size_t appcp_len = strlen(appcp);
+ if (appcp_len < len) {
+ return fail("Run time APP classpath is shorter than the one at dump time: ", appcp);
+ }
+ ResourceMark rm;
+ char* tmp_path;
+ if (len == appcp_len) {
+ tmp_path = (char*)appcp;
+ } else {
+ tmp_path = NEW_RESOURCE_ARRAY(char, len + 1);
+ strncpy(tmp_path, appcp, len);
+ tmp_path[len] = 0;
+ }
+ if (os::file_name_strcmp(path, tmp_path) != 0) {
+ return fail("[APP classpath mismatch, actual: -Djava.class.path=", appcp);
+ }
+ if (appcp[len] != '\0' && appcp[len] != os::path_separator()[0]) {
+ return fail("Dump time APP classpath is not a proper prefix of run time APP classpath: ", appcp);
+ }
+ }
+ break;
default:
return fail("Corrupted archive file header");
}
--- a/src/hotspot/share/classfile/sharedPathsMiscInfo.hpp Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/classfile/sharedPathsMiscInfo.hpp Thu Apr 26 13:40:58 2018 -0700
@@ -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
@@ -35,8 +35,6 @@
//
// + The values of Arguments::get_sysclasspath() used during dumping.
//
-// + The meta-index file(s) used during dumping (incl modification time and size)
-//
// + The class path elements specified during dumping but did not exist --
// these elements must also be specified at run time, and they also must not
// exist at run time.
@@ -53,6 +51,8 @@
// two situations. See below.
class SharedPathsMiscInfo : public CHeapObj<mtClass> {
+private:
+ int _app_offset;
protected:
char* _buf_start;
char* _cur_ptr;
@@ -67,7 +67,7 @@
protected:
static bool fail(const char* msg, const char* name = NULL);
- virtual bool check(jint type, const char* path);
+ bool check(jint type, const char* path);
public:
enum {
@@ -77,6 +77,7 @@
SharedPathsMiscInfo();
// This constructor is used when validating the misc info (during run time)
SharedPathsMiscInfo(char *buff, int size) {
+ _app_offset = 0;
_cur_ptr = _buf_start = buff;
_end_ptr = _buf_start + size;
_buf_size = size;
@@ -100,8 +101,20 @@
// The path must exist, and must contain exactly <num_entries> files/dirs
void add_boot_classpath(const char* path) {
- add_path(path, BOOT);
+ add_path(path, BOOT_PATH);
+ }
+
+ void add_app_classpath(const char* path) {
+ add_path(path, APP_PATH);
}
+ void record_app_offset() {
+ _app_offset = get_used_bytes();
+ }
+ void pop_app() {
+ _cur_ptr = _buf_start + _app_offset;
+ write_jint(0);
+ }
+
int write_jint(jint num) {
write(&num, sizeof(num));
return 0;
@@ -120,22 +133,24 @@
// reading --
+private:
enum {
- BOOT = 1,
- NON_EXIST = 2
+ BOOT_PATH = 1,
+ APP_PATH = 2,
+ NON_EXIST = 3
};
- virtual const char* type_name(int type) {
+ const char* type_name(int type) {
switch (type) {
- case BOOT: return "BOOT";
- case NON_EXIST: return "NON_EXIST";
- default: ShouldNotReachHere(); return "?";
+ case BOOT_PATH: return "BOOT";
+ case APP_PATH: return "APP";
+ case NON_EXIST: return "NON_EXIST";
+ default: ShouldNotReachHere(); return "?";
}
}
- virtual void print_path(outputStream* os, int type, const char* path);
+ void print_path(outputStream* os, int type, const char* path);
- bool check();
bool read_jint(jint *ptr) {
return read(ptr, sizeof(jint));
}
@@ -145,6 +160,9 @@
bool read_time(time_t *ptr) {
return read(ptr, sizeof(time_t));
}
+
+public:
+ bool check();
};
#endif // SHARE_VM_CLASSFILE_SHAREDPATHSMISCINFO_HPP
--- a/src/hotspot/share/classfile/systemDictionary.cpp Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/classfile/systemDictionary.cpp Thu Apr 26 13:40:58 2018 -0700
@@ -84,7 +84,6 @@
#include "trace/tracing.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_CDS
-#include "classfile/sharedClassUtil.hpp"
#include "classfile/systemDictionaryShared.hpp"
#endif
#if INCLUDE_JVMCI
--- a/src/hotspot/share/classfile/systemDictionary.hpp Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/classfile/systemDictionary.hpp Thu Apr 26 13:40:58 2018 -0700
@@ -26,7 +26,6 @@
#define SHARE_VM_CLASSFILE_SYSTEMDICTIONARY_HPP
#include "classfile/classLoader.hpp"
-#include "classfile/systemDictionary_ext.hpp"
#include "jvmci/systemDictionary_jvmci.hpp"
#include "oops/objArrayOop.hpp"
#include "oops/symbol.hpp"
@@ -186,6 +185,7 @@
do_klass(File_klass, java_io_File, Pre ) \
do_klass(URL_klass, java_net_URL, Pre ) \
do_klass(Jar_Manifest_klass, java_util_jar_Manifest, Pre ) \
+ do_klass(jdk_internal_loader_ClassLoaders_klass, jdk_internal_loader_ClassLoaders, Pre ) \
do_klass(jdk_internal_loader_ClassLoaders_AppClassLoader_klass, jdk_internal_loader_ClassLoaders_AppClassLoader, Pre ) \
do_klass(jdk_internal_loader_ClassLoaders_PlatformClassLoader_klass, jdk_internal_loader_ClassLoaders_PlatformClassLoader, Pre ) \
do_klass(CodeSource_klass, java_security_CodeSource, Pre ) \
@@ -212,8 +212,6 @@
do_klass(Integer_klass, java_lang_Integer, Pre ) \
do_klass(Long_klass, java_lang_Long, Pre ) \
\
- /* Extensions */ \
- WK_KLASSES_DO_EXT(do_klass) \
/* JVMCI classes. These are loaded on-demand. */ \
JVMCI_WK_KLASSES_DO(do_klass) \
\
@@ -223,7 +221,6 @@
class SystemDictionary : AllStatic {
friend class VMStructs;
friend class SystemDictionaryHandles;
- friend class SharedClassUtil;
public:
enum WKID {
--- a/src/hotspot/share/classfile/systemDictionaryShared.cpp Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp Thu Apr 26 13:40:58 2018 -0700
@@ -31,7 +31,6 @@
#include "classfile/compactHashtable.inline.hpp"
#include "classfile/dictionary.hpp"
#include "classfile/javaClasses.hpp"
-#include "classfile/sharedClassUtil.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/systemDictionaryShared.hpp"
@@ -92,7 +91,7 @@
Handle empty;
Handle manifest ;
if (shared_jar_manifest(shared_path_index) == NULL) {
- SharedClassPathEntryExt* ent = (SharedClassPathEntryExt*)FileMapInfo::shared_path(shared_path_index);
+ SharedClassPathEntry* ent = FileMapInfo::shared_path(shared_path_index);
long size = ent->manifest_size();
if (size <= 0) {
return empty; // No manifest - return NULL handle
@@ -303,8 +302,7 @@
if (ik != NULL) {
int index = ik->shared_classpath_index();
assert(index >= 0, "Sanity");
- SharedClassPathEntryExt* ent =
- (SharedClassPathEntryExt*)FileMapInfo::shared_path(index);
+ SharedClassPathEntry* ent = FileMapInfo::shared_path(index);
Symbol* class_name = ik->name();
if (ent->is_modules_image()) {
@@ -476,41 +474,38 @@
// [1] JVM_FindLoadedClass
// [2] java.lang.ClassLoader.findLoadedClass0()
// [3] java.lang.ClassLoader.findLoadedClass()
-// [4] java.lang.ClassLoader.loadClass()
-// [5] jdk.internal.loader.ClassLoaders$AppClassLoader_klass.loadClass()
-//
-// Because AppCDS supports only the PlatformClassLoader and AppClassLoader, we make the following
-// assumptions (based on the JDK 8.0 source code):
+// [4] jdk.internal.loader.BuiltinClassLoader.loadClassOrNull()
+// [5] jdk.internal.loader.BuiltinClassLoader.loadClass()
+// [6] jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(), or
+// jdk.internal.loader.ClassLoaders$PlatformClassLoader.loadClass()
//
-// [a] these two loaders use the default implementation of
-// ClassLoader.loadClass(String name, boolean resolve), which
-// [b] calls findLoadedClass(name), immediately followed by parent.loadClass(),
-// immediately followed by findClass(name).
-// [c] If the requested class is a shared class of the current class loader, parent.loadClass()
-// always returns null, and
-// [d] if AppCDS is not enabled, the class would be loaded by findClass() by decoding it from a
-// JAR file and then parsed.
+// AppCDS supports fast class loading for these 2 built-in class loaders:
+// jdk.internal.loader.ClassLoaders$PlatformClassLoader
+// jdk.internal.loader.ClassLoaders$AppClassLoader
+// with the following assumptions (based on the JDK core library source code):
+//
+// [a] these two loaders use the BuiltinClassLoader.loadClassOrNull() to
+// load the named class.
+// [b] BuiltinClassLoader.loadClassOrNull() first calls findLoadedClass(name).
+// [c] At this point, if we can find the named class inside the
+// shared_dictionary, we can perform further checks (see
+// is_shared_class_visible_for_classloader() to ensure that this class
+// was loaded by the same class loader during dump time.
//
// Given these assumptions, we intercept the findLoadedClass() call to invoke
// SystemDictionaryShared::find_or_load_shared_class() to load the shared class from
-// the archive. The reasons are:
-//
-// + Because AppCDS is a commercial feature, we want to hide the implementation. There
-// is currently no easy way to hide Java code, so we did it with native code.
-// + Start-up is improved because we avoid decoding the JAR file, and avoid delegating
-// to the parent (since we know the parent will not find this class).
+// the archive for the 2 built-in class loaders. This way,
+// we can improve start-up because we avoid decoding the classfile,
+// and avoid delegating to the parent loader.
//
// NOTE: there's a lot of assumption about the Java code. If any of that change, this
// needs to be redesigned.
-//
-// An alternative is to modify the Java code of AppClassLoader.loadClass().
-//
+
InstanceKlass* SystemDictionaryShared::find_or_load_shared_class(
Symbol* name, Handle class_loader, TRAPS) {
InstanceKlass* k = NULL;
if (UseSharedSpaces) {
- FileMapHeaderExt* header = (FileMapHeaderExt*)FileMapInfo::current_info()->header();
- if (!header->has_platform_or_app_classes()) {
+ if (!FileMapInfo::current_info()->header()->has_platform_or_app_classes()) {
return NULL;
}
--- a/src/hotspot/share/classfile/systemDictionary_ext.hpp Mon May 07 20:42:36 2018 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2015, 2017 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_CLASSFILE_SYSTEMDICTIONARY_EXT_HPP
-#define SHARE_VM_CLASSFILE_SYSTEMDICTIONARY_EXT_HPP
-
-#if INCLUDE_CDS
-
-#define WK_KLASSES_DO_EXT(do_klass) \
- /* well-known classes */ \
- do_klass(jdk_internal_loader_ClassLoaders_klass, jdk_internal_loader_ClassLoaders, Pre ) \
- /*end*/
-
-#else
-
-#define WK_KLASSES_DO_EXT(do_klass)
-
-#endif // INCLUDE_CDS
-
-#endif // SHARE_VM_CLASSFILE_SYSTEMDICTIONARY_EXT_HPP
--- a/src/hotspot/share/memory/filemap.cpp Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/memory/filemap.cpp Thu Apr 26 13:40:58 2018 -0700
@@ -25,8 +25,8 @@
#include "precompiled.hpp"
#include "jvm.h"
#include "classfile/classLoader.inline.hpp"
+#include "classfile/classLoaderExt.hpp"
#include "classfile/compactHashtable.inline.hpp"
-#include "classfile/sharedClassUtil.hpp"
#include "classfile/stringTable.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionaryShared.hpp"
@@ -159,8 +159,9 @@
memset((void*)this, 0, sizeof(FileMapInfo));
_file_offset = 0;
_file_open = false;
- _header = SharedClassUtil::allocate_file_map_header();
+ _header = new FileMapHeader();
_header->_version = _invalid_version;
+ _header->_has_platform_or_app_classes = true;
}
FileMapInfo::~FileMapInfo() {
@@ -172,10 +173,6 @@
_header->populate(this, alignment);
}
-size_t FileMapInfo::FileMapHeader::data_size() {
- return SharedClassUtil::file_map_header_size() - sizeof(FileMapInfo::FileMapHeaderBase);
-}
-
void FileMapInfo::FileMapHeader::populate(FileMapInfo* mapinfo, size_t alignment) {
_magic = 0xf00baba2;
_version = _current_version;
@@ -198,6 +195,14 @@
// JVM version string ... changes on each build.
get_header_version(_jvm_ident);
+
+ ClassLoaderExt::finalize_shared_paths_misc_info();
+ _app_class_paths_start_index = ClassLoaderExt::app_class_paths_start_index();
+ _app_module_paths_start_index = ClassLoaderExt::app_module_paths_start_index();
+
+ _verify_local = BytecodeVerificationLocal;
+ _verify_remote = BytecodeVerificationRemote;
+ _has_platform_or_app_classes = ClassLoaderExt::has_platform_or_app_classes();
}
void SharedClassPathEntry::init(const char* name, TRAPS) {
@@ -278,7 +283,7 @@
assert(jrt != NULL,
"No modular java runtime image present when allocating the CDS classpath entry table");
- size_t entry_size = SharedClassUtil::shared_class_path_entry_size(); // assert ( should be 8 byte aligned??)
+ size_t entry_size = sizeof(SharedClassPathEntry); // assert ( should be 8 byte aligned??)
int num_boot_classpath_entries = ClassLoader::num_boot_classpath_entries();
int num_app_classpath_entries = ClassLoader::num_app_classpath_entries();
int num_module_path_entries = ClassLoader::num_module_path_entries();
@@ -299,7 +304,7 @@
ent->init(cpe->name(), THREAD);
if (cpe != jrt) { // No need to do jimage.
EXCEPTION_MARK; // The following call should never throw, but would exit VM on error.
- SharedClassUtil::update_shared_classpath(cpe, ent, THREAD);
+ update_shared_classpath(cpe, ent, THREAD);
}
cpe = ClassLoader::get_next_boot_classpath_entry(cpe);
i++;
@@ -314,7 +319,7 @@
SharedClassPathEntry* ent = shared_path(i);
ent->init(acpe->name(), THREAD);
EXCEPTION_MARK;
- SharedClassUtil::update_shared_classpath(acpe, ent, THREAD);
+ update_shared_classpath(acpe, ent, THREAD);
acpe = acpe->next();
i++;
}
@@ -326,7 +331,7 @@
SharedClassPathEntry* ent = shared_path(i);
ent->init(mpe->name(), THREAD);
EXCEPTION_MARK;
- SharedClassUtil::update_shared_classpath(mpe, ent, THREAD);
+ update_shared_classpath(mpe, ent, THREAD);
mpe = mpe->next();
i++;
}
@@ -360,6 +365,84 @@
}
}
+class ManifestStream: public ResourceObj {
+ private:
+ u1* _buffer_start; // Buffer bottom
+ u1* _buffer_end; // Buffer top (one past last element)
+ u1* _current; // Current buffer position
+
+ public:
+ // Constructor
+ ManifestStream(u1* buffer, int length) : _buffer_start(buffer),
+ _current(buffer) {
+ _buffer_end = buffer + length;
+ }
+
+ static bool is_attr(u1* attr, const char* name) {
+ return strncmp((const char*)attr, name, strlen(name)) == 0;
+ }
+
+ static char* copy_attr(u1* value, size_t len) {
+ char* buf = NEW_RESOURCE_ARRAY(char, len + 1);
+ strncpy(buf, (char*)value, len);
+ buf[len] = 0;
+ return buf;
+ }
+
+ // The return value indicates if the JAR is signed or not
+ bool check_is_signed() {
+ u1* attr = _current;
+ bool isSigned = false;
+ while (_current < _buffer_end) {
+ if (*_current == '\n') {
+ *_current = '\0';
+ u1* value = (u1*)strchr((char*)attr, ':');
+ if (value != NULL) {
+ assert(*(value+1) == ' ', "Unrecognized format" );
+ if (strstr((char*)attr, "-Digest") != NULL) {
+ isSigned = true;
+ break;
+ }
+ }
+ *_current = '\n'; // restore
+ attr = _current + 1;
+ }
+ _current ++;
+ }
+ return isSigned;
+ }
+};
+
+void FileMapInfo::update_shared_classpath(ClassPathEntry *cpe, SharedClassPathEntry* ent, TRAPS) {
+ ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
+ ResourceMark rm(THREAD);
+ jint manifest_size;
+ bool isSigned;
+
+ if (cpe->is_jar_file()) {
+ char* manifest = ClassLoaderExt::read_manifest(cpe, &manifest_size, CHECK);
+ if (manifest != NULL) {
+ ManifestStream* stream = new ManifestStream((u1*)manifest,
+ manifest_size);
+ isSigned = stream->check_is_signed();
+ if (isSigned) {
+ ent->set_is_signed(true);
+ } else {
+ // Copy the manifest into the shared archive
+ manifest = ClassLoaderExt::read_raw_manifest(cpe, &manifest_size, CHECK);
+ Array<u1>* buf = MetadataFactory::new_array<u1>(loader_data,
+ manifest_size,
+ THREAD);
+ char* p = (char*)(buf->data());
+ memcpy(p, manifest, manifest_size);
+ ent->set_manifest(buf);
+ ent->set_is_signed(false);
+ }
+ }
+ }
+}
+
+
bool FileMapInfo::validate_shared_path_table() {
assert(UseSharedSpaces, "runtime only");
@@ -368,14 +451,13 @@
_shared_path_entry_size = _header->_shared_path_entry_size;
_shared_path_table_size = _header->_shared_path_table_size;
- FileMapHeaderExt* header = (FileMapHeaderExt*)FileMapInfo::current_info()->header();
- int module_paths_start_index = header->_app_module_paths_start_index;
+ int module_paths_start_index = _header->_app_module_paths_start_index;
// 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;
+ 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) {
@@ -1078,6 +1160,26 @@
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 &&
+ ((!_verify_local && BytecodeVerificationLocal) ||
+ (!_verify_remote && BytecodeVerificationRemote))) {
+ FileMapInfo::fail_continue("The shared archive file was created with less restrictive "
+ "verification setting than the current setting.");
+ return false;
+ }
+
return true;
}
--- a/src/hotspot/share/memory/filemap.hpp Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/memory/filemap.hpp Thu Apr 26 13:40:58 2018 -0700
@@ -49,6 +49,7 @@
long _filesize; // jar/jimage file size, -1 if is directory, -2 if other
Array<char>* _name;
Array<u1>* _manifest;
+ bool _is_signed;
public:
void init(const char* name, TRAPS);
@@ -70,6 +71,15 @@
int manifest_size() const {
return (_manifest == NULL) ? 0 : _manifest->length();
}
+ void set_manifest(Array<u1>* manifest) {
+ _manifest = manifest;
+ }
+ void set_is_signed(bool s) {
+ _is_signed = s;
+ }
+ bool is_signed() {
+ return _is_signed;
+ }
};
class FileMapInfo : public CHeapObj<mtInternal> {
@@ -97,13 +107,16 @@
public:
struct FileMapHeaderBase : public CHeapObj<mtClass> {
- virtual bool validate() = 0;
- virtual void populate(FileMapInfo* info, size_t alignment) = 0;
+ // Need to put something here. Otherwise, in product build, because CHeapObj has no virtual
+ // methods, we would get sizeof(FileMapHeaderBase) == 1 with gcc.
+ intx _dummy;
};
struct FileMapHeader : FileMapHeaderBase {
// Use data() and data_size() to memcopy to/from the FileMapHeader. We need to
// avoid read/writing the C++ vtable pointer.
- static size_t data_size();
+ static size_t data_size() {
+ return sizeof(FileMapHeader) - sizeof(FileMapInfo::FileMapHeaderBase);
+ }
char* data() {
return ((char*)this) + sizeof(FileMapHeaderBase);
}
@@ -146,7 +159,7 @@
// The _paths_misc_info is a variable-size structure that records "miscellaneous"
// information during dumping. It is generated and validated by the
- // SharedPathsMiscInfo class. See SharedPathsMiscInfo.hpp and sharedClassUtil.hpp for
+ // SharedPathsMiscInfo class. See SharedPathsMiscInfo.hpp for
// detailed description.
//
// The _paths_misc_info data is stored as a byte array in the archive file header,
@@ -172,10 +185,21 @@
size_t _shared_path_entry_size;
Array<u8>* _shared_path_table;
+ jshort _app_class_paths_start_index; // Index of first app classpath entry
+ jshort _app_module_paths_start_index; // Index of first module path entry
+ bool _verify_local; // BytecodeVerificationLocal setting
+ bool _verify_remote; // BytecodeVerificationRemote setting
+ bool _has_platform_or_app_classes; // Archive contains app classes
+
+ 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; }
+
char* region_addr(int idx);
- virtual bool validate();
- virtual void populate(FileMapInfo* info, size_t alignment);
+ bool validate();
+ void populate(FileMapInfo* info, size_t alignment);
int compute_crc();
};
@@ -274,6 +298,7 @@
static void allocate_shared_path_table();
static void check_nonempty_dir_in_shared_path_table();
bool validate_shared_path_table();
+ static void update_shared_classpath(ClassPathEntry *cpe, SharedClassPathEntry* ent, TRAPS);
static SharedClassPathEntry* shared_path(int index) {
if (index < 0) {
--- a/src/hotspot/share/memory/metaspaceShared.cpp Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/memory/metaspaceShared.cpp Thu Apr 26 13:40:58 2018 -0700
@@ -29,7 +29,6 @@
#include "classfile/dictionary.hpp"
#include "classfile/loaderConstraints.hpp"
#include "classfile/placeholders.hpp"
-#include "classfile/sharedClassUtil.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/stringTable.hpp"
#include "classfile/systemDictionary.hpp"
@@ -323,6 +322,46 @@
_shared_rs.size(), p2i(_shared_rs.base()));
}
+// Called by universe_post_init()
+void MetaspaceShared::post_initialize(TRAPS) {
+ if (UseSharedSpaces) {
+ int size = FileMapInfo::get_number_of_shared_paths();
+ if (size > 0) {
+ SystemDictionaryShared::allocate_shared_data_arrays(size, THREAD);
+ FileMapInfo::FileMapHeader* header = 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);
+ }
+ }
+
+ if (DumpSharedSpaces) {
+ if (SharedArchiveConfigFile) {
+ read_extra_data(SharedArchiveConfigFile, THREAD);
+ }
+ }
+}
+
+void MetaspaceShared::read_extra_data(const char* filename, TRAPS) {
+ HashtableTextDump reader(filename);
+ reader.check_version("VERSION: 1.0");
+
+ while (reader.remain() > 0) {
+ int utf8_length;
+ int prefix_type = reader.scan_prefix(&utf8_length);
+ ResourceMark rm(THREAD);
+ char* utf8_buffer = NEW_RESOURCE_ARRAY(char, utf8_length);
+ reader.get_utf8(utf8_buffer, utf8_length);
+
+ if (prefix_type == HashtableTextDump::SymbolPrefix) {
+ SymbolTable::new_symbol(utf8_buffer, utf8_length, THREAD);
+ } else{
+ assert(prefix_type == HashtableTextDump::StringPrefix, "Sanity");
+ utf8_buffer[utf8_length] = '\0';
+ oop s = StringTable::intern(utf8_buffer, THREAD);
+ }
+ }
+}
+
void MetaspaceShared::commit_shared_space_to(char* newtop) {
assert(DumpSharedSpaces, "dump-time only");
char* base = _shared_rs.base();
--- a/src/hotspot/share/memory/metaspaceShared.hpp Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/memory/metaspaceShared.hpp Thu Apr 26 13:40:58 2018 -0700
@@ -147,6 +147,7 @@
}
static void initialize_dumptime_shared_and_meta_spaces() NOT_CDS_RETURN;
static void initialize_runtime_shared_and_meta_spaces() NOT_CDS_RETURN;
+ static void post_initialize(TRAPS) NOT_CDS_RETURN;
// Delta of this object from the bottom of the archive.
static uintx object_delta(void* obj) {
@@ -250,5 +251,8 @@
static void relocate_klass_ptr(oop o);
static Klass* get_relocated_klass(Klass *k);
+
+private:
+ static void read_extra_data(const char* filename, TRAPS) NOT_CDS_RETURN;
};
#endif // SHARE_VM_MEMORY_METASPACESHARED_HPP
--- a/src/hotspot/share/memory/universe.cpp Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/memory/universe.cpp Thu Apr 26 13:40:58 2018 -0700
@@ -81,9 +81,6 @@
#include "utilities/macros.hpp"
#include "utilities/ostream.hpp"
#include "utilities/preserveException.hpp"
-#if INCLUDE_CDS
-#include "classfile/sharedClassUtil.hpp"
-#endif
// Known objects
Klass* Universe::_boolArrayKlassObj = NULL;
@@ -1094,7 +1091,7 @@
MemoryService::set_universe_heap(Universe::heap());
#if INCLUDE_CDS
- SharedClassUtil::initialize(CHECK_false);
+ MetaspaceShared::post_initialize(CHECK_false);
#endif
return true;
}
--- a/src/hotspot/share/oops/klass.hpp Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/oops/klass.hpp Thu Apr 26 13:40:58 2018 -0700
@@ -168,7 +168,6 @@
// in the open archive heap region when archiving java object is supported.
CDS_JAVA_HEAP_ONLY(narrowOop _archived_mirror;)
- friend class SharedClassUtil;
protected:
// Constructor
--- a/src/hotspot/share/prims/jvm.cpp Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/prims/jvm.cpp Thu Apr 26 13:40:58 2018 -0700
@@ -84,7 +84,6 @@
#include "utilities/macros.hpp"
#include "utilities/utf8.hpp"
#if INCLUDE_CDS
-#include "classfile/sharedClassUtil.hpp"
#include "classfile/systemDictionaryShared.hpp"
#endif