src/share/vm/classfile/classLoader.cpp
Print this page
rev 6841 : mq
rev 6842 : mq
*** 24,42 ****
--- 24,48 ----
#include "precompiled.hpp"
#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"
#include "gc_interface/collectedHeap.inline.hpp"
#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"
#include "oops/instanceKlass.hpp"
#include "oops/instanceRefKlass.hpp"
*** 112,123 ****
--- 118,133 ----
PerfCounter* ClassLoader::_isUnsyncloadClass = NULL;
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);
size_t str_to_find_len = strlen(str_to_find);
if (str_to_find_len > str_len) {
*** 192,201 ****
--- 202,217 ----
return NULL;
}
// check if file exists
struct stat st;
if (os::stat(path, &st) == 0) {
+ #if INCLUDE_CDS
+ if (DumpSharedSpaces) {
+ ShouldNotReachHere();
+ ClassLoader::exit_with_path_failure("VM internal error. Classes can be loaded only from JAR files during dump time: %s", path);
+ }
+ #endif
// found file, open it
int file_handle = os::open(path, 0, 0);
if (file_handle != -1) {
// read contents into resource array
u1* buffer = NEW_RESOURCE_ARRAY(u1, st.st_size);
*** 226,264 ****
(*ZipClose)(_zip);
}
FREE_C_HEAP_ARRAY(char, _zip_name, mtClass);
}
! ClassFileStream* ClassPathZipEntry::open_stream(const char* name, 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);
if (entry == NULL) return NULL;
u1* buffer;
char name_buf[128];
char* filename;
if (name_len < 128) {
filename = name_buf;
} else {
filename = NEW_RESOURCE_ARRAY(char, name_len + 1);
}
! // file found, get pointer to class in mmaped jar file.
if (ReadMappedEntry == NULL ||
!(*ReadMappedEntry)(_zip, entry, &buffer, filename)) {
! // mmaped access not available, perhaps due to compression,
// read contents into resource array
! buffer = NEW_RESOURCE_ARRAY(u1, filesize);
if (!(*ReadEntry)(_zip, entry, buffer, filename)) return NULL;
}
if (UsePerfData) {
ClassLoader::perf_sys_classfile_bytes_read()->inc(filesize);
}
- // return result
return new ClassFileStream(buffer, filesize, _zip_name); // Resource allocated
}
// invoke function for each entry in the zip file
void ClassPathZipEntry::contents_do(void f(const char* name, void* context), void* context) {
--- 242,294 ----
(*ZipClose)(_zip);
}
FREE_C_HEAP_ARRAY(char, _zip_name, mtClass);
}
! 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 name_len;
! jzentry* entry = (*FindEntry)(_zip, name, filesize, &name_len);
if (entry == NULL) return NULL;
u1* buffer;
char name_buf[128];
char* filename;
if (name_len < 128) {
filename = name_buf;
} else {
filename = NEW_RESOURCE_ARRAY(char, name_len + 1);
}
! // file found, get pointer to the entry in mmapped jar file.
if (ReadMappedEntry == NULL ||
!(*ReadMappedEntry)(_zip, entry, &buffer, filename)) {
! // mmapped access not available, perhaps due to compression,
// read contents into resource array
! 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 new ClassFileStream(buffer, filesize, _zip_name); // Resource allocated
}
// invoke function for each entry in the zip file
void ClassPathZipEntry::contents_do(void f(const char* name, void* context), void* context) {
*** 270,285 ****
if (ze == NULL) break;
(*f)(ze->name, context);
}
}
! LazyClassPathEntry::LazyClassPathEntry(char* path, const struct stat* st) : ClassPathEntry() {
_path = strdup(path);
_st = *st;
_meta_index = NULL;
_resolved_entry = NULL;
_has_error = false;
}
bool LazyClassPathEntry::is_jar_file() {
return ((_st.st_mode & S_IFREG) == S_IFREG);
}
--- 300,316 ----
if (ze == NULL) break;
(*f)(ze->name, context);
}
}
! LazyClassPathEntry::LazyClassPathEntry(char* path, const struct stat* st, bool throw_exception) : ClassPathEntry() {
_path = strdup(path);
_st = *st;
_meta_index = NULL;
_resolved_entry = NULL;
_has_error = false;
+ _throw_exception = throw_exception;
}
bool LazyClassPathEntry::is_jar_file() {
return ((_st.st_mode & S_IFREG) == S_IFREG);
}
*** 287,297 ****
ClassPathEntry* LazyClassPathEntry::resolve_entry(TRAPS) {
if (_resolved_entry != NULL) {
return (ClassPathEntry*) _resolved_entry;
}
ClassPathEntry* new_entry = NULL;
! new_entry = ClassLoader::create_class_path_entry(_path, &_st, false, CHECK_NULL);
{
ThreadCritical tc;
if (_resolved_entry == NULL) {
_resolved_entry = new_entry;
return new_entry;
--- 318,332 ----
ClassPathEntry* LazyClassPathEntry::resolve_entry(TRAPS) {
if (_resolved_entry != NULL) {
return (ClassPathEntry*) _resolved_entry;
}
ClassPathEntry* new_entry = 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) {
_resolved_entry = new_entry;
return new_entry;
*** 321,349 ****
bool LazyClassPathEntry::is_lazy() {
return true;
}
static void print_meta_index(LazyClassPathEntry* entry,
GrowableArray<char*>& meta_packages) {
tty->print("[Meta index for %s=", entry->name());
for (int i = 0; i < meta_packages.length(); i++) {
if (i > 0) tty->print(" ");
tty->print("%s", meta_packages.at(i));
}
tty->print_cr("]");
}
! void ClassLoader::setup_meta_index() {
// Set up meta index which allows us to open boot jars lazily if
// class data sharing is enabled
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 (file != NULL) {
ResourceMark rm;
LazyClassPathEntry* cur_entry = NULL;
GrowableArray<char*> boot_class_path_packages(10);
char package_name[256];
--- 356,446 ----
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());
for (int i = 0; i < meta_packages.length(); i++) {
if (i > 0) tty->print(" ");
tty->print("%s", meta_packages.at(i));
}
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::trace_class_path(const char* msg, const char* name) {
+ if (TraceClassPaths) {
+ 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";
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;
GrowableArray<char*> boot_class_path_packages(10);
char package_name[256];
*** 374,396 ****
case '@':
{
// Hand off current packages to current lazy entry (if any)
if ((cur_entry != NULL) &&
(boot_class_path_packages.length() > 0)) {
! if (TraceClassLoading && Verbose) {
print_meta_index(cur_entry, boot_class_path_packages);
}
MetaIndex* index = new MetaIndex(boot_class_path_packages.adr_at(0),
boot_class_path_packages.length());
cur_entry->set_meta_index(index);
}
cur_entry = NULL;
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() &&
string_starts_with(entry->name(), meta_index_dir) &&
string_ends_with(entry->name(), &package_name[2])) {
cur_entry = (LazyClassPathEntry*) entry;
break;
}
--- 471,495 ----
case '@':
{
// Hand off current packages to current lazy entry (if any)
if ((cur_entry != NULL) &&
(boot_class_path_packages.length() > 0)) {
! if ((TraceClassLoading || TraceClassPaths) && Verbose) {
print_meta_index(cur_entry, boot_class_path_packages);
}
MetaIndex* index = new MetaIndex(boot_class_path_packages.adr_at(0),
boot_class_path_packages.length());
cur_entry->set_meta_index(index);
}
cur_entry = NULL;
boot_class_path_packages.clear();
// Find lazy entry corresponding to this jar file
! 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;
break;
}
*** 423,482 ****
}
}
// Hand off current packages to current lazy entry (if any)
if ((cur_entry != NULL) &&
(boot_class_path_packages.length() > 0)) {
! if (TraceClassLoading && Verbose) {
print_meta_index(cur_entry, boot_class_path_packages);
}
MetaIndex* index = new MetaIndex(boot_class_path_packages.adr_at(0),
boot_class_path_packages.length());
cur_entry->set_meta_index(index);
}
fclose(file);
}
}
void ClassLoader::setup_bootstrap_search_path() {
assert(_first_entry == NULL, "should not setup bootstrap class search path twice");
char* sys_class_path = os::strdup(Arguments::get_sysclasspath());
! if (TraceClassLoading && Verbose) {
! tty->print_cr("[Bootstrap loader class path=%s]", sys_class_path);
}
! int len = (int)strlen(sys_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]) {
end++;
}
! char* path = NEW_C_HEAP_ARRAY(char, end-start+1, mtClass);
! strncpy(path, &sys_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]) {
end++;
}
}
}
! ClassPathEntry* ClassLoader::create_class_path_entry(char *path, const struct stat* st, bool lazy, TRAPS) {
JavaThread* thread = JavaThread::current();
if (lazy) {
! return new LazyClassPathEntry(path, st);
}
ClassPathEntry* new_entry = NULL;
if ((st->st_mode & S_IFREG) == S_IFREG) {
// Regular file, should be a zip file
// Canonicalized filename
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);
}
char* error_msg = NULL;
jzfile* zip;
{
// enable call to C land
--- 522,636 ----
}
}
// Hand off current packages to current lazy entry (if any)
if ((cur_entry != NULL) &&
(boot_class_path_packages.length() > 0)) {
! if ((TraceClassLoading || TraceClassPaths) && Verbose) {
print_meta_index(cur_entry, boot_class_path_packages);
}
MetaIndex* index = new MetaIndex(boot_class_path_packages.adr_at(0),
boot_class_path_packages.length());
cur_entry->set_meta_index(index);
}
fclose(file);
}
}
+ #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("Cannot have non-empty directory 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(Arguments::get_sysclasspath());
! 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);
+ }
+
+ #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 (class_path[end] && class_path[end] != os::path_separator()[0]) {
end++;
}
! 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);
! #if INCLUDE_CDS
! if (DumpSharedSpaces) {
! check_shared_classpath(path);
! }
! #endif
! while (class_path[end] == os::path_separator()[0]) {
end++;
}
}
}
! 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, throw_exception);
}
ClassPathEntry* new_entry = NULL;
if ((st->st_mode & S_IFREG) == S_IFREG) {
// Regular file, should be a zip file
// Canonicalized filename
char canonical_path[JVM_MAXPATHLEN];
if (!get_canonical_path(path, canonical_path, JVM_MAXPATHLEN)) {
// This matches the classic VM
+ if (throw_exception) {
THROW_MSG_(vmSymbols::java_io_IOException(), "Bad pathname", NULL);
+ } else {
+ return NULL;
+ }
}
char* error_msg = NULL;
jzfile* zip;
{
// enable call to C land
*** 484,494 ****
HandleMark hm(thread);
zip = (*ZipOpen)(canonical_path, &error_msg);
}
if (zip != NULL && error_msg == NULL) {
new_entry = new ClassPathZipEntry(zip, path);
! if (TraceClassLoading) {
tty->print_cr("[Opened %s]", path);
}
} else {
ResourceMark rm(thread);
char *msg;
--- 638,648 ----
HandleMark hm(thread);
zip = (*ZipOpen)(canonical_path, &error_msg);
}
if (zip != NULL && error_msg == NULL) {
new_entry = new ClassPathZipEntry(zip, path);
! if (TraceClassLoading || TraceClassPaths) {
tty->print_cr("[Opened %s]", path);
}
} else {
ResourceMark rm(thread);
char *msg;
*** 498,513 ****
} else {
int len = (int)(strlen(path) + strlen(error_msg) + 128);
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);
}
} else {
// Directory
new_entry = new ClassPathDirEntry(path);
! if (TraceClassLoading) {
tty->print_cr("[Path %s]", path);
}
}
return new_entry;
}
--- 652,671 ----
} else {
int len = (int)(strlen(path) + strlen(error_msg) + 128);
msg = NEW_RESOURCE_ARRAY(char, len); ;
jio_snprintf(msg, len - 1, "error in opening JAR file <%s> %s", error_msg, path);
}
+ if (throw_exception) {
THROW_MSG_(vmSymbols::java_lang_ClassNotFoundException(), msg, NULL);
+ } else {
+ return NULL;
+ }
}
} else {
// Directory
new_entry = new ClassPathDirEntry(path);
! if (TraceClassLoading || TraceClassPaths) {
tty->print_cr("[Path %s]", path);
}
}
return new_entry;
}
*** 564,590 ****
} else {
_last_entry->set_next(new_entry);
_last_entry = new_entry;
}
}
}
! void ClassLoader::update_class_path_entry_list(char *path,
! bool check_for_duplicates) {
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);
// 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);
}
}
}
void ClassLoader::print_bootclasspath() {
ClassPathEntry* e = _first_entry;
--- 722,762 ----
} else {
_last_entry->set_next(new_entry);
_last_entry = new_entry;
}
}
+ _num_entries ++;
}
! // 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, 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)) {
! 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
}
}
void ClassLoader::print_bootclasspath() {
ClassPathEntry* e = _first_entry;
*** 732,790 ****
}
}
assert(n == number_of_entries(), "just checking");
}
! void copy_table(char** top, char* end, PackageHashtable* table);
};
!
void PackageHashtable::copy_table(char** top, char* end,
PackageHashtable* table) {
// Copy (relocate) the table to the shared space.
BasicHashtable<mtClass>::copy_table(top, 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);
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);
pp->set_pkgname((char*)memcpy(*top, pp->pkgname(), n1));
*top += n1;
}
}
*top = (char*)align_size_up((intptr_t)*top, sizeof(HeapWord));
}
void ClassLoader::copy_package_info_buckets(char** top, char* end) {
_package_hash_table->copy_buckets(top, end);
}
void ClassLoader::copy_package_info_table(char** top, char* end) {
_package_hash_table->copy_table(top, end, _package_hash_table);
}
!
PackageInfo* ClassLoader::lookup_package(const char *pkgname) {
const char *cp = strrchr(pkgname, '/');
if (cp != NULL) {
// Package prefix found
--- 904,959 ----
}
}
assert(n == number_of_entries(), "just checking");
}
! 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.
BasicHashtable<mtClass>::copy_table(top, end);
// Calculate the space needed for the package name strings.
int i;
! 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;
}
void ClassLoader::copy_package_info_buckets(char** top, char* end) {
_package_hash_table->copy_buckets(top, 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, '/');
if (cp != NULL) {
// Package prefix found
*** 873,928 ****
}
instanceKlassHandle ClassLoader::load_classfile(Symbol* h_name, TRAPS) {
ResourceMark rm(THREAD);
! EventMark m("loading class %s", h_name->as_C_string());
ThreadProfilerMark tpm(ThreadProfilerMark::classLoaderRegion);
stringStream st;
// st.print() uses too much stack space while handling a StackOverflowError
// st.print("%s.class", h_name->as_utf8());
st.print_raw(h_name->as_utf8());
st.print_raw(".class");
! char* name = st.as_string();
// Lookup stream for parsing .class file
ClassFileStream* stream = NULL;
int classpath_index = 0;
{
PerfClassTraceTime vmtimer(perf_sys_class_lookup_time(),
((JavaThread*) THREAD)->get_thread_stat()->perf_timers_addr(),
PerfClassTraceTime::CLASS_LOAD);
! ClassPathEntry* e = _first_entry;
while (e != NULL) {
! stream = e->open_stream(name, CHECK_NULL);
if (stream != NULL) {
break;
}
e = e->next();
++classpath_index;
}
}
- instanceKlassHandle h;
if (stream != NULL) {
-
// class file found, parse it
ClassFileParser parser(stream);
ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
Handle protection_domain;
TempNewSymbol parsed_name = NULL;
instanceKlassHandle result = parser.parseClassFile(h_name,
loader_data,
protection_domain,
parsed_name,
! false,
! CHECK_(h));
!
! // add to package table
! if (add_package(name, classpath_index, THREAD)) {
! h = result;
}
}
return h;
}
--- 1042,1109 ----
}
instanceKlassHandle ClassLoader::load_classfile(Symbol* h_name, TRAPS) {
ResourceMark rm(THREAD);
! const char* class_name = h_name->as_C_string();
! EventMark m("loading class %s", class_name);
ThreadProfilerMark tpm(ThreadProfilerMark::classLoaderRegion);
stringStream st;
// st.print() uses too much stack space while handling a StackOverflowError
// st.print("%s.class", h_name->as_utf8());
st.print_raw(h_name->as_utf8());
st.print_raw(".class");
! 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);
! e = _first_entry;
while (e != NULL) {
! stream = e->open_stream(file_name, CHECK_NULL);
! if (!context.check(stream, classpath_index)) {
! return h; // NULL
! }
if (stream != NULL) {
break;
}
e = e->next();
++classpath_index;
}
}
if (stream != NULL) {
// class file found, parse it
ClassFileParser parser(stream);
ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
Handle protection_domain;
TempNewSymbol parsed_name = NULL;
instanceKlassHandle result = parser.parseClassFile(h_name,
loader_data,
protection_domain,
parsed_name,
! 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);
}
}
return h;
}
*** 1013,1030 ****
}
}
// lookup zip library entry points
load_zip_library();
// initialize search path
setup_bootstrap_search_path();
if (LazyBootClassLoader) {
// set up meta index which makes boot classpath initialization lazier
! setup_meta_index();
}
}
jlong ClassLoader::classloader_time_ms() {
return UsePerfData ?
Management::ticks_to_ms(_perf_accumulated_time->get_value()) : -1;
}
--- 1194,1224 ----
}
}
// 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_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 ?
Management::ticks_to_ms(_perf_accumulated_time->get_value()) : -1;
}