8144940: Broken hash in string table entry in closed/runtime/7158800/BadUtf8.java

Fix code broken with compact Strings.

Reviewed-by: iklam, thartmann, hseigel, jiangli
This commit is contained in:
Coleen Phillimore 2016-03-22 13:32:18 -04:00
parent d444e55969
commit ff04be3cf5
4 changed files with 22 additions and 29 deletions

View File

@ -513,21 +513,6 @@ char* java_lang_String::as_quoted_ascii(oop java_string) {
return result; return result;
} }
unsigned int java_lang_String::hash_string(oop java_string) {
int length = java_lang_String::length(java_string);
// Zero length string doesn't necessarily hash to zero.
if (length == 0) {
return StringTable::hash_string((jchar*) NULL, 0);
}
typeArrayOop value = java_lang_String::value(java_string);
bool is_latin1 = java_lang_String::is_latin1(java_string);
if (is_latin1) {
return StringTable::hash_string(value->byte_at_addr(0), length);
} else {
return StringTable::hash_string(value->char_at_addr(0), length);
}
}
Symbol* java_lang_String::as_symbol(Handle java_string, TRAPS) { Symbol* java_lang_String::as_symbol(Handle java_string, TRAPS) {
oop obj = java_string(); oop obj = java_string();

View File

@ -155,11 +155,6 @@ class java_lang_String : AllStatic {
} }
static unsigned int hash_code(oop java_string); static unsigned int hash_code(oop java_string);
static unsigned int latin1_hash_code(typeArrayOop value, int len);
// This is the string hash code used by the StringTable, which may be
// the same as String.hashCode or an alternate hash code.
static unsigned int hash_string(oop java_string);
static bool equals(oop java_string, jchar* chars, int len); static bool equals(oop java_string, jchar* chars, int len);
static bool equals(oop str1, oop str2); static bool equals(oop str1, oop str2);

View File

@ -94,15 +94,27 @@ volatile int StringTable::_parallel_claimed_idx = 0;
CompactHashtable<oop, char> StringTable::_shared_table; CompactHashtable<oop, char> StringTable::_shared_table;
// Pick hashing algorithm // Pick hashing algorithm
template<typename T> unsigned int StringTable::hash_string(const jchar* s, int len) {
unsigned int StringTable::hash_string(const T* s, int len) {
return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) : return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) :
java_lang_String::hash_code(s, len); java_lang_String::hash_code(s, len);
} }
// Explicit instantiation for all supported types. unsigned int StringTable::hash_string(oop string) {
template unsigned int StringTable::hash_string<jchar>(const jchar* s, int len); EXCEPTION_MARK;
template unsigned int StringTable::hash_string<jbyte>(const jbyte* s, int len); if (string == NULL) {
return hash_string((jchar*)NULL, 0);
}
ResourceMark rm(THREAD);
// All String oops are hashed as unicode
int length;
jchar* chars = java_lang_String::as_unicode_string(string, length, THREAD);
if (chars != NULL) {
return hash_string(chars, length);
} else {
vm_exit_out_of_memory(length, OOM_MALLOC_ERROR, "unable to create Unicode string for verification");
return 0;
}
}
oop StringTable::lookup_shared(jchar* name, int len) { oop StringTable::lookup_shared(jchar* name, int len) {
// java_lang_String::hash_code() was used to compute hash values in the shared table. Don't // java_lang_String::hash_code() was used to compute hash values in the shared table. Don't
@ -398,7 +410,7 @@ void StringTable::verify() {
for ( ; p != NULL; p = p->next()) { for ( ; p != NULL; p = p->next()) {
oop s = p->literal(); oop s = p->literal();
guarantee(s != NULL, "interned string is NULL"); guarantee(s != NULL, "interned string is NULL");
unsigned int h = java_lang_String::hash_string(s); unsigned int h = hash_string(s);
guarantee(p->hash() == h, "broken hash in string table entry"); guarantee(p->hash() == h, "broken hash in string table entry");
guarantee(the_table()->hash_to_index(h) == i, guarantee(the_table()->hash_to_index(h) == i,
"wrong index in string table"); "wrong index in string table");
@ -498,7 +510,7 @@ StringTable::VerifyRetTypes StringTable::verify_entry(int bkt, int e_cnt,
return _verify_fail_done; return _verify_fail_done;
} }
unsigned int h = java_lang_String::hash_string(str); unsigned int h = hash_string(str);
if (e_ptr->hash() != h) { if (e_ptr->hash() != h) {
if (mesg_mode == _verify_with_mesgs) { if (mesg_mode == _verify_with_mesgs) {
tty->print_cr("ERROR: broken hash value in entry @ bucket[%d][%d], " tty->print_cr("ERROR: broken hash value in entry @ bucket[%d][%d], "

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -111,7 +111,8 @@ public:
// Hashing algorithm, used as the hash value used by the // Hashing algorithm, used as the hash value used by the
// StringTable for bucket selection and comparison (stored in the // StringTable for bucket selection and comparison (stored in the
// HashtableEntry structures). This is used in the String.intern() method. // HashtableEntry structures). This is used in the String.intern() method.
template<typename T> static unsigned int hash_string(const T* s, int len); static unsigned int hash_string(const jchar* s, int len);
static unsigned int hash_string(oop string);
// Internal test. // Internal test.
static void test_alt_hash() PRODUCT_RETURN; static void test_alt_hash() PRODUCT_RETURN;