|
@@ -72,6 +72,7 @@ |
|
|
#include "utilities/events.hpp" |
|
|
#include "utilities/hashtable.inline.hpp" |
|
|
#include "utilities/macros.hpp" |
|
|
#include "utilities/utf8.hpp" |
|
|
|
|
|
// Entry point in java.dll for path canonicalization |
|
|
|
|
@@ -177,75 +178,58 @@ bool ClassLoader::string_ends_with(const char* str, const char* str_to_find) { |
|
|
} |
|
|
|
|
|
// Used to obtain the package name from a fully qualified class name. |
|
|
// It is the responsibility of the caller to establish a ResourceMark. |
|
|
const char* ClassLoader::package_from_name(const char* const class_name, bool* bad_class_name) { |
|
|
if (class_name == NULL) { |
|
|
Symbol* ClassLoader::package_from_class_name(const Symbol* name, bool* bad_class_name) { |
|
|
if (name == NULL) { |
|
|
if (bad_class_name != NULL) { |
|
|
*bad_class_name = true; |
|
|
} |
|
|
return NULL; |
|
|
} |
|
|
|
|
|
if (bad_class_name != NULL) { |
|
|
*bad_class_name = false; |
|
|
} |
|
|
|
|
|
const char* const last_slash = strrchr(class_name, JVM_SIGNATURE_SLASH); |
|
|
if (last_slash == NULL) { |
|
|
// No package name |
|
|
int utf_len = name->utf8_length(); |
|
|
const jbyte* base = (const jbyte*)name->base(); |
|
|
const jbyte* start = base; |
|
|
const jbyte* end = UTF8::strrchr(start, utf_len, JVM_SIGNATURE_SLASH); |
|
|
if (end == NULL) { |
|
|
return NULL; |
|
|
} |
|
|
|
|
|
char* class_name_ptr = (char*) class_name; |
|
|
// Skip over '['s |
|
|
if (*class_name_ptr == JVM_SIGNATURE_ARRAY) { |
|
|
if (*start == JVM_SIGNATURE_ARRAY) { |
|
|
do { |
|
|
class_name_ptr++; |
|
|
} while (*class_name_ptr == JVM_SIGNATURE_ARRAY); |
|
|
start++; |
|
|
} while (start < end && *start == JVM_SIGNATURE_ARRAY); |
|
|
|
|
|
// Fully qualified class names should not contain a 'L'. |
|
|
// Set bad_class_name to true to indicate that the package name |
|
|
// could not be obtained due to an error condition. |
|
|
// In this situation, is_same_class_package returns false. |
|
|
if (*class_name_ptr == JVM_SIGNATURE_CLASS) { |
|
|
if (*start == JVM_SIGNATURE_CLASS) { |
|
|
if (bad_class_name != NULL) { |
|
|
*bad_class_name = true; |
|
|
} |
|
|
return NULL; |
|
|
} |
|
|
} |
|
|
|
|
|
int length = last_slash - class_name_ptr; |
|
|
|
|
|
// A class name could have just the slash character in the name. |
|
|
if (length <= 0) { |
|
|
// A class name could have just the slash character in the name, |
|
|
// in which case start > end |
|
|
if (start >= end) { |
|
|
// No package name |
|
|
if (bad_class_name != NULL) { |
|
|
*bad_class_name = true; |
|
|
} |
|
|
return NULL; |
|
|
} |
|
|
|
|
|
// drop name after last slash (including slash) |
|
|
// Ex., "java/lang/String.class" => "java/lang" |
|
|
char* pkg_name = NEW_RESOURCE_ARRAY(char, length + 1); |
|
|
strncpy(pkg_name, class_name_ptr, length); |
|
|
*(pkg_name+length) = '\0'; |
|
|
|
|
|
return (const char *)pkg_name; |
|
|
return SymbolTable::new_symbol(name, start - base, end - base); |
|
|
} |
|
|
|
|
|
// Given a fully qualified class name, find its defining package in the class loader's |
|
|
// package entry table. |
|
|
PackageEntry* ClassLoader::get_package_entry(const char* class_name, ClassLoaderData* loader_data, TRAPS) { |
|
|
ResourceMark rm(THREAD); |
|
|
const char *pkg_name = ClassLoader::package_from_name(class_name); |
|
|
PackageEntry* ClassLoader::get_package_entry(Symbol* pkg_name, ClassLoaderData* loader_data, TRAPS) { |
|
|
if (pkg_name == NULL) { |
|
|
return NULL; |
|
|
} |
|
|
PackageEntryTable* pkgEntryTable = loader_data->packages(); |
|
|
TempNewSymbol pkg_symbol = SymbolTable::new_symbol(pkg_name); |
|
|
return pkgEntryTable->lookup_only(pkg_symbol); |
|
|
return pkgEntryTable->lookup_only(pkg_name); |
|
|
} |
|
|
|
|
|
const char* ClassPathEntry::copy_path(const char* path) { |
|
@@ -407,14 +391,14 @@ ClassFileStream* ClassPathImageEntry::open_stream_for_loader(const char* name, C |
|
|
JImageLocationRef location = (*JImageFindResource)(_jimage, "", get_jimage_version_string(), name, &size); |
|
|
|
|
|
if (location == 0) { |
|
|
ResourceMark rm; |
|
|
const char* pkg_name = ClassLoader::package_from_name(name); |
|
|
TempNewSymbol class_name = SymbolTable::new_symbol(name); |
|
|
TempNewSymbol pkg_name = ClassLoader::package_from_class_name(class_name); |
|
|
|
|
|
if (pkg_name != NULL) { |
|
|
if (!Universe::is_module_initialized()) { |
|
|
location = (*JImageFindResource)(_jimage, JAVA_BASE_NAME, get_jimage_version_string(), name, &size); |
|
|
} else { |
|
|
PackageEntry* package_entry = ClassLoader::get_package_entry(name, loader_data, CHECK_NULL); |
|
|
PackageEntry* package_entry = ClassLoader::get_package_entry(pkg_name, loader_data, CHECK_NULL); |
|
|
if (package_entry != NULL) { |
|
|
ResourceMark rm; |
|
|
// Get the module name |
|
@@ -1029,25 +1013,22 @@ int ClassLoader::crc32(int crc, const char* buf, int len) { |
|
|
return (*Crc32)(crc, (const jbyte*)buf, len); |
|
|
} |
|
|
|
|
|
// Function add_package extracts the package from the fully qualified class name |
|
|
// and checks if the package is in the boot loader's package entry table. If so, |
|
|
// then it sets the classpath_index in the package entry record. |
|
|
// Function add_package checks if the package of the InstanceKlass is in the |
|
|
// boot loader's package entry table. If so, then it sets the classpath_index |
|
|
// in the package entry record. |
|
|
// |
|
|
// The classpath_index field is used to find the entry on the boot loader class |
|
|
// path for packages with classes loaded by the boot loader from -Xbootclasspath/a |
|
|
// in an unnamed module. It is also used to indicate (for all packages whose |
|
|
// classes are loaded by the boot loader) that at least one of the package's |
|
|
// classes has been loaded. |
|
|
bool ClassLoader::add_package(const char *fullq_class_name, s2 classpath_index, TRAPS) { |
|
|
assert(fullq_class_name != NULL, "just checking"); |
|
|
bool ClassLoader::add_package(const InstanceKlass* ik, s2 classpath_index, TRAPS) { |
|
|
assert(ik != NULL, "just checking"); |
|
|
|
|
|
// Get package name from fully qualified class name. |
|
|
ResourceMark rm(THREAD); |
|
|
const char *cp = package_from_name(fullq_class_name); |
|
|
if (cp != NULL) { |
|
|
PackageEntry* ik_pkg = ik->package(); |
|
|
if (ik_pkg != NULL) { |
|
|
PackageEntryTable* pkg_entry_tbl = ClassLoaderData::the_null_class_loader_data()->packages(); |
|
|
TempNewSymbol pkg_symbol = SymbolTable::new_symbol(cp); |
|
|
PackageEntry* pkg_entry = pkg_entry_tbl->lookup_only(pkg_symbol); |
|
|
PackageEntry* pkg_entry = pkg_entry_tbl->lookup_only(ik_pkg->name()); |
|
|
if (pkg_entry != NULL) { |
|
|
assert(classpath_index != -1, "Unexpected classpath_index"); |
|
|
pkg_entry->set_classpath_index(classpath_index); |
|
@@ -1166,7 +1147,9 @@ ClassFileStream* ClassLoader::search_module_entries(const GrowableArray<ModuleCl |
|
|
ClassFileStream* stream = NULL; |
|
|
|
|
|
// Find the class' defining module in the boot loader's module entry table |
|
|
PackageEntry* pkg_entry = get_package_entry(class_name, ClassLoaderData::the_null_class_loader_data(), CHECK_NULL); |
|
|
TempNewSymbol class_name_symbol = SymbolTable::new_symbol(class_name); |
|
|
TempNewSymbol pkg_name = package_from_class_name(class_name_symbol); |
|
|
PackageEntry* pkg_entry = get_package_entry(pkg_name, ClassLoaderData::the_null_class_loader_data(), CHECK_NULL); |
|
|
ModuleEntry* mod_entry = (pkg_entry != NULL) ? pkg_entry->module() : NULL; |
|
|
|
|
|
// If the module system has not defined java.base yet, then |
|
@@ -1317,7 +1300,7 @@ InstanceKlass* ClassLoader::load_class(Symbol* name, bool search_append_only, TR |
|
|
return NULL; |
|
|
} |
|
|
|
|
|
if (!add_package(file_name, classpath_index, THREAD)) { |
|
|
if (!add_package(result, classpath_index, THREAD)) { |
|
|
return NULL; |
|
|
} |
|
|
|
|
|