< prev index next >

src/hotspot/share/oops/instanceKlass.cpp

Print this page
rev 58452 : imported patch pkg_name_from_class

@@ -80,10 +80,11 @@
 #include "services/threadService.hpp"
 #include "utilities/dtrace.hpp"
 #include "utilities/events.hpp"
 #include "utilities/macros.hpp"
 #include "utilities/stringUtils.hpp"
+#include "utilities/utf8.hpp"
 #ifdef COMPILER1
 #include "c1/c1_Compiler.hpp"
 #endif
 #if INCLUDE_JFR
 #include "jfr/jfrEvents.hpp"

@@ -2640,25 +2641,54 @@
   dest[dest_index] = '\0';
   return dest;
 }
 
 // Used to obtain the package name from a fully qualified class name.
-Symbol* InstanceKlass::package_from_name(const Symbol* name, TRAPS) {
+Symbol* InstanceKlass::package_from_name(const Symbol* name, bool* bad_class_name) {
   if (name == NULL) {
+    if (bad_class_name != NULL) {
+      *bad_class_name = true;
+    }
     return NULL;
-  } else {
-    if (name->utf8_length() <= 0) {
+  }
+
+  int utf_len = name->utf8_length();
+  if (utf_len == 0 ) {
       return NULL;
     }
-    ResourceMark rm(THREAD);
-    const char* package_name = ClassLoader::package_from_name((const char*) name->as_C_string());
-    if (package_name == NULL) {
+  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;
     }
-    Symbol* pkg_name = SymbolTable::new_symbol(package_name);
-    return pkg_name;
+  // Skip over '['s
+  if (*start == JVM_SIGNATURE_ARRAY) {
+    do {
+      start++;
+    } while (*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 (start != base && *start == JVM_SIGNATURE_CLASS) {
+      if (bad_class_name != NULL) {
+        *bad_class_name = true;
   }
+      return NULL;
+    }
+  }
+  if (start == end || end == base + utf_len) {
+    // A package or class name could have just the slash character in the name.
+    if (bad_class_name != NULL) {
+      *bad_class_name = true;
+    }
+    return NULL;
+  }
+  Symbol* pkg_name = SymbolTable::new_symbol(name, start - base, end - base);
+  return pkg_name;
 }
 
 ModuleEntry* InstanceKlass::module() const {
   // For an unsafe anonymous class return the host class' module
   if (is_unsafe_anonymous()) {

@@ -2678,11 +2708,11 @@
 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 = package_from_name(name());
 
   if (pkg_name != NULL && loader_data != NULL) {
 
     // Find in class loader's package entry table.
     _package_entry = loader_data->packages()->lookup_only(pkg_name);

@@ -2774,29 +2804,28 @@
 
   {
     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 = InstanceKlass::package_from_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");
+    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;
 
     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;
   }
 }
 
 // Returns true iff super_method can be overridden by a method in targetclassname
 // See JLS 3rd edition 8.4.6.1

@@ -2826,11 +2855,11 @@
       !loader_data->is_platform_class_loader_data() &&
       class_name != NULL) {
     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 = InstanceKlass::package_from_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();
       StringUtils::replace_no_expand(name, "/", ".");
       const char* msg_text1 = "Class loader (instance of): ";
< prev index next >