8241371: Refactor and consolidate package_from_name

Reviewed-by: iklam, lfoltan
This commit is contained in:
Claes Redestad 2020-03-23 23:18:42 +01:00
parent 7dc952ec20
commit 23d6a788b4
12 changed files with 145 additions and 180 deletions

@ -5877,16 +5877,16 @@ void ClassFileParser::prepend_host_package_name(const InstanceKlass* unsafe_anon
ResourceMark rm(THREAD);
assert(strrchr(_class_name->as_C_string(), JVM_SIGNATURE_SLASH) == NULL,
"Unsafe anonymous class should not be in a package");
const char* host_pkg_name =
ClassLoader::package_from_name(unsafe_anonymous_host->name()->as_C_string(), NULL);
TempNewSymbol host_pkg_name =
ClassLoader::package_from_class_name(unsafe_anonymous_host->name());
if (host_pkg_name != NULL) {
int host_pkg_len = (int)strlen(host_pkg_name);
int host_pkg_len = host_pkg_name->utf8_length();
int class_name_len = _class_name->utf8_length();
int symbol_len = host_pkg_len + 1 + class_name_len;
char* new_anon_name = NEW_RESOURCE_ARRAY(char, symbol_len + 1);
int n = os::snprintf(new_anon_name, symbol_len + 1, "%s/%.*s",
host_pkg_name, class_name_len, _class_name->base());
int n = os::snprintf(new_anon_name, symbol_len + 1, "%.*s/%.*s",
host_pkg_len, host_pkg_name->base(), class_name_len, _class_name->base());
assert(n == symbol_len, "Unexpected number of characters in string");
// Decrement old _class_name to avoid leaking.

@ -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;
}

@ -260,21 +260,21 @@ class ClassLoader: AllStatic {
bool is_boot_append,
bool from_class_path_attr, TRAPS);
// If the package for the fully qualified class name is in the boot
// loader's package entry table then add_package() sets the classpath_index
// field so that get_system_package() will know to return a non-null value
// for the package's location. And, so that the package will be added to
// the list of packages returned by get_system_packages().
// If the package for InstanceKlass is in the boot loader's package entry
// table then add_package() sets the classpath_index field so that
// get_system_package() will know to return a non-null value for the
// package's location. And, so that the package will be added to the list of
// packages returned by get_system_packages().
// For packages whose classes are loaded from the boot loader class path, the
// classpath_index indicates which entry on the boot loader class path.
static bool add_package(const char *fullq_class_name, s2 classpath_index, TRAPS);
static bool add_package(const InstanceKlass* ik, s2 classpath_index, TRAPS);
// Canonicalizes path names, so strcmp will work properly. This is mainly
// to avoid confusing the zip library
static bool get_canonical_path(const char* orig, char* out, int len);
static const char* file_name_for_class_name(const char* class_name,
int class_name_len);
static PackageEntry* get_package_entry(const char* class_name, ClassLoaderData* loader_data, TRAPS);
static PackageEntry* get_package_entry(Symbol* pkg_name, ClassLoaderData* loader_data, TRAPS);
public:
static int crc32(int crc, const char* buf, int len);
@ -440,10 +440,10 @@ class ClassLoader: AllStatic {
static bool string_ends_with(const char* str, const char* str_to_find);
// obtain package name from a fully qualified class name
// Extract package name from a fully qualified class name
// *bad_class_name is set to true if there's a problem with parsing class_name, to
// distinguish from a class_name with no package name, as both cases have a NULL return value
static const char* package_from_name(const char* const class_name, bool* bad_class_name = NULL);
static Symbol* package_from_class_name(const Symbol* class_name, bool* bad_class_name = NULL);
// Debugging
static void verify() PRODUCT_RETURN;

@ -94,8 +94,7 @@ InstanceKlass* KlassFactory::check_shared_class_file_load_hook(
}
if (class_loader.is_null()) {
ResourceMark rm;
ClassLoader::add_package(class_name->as_C_string(), path_index, THREAD);
ClassLoader::add_package(new_ik, path_index, THREAD);
}
return new_ik;

@ -1197,23 +1197,21 @@ bool SystemDictionary::is_shared_class_visible(Symbol* class_name,
return true;
}
// Get the pkg_entry from the classloader
TempNewSymbol pkg_name = NULL;
PackageEntry* pkg_entry = NULL;
ModuleEntry* mod_entry = NULL;
pkg_name = InstanceKlass::package_from_name(class_name, CHECK_false);
TempNewSymbol pkg_name = ClassLoader::package_from_class_name(class_name);
if (pkg_name != NULL) {
if (loader_data != NULL) {
pkg_entry = loader_data->packages()->lookup_only(pkg_name);
if (pkg_entry != NULL) {
mod_entry = pkg_entry->module();
// If the archived class is from a module that has been patched at runtime,
// the class cannot be loaded from the archive.
if (mod_entry != NULL && mod_entry->is_patched()) {
return false;
}
}
}
if (pkg_entry != NULL) {
mod_entry = pkg_entry->module();
}
}
// If the archived class is from a module that has been patched at runtime,
// the class cannot be loaded from the archive.
if (mod_entry != NULL && mod_entry->is_patched()) {
return false;
}
if (class_loader.is_null()) {
@ -1357,8 +1355,7 @@ void SystemDictionary::load_shared_class_misc(InstanceKlass* ik, ClassLoaderData
// package was loaded.
if (loader_data->is_the_null_class_loader_data()) {
int path_index = ik->shared_classpath_index();
ResourceMark rm(THREAD);
ClassLoader::add_package(ik->name()->as_C_string(), path_index, THREAD);
ClassLoader::add_package(ik, path_index, THREAD);
}
if (DumpLoadedClassList != NULL && classlist_file->is_open()) {
@ -1430,7 +1427,7 @@ InstanceKlass* SystemDictionary::load_instance_class(Symbol* class_name, Handle
ClassLoaderData *loader_data = class_loader_data(class_loader);
// Find the package in the boot loader's package entry table.
TempNewSymbol pkg_name = InstanceKlass::package_from_name(class_name, CHECK_NULL);
TempNewSymbol pkg_name = ClassLoader::package_from_class_name(class_name);
if (pkg_name != NULL) {
pkg_entry = loader_data->packages()->lookup_only(pkg_name);
}

@ -443,9 +443,9 @@ Handle SystemDictionaryShared::get_shared_jar_url(int shared_path_index, TRAPS)
Handle SystemDictionaryShared::get_package_name(Symbol* class_name, TRAPS) {
ResourceMark rm(THREAD);
Handle pkgname_string;
char* pkgname = (char*) ClassLoader::package_from_name((const char*) class_name->as_C_string());
if (pkgname != NULL) { // Package prefix found
StringUtils::replace_no_expand(pkgname, "/", ".");
Symbol* pkg = ClassLoader::package_from_class_name(class_name);
if (pkg != NULL) { // Package prefix found
const char* pkgname = pkg->as_klass_external_name();
pkgname_string = java_lang_String::create_from_str(pkgname,
CHECK_(pkgname_string));
}
@ -602,7 +602,7 @@ Handle SystemDictionaryShared::init_security_info(Handle class_loader, InstanceK
ClassLoaderData *loader_data =
ClassLoaderData::class_loader_data(class_loader());
PackageEntryTable* pkgEntryTable = loader_data->packages();
TempNewSymbol pkg_name = InstanceKlass::package_from_name(class_name, CHECK_(pd));
TempNewSymbol pkg_name = ClassLoader::package_from_class_name(class_name);
if (pkg_name != NULL) {
PackageEntry* pkg_entry = pkgEntryTable->lookup_only(pkg_name);
if (pkg_entry != NULL) {

@ -2641,24 +2641,6 @@ const char* InstanceKlass::signature_name() const {
return dest;
}
// Used to obtain the package name from a fully qualified class name.
Symbol* InstanceKlass::package_from_name(const Symbol* name, TRAPS) {
if (name == NULL) {
return NULL;
} else {
if (name->utf8_length() <= 0) {
return NULL;
}
ResourceMark rm(THREAD);
const char* package_name = ClassLoader::package_from_name((const char*) name->as_C_string());
if (package_name == NULL) {
return NULL;
}
Symbol* pkg_name = SymbolTable::new_symbol(package_name);
return pkg_name;
}
}
ModuleEntry* InstanceKlass::module() const {
// For an unsafe anonymous class return the host class' module
if (is_unsafe_anonymous()) {
@ -2680,7 +2662,7 @@ void InstanceKlass::set_package(ClassLoaderData* loader_data, TRAPS) {
// ensure java/ packages only loaded by boot or platform builtin loaders
check_prohibited_package(name(), loader_data, CHECK);
TempNewSymbol pkg_name = package_from_name(name(), CHECK);
TempNewSymbol pkg_name = ClassLoader::package_from_class_name(name());
if (pkg_name != NULL && loader_data != NULL) {
@ -2776,13 +2758,12 @@ bool InstanceKlass::is_same_class_package(oop other_class_loader,
ResourceMark rm;
bool bad_class_name = false;
const char* other_pkg =
ClassLoader::package_from_name((const char*) other_class_name->as_C_string(), &bad_class_name);
TempNewSymbol other_pkg = ClassLoader::package_from_class_name(other_class_name, &bad_class_name);
if (bad_class_name) {
return false;
}
// Check that package_from_name() returns NULL, not "", if there is no package.
assert(other_pkg == NULL || strlen(other_pkg) > 0, "package name is empty string");
// Check that package_from_class_name() returns NULL, not "", if there is no package.
assert(other_pkg == NULL || other_pkg->utf8_length() > 0, "package name is empty string");
const Symbol* const this_package_name =
this->package() != NULL ? this->package()->name() : NULL;
@ -2790,11 +2771,11 @@ bool InstanceKlass::is_same_class_package(oop other_class_loader,
if (this_package_name == NULL || other_pkg == NULL) {
// One of the two doesn't have a package. Only return true if the other
// one also doesn't have a package.
return (const char*)this_package_name == other_pkg;
return this_package_name == other_pkg;
}
// Check if package is identical
return this_package_name->equals(other_pkg);
return this_package_name->fast_compare(other_pkg) == 0;
}
}
@ -2828,7 +2809,7 @@ void InstanceKlass::check_prohibited_package(Symbol* class_name,
ResourceMark rm(THREAD);
char* name = class_name->as_C_string();
if (strncmp(name, JAVAPKG, JAVAPKG_LEN) == 0 && name[JAVAPKG_LEN] == '/') {
TempNewSymbol pkg_name = InstanceKlass::package_from_name(class_name, CHECK);
TempNewSymbol pkg_name = ClassLoader::package_from_class_name(class_name);
assert(pkg_name != NULL, "Error in parsing package name starting with 'java/'");
name = pkg_name->as_C_string();
const char* class_loader_name = loader_data->loader_name_and_id();

@ -1209,7 +1209,6 @@ public:
// Naming
const char* signature_name() const;
static Symbol* package_from_name(const Symbol* name, TRAPS);
// Oop fields (and metadata) iterators
//

@ -306,16 +306,6 @@ const char* UTF8::from_quoted_ascii(const char* quoted_ascii_str) {
}
#endif // !PRODUCT
// Returns NULL if 'c' it not found. This only works as long
// as 'c' is an ASCII character
const jbyte* UTF8::strrchr(const jbyte* base, int length, jbyte c) {
assert(length >= 0, "sanity check");
assert(c >= 0, "does not work for non-ASCII characters");
// Skip backwards in string until 'c' is found or end is reached
while(--length >= 0 && base[length] != c);
return (length < 0) ? NULL : &base[length];
}
bool UTF8::equal(const jbyte* base1, int length1, const jbyte* base2, int length2) {
// Length must be the same
if (length1 != length2) return false;

@ -70,7 +70,16 @@ class UTF8 : AllStatic {
static char* next_character(const char* str, jint* value);
// Utility methods
static const jbyte* strrchr(const jbyte* base, int length, jbyte c);
// Returns NULL if 'c' it not found. This only works as long
// as 'c' is an ASCII character
static const jbyte* strrchr(const jbyte* base, int length, jbyte c) {
assert(length >= 0, "sanity check");
assert(c >= 0, "does not work for non-ASCII characters");
// Skip backwards in string until 'c' is found or end is reached
while(--length >= 0 && base[length] != c);
return (length < 0) ? NULL : &base[length];
}
static bool equal(const jbyte* base1, int length1, const jbyte* base2,int length2);
static bool is_supplementary_character(const unsigned char* str);
static jint get_supplementary_character(const unsigned char* str);

@ -22,19 +22,11 @@
*/
#include "precompiled.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "memory/resourceArea.hpp"
#include "oops/instanceKlass.hpp"
#include "unittest.hpp"
// Tests InstanceKlass::package_from_name()
TEST_VM(InstanceKlass, null_symbol) {
ResourceMark rm;
TempNewSymbol package_sym = InstanceKlass::package_from_name(NULL, NULL);
ASSERT_TRUE(package_sym == NULL) << "Wrong package for NULL symbol";
}
// Tests for InstanceKlass::is_class_loader_instance_klass() function
TEST_VM(InstanceKlass, class_loader_class) {
InstanceKlass* klass = SystemDictionary::ClassLoader_klass();

@ -23,70 +23,85 @@
#include "precompiled.hpp"
#include "classfile/classLoader.hpp"
#include "classfile/symbolTable.hpp"
#include "memory/resourceArea.hpp"
#include "unittest.hpp"
// Tests ClassLoader::package_from_name()
TEST_VM(classLoader, null_class_name) {
ResourceMark rm;
// Tests ClassLoader::package_from_class_name()
TEST_VM(ClassLoader, null_class_name) {
bool bad_class_name = false;
const char* retval= ClassLoader::package_from_name(NULL, &bad_class_name);
TempNewSymbol retval = ClassLoader::package_from_class_name(NULL, &bad_class_name);
ASSERT_TRUE(bad_class_name) << "Function did not set bad_class_name with NULL class name";
ASSERT_STREQ(retval, NULL) << "Wrong package for NULL class name pointer";
ASSERT_TRUE(retval == NULL) << "Wrong package for NULL class name pointer";
}
TEST_VM(classLoader, empty_class_name) {
ResourceMark rm;
const char* retval = ClassLoader::package_from_name("");
ASSERT_STREQ(retval, NULL) << "Wrong package for empty string";
}
TEST_VM(classLoader, no_slash) {
ResourceMark rm;
const char* retval = ClassLoader::package_from_name("L");
ASSERT_STREQ(retval, NULL) << "Wrong package for class with no slashes";
}
TEST_VM(classLoader, just_slash) {
ResourceMark rm;
TEST_VM(ClassLoader, empty_class_name) {
bool bad_class_name = false;
const char* retval = ClassLoader::package_from_name("/", &bad_class_name);
TempNewSymbol name = SymbolTable::new_symbol("");
TempNewSymbol retval = ClassLoader::package_from_class_name(name, &bad_class_name);
ASSERT_TRUE(retval == NULL) << "Wrong package for empty string";
}
TEST_VM(ClassLoader, no_slash) {
bool bad_class_name = false;
TempNewSymbol name = SymbolTable::new_symbol("L");
TempNewSymbol retval = ClassLoader::package_from_class_name(name, &bad_class_name);
ASSERT_FALSE(bad_class_name) << "Function set bad_class_name with empty package";
ASSERT_TRUE(retval == NULL) << "Wrong package for class with no slashes";
}
TEST_VM(ClassLoader, just_slash) {
bool bad_class_name = false;
TempNewSymbol name = SymbolTable::new_symbol("/");
TempNewSymbol retval = ClassLoader::package_from_class_name(name, &bad_class_name);
ASSERT_TRUE(bad_class_name) << "Function did not set bad_class_name with package of length 0";
ASSERT_STREQ(retval, NULL) << "Wrong package for class with just slash";
ASSERT_TRUE(retval == NULL) << "Wrong package for class with just slash";
}
TEST_VM(classLoader, multiple_slashes) {
ResourceMark rm;
const char* retval = ClassLoader::package_from_name("///");
ASSERT_STREQ(retval, "//") << "Wrong package for class with just slashes";
}
TEST_VM(classLoader, standard_case_1) {
ResourceMark rm;
bool bad_class_name = true;
const char* retval = ClassLoader::package_from_name("package/class", &bad_class_name);
ASSERT_FALSE(bad_class_name) << "Function did not reset bad_class_name";
ASSERT_STREQ(retval, "package") << "Wrong package for class with one slash";
}
TEST_VM(classLoader, standard_case_2) {
ResourceMark rm;
const char* retval = ClassLoader::package_from_name("package/folder/class");
ASSERT_STREQ(retval, "package/folder") << "Wrong package for class with multiple slashes";
}
TEST_VM(classLoader, class_array) {
ResourceMark rm;
TEST_VM(ClassLoader, multiple_slashes) {
bool bad_class_name = false;
const char* retval = ClassLoader::package_from_name("[package/class", &bad_class_name);
TempNewSymbol name = SymbolTable::new_symbol("///");
TempNewSymbol retval = ClassLoader::package_from_class_name(name, &bad_class_name);
ASSERT_FALSE(bad_class_name) << "Function set bad_class_name with slashes package";
ASSERT_TRUE(retval->equals("//")) << "Wrong package for class with just slashes";
}
TEST_VM(ClassLoader, standard_case_1) {
bool bad_class_name = false;
TempNewSymbol name = SymbolTable::new_symbol("package/class");
TempNewSymbol retval = ClassLoader::package_from_class_name(name, &bad_class_name);
ASSERT_FALSE(bad_class_name) << "Function set bad_class_name for valid package";
ASSERT_TRUE(retval->equals("package")) << "Wrong package for class with one slash";
}
TEST_VM(ClassLoader, standard_case_2) {
bool bad_class_name = false;
TempNewSymbol name = SymbolTable::new_symbol("package/folder/class");
TempNewSymbol retval = ClassLoader::package_from_class_name(name, &bad_class_name);
ASSERT_FALSE(bad_class_name) << "Function set bad_class_name for valid package";
ASSERT_TRUE(retval->equals("package/folder")) << "Wrong package for class with multiple slashes";
}
TEST_VM(ClassLoader, class_array) {
bool bad_class_name = false;
TempNewSymbol name = SymbolTable::new_symbol("[package/class");
TempNewSymbol retval = ClassLoader::package_from_class_name(name, &bad_class_name);
ASSERT_FALSE(bad_class_name) << "Function set bad_class_name with class array";
ASSERT_STREQ(retval, "package") << "Wrong package for class with leading bracket";
ASSERT_TRUE(retval->equals("package")) << "Wrong package for class with leading bracket";
}
TEST_VM(classLoader, class_object_array) {
ResourceMark rm;
TEST_VM(ClassLoader, class_multiarray) {
bool bad_class_name = false;
const char* retval = ClassLoader::package_from_name("[Lpackage/class", &bad_class_name);
ASSERT_TRUE(bad_class_name) << "Function did not set bad_class_name with array of class objects";
ASSERT_STREQ(retval, NULL) << "Wrong package for class with leading '[L'";
TempNewSymbol name = SymbolTable::new_symbol("[[package/class");
TempNewSymbol retval = ClassLoader::package_from_class_name(name, &bad_class_name);
ASSERT_FALSE(bad_class_name) << "Function set bad_class_name with class array";
ASSERT_TRUE(retval->equals("package")) << "Wrong package for class with leading bracket";
}
TEST_VM(ClassLoader, class_object_array) {
bool bad_class_name = false;
TempNewSymbol name = SymbolTable::new_symbol("[Lpackage/class");
TempNewSymbol retval = ClassLoader::package_from_class_name(name, &bad_class_name);
ASSERT_TRUE(bad_class_name) << "Function did not set bad_class_name with array of class objects";
ASSERT_TRUE(retval == NULL) << "Wrong package for class with leading '[L'";
}