mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 11:04:34 +02:00
8022683: JNI GetStringUTFChars should return NULL on allocation failure not abort the VM
Return NULL on OOM from GetStringChars, GetStringUTFChars and Get<PrimitiveType>ArrayElements family of functions. Reviewed-by: dholmes, coleenp
This commit is contained in:
parent
6a548048a3
commit
618cb11a73
2 changed files with 42 additions and 24 deletions
|
@ -666,7 +666,7 @@ class ResourceObj ALLOCATION_SUPER_CLASS_SPEC {
|
||||||
NEW_RESOURCE_ARRAY_RETURN_NULL(type, 1)
|
NEW_RESOURCE_ARRAY_RETURN_NULL(type, 1)
|
||||||
|
|
||||||
#define NEW_C_HEAP_ARRAY3(type, size, memflags, pc, allocfail)\
|
#define NEW_C_HEAP_ARRAY3(type, size, memflags, pc, allocfail)\
|
||||||
(type*) AllocateHeap(size * sizeof(type), memflags, pc, allocfail)
|
(type*) AllocateHeap((size) * sizeof(type), memflags, pc, allocfail)
|
||||||
|
|
||||||
#define NEW_C_HEAP_ARRAY2(type, size, memflags, pc)\
|
#define NEW_C_HEAP_ARRAY2(type, size, memflags, pc)\
|
||||||
(type*) (AllocateHeap((size) * sizeof(type), memflags, pc))
|
(type*) (AllocateHeap((size) * sizeof(type), memflags, pc))
|
||||||
|
@ -675,16 +675,16 @@ class ResourceObj ALLOCATION_SUPER_CLASS_SPEC {
|
||||||
(type*) (AllocateHeap((size) * sizeof(type), memflags))
|
(type*) (AllocateHeap((size) * sizeof(type), memflags))
|
||||||
|
|
||||||
#define NEW_C_HEAP_ARRAY2_RETURN_NULL(type, size, memflags, pc)\
|
#define NEW_C_HEAP_ARRAY2_RETURN_NULL(type, size, memflags, pc)\
|
||||||
NEW_C_HEAP_ARRAY3(type, size, memflags, pc, AllocFailStrategy::RETURN_NULL)
|
NEW_C_HEAP_ARRAY3(type, (size), memflags, pc, AllocFailStrategy::RETURN_NULL)
|
||||||
|
|
||||||
#define NEW_C_HEAP_ARRAY_RETURN_NULL(type, size, memflags)\
|
#define NEW_C_HEAP_ARRAY_RETURN_NULL(type, size, memflags)\
|
||||||
NEW_C_HEAP_ARRAY3(type, size, memflags, (address)0, AllocFailStrategy::RETURN_NULL)
|
NEW_C_HEAP_ARRAY3(type, (size), memflags, (address)0, AllocFailStrategy::RETURN_NULL)
|
||||||
|
|
||||||
#define REALLOC_C_HEAP_ARRAY(type, old, size, memflags)\
|
#define REALLOC_C_HEAP_ARRAY(type, old, size, memflags)\
|
||||||
(type*) (ReallocateHeap((char*)old, (size) * sizeof(type), memflags))
|
(type*) (ReallocateHeap((char*)(old), (size) * sizeof(type), memflags))
|
||||||
|
|
||||||
#define REALLOC_C_HEAP_ARRAY_RETURN_NULL(type, old, size, memflags)\
|
#define REALLOC_C_HEAP_ARRAY_RETURN_NULL(type, old, size, memflags)\
|
||||||
(type*) (ReallocateHeap((char*)old, (size) * sizeof(type), memflags, AllocFailStrategy::RETURN_NULL))
|
(type*) (ReallocateHeap((char*)(old), (size) * sizeof(type), memflags, AllocFailStrategy::RETURN_NULL))
|
||||||
|
|
||||||
#define FREE_C_HEAP_ARRAY(type, old, memflags) \
|
#define FREE_C_HEAP_ARRAY(type, old, memflags) \
|
||||||
FreeHeap((char*)(old), memflags)
|
FreeHeap((char*)(old), memflags)
|
||||||
|
|
|
@ -3234,19 +3234,22 @@ JNI_QUICK_ENTRY(const jchar*, jni_GetStringChars(
|
||||||
HOTSPOT_JNI_GETSTRINGCHARS_ENTRY(
|
HOTSPOT_JNI_GETSTRINGCHARS_ENTRY(
|
||||||
env, string, (uintptr_t *) isCopy);
|
env, string, (uintptr_t *) isCopy);
|
||||||
#endif /* USDT2 */
|
#endif /* USDT2 */
|
||||||
//%note jni_5
|
|
||||||
if (isCopy != NULL) {
|
|
||||||
*isCopy = JNI_TRUE;
|
|
||||||
}
|
|
||||||
oop s = JNIHandles::resolve_non_null(string);
|
oop s = JNIHandles::resolve_non_null(string);
|
||||||
int s_len = java_lang_String::length(s);
|
int s_len = java_lang_String::length(s);
|
||||||
typeArrayOop s_value = java_lang_String::value(s);
|
typeArrayOop s_value = java_lang_String::value(s);
|
||||||
int s_offset = java_lang_String::offset(s);
|
int s_offset = java_lang_String::offset(s);
|
||||||
jchar* buf = NEW_C_HEAP_ARRAY(jchar, s_len + 1, mtInternal); // add one for zero termination
|
jchar* buf = NEW_C_HEAP_ARRAY_RETURN_NULL(jchar, s_len + 1, mtInternal); // add one for zero termination
|
||||||
|
/* JNI Specification states return NULL on OOM */
|
||||||
|
if (buf != NULL) {
|
||||||
if (s_len > 0) {
|
if (s_len > 0) {
|
||||||
memcpy(buf, s_value->char_at_addr(s_offset), sizeof(jchar)*s_len);
|
memcpy(buf, s_value->char_at_addr(s_offset), sizeof(jchar)*s_len);
|
||||||
}
|
}
|
||||||
buf[s_len] = 0;
|
buf[s_len] = 0;
|
||||||
|
//%note jni_5
|
||||||
|
if (isCopy != NULL) {
|
||||||
|
*isCopy = JNI_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
#ifndef USDT2
|
#ifndef USDT2
|
||||||
DTRACE_PROBE1(hotspot_jni, GetStringChars__return, buf);
|
DTRACE_PROBE1(hotspot_jni, GetStringChars__return, buf);
|
||||||
#else /* USDT2 */
|
#else /* USDT2 */
|
||||||
|
@ -3335,9 +3338,14 @@ JNI_ENTRY(const char*, jni_GetStringUTFChars(JNIEnv *env, jstring string, jboole
|
||||||
#endif /* USDT2 */
|
#endif /* USDT2 */
|
||||||
oop java_string = JNIHandles::resolve_non_null(string);
|
oop java_string = JNIHandles::resolve_non_null(string);
|
||||||
size_t length = java_lang_String::utf8_length(java_string);
|
size_t length = java_lang_String::utf8_length(java_string);
|
||||||
char* result = AllocateHeap(length + 1, mtInternal);
|
/* JNI Specification states return NULL on OOM */
|
||||||
|
char* 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, result, (int) length + 1);
|
||||||
if (isCopy != NULL) *isCopy = JNI_TRUE;
|
if (isCopy != NULL) {
|
||||||
|
*isCopy = JNI_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
#ifndef USDT2
|
#ifndef USDT2
|
||||||
DTRACE_PROBE1(hotspot_jni, GetStringUTFChars__return, result);
|
DTRACE_PROBE1(hotspot_jni, GetStringUTFChars__return, result);
|
||||||
#else /* USDT2 */
|
#else /* USDT2 */
|
||||||
|
@ -3591,11 +3599,16 @@ JNI_QUICK_ENTRY(ElementType*, \
|
||||||
* Avoid asserts in typeArrayOop. */ \
|
* Avoid asserts in typeArrayOop. */ \
|
||||||
result = (ElementType*)get_bad_address(); \
|
result = (ElementType*)get_bad_address(); \
|
||||||
} else { \
|
} else { \
|
||||||
result = NEW_C_HEAP_ARRAY(ElementType, len, mtInternal); \
|
/* JNI Specification states return NULL on OOM */ \
|
||||||
|
result = NEW_C_HEAP_ARRAY_RETURN_NULL(ElementType, len, mtInternal); \
|
||||||
|
if (result != NULL) { \
|
||||||
/* copy the array to the c chunk */ \
|
/* copy the array to the c chunk */ \
|
||||||
memcpy(result, a->Tag##_at_addr(0), sizeof(ElementType)*len); \
|
memcpy(result, a->Tag##_at_addr(0), sizeof(ElementType)*len); \
|
||||||
|
if (isCopy) { \
|
||||||
|
*isCopy = JNI_TRUE; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
} \
|
} \
|
||||||
if (isCopy) *isCopy = JNI_TRUE; \
|
|
||||||
DTRACE_PROBE1(hotspot_jni, Get##Result##ArrayElements__return, result);\
|
DTRACE_PROBE1(hotspot_jni, Get##Result##ArrayElements__return, result);\
|
||||||
return result; \
|
return result; \
|
||||||
JNI_END
|
JNI_END
|
||||||
|
@ -3628,11 +3641,16 @@ JNI_QUICK_ENTRY(ElementType*, \
|
||||||
* Avoid asserts in typeArrayOop. */ \
|
* Avoid asserts in typeArrayOop. */ \
|
||||||
result = (ElementType*)get_bad_address(); \
|
result = (ElementType*)get_bad_address(); \
|
||||||
} else { \
|
} else { \
|
||||||
result = NEW_C_HEAP_ARRAY(ElementType, len, mtInternal); \
|
/* JNI Specification states return NULL on OOM */ \
|
||||||
|
result = NEW_C_HEAP_ARRAY_RETURN_NULL(ElementType, len, mtInternal); \
|
||||||
|
if (result != NULL) { \
|
||||||
/* copy the array to the c chunk */ \
|
/* copy the array to the c chunk */ \
|
||||||
memcpy(result, a->Tag##_at_addr(0), sizeof(ElementType)*len); \
|
memcpy(result, a->Tag##_at_addr(0), sizeof(ElementType)*len); \
|
||||||
|
if (isCopy) { \
|
||||||
|
*isCopy = JNI_TRUE; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
} \
|
} \
|
||||||
if (isCopy) *isCopy = JNI_TRUE; \
|
|
||||||
ReturnProbe; \
|
ReturnProbe; \
|
||||||
return result; \
|
return result; \
|
||||||
JNI_END
|
JNI_END
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue