< prev index next >
src/share/vm/runtime/sharedRuntime.cpp
Print this page
@@ -53,10 +53,11 @@
#include "runtime/biasedLocking.hpp"
#include "runtime/compilationPolicy.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/init.hpp"
#include "runtime/interfaceSupport.hpp"
+#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/vframe.hpp"
#include "runtime/vframeArray.hpp"
@@ -1931,48 +1932,106 @@
Klass* target_klass = vfst.method()->constants()->klass_at(
cc.index(), thread);
return generate_class_cast_message(caster_klass, target_klass);
}
-char* SharedRuntime::generate_class_cast_message(
- Klass* caster_klass, 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 = "/";
+ int 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();
+ if (cld == NULL || !cld->is_builtin_class_loader_data()) {
+ // If not builtin, look for internal name
+ oop loader = klass->class_loader();
+ if (loader != NULL) {
+ oopDesc* class_loader = java_lang_ClassLoader::name(loader);
+ if (class_loader != NULL && class_loader->klass() != NULL) {
+ class_loader_name = class_loader->klass()->internal_name();
+ if (class_loader_name != NULL && class_loader_name[0] != '\0') {
+ has_cl_name = true;
+ msglen += strlen(class_loader_name) + delim_len;
+ }
+ }
+ }
+ }
- const char* caster_klass_name = caster_klass->external_name();
- Klass* c_klass = caster_klass->is_objArray_klass() ?
- ObjArrayKlass::cast(caster_klass)->bottom_klass() : caster_klass;
- ModuleEntry* caster_module;
- const char* caster_module_name;
- if (c_klass->is_instance_klass()) {
- caster_module = InstanceKlass::cast(c_klass)->module();
- caster_module_name = caster_module->is_named() ?
- caster_module->name()->as_C_string() : UNNAMED_MODULE;
- } else {
- caster_module_name = "java.base";
- }
- const char* target_klass_name = target_klass->external_name();
- Klass* t_klass = target_klass->is_objArray_klass() ?
- ObjArrayKlass::cast(target_klass)->bottom_klass() : target_klass;
- ModuleEntry* target_module;
- const char* target_module_name;
- if (t_klass->is_instance_klass()) {
- target_module = InstanceKlass::cast(t_klass)->module();
- target_module_name = target_module->is_named() ?
- target_module->name()->as_C_string(): UNNAMED_MODULE;
+ 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 {
- target_module_name = "java.base";
+ // klass is an array of primitives, so its module is java.base
+ module_name = "java.base";
}
- size_t msglen = strlen(caster_klass_name) + strlen(caster_module_name) +
- strlen(target_klass_name) + strlen(target_module_name) + 50;
+ if (has_cl_name || has_mod_name) {
+ msglen += delim_len;
+ }
+
+ char* message = NEW_RESOURCE_ARRAY(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;
+}
+
+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);
+
+ size_t msglen = strlen(caster_name) + strlen(" cannot be cast to ") + strlen(target_name) + 1;
char* message = NEW_RESOURCE_ARRAY(char, msglen);
if (NULL == message) {
// Shouldn't happen, but don't cause even more problems if it does
- message = const_cast<char*>(caster_klass_name);
+ message = const_cast<char*>(caster_klass->external_name());
} else {
- jio_snprintf(message, msglen, "%s (in module: %s) cannot be cast to %s (in module: %s)",
- caster_klass_name, caster_module_name, target_klass_name, target_module_name);
+ jio_snprintf(message,
+ msglen,
+ "%s cannot be cast to %s",
+ caster_name,
+ target_name);
}
return message;
}
JRT_LEAF(void, SharedRuntime::reguard_yellow_pages())
< prev index next >