# HG changeset patch # User coleenp # Date 1458667938 14400 # Node ID ff4d69314a4c27ffb8cc71a4cc1432dc07eac592 # Parent b968bbc6291ccc59287873227815f6a3fa8b98a4 8144940: Broken hash in string table entry in closed/runtime/7158800/BadUtf8.java Summary: Fix code broken with compact Strings. Reviewed-by: iklam, thartmann, hseigel, jiangli diff -r b968bbc6291c -r ff4d69314a4c hotspot/src/share/vm/classfile/javaClasses.cpp --- a/hotspot/src/share/vm/classfile/javaClasses.cpp Tue Mar 22 13:41:52 2016 +0100 +++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Tue Mar 22 13:32:18 2016 -0400 @@ -513,21 +513,6 @@ 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) { oop obj = java_string(); diff -r b968bbc6291c -r ff4d69314a4c hotspot/src/share/vm/classfile/javaClasses.hpp --- a/hotspot/src/share/vm/classfile/javaClasses.hpp Tue Mar 22 13:41:52 2016 +0100 +++ b/hotspot/src/share/vm/classfile/javaClasses.hpp Tue Mar 22 13:32:18 2016 -0400 @@ -155,11 +155,6 @@ } 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 str1, oop str2); diff -r b968bbc6291c -r ff4d69314a4c hotspot/src/share/vm/classfile/stringTable.cpp --- a/hotspot/src/share/vm/classfile/stringTable.cpp Tue Mar 22 13:41:52 2016 +0100 +++ b/hotspot/src/share/vm/classfile/stringTable.cpp Tue Mar 22 13:32:18 2016 -0400 @@ -94,15 +94,27 @@ CompactHashtable<oop, char> StringTable::_shared_table; // Pick hashing algorithm -template<typename T> -unsigned int StringTable::hash_string(const T* s, int len) { +unsigned int StringTable::hash_string(const jchar* s, int len) { return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) : java_lang_String::hash_code(s, len); } -// Explicit instantiation for all supported types. -template unsigned int StringTable::hash_string<jchar>(const jchar* s, int len); -template unsigned int StringTable::hash_string<jbyte>(const jbyte* s, int len); +unsigned int StringTable::hash_string(oop string) { + EXCEPTION_MARK; + 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) { // java_lang_String::hash_code() was used to compute hash values in the shared table. Don't @@ -398,7 +410,7 @@ for ( ; p != NULL; p = p->next()) { oop s = p->literal(); 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(the_table()->hash_to_index(h) == i, "wrong index in string table"); @@ -498,7 +510,7 @@ 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 (mesg_mode == _verify_with_mesgs) { tty->print_cr("ERROR: broken hash value in entry @ bucket[%d][%d], " diff -r b968bbc6291c -r ff4d69314a4c hotspot/src/share/vm/classfile/stringTable.hpp --- a/hotspot/src/share/vm/classfile/stringTable.hpp Tue Mar 22 13:41:52 2016 +0100 +++ b/hotspot/src/share/vm/classfile/stringTable.hpp Tue Mar 22 13:32:18 2016 -0400 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -111,7 +111,8 @@ // Hashing algorithm, used as the hash value used by the // StringTable for bucket selection and comparison (stored in the // 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. static void test_alt_hash() PRODUCT_RETURN;