8217442: Optimize native accesses to String.value
Reviewed-by: shade, dholmes
This commit is contained in:
parent
5f5d4425c2
commit
911c7ff446
@ -421,7 +421,7 @@ Handle java_lang_String::char_converter(Handle java_string, jchar from_char, jch
|
||||
oop obj = java_string();
|
||||
// Typical usage is to convert all '/' to '.' in string.
|
||||
typeArrayOop value = java_lang_String::value(obj);
|
||||
int length = java_lang_String::length(obj);
|
||||
int length = java_lang_String::length(obj, value);
|
||||
bool is_latin1 = java_lang_String::is_latin1(obj);
|
||||
|
||||
// First check if any from_char exist
|
||||
@ -485,7 +485,7 @@ Handle java_lang_String::char_converter(Handle java_string, jchar from_char, jch
|
||||
|
||||
jchar* java_lang_String::as_unicode_string(oop java_string, int& length, TRAPS) {
|
||||
typeArrayOop value = java_lang_String::value(java_string);
|
||||
length = java_lang_String::length(java_string);
|
||||
length = java_lang_String::length(java_string, value);
|
||||
bool is_latin1 = java_lang_String::is_latin1(java_string);
|
||||
|
||||
jchar* result = NEW_RESOURCE_ARRAY_RETURN_NULL(jchar, length);
|
||||
@ -506,11 +506,11 @@ jchar* java_lang_String::as_unicode_string(oop java_string, int& length, TRAPS)
|
||||
}
|
||||
|
||||
unsigned int java_lang_String::hash_code(oop java_string) {
|
||||
int length = java_lang_String::length(java_string);
|
||||
typeArrayOop value = java_lang_String::value(java_string);
|
||||
int length = java_lang_String::length(java_string, value);
|
||||
// Zero length string will hash to zero with String.hashCode() function.
|
||||
if (length == 0) return 0;
|
||||
|
||||
typeArrayOop value = java_lang_String::value(java_string);
|
||||
bool is_latin1 = java_lang_String::is_latin1(java_string);
|
||||
|
||||
if (is_latin1) {
|
||||
@ -522,7 +522,7 @@ unsigned int java_lang_String::hash_code(oop java_string) {
|
||||
|
||||
char* java_lang_String::as_quoted_ascii(oop java_string) {
|
||||
typeArrayOop value = java_lang_String::value(java_string);
|
||||
int length = java_lang_String::length(java_string);
|
||||
int length = java_lang_String::length(java_string, value);
|
||||
bool is_latin1 = java_lang_String::is_latin1(java_string);
|
||||
|
||||
if (length == 0) return NULL;
|
||||
@ -547,7 +547,7 @@ char* java_lang_String::as_quoted_ascii(oop java_string) {
|
||||
|
||||
Symbol* java_lang_String::as_symbol(oop java_string, TRAPS) {
|
||||
typeArrayOop value = java_lang_String::value(java_string);
|
||||
int length = java_lang_String::length(java_string);
|
||||
int length = java_lang_String::length(java_string, value);
|
||||
bool is_latin1 = java_lang_String::is_latin1(java_string);
|
||||
if (!is_latin1) {
|
||||
jchar* base = (length == 0) ? NULL : value->char_at_addr(0);
|
||||
@ -564,7 +564,7 @@ Symbol* java_lang_String::as_symbol(oop java_string, TRAPS) {
|
||||
|
||||
Symbol* java_lang_String::as_symbol_or_null(oop java_string) {
|
||||
typeArrayOop value = java_lang_String::value(java_string);
|
||||
int length = java_lang_String::length(java_string);
|
||||
int length = java_lang_String::length(java_string, value);
|
||||
bool is_latin1 = java_lang_String::is_latin1(java_string);
|
||||
if (!is_latin1) {
|
||||
jchar* base = (length == 0) ? NULL : value->char_at_addr(0);
|
||||
@ -577,23 +577,28 @@ Symbol* java_lang_String::as_symbol_or_null(oop java_string) {
|
||||
}
|
||||
}
|
||||
|
||||
int java_lang_String::utf8_length(oop java_string) {
|
||||
typeArrayOop value = java_lang_String::value(java_string);
|
||||
int length = java_lang_String::length(java_string);
|
||||
bool is_latin1 = java_lang_String::is_latin1(java_string);
|
||||
int java_lang_String::utf8_length(oop java_string, typeArrayOop value) {
|
||||
assert(oopDesc::equals_raw(value, java_lang_String::value(java_string)),
|
||||
"value must be same as java_lang_String::value(java_string)");
|
||||
int length = java_lang_String::length(java_string, value);
|
||||
if (length == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (!is_latin1) {
|
||||
if (!java_lang_String::is_latin1(java_string)) {
|
||||
return UNICODE::utf8_length(value->char_at_addr(0), length);
|
||||
} else {
|
||||
return UNICODE::utf8_length(value->byte_at_addr(0), length);
|
||||
}
|
||||
}
|
||||
|
||||
int java_lang_String::utf8_length(oop java_string) {
|
||||
typeArrayOop value = java_lang_String::value(java_string);
|
||||
return utf8_length(java_string, value);
|
||||
}
|
||||
|
||||
char* java_lang_String::as_utf8_string(oop java_string) {
|
||||
typeArrayOop value = java_lang_String::value(java_string);
|
||||
int length = java_lang_String::length(java_string);
|
||||
int length = java_lang_String::length(java_string, value);
|
||||
bool is_latin1 = java_lang_String::is_latin1(java_string);
|
||||
if (!is_latin1) {
|
||||
jchar* position = (length == 0) ? NULL : value->char_at_addr(0);
|
||||
@ -604,24 +609,29 @@ char* java_lang_String::as_utf8_string(oop java_string) {
|
||||
}
|
||||
}
|
||||
|
||||
char* java_lang_String::as_utf8_string(oop java_string, typeArrayOop value, char* buf, int buflen) {
|
||||
assert(oopDesc::equals_raw(value, java_lang_String::value(java_string)),
|
||||
"value must be same as java_lang_String::value(java_string)");
|
||||
int length = java_lang_String::length(java_string, value);
|
||||
bool is_latin1 = java_lang_String::is_latin1(java_string);
|
||||
if (!is_latin1) {
|
||||
jchar* position = (length == 0) ? NULL : value->char_at_addr(0);
|
||||
return UNICODE::as_utf8(position, length, buf, buflen);
|
||||
} else {
|
||||
jbyte* position = (length == 0) ? NULL : value->byte_at_addr(0);
|
||||
return UNICODE::as_utf8(position, length, buf, buflen);
|
||||
}
|
||||
}
|
||||
|
||||
char* java_lang_String::as_utf8_string(oop java_string, char* buf, int buflen) {
|
||||
typeArrayOop value = java_lang_String::value(java_string);
|
||||
int length = java_lang_String::length(java_string);
|
||||
bool is_latin1 = java_lang_String::is_latin1(java_string);
|
||||
if (!is_latin1) {
|
||||
jchar* position = (length == 0) ? NULL : value->char_at_addr(0);
|
||||
return UNICODE::as_utf8(position, length, buf, buflen);
|
||||
} else {
|
||||
jbyte* position = (length == 0) ? NULL : value->byte_at_addr(0);
|
||||
return UNICODE::as_utf8(position, length, buf, buflen);
|
||||
}
|
||||
typeArrayOop value = java_lang_String::value(java_string);
|
||||
return as_utf8_string(java_string, value, buf, buflen);
|
||||
}
|
||||
|
||||
char* java_lang_String::as_utf8_string(oop java_string, int start, int len) {
|
||||
typeArrayOop value = java_lang_String::value(java_string);
|
||||
int length = java_lang_String::length(java_string);
|
||||
assert(start + len <= length, "just checking");
|
||||
bool is_latin1 = java_lang_String::is_latin1(java_string);
|
||||
assert(start + len <= java_lang_String::length(java_string), "just checking");
|
||||
if (!is_latin1) {
|
||||
jchar* position = value->char_at_addr(start);
|
||||
return UNICODE::as_utf8(position, len);
|
||||
@ -631,11 +641,11 @@ char* java_lang_String::as_utf8_string(oop java_string, int start, int len) {
|
||||
}
|
||||
}
|
||||
|
||||
char* java_lang_String::as_utf8_string(oop java_string, int start, int len, char* buf, int buflen) {
|
||||
typeArrayOop value = java_lang_String::value(java_string);
|
||||
int length = java_lang_String::length(java_string);
|
||||
assert(start + len <= length, "just checking");
|
||||
bool is_latin1 = java_lang_String::is_latin1(java_string);
|
||||
char* java_lang_String::as_utf8_string(oop java_string, typeArrayOop value, int start, int len, char* buf, int buflen) {
|
||||
assert(oopDesc::equals_raw(value, java_lang_String::value(java_string)),
|
||||
"value must be same as java_lang_String::value(java_string)");
|
||||
assert(start + len <= java_lang_String::length(java_string), "just checking");
|
||||
bool is_latin1 = java_lang_String::is_latin1(java_string);
|
||||
if (!is_latin1) {
|
||||
jchar* position = value->char_at_addr(start);
|
||||
return UNICODE::as_utf8(position, len, buf, buflen);
|
||||
@ -649,7 +659,7 @@ bool java_lang_String::equals(oop java_string, const jchar* chars, int len) {
|
||||
assert(java_string->klass() == SystemDictionary::String_klass(),
|
||||
"must be java_string");
|
||||
typeArrayOop value = java_lang_String::value_no_keepalive(java_string);
|
||||
int length = java_lang_String::length(java_string);
|
||||
int length = java_lang_String::length(java_string, value);
|
||||
if (length != len) {
|
||||
return false;
|
||||
}
|
||||
@ -676,10 +686,10 @@ bool java_lang_String::equals(oop str1, oop str2) {
|
||||
assert(str2->klass() == SystemDictionary::String_klass(),
|
||||
"must be java String");
|
||||
typeArrayOop value1 = java_lang_String::value_no_keepalive(str1);
|
||||
int length1 = java_lang_String::length(str1);
|
||||
int length1 = java_lang_String::length(str1, value1);
|
||||
bool is_latin1 = java_lang_String::is_latin1(str1);
|
||||
typeArrayOop value2 = java_lang_String::value_no_keepalive(str2);
|
||||
int length2 = java_lang_String::length(str2);
|
||||
int length2 = java_lang_String::length(str2, value2);
|
||||
bool is_latin2 = java_lang_String::is_latin1(str2);
|
||||
|
||||
if ((length1 != length2) || (is_latin1 != is_latin2)) {
|
||||
@ -707,7 +717,7 @@ void java_lang_String::print(oop java_string, outputStream* st) {
|
||||
return;
|
||||
}
|
||||
|
||||
int length = java_lang_String::length(java_string);
|
||||
int length = java_lang_String::length(java_string, value);
|
||||
bool is_latin1 = java_lang_String::is_latin1(java_string);
|
||||
|
||||
st->print("\"");
|
||||
|
@ -147,13 +147,16 @@ class java_lang_String : AllStatic {
|
||||
static inline unsigned int hash(oop java_string);
|
||||
static inline bool is_latin1(oop java_string);
|
||||
static inline int length(oop java_string);
|
||||
static inline int length(oop java_string, typeArrayOop string_value);
|
||||
static int utf8_length(oop java_string);
|
||||
static int utf8_length(oop java_string, typeArrayOop string_value);
|
||||
|
||||
// String converters
|
||||
static char* as_utf8_string(oop java_string);
|
||||
static char* as_utf8_string(oop java_string, char* buf, int buflen);
|
||||
static char* as_utf8_string(oop java_string, int start, int len);
|
||||
static char* as_utf8_string(oop java_string, int start, int len, char* buf, int buflen);
|
||||
static char* as_utf8_string(oop java_string, typeArrayOop value, char* buf, int buflen);
|
||||
static char* as_utf8_string(oop java_string, typeArrayOop value, int start, int len, char* buf, int buflen);
|
||||
static char* as_platform_dependent_str(Handle java_string, TRAPS);
|
||||
static jchar* as_unicode_string(oop java_string, int& length, TRAPS);
|
||||
// produce an ascii string with all other values quoted using \u####
|
||||
|
@ -71,10 +71,11 @@ bool java_lang_String::is_latin1(oop java_string) {
|
||||
assert(CompactStrings || coder == CODER_UTF16, "Must be UTF16 without CompactStrings");
|
||||
return coder == CODER_LATIN1;
|
||||
}
|
||||
int java_lang_String::length(oop java_string) {
|
||||
int java_lang_String::length(oop java_string, typeArrayOop value) {
|
||||
assert(initialized, "Must be initialized");
|
||||
assert(is_instance(java_string), "must be java_string");
|
||||
typeArrayOop value = java_lang_String::value_no_keepalive(java_string);
|
||||
assert(oopDesc::equals_raw(value, java_lang_String::value(java_string)),
|
||||
"value must be same as java_lang_String::value(java_string)");
|
||||
if (value == NULL) {
|
||||
return 0;
|
||||
}
|
||||
@ -85,6 +86,12 @@ int java_lang_String::length(oop java_string) {
|
||||
}
|
||||
return arr_length;
|
||||
}
|
||||
int java_lang_String::length(oop java_string) {
|
||||
assert(initialized, "Must be initialized");
|
||||
assert(is_instance(java_string), "must be java_string");
|
||||
typeArrayOop value = java_lang_String::value_no_keepalive(java_string);
|
||||
return length(java_string, value);
|
||||
}
|
||||
|
||||
bool java_lang_String::is_instance_inlined(oop obj) {
|
||||
return obj != NULL && obj->klass() == SystemDictionary::String_klass();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2019, 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
|
||||
@ -474,15 +474,16 @@ const char* JfrJavaSupport::c_str(jstring string, Thread* t) {
|
||||
}
|
||||
const char* temp = NULL;
|
||||
const oop java_string = resolve_non_null(string);
|
||||
if (java_lang_String::value(java_string) != NULL) {
|
||||
const size_t length = java_lang_String::utf8_length(java_string);
|
||||
const typeArrayOop value = java_lang_String::value(java_string);
|
||||
if (value != NULL) {
|
||||
const size_t length = java_lang_String::utf8_length(java_string, value);
|
||||
temp = NEW_RESOURCE_ARRAY_IN_THREAD(t, const char, (length + 1));
|
||||
if (temp == NULL) {
|
||||
JfrJavaSupport::throw_out_of_memory_error("Unable to allocate thread local native memory", t);
|
||||
return NULL;
|
||||
}
|
||||
assert(temp != NULL, "invariant");
|
||||
java_lang_String::as_utf8_string(java_string, const_cast<char*>(temp), (int) length + 1);
|
||||
java_lang_String::as_utf8_string(java_string, value, const_cast<char*>(temp), (int) length + 1);
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
@ -2428,9 +2428,7 @@ JNI_QUICK_ENTRY(jsize, jni_GetStringLength(JNIEnv *env, jstring string))
|
||||
HOTSPOT_JNI_GETSTRINGLENGTH_ENTRY(env, string);
|
||||
jsize ret = 0;
|
||||
oop s = JNIHandles::resolve_non_null(string);
|
||||
if (java_lang_String::value(s) != NULL) {
|
||||
ret = java_lang_String::length(s);
|
||||
}
|
||||
ret = java_lang_String::length(s);
|
||||
HOTSPOT_JNI_GETSTRINGLENGTH_RETURN(ret);
|
||||
return ret;
|
||||
JNI_END
|
||||
@ -2444,7 +2442,7 @@ JNI_QUICK_ENTRY(const jchar*, jni_GetStringChars(
|
||||
oop s = JNIHandles::resolve_non_null(string);
|
||||
typeArrayOop s_value = java_lang_String::value(s);
|
||||
if (s_value != NULL) {
|
||||
int s_len = java_lang_String::length(s);
|
||||
int s_len = java_lang_String::length(s, s_value);
|
||||
bool is_latin1 = java_lang_String::is_latin1(s);
|
||||
buf = NEW_C_HEAP_ARRAY_RETURN_NULL(jchar, s_len + 1, mtInternal); // add one for zero termination
|
||||
/* JNI Specification states return NULL on OOM */
|
||||
@ -2504,11 +2502,8 @@ JNI_END
|
||||
JNI_ENTRY(jsize, jni_GetStringUTFLength(JNIEnv *env, jstring string))
|
||||
JNIWrapper("GetStringUTFLength");
|
||||
HOTSPOT_JNI_GETSTRINGUTFLENGTH_ENTRY(env, string);
|
||||
jsize ret = 0;
|
||||
oop java_string = JNIHandles::resolve_non_null(string);
|
||||
if (java_lang_String::value(java_string) != NULL) {
|
||||
ret = java_lang_String::utf8_length(java_string);
|
||||
}
|
||||
jsize ret = java_lang_String::utf8_length(java_string);
|
||||
HOTSPOT_JNI_GETSTRINGUTFLENGTH_RETURN(ret);
|
||||
return ret;
|
||||
JNI_END
|
||||
@ -2519,12 +2514,13 @@ JNI_ENTRY(const char*, jni_GetStringUTFChars(JNIEnv *env, jstring string, jboole
|
||||
HOTSPOT_JNI_GETSTRINGUTFCHARS_ENTRY(env, string, (uintptr_t *) isCopy);
|
||||
char* result = NULL;
|
||||
oop java_string = JNIHandles::resolve_non_null(string);
|
||||
if (java_lang_String::value(java_string) != NULL) {
|
||||
size_t length = java_lang_String::utf8_length(java_string);
|
||||
typeArrayOop s_value = java_lang_String::value(java_string);
|
||||
if (s_value != NULL) {
|
||||
size_t length = java_lang_String::utf8_length(java_string, s_value);
|
||||
/* JNI Specification states return NULL on OOM */
|
||||
result = AllocateHeap(length + 1, mtInternal, 0, AllocFailStrategy::RETURN_NULL);
|
||||
if (result != NULL) {
|
||||
java_lang_String::as_utf8_string(java_string, result, (int) length + 1);
|
||||
java_lang_String::as_utf8_string(java_string, s_value, result, (int) length + 1);
|
||||
if (isCopy != NULL) {
|
||||
*isCopy = JNI_TRUE;
|
||||
}
|
||||
@ -3097,12 +3093,12 @@ JNI_ENTRY(void, jni_GetStringRegion(JNIEnv *env, jstring string, jsize start, js
|
||||
HOTSPOT_JNI_GETSTRINGREGION_ENTRY(env, string, start, len, buf);
|
||||
DT_VOID_RETURN_MARK(GetStringRegion);
|
||||
oop s = JNIHandles::resolve_non_null(string);
|
||||
int s_len = java_lang_String::length(s);
|
||||
typeArrayOop s_value = java_lang_String::value(s);
|
||||
int s_len = java_lang_String::length(s, s_value);
|
||||
if (start < 0 || len < 0 || start > s_len - len) {
|
||||
THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());
|
||||
} else {
|
||||
if (len > 0) {
|
||||
typeArrayOop s_value = java_lang_String::value(s);
|
||||
bool is_latin1 = java_lang_String::is_latin1(s);
|
||||
if (!is_latin1) {
|
||||
ArrayAccess<>::arraycopy_to_native(s_value, typeArrayOopDesc::element_offset<jchar>(start),
|
||||
@ -3124,14 +3120,15 @@ JNI_ENTRY(void, jni_GetStringUTFRegion(JNIEnv *env, jstring string, jsize start,
|
||||
HOTSPOT_JNI_GETSTRINGUTFREGION_ENTRY(env, string, start, len, buf);
|
||||
DT_VOID_RETURN_MARK(GetStringUTFRegion);
|
||||
oop s = JNIHandles::resolve_non_null(string);
|
||||
int s_len = java_lang_String::length(s);
|
||||
typeArrayOop s_value = java_lang_String::value(s);
|
||||
int s_len = java_lang_String::length(s, s_value);
|
||||
if (start < 0 || len < 0 || start > s_len - len) {
|
||||
THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());
|
||||
} else {
|
||||
//%note jni_7
|
||||
if (len > 0) {
|
||||
// Assume the buffer is large enough as the JNI spec. does not require user error checking
|
||||
java_lang_String::as_utf8_string(s, start, len, buf, INT_MAX);
|
||||
java_lang_String::as_utf8_string(s, s_value, start, len, buf, INT_MAX);
|
||||
// as_utf8_string null-terminates the result string
|
||||
} else {
|
||||
// JDK null-terminates the buffer even in len is zero
|
||||
@ -3203,7 +3200,7 @@ JNI_ENTRY(const jchar*, jni_GetStringCritical(JNIEnv *env, jstring string, jbool
|
||||
ret = (jchar*) s_value->base(T_CHAR);
|
||||
} else {
|
||||
// Inflate latin1 encoded string to UTF16
|
||||
int s_len = java_lang_String::length(s);
|
||||
int s_len = java_lang_String::length(s, s_value);
|
||||
ret = NEW_C_HEAP_ARRAY_RETURN_NULL(jchar, s_len + 1, mtInternal); // add one for zero termination
|
||||
/* JNI Specification states return NULL on OOM */
|
||||
if (ret != NULL) {
|
||||
|
Loading…
Reference in New Issue
Block a user