mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-18 10:04:42 +02:00
8195690: JNI GetObjectRefType doesn't handle NULL
Properly handle NULL, add some non-NULL preconditions. Reviewed-by: dholmes, mdoerr
This commit is contained in:
parent
490d2ce747
commit
2d847b1eb6
7 changed files with 26 additions and 6 deletions
|
@ -467,6 +467,7 @@ void OopStorage::release(const oop* ptr) {
|
||||||
void OopStorage::release(const oop* const* ptrs, size_t size) {
|
void OopStorage::release(const oop* const* ptrs, size_t size) {
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
while (i < size) {
|
while (i < size) {
|
||||||
|
check_release_entry(ptrs[i]);
|
||||||
Block* block = find_block_or_null(ptrs[i]);
|
Block* block = find_block_or_null(ptrs[i]);
|
||||||
check_release(block, ptrs[i]);
|
check_release(block, ptrs[i]);
|
||||||
log_info(oopstorage, ref)("%s: released " PTR_FORMAT, name(), p2i(ptrs[i]));
|
log_info(oopstorage, ref)("%s: released " PTR_FORMAT, name(), p2i(ptrs[i]));
|
||||||
|
|
|
@ -103,6 +103,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// Locks _allocate_mutex.
|
// Locks _allocate_mutex.
|
||||||
|
// precondition: ptr != NULL.
|
||||||
EntryStatus allocation_status(const oop* ptr) const;
|
EntryStatus allocation_status(const oop* ptr) const;
|
||||||
|
|
||||||
// Allocates and returns a new entry. Returns NULL if memory allocation
|
// Allocates and returns a new entry. Returns NULL if memory allocation
|
||||||
|
|
|
@ -862,7 +862,10 @@ JNI_LEAF(jobjectRefType, jni_GetObjectRefType(JNIEnv *env, jobject obj))
|
||||||
|
|
||||||
HOTSPOT_JNI_GETOBJECTREFTYPE_ENTRY(env, obj);
|
HOTSPOT_JNI_GETOBJECTREFTYPE_ENTRY(env, obj);
|
||||||
|
|
||||||
jobjectRefType ret = JNIHandles::handle_type(thread, obj);
|
jobjectRefType ret = JNIInvalidRefType;
|
||||||
|
if (obj != NULL) {
|
||||||
|
ret = JNIHandles::handle_type(thread, obj);
|
||||||
|
}
|
||||||
|
|
||||||
HOTSPOT_JNI_GETOBJECTREFTYPE_RETURN((void *) ret);
|
HOTSPOT_JNI_GETOBJECTREFTYPE_RETURN((void *) ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -435,7 +435,7 @@ static void* check_wrapped_array_release(JavaThread* thr, const char* fn_name,
|
||||||
}
|
}
|
||||||
|
|
||||||
oop jniCheck::validate_handle(JavaThread* thr, jobject obj) {
|
oop jniCheck::validate_handle(JavaThread* thr, jobject obj) {
|
||||||
if (JNIHandles::handle_type(thr, obj) != JNIInvalidRefType) {
|
if ((obj != NULL) && (JNIHandles::handle_type(thr, obj) != JNIInvalidRefType)) {
|
||||||
ASSERT_OOPS_ALLOWED;
|
ASSERT_OOPS_ALLOWED;
|
||||||
return JNIHandles::resolve_external_guard(obj);
|
return JNIHandles::resolve_external_guard(obj);
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,6 +136,7 @@ jobject JNIHandles::make_weak_global(Handle obj, AllocFailType alloc_failmode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
oop JNIHandles::resolve_jweak(jweak handle) {
|
oop JNIHandles::resolve_jweak(jweak handle) {
|
||||||
|
assert(handle != NULL, "precondition");
|
||||||
assert(is_jweak(handle), "precondition");
|
assert(is_jweak(handle), "precondition");
|
||||||
oop result = jweak_ref(handle);
|
oop result = jweak_ref(handle);
|
||||||
#if INCLUDE_ALL_GCS
|
#if INCLUDE_ALL_GCS
|
||||||
|
@ -147,6 +148,7 @@ oop JNIHandles::resolve_jweak(jweak handle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JNIHandles::is_global_weak_cleared(jweak handle) {
|
bool JNIHandles::is_global_weak_cleared(jweak handle) {
|
||||||
|
assert(handle != NULL, "precondition");
|
||||||
assert(is_jweak(handle), "not a weak handle");
|
assert(is_jweak(handle), "not a weak handle");
|
||||||
return jweak_ref(handle) == NULL;
|
return jweak_ref(handle) == NULL;
|
||||||
}
|
}
|
||||||
|
@ -200,6 +202,7 @@ inline bool is_storage_handle(const OopStorage* storage, const oop* ptr) {
|
||||||
|
|
||||||
|
|
||||||
jobjectRefType JNIHandles::handle_type(Thread* thread, jobject handle) {
|
jobjectRefType JNIHandles::handle_type(Thread* thread, jobject handle) {
|
||||||
|
assert(handle != NULL, "precondition");
|
||||||
jobjectRefType result = JNIInvalidRefType;
|
jobjectRefType result = JNIInvalidRefType;
|
||||||
if (is_jweak(handle)) {
|
if (is_jweak(handle)) {
|
||||||
if (is_storage_handle(_weak_global_handles, &jweak_ref(handle))) {
|
if (is_storage_handle(_weak_global_handles, &jweak_ref(handle))) {
|
||||||
|
@ -232,6 +235,7 @@ jobjectRefType JNIHandles::handle_type(Thread* thread, jobject handle) {
|
||||||
|
|
||||||
|
|
||||||
bool JNIHandles::is_local_handle(Thread* thread, jobject handle) {
|
bool JNIHandles::is_local_handle(Thread* thread, jobject handle) {
|
||||||
|
assert(handle != NULL, "precondition");
|
||||||
JNIHandleBlock* block = thread->active_handles();
|
JNIHandleBlock* block = thread->active_handles();
|
||||||
|
|
||||||
// Look back past possible native calls to jni_PushLocalFrame.
|
// Look back past possible native calls to jni_PushLocalFrame.
|
||||||
|
@ -249,22 +253,25 @@ bool JNIHandles::is_local_handle(Thread* thread, jobject handle) {
|
||||||
// We easily can't isolate any particular stack frame the handle might
|
// We easily can't isolate any particular stack frame the handle might
|
||||||
// come from, so we'll check the whole stack.
|
// come from, so we'll check the whole stack.
|
||||||
|
|
||||||
bool JNIHandles::is_frame_handle(JavaThread* thr, jobject obj) {
|
bool JNIHandles::is_frame_handle(JavaThread* thr, jobject handle) {
|
||||||
|
assert(handle != NULL, "precondition");
|
||||||
// If there is no java frame, then this must be top level code, such
|
// If there is no java frame, then this must be top level code, such
|
||||||
// as the java command executable, in which case, this type of handle
|
// as the java command executable, in which case, this type of handle
|
||||||
// is not permitted.
|
// is not permitted.
|
||||||
return (thr->has_last_Java_frame() &&
|
return (thr->has_last_Java_frame() &&
|
||||||
(void*)obj < (void*)thr->stack_base() &&
|
(void*)handle < (void*)thr->stack_base() &&
|
||||||
(void*)obj >= (void*)thr->last_Java_sp());
|
(void*)handle >= (void*)thr->last_Java_sp());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool JNIHandles::is_global_handle(jobject handle) {
|
bool JNIHandles::is_global_handle(jobject handle) {
|
||||||
|
assert(handle != NULL, "precondition");
|
||||||
return !is_jweak(handle) && is_storage_handle(_global_handles, &jobject_ref(handle));
|
return !is_jweak(handle) && is_storage_handle(_global_handles, &jobject_ref(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool JNIHandles::is_weak_global_handle(jobject handle) {
|
bool JNIHandles::is_weak_global_handle(jobject handle) {
|
||||||
|
assert(handle != NULL, "precondition");
|
||||||
return is_jweak(handle) && is_storage_handle(_weak_global_handles, &jweak_ref(handle));
|
return is_jweak(handle) && is_storage_handle(_weak_global_handles, &jweak_ref(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -603,6 +610,7 @@ bool JNIHandles::is_local_handle(jobject handle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JNIHandleBlock::any_contains(jobject handle) {
|
bool JNIHandleBlock::any_contains(jobject handle) {
|
||||||
|
assert(handle != NULL, "precondition");
|
||||||
for (JNIHandleBlock* current = _block_list; current != NULL; current = current->_block_list_link) {
|
for (JNIHandleBlock* current = _block_list; current != NULL; current = current->_block_list_link) {
|
||||||
if (current->contains(handle)) {
|
if (current->contains(handle)) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -94,8 +94,9 @@ class JNIHandles : AllStatic {
|
||||||
static void print_on(outputStream* st);
|
static void print_on(outputStream* st);
|
||||||
static void print() { print_on(tty); }
|
static void print() { print_on(tty); }
|
||||||
static void verify();
|
static void verify();
|
||||||
|
// The category predicates all require handle != NULL.
|
||||||
static bool is_local_handle(Thread* thread, jobject handle);
|
static bool is_local_handle(Thread* thread, jobject handle);
|
||||||
static bool is_frame_handle(JavaThread* thr, jobject obj);
|
static bool is_frame_handle(JavaThread* thread, jobject handle);
|
||||||
static bool is_global_handle(jobject handle);
|
static bool is_global_handle(jobject handle);
|
||||||
static bool is_weak_global_handle(jobject handle);
|
static bool is_weak_global_handle(jobject handle);
|
||||||
static size_t global_handle_memory_usage();
|
static size_t global_handle_memory_usage();
|
||||||
|
@ -106,6 +107,7 @@ class JNIHandles : AllStatic {
|
||||||
static bool is_local_handle(jobject handle);
|
static bool is_local_handle(jobject handle);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// precondition: handle != NULL.
|
||||||
static jobjectRefType handle_type(Thread* thread, jobject handle);
|
static jobjectRefType handle_type(Thread* thread, jobject handle);
|
||||||
|
|
||||||
// Garbage collection support(global handles only, local handles are traversed from thread)
|
// Garbage collection support(global handles only, local handles are traversed from thread)
|
||||||
|
|
|
@ -987,6 +987,11 @@ void os::print_date_and_time(outputStream *st, char* buf, size_t buflen) {
|
||||||
// The verbose parameter is only set by the debug code in one case
|
// The verbose parameter is only set by the debug code in one case
|
||||||
void os::print_location(outputStream* st, intptr_t x, bool verbose) {
|
void os::print_location(outputStream* st, intptr_t x, bool verbose) {
|
||||||
address addr = (address)x;
|
address addr = (address)x;
|
||||||
|
// Handle NULL first, so later checks don't need to protect against it.
|
||||||
|
if (addr == NULL) {
|
||||||
|
st->print_cr("0x0 is NULL");
|
||||||
|
return;
|
||||||
|
}
|
||||||
CodeBlob* b = CodeCache::find_blob_unsafe(addr);
|
CodeBlob* b = CodeCache::find_blob_unsafe(addr);
|
||||||
if (b != NULL) {
|
if (b != NULL) {
|
||||||
if (b->is_buffer_blob()) {
|
if (b->is_buffer_blob()) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue