Skip to content

Commit 75c651f

Browse files
committed
8327156: Avoid copying in StringTable::intern(oop, TRAPS)
8326865: Avoid copying in StringTable::intern(Symbol*, TRAPS) 8327825: StringTable::intern is slow Reviewed-by: dholmes, coleenp, jsjolen
1 parent 3eece6e commit 75c651f

File tree

6 files changed

+548
-85
lines changed

6 files changed

+548
-85
lines changed

src/hotspot/share/classfile/javaClasses.cpp

+33-2
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ Handle java_lang_String::create_from_str(const char* utf8_str, TRAPS) {
347347
#ifdef ASSERT
348348
// This check is too strict when the input string is not a valid UTF8.
349349
// For example, it may be created with arbitrary content via jni_NewStringUTF.
350-
if (UTF8::is_legal_utf8((const unsigned char*)utf8_str, strlen(utf8_str), false)) {
350+
if (UTF8::is_legal_utf8((const unsigned char*)utf8_str, strlen(utf8_str), /*version_leq_47*/false)) {
351351
ResourceMark rm;
352352
const char* expected = utf8_str;
353353
char* actual = as_utf8_string(h_obj());
@@ -365,7 +365,7 @@ oop java_lang_String::create_oop_from_str(const char* utf8_str, TRAPS) {
365365
return h_obj();
366366
}
367367

368-
Handle java_lang_String::create_from_symbol(Symbol* symbol, TRAPS) {
368+
Handle java_lang_String::create_from_symbol(const Symbol* symbol, TRAPS) {
369369
const char* utf8_str = (char*)symbol->bytes();
370370
int utf8_len = symbol->utf8_length();
371371

@@ -389,6 +389,8 @@ Handle java_lang_String::create_from_symbol(Symbol* symbol, TRAPS) {
389389
}
390390

391391
#ifdef ASSERT
392+
// This check is too strict on older classfile versions
393+
if (UTF8::is_legal_utf8((const unsigned char*)utf8_str, utf8_len, /*version_leq_47*/false))
392394
{
393395
ResourceMark rm;
394396
const char* expected = symbol->as_utf8();
@@ -755,6 +757,35 @@ bool java_lang_String::equals(oop java_string, const jchar* chars, int len) {
755757
return true;
756758
}
757759

760+
bool java_lang_String::equals(oop java_string, const char* utf8_string, size_t utf8_len) {
761+
assert(java_string->klass() == vmClasses::String_klass(),
762+
"must be java_string");
763+
typeArrayOop value = java_lang_String::value_no_keepalive(java_string);
764+
int length = java_lang_String::length(java_string, value);
765+
int unicode_length = UTF8::unicode_length(utf8_string, utf8_len);
766+
if (length != unicode_length) {
767+
return false;
768+
}
769+
bool is_latin1 = java_lang_String::is_latin1(java_string);
770+
jchar c;
771+
if (!is_latin1) {
772+
for (int i = 0; i < unicode_length; i++) {
773+
utf8_string = UTF8::next(utf8_string, &c);
774+
if (value->char_at(i) != c) {
775+
return false;
776+
}
777+
}
778+
} else {
779+
for (int i = 0; i < unicode_length; i++) {
780+
utf8_string = UTF8::next(utf8_string, &c);
781+
if ((((jchar) value->byte_at(i)) & 0xff) != c) {
782+
return false;
783+
}
784+
}
785+
}
786+
return true;
787+
}
788+
758789
bool java_lang_String::equals(oop str1, oop str2) {
759790
assert(str1->klass() == vmClasses::String_klass(),
760791
"must be java String");

src/hotspot/share/classfile/javaClasses.hpp

+16-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "runtime/handles.hpp"
3333
#include "runtime/os.hpp"
3434
#include "utilities/macros.hpp"
35+
#include "utilities/utf8.hpp"
3536
#include "utilities/vmEnums.hpp"
3637

3738
class JvmtiThreadState;
@@ -99,7 +100,7 @@ class java_lang_String : AllStatic {
99100
static oop create_oop_from_unicode(const jchar* unicode, int len, TRAPS);
100101
static Handle create_from_str(const char* utf8_str, TRAPS);
101102
static oop create_oop_from_str(const char* utf8_str, TRAPS);
102-
static Handle create_from_symbol(Symbol* symbol, TRAPS);
103+
static Handle create_from_symbol(const Symbol* symbol, TRAPS);
103104
static Handle create_from_platform_dependent_str(const char* str, TRAPS);
104105

105106
static void set_compact_strings(bool value);
@@ -180,10 +181,24 @@ class java_lang_String : AllStatic {
180181
return h;
181182
}
182183

184+
static unsigned int hash_code(const char* utf8_str, size_t utf8_len) {
185+
unsigned int h = 0;
186+
int unicode_length = UTF8::unicode_length(utf8_str, utf8_len);
187+
188+
jchar c;
189+
while (unicode_length-- > 0) {
190+
utf8_str = UTF8::next(utf8_str, &c);
191+
h = 31 * h + ((unsigned int)c);
192+
}
193+
return h;
194+
}
195+
183196
static unsigned int hash_code(oop java_string);
184197
static unsigned int hash_code_noupdate(oop java_string);
185198

199+
// Compare strings (of different types/encodings), length is the string (array) length
186200
static bool equals(oop java_string, const jchar* chars, int len);
201+
static bool equals(oop java_string, const char* utf8_str, size_t utf8_len);
187202
static bool equals(oop str1, oop str2);
188203
static inline bool value_equals(typeArrayOop str_value1, typeArrayOop str_value2);
189204

0 commit comments

Comments
 (0)