1931 Klass* target_klass = vfst.method()->constants()->klass_at( |
1932 Klass* target_klass = vfst.method()->constants()->klass_at( |
1932 cc.index(), thread); |
1933 cc.index(), thread); |
1933 return generate_class_cast_message(caster_klass, target_klass); |
1934 return generate_class_cast_message(caster_klass, target_klass); |
1934 } |
1935 } |
1935 |
1936 |
|
1937 // The caller of class_loader_and_module_name() (or one of its callers) |
|
1938 // must use a ResourceMark in order to correctly free the result. |
|
1939 const char* class_loader_and_module_name(Klass* klass) { |
|
1940 const char* delim = "/"; |
|
1941 size_t delim_len = strlen(delim); |
|
1942 |
|
1943 const char* fqn = klass->external_name(); |
|
1944 // Length of message to return; always include FQN |
|
1945 size_t msglen = strlen(fqn) + 1; |
|
1946 |
|
1947 bool has_cl_name = false; |
|
1948 bool has_mod_name = false; |
|
1949 bool has_version = false; |
|
1950 |
|
1951 // Use class loader name, if exists and not builtin |
|
1952 const char* class_loader_name = ""; |
|
1953 ClassLoaderData* cld = klass->class_loader_data(); |
|
1954 assert(cld != NULL, "class_loader_data should not be NULL"); |
|
1955 if (!cld->is_builtin_class_loader_data()) { |
|
1956 // If not builtin, look for name |
|
1957 oop loader = klass->class_loader(); |
|
1958 if (loader != NULL) { |
|
1959 oop class_loader_name_oop = java_lang_ClassLoader::name(loader); |
|
1960 if (class_loader_name_oop != NULL) { |
|
1961 class_loader_name = java_lang_String::as_utf8_string(class_loader_name_oop); |
|
1962 if (class_loader_name != NULL && class_loader_name[0] != '\0') { |
|
1963 has_cl_name = true; |
|
1964 msglen += strlen(class_loader_name) + delim_len; |
|
1965 } |
|
1966 } |
|
1967 } |
|
1968 } |
|
1969 |
|
1970 const char* module_name = ""; |
|
1971 const char* version = ""; |
|
1972 Klass* bottom_klass = klass->is_objArray_klass() ? |
|
1973 ObjArrayKlass::cast(klass)->bottom_klass() : klass; |
|
1974 if (bottom_klass->is_instance_klass()) { |
|
1975 ModuleEntry* module = InstanceKlass::cast(bottom_klass)->module(); |
|
1976 // Use module name, if exists |
|
1977 if (module->is_named()) { |
|
1978 has_mod_name = true; |
|
1979 module_name = module->name()->as_C_string(); |
|
1980 msglen += strlen(module_name); |
|
1981 // Use version if exists and is not a jdk module |
|
1982 if (module->is_non_jdk_module() && module->version() != NULL) { |
|
1983 has_version = true; |
|
1984 version = module->version()->as_C_string(); |
|
1985 msglen += strlen("@") + strlen(version); |
|
1986 } |
|
1987 } |
|
1988 } else { |
|
1989 // klass is an array of primitives, so its module is java.base |
|
1990 module_name = JAVA_BASE_NAME; |
|
1991 } |
|
1992 |
|
1993 if (has_cl_name || has_mod_name) { |
|
1994 msglen += delim_len; |
|
1995 } |
|
1996 |
|
1997 char* message = NEW_RESOURCE_ARRAY_RETURN_NULL(char, msglen); |
|
1998 |
|
1999 // Just return the FQN if error in allocating string |
|
2000 if (message == NULL) { |
|
2001 return fqn; |
|
2002 } |
|
2003 |
|
2004 jio_snprintf(message, msglen, "%s%s%s%s%s%s%s", |
|
2005 class_loader_name, |
|
2006 (has_cl_name) ? delim : "", |
|
2007 (has_mod_name) ? module_name : "", |
|
2008 (has_version) ? "@" : "", |
|
2009 (has_version) ? version : "", |
|
2010 (has_cl_name || has_mod_name) ? delim : "", |
|
2011 fqn); |
|
2012 return message; |
|
2013 } |
|
2014 |
1936 char* SharedRuntime::generate_class_cast_message( |
2015 char* SharedRuntime::generate_class_cast_message( |
1937 Klass* caster_klass, Klass* target_klass) { |
2016 Klass* caster_klass, Klass* target_klass) { |
1938 |
2017 |
1939 const char* caster_klass_name = caster_klass->external_name(); |
2018 const char* caster_name = class_loader_and_module_name(caster_klass); |
1940 Klass* c_klass = caster_klass->is_objArray_klass() ? |
2019 |
1941 ObjArrayKlass::cast(caster_klass)->bottom_klass() : caster_klass; |
2020 const char* target_name = class_loader_and_module_name(target_klass); |
1942 ModuleEntry* caster_module; |
2021 |
1943 const char* caster_module_name; |
2022 size_t msglen = strlen(caster_name) + strlen(" cannot be cast to ") + strlen(target_name) + 1; |
1944 if (c_klass->is_instance_klass()) { |
2023 |
1945 caster_module = InstanceKlass::cast(c_klass)->module(); |
2024 char* message = NEW_RESOURCE_ARRAY_RETURN_NULL(char, msglen); |
1946 caster_module_name = caster_module->is_named() ? |
2025 if (message == NULL) { |
1947 caster_module->name()->as_C_string() : UNNAMED_MODULE; |
2026 // Shouldn't happen, but don't cause even more problems if it does |
|
2027 message = const_cast<char*>(caster_klass->external_name()); |
1948 } else { |
2028 } else { |
1949 caster_module_name = "java.base"; |
2029 jio_snprintf(message, |
1950 } |
2030 msglen, |
1951 const char* target_klass_name = target_klass->external_name(); |
2031 "%s cannot be cast to %s", |
1952 Klass* t_klass = target_klass->is_objArray_klass() ? |
2032 caster_name, |
1953 ObjArrayKlass::cast(target_klass)->bottom_klass() : target_klass; |
2033 target_name); |
1954 ModuleEntry* target_module; |
|
1955 const char* target_module_name; |
|
1956 if (t_klass->is_instance_klass()) { |
|
1957 target_module = InstanceKlass::cast(t_klass)->module(); |
|
1958 target_module_name = target_module->is_named() ? |
|
1959 target_module->name()->as_C_string(): UNNAMED_MODULE; |
|
1960 } else { |
|
1961 target_module_name = "java.base"; |
|
1962 } |
|
1963 |
|
1964 size_t msglen = strlen(caster_klass_name) + strlen(caster_module_name) + |
|
1965 strlen(target_klass_name) + strlen(target_module_name) + 50; |
|
1966 |
|
1967 char* message = NEW_RESOURCE_ARRAY(char, msglen); |
|
1968 if (NULL == message) { |
|
1969 // Shouldn't happen, but don't cause even more problems if it does |
|
1970 message = const_cast<char*>(caster_klass_name); |
|
1971 } else { |
|
1972 jio_snprintf(message, msglen, "%s (in module: %s) cannot be cast to %s (in module: %s)", |
|
1973 caster_klass_name, caster_module_name, target_klass_name, target_module_name); |
|
1974 } |
2034 } |
1975 return message; |
2035 return message; |
1976 } |
2036 } |
1977 |
2037 |
1978 JRT_LEAF(void, SharedRuntime::reguard_yellow_pages()) |
2038 JRT_LEAF(void, SharedRuntime::reguard_yellow_pages()) |