src/hotspot/share/runtime/sharedRuntime.cpp
changeset 49056 91ada5977172
parent 48961 120b61d50f85
child 49340 4e82736053ae
--- a/src/hotspot/share/runtime/sharedRuntime.cpp	Fri Feb 23 12:47:36 2018 +0100
+++ b/src/hotspot/share/runtime/sharedRuntime.cpp	Fri Feb 23 07:47:29 2018 -0500
@@ -1922,95 +1922,27 @@
   vframeStream vfst(thread, true);
   assert(!vfst.at_end(), "Java frame must exist");
   Bytecode_checkcast cc(vfst.method(), vfst.method()->bcp_from(vfst.bci()));
-  Klass* target_klass = vfst.method()->constants()->klass_at(
-    cc.index(), thread);
-  return generate_class_cast_message(caster_klass, target_klass);
-}
-
-// The caller of class_loader_and_module_name() (or one of its callers)
-// must use a ResourceMark in order to correctly free the result.
-const char* class_loader_and_module_name(Klass* klass) {
-  const char* delim = "/";
-  size_t delim_len = strlen(delim);
-
-  const char* fqn = klass->external_name();
-  // Length of message to return; always include FQN
-  size_t msglen = strlen(fqn) + 1;
-
-  bool has_cl_name = false;
-  bool has_mod_name = false;
-  bool has_version = false;
-
-  // Use class loader name, if exists and not builtin
-  const char* class_loader_name = "";
-  ClassLoaderData* cld = klass->class_loader_data();
-  assert(cld != NULL, "class_loader_data should not be NULL");
-  if (!cld->is_builtin_class_loader_data()) {
-    // If not builtin, look for name
-    oop loader = klass->class_loader();
-    if (loader != NULL) {
-      oop class_loader_name_oop = java_lang_ClassLoader::name(loader);
-      if (class_loader_name_oop != NULL) {
-        class_loader_name = java_lang_String::as_utf8_string(class_loader_name_oop);
-        if (class_loader_name != NULL && class_loader_name[0] != '\0') {
-          has_cl_name = true;
-          msglen += strlen(class_loader_name) + delim_len;
-        }
-      }
-    }
+  constantPoolHandle cpool(thread, vfst.method()->constants());
+  Klass* target_klass = ConstantPool::klass_at_if_loaded(cpool, cc.index());
+  Symbol* target_klass_name = NULL;
+  if (target_klass == NULL) {
+    // This klass should be resolved, but just in case, get the name in the klass slot.
+    target_klass_name = cpool->klass_name_at(cc.index());
   }
-
-  const char* module_name = "";
-  const char* version = "";
-  Klass* bottom_klass = klass->is_objArray_klass() ?
-    ObjArrayKlass::cast(klass)->bottom_klass() : klass;
-  if (bottom_klass->is_instance_klass()) {
-    ModuleEntry* module = InstanceKlass::cast(bottom_klass)->module();
-    // Use module name, if exists
-    if (module->is_named()) {
-      has_mod_name = true;
-      module_name = module->name()->as_C_string();
-      msglen += strlen(module_name);
-      // Use version if exists and is not a jdk module
-      if (module->is_non_jdk_module() && module->version() != NULL) {
-        has_version = true;
-        version = module->version()->as_C_string();
-        msglen += strlen("@") + strlen(version);
-      }
-    }
-  } else {
-    // klass is an array of primitives, so its module is java.base
-    module_name = JAVA_BASE_NAME;
-  }
-
-  if (has_cl_name || has_mod_name) {
-    msglen += delim_len;
-  }
-
-  char* message = NEW_RESOURCE_ARRAY_RETURN_NULL(char, msglen);
-
-  // Just return the FQN if error in allocating string
-  if (message == NULL) {
-    return fqn;
-  }
-
-  jio_snprintf(message, msglen, "%s%s%s%s%s%s%s",
-               class_loader_name,
-               (has_cl_name) ? delim : "",
-               (has_mod_name) ? module_name : "",
-               (has_version) ? "@" : "",
-               (has_version) ? version : "",
-               (has_cl_name || has_mod_name) ? delim : "",
-               fqn);
-  return message;
+  return generate_class_cast_message(caster_klass, target_klass, target_klass_name);
 }
 
+
+// The caller of generate_class_cast_message() (or one of its callers)
+// must use a ResourceMark in order to correctly free the result.
 char* SharedRuntime::generate_class_cast_message(
-    Klass* caster_klass, Klass* target_klass) {
-
-  const char* caster_name = class_loader_and_module_name(caster_klass);
-
-  const char* target_name = class_loader_and_module_name(target_klass);
+    Klass* caster_klass, Klass* target_klass, Symbol* target_klass_name) {
+
+  const char* caster_name = caster_klass->class_loader_and_module_name();
+
+  assert(target_klass != NULL || target_klass_name != NULL, "one must be provided");
+  const char* target_name = target_klass == NULL ? target_klass_name->as_C_string() :
+                                                   target_klass->class_loader_and_module_name();
 
   size_t msglen = strlen(caster_name) + strlen(" cannot be cast to ") + strlen(target_name) + 1;