# HG changeset patch # User hseigel # Date 1513368798 18000 # Node ID f82e79958beb36d1e447dc7945a0521f647d216b # Parent 0c0b618a20b1c408c054f42d10965aea762a96e1 8167372: Add code to check for getting oops while thread is in native Summary: Add asserts that detect when a thread is getting oops while in native Reviewed-by: coleenp, shade, jiangli, gtriantafill diff -r 0c0b618a20b1 -r f82e79958beb src/hotspot/share/runtime/jniHandles.cpp --- a/src/hotspot/share/runtime/jniHandles.cpp Fri Dec 15 16:54:17 2017 +0100 +++ b/src/hotspot/share/runtime/jniHandles.cpp Fri Dec 15 15:13:18 2017 -0500 @@ -47,6 +47,7 @@ } else { Thread* thread = Thread::current(); assert(Universe::heap()->is_in_reserved(obj), "sanity check"); + assert(!current_thread_in_native(), "must not be in native"); return thread->active_handles()->allocate_handle(obj); } } @@ -59,6 +60,8 @@ return NULL; // ignore null handles } else { assert(Universe::heap()->is_in_reserved(obj), "sanity check"); + assert(thread->is_Java_thread(), "not a Java thread"); + assert(!current_thread_in_native(), "must not be in native"); return thread->active_handles()->allocate_handle(obj); } } @@ -70,6 +73,7 @@ } else { JavaThread* thread = JavaThread::thread_from_jni_environment(env); assert(Universe::heap()->is_in_reserved(obj), "sanity check"); + assert(!current_thread_in_native(), "must not be in native"); return thread->active_handles()->allocate_handle(obj); } } @@ -77,6 +81,7 @@ jobject JNIHandles::make_global(Handle obj) { assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC"); + assert(!current_thread_in_native(), "must not be in native"); jobject res = NULL; if (!obj.is_null()) { // ignore null handles @@ -93,6 +98,7 @@ jobject JNIHandles::make_weak_global(Handle obj) { assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC"); + assert(!current_thread_in_native(), "must not be in native"); jobject res = NULL; if (!obj.is_null()) { // ignore null handles @@ -265,6 +271,13 @@ weak_oops_do(&verify_handle); } +// This method is implemented here to avoid circular includes between +// jniHandles.hpp and thread.hpp. +bool JNIHandles::current_thread_in_native() { + Thread* thread = Thread::current(); + return (thread->is_Java_thread() && + JavaThread::current()->thread_state() == _thread_in_native); +} void jni_handles_init() { diff -r 0c0b618a20b1 -r f82e79958beb src/hotspot/share/runtime/jniHandles.hpp --- a/src/hotspot/share/runtime/jniHandles.hpp Fri Dec 15 16:54:17 2017 +0100 +++ b/src/hotspot/share/runtime/jniHandles.hpp Fri Dec 15 15:13:18 2017 -0500 @@ -48,6 +48,10 @@ template inline static oop resolve_impl(jobject handle); template static oop resolve_jweak(jweak handle); + // This method is not inlined in order to avoid circular includes between + // this header file and thread.hpp. + static bool current_thread_in_native(); + public: // Low tag bit in jobject used to distinguish a jweak. jweak is // type equivalent to jobject, but there are places where we need to @@ -230,6 +234,7 @@ template inline oop JNIHandles::resolve_impl(jobject handle) { assert(handle != NULL, "precondition"); + assert(!current_thread_in_native(), "must not be in native"); oop result; if (is_jweak(handle)) { // Unlikely result = resolve_jweak(handle);