mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-25 05:45:11 +02:00
8046070: Class Data Sharing clean up and refactoring
Cleaned up CDS to be more configurable, maintainable and extensible Reviewed-by: dholmes, coleenp, acorn, mchung
This commit is contained in:
parent
1fec07f4bf
commit
bbe6f51f81
42 changed files with 2087 additions and 434 deletions
|
@ -26,8 +26,13 @@
|
|||
#include "classfile/classFileParser.hpp"
|
||||
#include "classfile/classFileStream.hpp"
|
||||
#include "classfile/classLoader.hpp"
|
||||
#include "classfile/classLoaderExt.hpp"
|
||||
#include "classfile/classLoaderData.inline.hpp"
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#if INCLUDE_CDS
|
||||
#include "classfile/sharedPathsMiscInfo.hpp"
|
||||
#include "classfile/sharedClassUtil.hpp"
|
||||
#endif
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "compiler/compileBroker.hpp"
|
||||
|
@ -35,6 +40,7 @@
|
|||
#include "interpreter/bytecodeStream.hpp"
|
||||
#include "interpreter/oopMapCache.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "memory/filemap.hpp"
|
||||
#include "memory/generation.hpp"
|
||||
#include "memory/oopFactory.hpp"
|
||||
#include "memory/universe.inline.hpp"
|
||||
|
@ -114,8 +120,12 @@ PerfCounter* ClassLoader::_load_instance_class_failCounter = NULL;
|
|||
|
||||
ClassPathEntry* ClassLoader::_first_entry = NULL;
|
||||
ClassPathEntry* ClassLoader::_last_entry = NULL;
|
||||
int ClassLoader::_num_entries = 0;
|
||||
PackageHashtable* ClassLoader::_package_hash_table = NULL;
|
||||
|
||||
#if INCLUDE_CDS
|
||||
SharedPathsMiscInfo* ClassLoader::_shared_paths_misc_info = NULL;
|
||||
#endif
|
||||
// helper routines
|
||||
bool string_starts_with(const char* str, const char* str_to_find) {
|
||||
size_t str_len = strlen(str);
|
||||
|
@ -194,6 +204,14 @@ 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) {
|
||||
|
@ -228,13 +246,13 @@ ClassPathZipEntry::~ClassPathZipEntry() {
|
|||
FREE_C_HEAP_ARRAY(char, _zip_name, mtClass);
|
||||
}
|
||||
|
||||
ClassFileStream* ClassPathZipEntry::open_stream(const char* name, TRAPS) {
|
||||
// enable call to C land
|
||||
u1* ClassPathZipEntry::open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS) {
|
||||
// enable call to C land
|
||||
JavaThread* thread = JavaThread::current();
|
||||
ThreadToNativeFromVM ttn(thread);
|
||||
// check whether zip archive contains name
|
||||
jint filesize, name_len;
|
||||
jzentry* entry = (*FindEntry)(_zip, name, &filesize, &name_len);
|
||||
jint name_len;
|
||||
jzentry* entry = (*FindEntry)(_zip, name, filesize, &name_len);
|
||||
if (entry == NULL) return NULL;
|
||||
u1* buffer;
|
||||
char name_buf[128];
|
||||
|
@ -245,19 +263,33 @@ ClassFileStream* ClassPathZipEntry::open_stream(const char* name, TRAPS) {
|
|||
filename = NEW_RESOURCE_ARRAY(char, name_len + 1);
|
||||
}
|
||||
|
||||
// file found, get pointer to class in mmaped jar file.
|
||||
// file found, get pointer to the entry in mmapped jar file.
|
||||
if (ReadMappedEntry == NULL ||
|
||||
!(*ReadMappedEntry)(_zip, entry, &buffer, filename)) {
|
||||
// mmaped access not available, perhaps due to compression,
|
||||
// mmapped access not available, perhaps due to compression,
|
||||
// read contents into resource array
|
||||
buffer = NEW_RESOURCE_ARRAY(u1, filesize);
|
||||
int size = (*filesize) + ((nul_terminate) ? 1 : 0);
|
||||
buffer = NEW_RESOURCE_ARRAY(u1, size);
|
||||
if (!(*ReadEntry)(_zip, entry, buffer, filename)) return NULL;
|
||||
}
|
||||
|
||||
// return result
|
||||
if (nul_terminate) {
|
||||
buffer[*filesize] = 0;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
ClassFileStream* ClassPathZipEntry::open_stream(const char* name, TRAPS) {
|
||||
jint filesize;
|
||||
u1* buffer = open_entry(name, &filesize, false, CHECK_NULL);
|
||||
if (buffer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (UsePerfData) {
|
||||
ClassLoader::perf_sys_classfile_bytes_read()->inc(filesize);
|
||||
}
|
||||
// return result
|
||||
return new ClassFileStream(buffer, filesize, _zip_name); // Resource allocated
|
||||
return new ClassFileStream(buffer, filesize, _zip_name); // Resource allocated
|
||||
}
|
||||
|
||||
// invoke function for each entry in the zip file
|
||||
|
@ -272,12 +304,13 @@ void ClassPathZipEntry::contents_do(void f(const char* name, void* context), voi
|
|||
}
|
||||
}
|
||||
|
||||
LazyClassPathEntry::LazyClassPathEntry(char* path, const struct stat* st) : ClassPathEntry() {
|
||||
LazyClassPathEntry::LazyClassPathEntry(char* path, const struct stat* st, bool throw_exception) : ClassPathEntry() {
|
||||
_path = os::strdup_check_oom(path);
|
||||
_st = *st;
|
||||
_meta_index = NULL;
|
||||
_resolved_entry = NULL;
|
||||
_has_error = false;
|
||||
_throw_exception = throw_exception;
|
||||
}
|
||||
|
||||
LazyClassPathEntry::~LazyClassPathEntry() {
|
||||
|
@ -293,7 +326,11 @@ ClassPathEntry* LazyClassPathEntry::resolve_entry(TRAPS) {
|
|||
return (ClassPathEntry*) _resolved_entry;
|
||||
}
|
||||
ClassPathEntry* new_entry = NULL;
|
||||
new_entry = ClassLoader::create_class_path_entry(_path, &_st, false, CHECK_NULL);
|
||||
new_entry = ClassLoader::create_class_path_entry(_path, &_st, false, _throw_exception, CHECK_NULL);
|
||||
if (!_throw_exception && new_entry == NULL) {
|
||||
assert(!HAS_PENDING_EXCEPTION, "must be");
|
||||
return NULL;
|
||||
}
|
||||
{
|
||||
ThreadCritical tc;
|
||||
if (_resolved_entry == NULL) {
|
||||
|
@ -327,6 +364,23 @@ bool LazyClassPathEntry::is_lazy() {
|
|||
return true;
|
||||
}
|
||||
|
||||
u1* LazyClassPathEntry::open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS) {
|
||||
if (_has_error) {
|
||||
return NULL;
|
||||
}
|
||||
ClassPathEntry* cpe = resolve_entry(THREAD);
|
||||
if (cpe == NULL) {
|
||||
_has_error = true;
|
||||
return NULL;
|
||||
} else if (cpe->is_jar_file()) {
|
||||
return ((ClassPathZipEntry*)cpe)->open_entry(name, filesize, nul_terminate,THREAD);
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
*filesize = 0;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void print_meta_index(LazyClassPathEntry* entry,
|
||||
GrowableArray<char*>& meta_packages) {
|
||||
tty->print("[Meta index for %s=", entry->name());
|
||||
|
@ -337,15 +391,62 @@ static void print_meta_index(LazyClassPathEntry* entry,
|
|||
tty->print_cr("]");
|
||||
}
|
||||
|
||||
#if INCLUDE_CDS
|
||||
void ClassLoader::exit_with_path_failure(const char* error, const char* message) {
|
||||
assert(DumpSharedSpaces, "only called at dump time");
|
||||
tty->print_cr("Hint: enable -XX:+TraceClassPaths to diagnose the failure");
|
||||
vm_exit_during_initialization(error, message);
|
||||
}
|
||||
#endif
|
||||
|
||||
void ClassLoader::setup_meta_index() {
|
||||
void ClassLoader::trace_class_path(const char* msg, const char* name) {
|
||||
if (!TraceClassPaths) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg) {
|
||||
tty->print("%s", msg);
|
||||
}
|
||||
if (name) {
|
||||
if (strlen(name) < 256) {
|
||||
tty->print("%s", name);
|
||||
} else {
|
||||
// For very long paths, we need to print each character separately,
|
||||
// as print_cr() has a length limit
|
||||
while (name[0] != '\0') {
|
||||
tty->print("%c", name[0]);
|
||||
name++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (msg && msg[0] == '[') {
|
||||
tty->print_cr("]");
|
||||
} else {
|
||||
tty->cr();
|
||||
}
|
||||
}
|
||||
|
||||
void ClassLoader::setup_bootstrap_meta_index() {
|
||||
// Set up meta index which allows us to open boot jars lazily if
|
||||
// class data sharing is enabled
|
||||
const char* meta_index_path = Arguments::get_meta_index_path();
|
||||
const char* meta_index_dir = Arguments::get_meta_index_dir();
|
||||
setup_meta_index(meta_index_path, meta_index_dir, 0);
|
||||
}
|
||||
|
||||
void ClassLoader::setup_meta_index(const char* meta_index_path, const char* meta_index_dir, int start_index) {
|
||||
const char* known_version = "% VERSION 2";
|
||||
char* meta_index_path = Arguments::get_meta_index_path();
|
||||
char* meta_index_dir = Arguments::get_meta_index_dir();
|
||||
FILE* file = fopen(meta_index_path, "r");
|
||||
int line_no = 0;
|
||||
#if INCLUDE_CDS
|
||||
if (DumpSharedSpaces) {
|
||||
if (file != NULL) {
|
||||
_shared_paths_misc_info->add_required_file(meta_index_path);
|
||||
} else {
|
||||
_shared_paths_misc_info->add_nonexist_path(meta_index_path);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (file != NULL) {
|
||||
ResourceMark rm;
|
||||
LazyClassPathEntry* cur_entry = NULL;
|
||||
|
@ -380,7 +481,7 @@ void ClassLoader::setup_meta_index() {
|
|||
// Hand off current packages to current lazy entry (if any)
|
||||
if ((cur_entry != NULL) &&
|
||||
(boot_class_path_packages.length() > 0)) {
|
||||
if (TraceClassLoading && Verbose) {
|
||||
if ((TraceClassLoading || TraceClassPaths) && Verbose) {
|
||||
print_meta_index(cur_entry, boot_class_path_packages);
|
||||
}
|
||||
MetaIndex* index = new MetaIndex(boot_class_path_packages.adr_at(0),
|
||||
|
@ -391,8 +492,10 @@ void ClassLoader::setup_meta_index() {
|
|||
boot_class_path_packages.clear();
|
||||
|
||||
// Find lazy entry corresponding to this jar file
|
||||
for (ClassPathEntry* entry = _first_entry; entry != NULL; entry = entry->next()) {
|
||||
if (entry->is_lazy() &&
|
||||
int count = 0;
|
||||
for (ClassPathEntry* entry = _first_entry; entry != NULL; entry = entry->next(), count++) {
|
||||
if (count >= start_index &&
|
||||
entry->is_lazy() &&
|
||||
string_starts_with(entry->name(), meta_index_dir) &&
|
||||
string_ends_with(entry->name(), &package_name[2])) {
|
||||
cur_entry = (LazyClassPathEntry*) entry;
|
||||
|
@ -429,7 +532,7 @@ void ClassLoader::setup_meta_index() {
|
|||
// Hand off current packages to current lazy entry (if any)
|
||||
if ((cur_entry != NULL) &&
|
||||
(boot_class_path_packages.length() > 0)) {
|
||||
if (TraceClassLoading && Verbose) {
|
||||
if ((TraceClassLoading || TraceClassPaths) && Verbose) {
|
||||
print_meta_index(cur_entry, boot_class_path_packages);
|
||||
}
|
||||
MetaIndex* index = new MetaIndex(boot_class_path_packages.adr_at(0),
|
||||
|
@ -440,37 +543,88 @@ void ClassLoader::setup_meta_index() {
|
|||
}
|
||||
}
|
||||
|
||||
#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_IFREG) != S_IFREG) { // is directory
|
||||
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() {
|
||||
assert(_first_entry == NULL, "should not setup bootstrap class search path twice");
|
||||
char* sys_class_path = os::strdup_check_oom(Arguments::get_sysclasspath());
|
||||
if (TraceClassLoading && Verbose) {
|
||||
tty->print_cr("[Bootstrap loader class path=%s]", sys_class_path);
|
||||
if (!PrintSharedArchiveAndExit) {
|
||||
trace_class_path("[Bootstrap loader class path=", sys_class_path);
|
||||
}
|
||||
#if INCLUDE_CDS
|
||||
if (DumpSharedSpaces) {
|
||||
_shared_paths_misc_info->add_boot_classpath(Arguments::get_sysclasspath());
|
||||
}
|
||||
#endif
|
||||
setup_search_path(sys_class_path);
|
||||
os::free(sys_class_path);
|
||||
}
|
||||
|
||||
int len = (int)strlen(sys_class_path);
|
||||
#if INCLUDE_CDS
|
||||
int ClassLoader::get_shared_paths_misc_info_size() {
|
||||
return _shared_paths_misc_info->get_used_bytes();
|
||||
}
|
||||
|
||||
void* ClassLoader::get_shared_paths_misc_info() {
|
||||
return _shared_paths_misc_info->buffer();
|
||||
}
|
||||
|
||||
bool ClassLoader::check_shared_paths_misc_info(void *buf, int size) {
|
||||
SharedPathsMiscInfo* checker = SharedClassUtil::allocate_shared_paths_misc_info((char*)buf, size);
|
||||
bool result = checker->check();
|
||||
delete checker;
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
void ClassLoader::setup_search_path(char *class_path) {
|
||||
int offset = 0;
|
||||
int len = (int)strlen(class_path);
|
||||
int end = 0;
|
||||
|
||||
// Iterate over class path entries
|
||||
for (int start = 0; start < len; start = end) {
|
||||
while (sys_class_path[end] && sys_class_path[end] != os::path_separator()[0]) {
|
||||
while (class_path[end] && class_path[end] != os::path_separator()[0]) {
|
||||
end++;
|
||||
}
|
||||
char* path = NEW_C_HEAP_ARRAY(char, end-start+1, mtClass);
|
||||
strncpy(path, &sys_class_path[start], end-start);
|
||||
path[end-start] = '\0';
|
||||
EXCEPTION_MARK;
|
||||
ResourceMark rm(THREAD);
|
||||
char* path = NEW_RESOURCE_ARRAY(char, end - start + 1);
|
||||
strncpy(path, &class_path[start], end - start);
|
||||
path[end - start] = '\0';
|
||||
update_class_path_entry_list(path, false);
|
||||
FREE_C_HEAP_ARRAY(char, path, mtClass);
|
||||
while (sys_class_path[end] == os::path_separator()[0]) {
|
||||
#if INCLUDE_CDS
|
||||
if (DumpSharedSpaces) {
|
||||
check_shared_classpath(path);
|
||||
}
|
||||
#endif
|
||||
while (class_path[end] == os::path_separator()[0]) {
|
||||
end++;
|
||||
}
|
||||
}
|
||||
os::free(sys_class_path);
|
||||
}
|
||||
|
||||
ClassPathEntry* ClassLoader::create_class_path_entry(char *path, const struct stat* st, bool lazy, TRAPS) {
|
||||
ClassPathEntry* ClassLoader::create_class_path_entry(char *path, const struct stat* st,
|
||||
bool lazy, bool throw_exception, TRAPS) {
|
||||
JavaThread* thread = JavaThread::current();
|
||||
if (lazy) {
|
||||
return new LazyClassPathEntry(path, st);
|
||||
return new LazyClassPathEntry(path, st, throw_exception);
|
||||
}
|
||||
ClassPathEntry* new_entry = NULL;
|
||||
if ((st->st_mode & S_IFREG) == S_IFREG) {
|
||||
|
@ -479,7 +633,11 @@ ClassPathEntry* ClassLoader::create_class_path_entry(char *path, const struct st
|
|||
char canonical_path[JVM_MAXPATHLEN];
|
||||
if (!get_canonical_path(path, canonical_path, JVM_MAXPATHLEN)) {
|
||||
// This matches the classic VM
|
||||
THROW_MSG_(vmSymbols::java_io_IOException(), "Bad pathname", NULL);
|
||||
if (throw_exception) {
|
||||
THROW_MSG_(vmSymbols::java_io_IOException(), "Bad pathname", NULL);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
char* error_msg = NULL;
|
||||
jzfile* zip;
|
||||
|
@ -491,7 +649,7 @@ ClassPathEntry* ClassLoader::create_class_path_entry(char *path, const struct st
|
|||
}
|
||||
if (zip != NULL && error_msg == NULL) {
|
||||
new_entry = new ClassPathZipEntry(zip, path);
|
||||
if (TraceClassLoading) {
|
||||
if (TraceClassLoading || TraceClassPaths) {
|
||||
tty->print_cr("[Opened %s]", path);
|
||||
}
|
||||
} else {
|
||||
|
@ -505,12 +663,16 @@ ClassPathEntry* ClassLoader::create_class_path_entry(char *path, const struct st
|
|||
msg = NEW_RESOURCE_ARRAY(char, len); ;
|
||||
jio_snprintf(msg, len - 1, "error in opening JAR file <%s> %s", error_msg, path);
|
||||
}
|
||||
THROW_MSG_(vmSymbols::java_lang_ClassNotFoundException(), msg, NULL);
|
||||
if (throw_exception) {
|
||||
THROW_MSG_(vmSymbols::java_lang_ClassNotFoundException(), msg, NULL);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Directory
|
||||
new_entry = new ClassPathDirEntry(path);
|
||||
if (TraceClassLoading) {
|
||||
if (TraceClassLoading || TraceClassPaths) {
|
||||
tty->print_cr("[Path %s]", path);
|
||||
}
|
||||
}
|
||||
|
@ -571,23 +733,37 @@ void ClassLoader::add_to_list(ClassPathEntry *new_entry) {
|
|||
_last_entry = new_entry;
|
||||
}
|
||||
}
|
||||
_num_entries ++;
|
||||
}
|
||||
|
||||
void ClassLoader::update_class_path_entry_list(char *path,
|
||||
bool check_for_duplicates) {
|
||||
// Returns true IFF the file/dir exists and the entry was successfully created.
|
||||
bool ClassLoader::update_class_path_entry_list(char *path,
|
||||
bool check_for_duplicates,
|
||||
bool throw_exception) {
|
||||
struct stat st;
|
||||
if (os::stat(path, &st) == 0) {
|
||||
// File or directory found
|
||||
ClassPathEntry* new_entry = NULL;
|
||||
Thread* THREAD = Thread::current();
|
||||
new_entry = create_class_path_entry(path, &st, LazyBootClassLoader, CHECK);
|
||||
new_entry = create_class_path_entry(path, &st, LazyBootClassLoader, throw_exception, CHECK_(false));
|
||||
if (new_entry == NULL) {
|
||||
return false;
|
||||
}
|
||||
// The kernel VM adds dynamically to the end of the classloader path and
|
||||
// doesn't reorder the bootclasspath which would break java.lang.Package
|
||||
// (see PackageInfo).
|
||||
// Add new entry to linked list
|
||||
if (!check_for_duplicates || !contains_entry(new_entry)) {
|
||||
add_to_list(new_entry);
|
||||
ClassLoaderExt::add_class_path_entry(path, check_for_duplicates, new_entry);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
#if INCLUDE_CDS
|
||||
if (DumpSharedSpaces) {
|
||||
_shared_paths_misc_info->add_nonexist_path(path);
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -739,10 +915,10 @@ public:
|
|||
assert(n == number_of_entries(), "just checking");
|
||||
}
|
||||
|
||||
void copy_table(char** top, char* end, PackageHashtable* table);
|
||||
CDS_ONLY(void copy_table(char** top, char* end, PackageHashtable* table);)
|
||||
};
|
||||
|
||||
|
||||
#if INCLUDE_CDS
|
||||
void PackageHashtable::copy_table(char** top, char* end,
|
||||
PackageHashtable* table) {
|
||||
// Copy (relocate) the table to the shared space.
|
||||
|
@ -750,33 +926,30 @@ void PackageHashtable::copy_table(char** top, char* end,
|
|||
|
||||
// Calculate the space needed for the package name strings.
|
||||
int i;
|
||||
int n = 0;
|
||||
for (i = 0; i < table_size(); ++i) {
|
||||
for (PackageInfo* pp = table->bucket(i);
|
||||
pp != NULL;
|
||||
pp = pp->next()) {
|
||||
n += (int)(strlen(pp->pkgname()) + 1);
|
||||
}
|
||||
}
|
||||
if (*top + n + sizeof(intptr_t) >= end) {
|
||||
report_out_of_shared_space(SharedMiscData);
|
||||
}
|
||||
|
||||
// Copy the table data (the strings) to the shared space.
|
||||
n = align_size_up(n, sizeof(HeapWord));
|
||||
*(intptr_t*)(*top) = n;
|
||||
*top += sizeof(intptr_t);
|
||||
intptr_t* tableSize = (intptr_t*)(*top);
|
||||
*top += sizeof(intptr_t); // For table size
|
||||
char* tableStart = *top;
|
||||
|
||||
for (i = 0; i < table_size(); ++i) {
|
||||
for (PackageInfo* pp = table->bucket(i);
|
||||
pp != NULL;
|
||||
pp = pp->next()) {
|
||||
int n1 = (int)(strlen(pp->pkgname()) + 1);
|
||||
if (*top + n1 >= end) {
|
||||
report_out_of_shared_space(SharedMiscData);
|
||||
}
|
||||
pp->set_pkgname((char*)memcpy(*top, pp->pkgname(), n1));
|
||||
*top += n1;
|
||||
}
|
||||
}
|
||||
*top = (char*)align_size_up((intptr_t)*top, sizeof(HeapWord));
|
||||
if (*top >= end) {
|
||||
report_out_of_shared_space(SharedMiscData);
|
||||
}
|
||||
|
||||
// Write table size
|
||||
intptr_t len = *top - (char*)tableStart;
|
||||
*tableSize = len;
|
||||
}
|
||||
|
||||
|
||||
|
@ -787,7 +960,7 @@ void ClassLoader::copy_package_info_buckets(char** top, char* end) {
|
|||
void ClassLoader::copy_package_info_table(char** top, char* end) {
|
||||
_package_hash_table->copy_table(top, end, _package_hash_table);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
PackageInfo* ClassLoader::lookup_package(const char *pkgname) {
|
||||
const char *cp = strrchr(pkgname, '/');
|
||||
|
@ -880,7 +1053,8 @@ objArrayOop ClassLoader::get_system_packages(TRAPS) {
|
|||
|
||||
instanceKlassHandle ClassLoader::load_classfile(Symbol* h_name, TRAPS) {
|
||||
ResourceMark rm(THREAD);
|
||||
EventMark m("loading class %s", h_name->as_C_string());
|
||||
const char* class_name = h_name->as_C_string();
|
||||
EventMark m("loading class %s", class_name);
|
||||
ThreadProfilerMark tpm(ThreadProfilerMark::classLoaderRegion);
|
||||
|
||||
stringStream st;
|
||||
|
@ -888,18 +1062,24 @@ instanceKlassHandle ClassLoader::load_classfile(Symbol* h_name, TRAPS) {
|
|||
// st.print("%s.class", h_name->as_utf8());
|
||||
st.print_raw(h_name->as_utf8());
|
||||
st.print_raw(".class");
|
||||
char* name = st.as_string();
|
||||
const char* file_name = st.as_string();
|
||||
ClassLoaderExt::Context context(class_name, file_name, THREAD);
|
||||
|
||||
// Lookup stream for parsing .class file
|
||||
ClassFileStream* stream = NULL;
|
||||
int classpath_index = 0;
|
||||
ClassPathEntry* e = NULL;
|
||||
instanceKlassHandle h;
|
||||
{
|
||||
PerfClassTraceTime vmtimer(perf_sys_class_lookup_time(),
|
||||
((JavaThread*) THREAD)->get_thread_stat()->perf_timers_addr(),
|
||||
PerfClassTraceTime::CLASS_LOAD);
|
||||
ClassPathEntry* e = _first_entry;
|
||||
e = _first_entry;
|
||||
while (e != NULL) {
|
||||
stream = e->open_stream(name, CHECK_NULL);
|
||||
stream = e->open_stream(file_name, CHECK_NULL);
|
||||
if (!context.check(stream, classpath_index)) {
|
||||
return h; // NULL
|
||||
}
|
||||
if (stream != NULL) {
|
||||
break;
|
||||
}
|
||||
|
@ -908,9 +1088,7 @@ instanceKlassHandle ClassLoader::load_classfile(Symbol* h_name, TRAPS) {
|
|||
}
|
||||
}
|
||||
|
||||
instanceKlassHandle h;
|
||||
if (stream != NULL) {
|
||||
|
||||
// class file found, parse it
|
||||
ClassFileParser parser(stream);
|
||||
ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
|
||||
|
@ -920,12 +1098,19 @@ instanceKlassHandle ClassLoader::load_classfile(Symbol* h_name, TRAPS) {
|
|||
loader_data,
|
||||
protection_domain,
|
||||
parsed_name,
|
||||
false,
|
||||
CHECK_(h));
|
||||
|
||||
// add to package table
|
||||
if (add_package(name, classpath_index, THREAD)) {
|
||||
h = result;
|
||||
context.should_verify(classpath_index),
|
||||
THREAD);
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
ResourceMark rm;
|
||||
if (DumpSharedSpaces) {
|
||||
tty->print_cr("Preload Error: Failed to load %s", class_name);
|
||||
}
|
||||
return h;
|
||||
}
|
||||
h = context.record_result(classpath_index, e, result, THREAD);
|
||||
} else {
|
||||
if (DumpSharedSpaces) {
|
||||
tty->print_cr("Preload Error: Cannot find %s", class_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1020,14 +1205,27 @@ void ClassLoader::initialize() {
|
|||
|
||||
// lookup zip library entry points
|
||||
load_zip_library();
|
||||
#if INCLUDE_CDS
|
||||
// initialize search path
|
||||
if (DumpSharedSpaces) {
|
||||
_shared_paths_misc_info = SharedClassUtil::allocate_shared_paths_misc_info();
|
||||
}
|
||||
#endif
|
||||
setup_bootstrap_search_path();
|
||||
if (LazyBootClassLoader) {
|
||||
// set up meta index which makes boot classpath initialization lazier
|
||||
setup_meta_index();
|
||||
setup_bootstrap_meta_index();
|
||||
}
|
||||
}
|
||||
|
||||
#if INCLUDE_CDS
|
||||
void ClassLoader::initialize_shared_path() {
|
||||
if (DumpSharedSpaces) {
|
||||
ClassLoaderExt::setup_search_paths();
|
||||
_shared_paths_misc_info->write_jint(0); // see comments in SharedPathsMiscInfo::check()
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
jlong ClassLoader::classloader_time_ms() {
|
||||
return UsePerfData ?
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue