12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "classfile/systemDictionary.hpp" 27 #include "oops/oop.inline.hpp" 28 #include "prims/jvmtiExport.hpp" 29 #include "runtime/jniHandles.hpp" 30 #include "runtime/mutexLocker.hpp" 31 #include "runtime/thread.inline.hpp" 32 33 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC 34 35 JNIHandleBlock* JNIHandles::_global_handles = NULL; 36 JNIHandleBlock* JNIHandles::_weak_global_handles = NULL; 37 oop JNIHandles::_deleted_handle = NULL; 38 39 40 jobject JNIHandles::make_local(oop obj) { 41 if (obj == NULL) { 42 return NULL; // ignore null handles 43 } else { 44 Thread* thread = Thread::current(); 45 assert(Universe::heap()->is_in_reserved(obj), "sanity check"); 46 return thread->active_handles()->allocate_handle(obj); 47 } 48 } 49 50 51 // optimized versions 69 return thread->active_handles()->allocate_handle(obj); 70 } 71 } 72 73 74 jobject JNIHandles::make_global(Handle obj) { 75 assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC"); 76 jobject res = NULL; 77 if (!obj.is_null()) { 78 // ignore null handles 79 MutexLocker ml(JNIGlobalHandle_lock); 80 assert(Universe::heap()->is_in_reserved(obj()), "sanity check"); 81 res = _global_handles->allocate_handle(obj()); 82 } else { 83 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); 84 } 85 86 return res; 87 } 88 89 90 jobject JNIHandles::make_weak_global(Handle obj) { 91 assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC"); 92 jobject res = NULL; 93 if (!obj.is_null()) { 94 // ignore null handles 95 MutexLocker ml(JNIGlobalHandle_lock); 96 assert(Universe::heap()->is_in_reserved(obj()), "sanity check"); 97 res = _weak_global_handles->allocate_handle(obj()); 98 } else { 99 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); 100 } 101 return res; 102 } 103 104 105 void JNIHandles::destroy_global(jobject handle) { 106 if (handle != NULL) { 107 assert(is_global_handle(handle), "Invalid delete of global JNI handle"); 108 *((oop*)handle) = deleted_handle(); // Mark the handle as deleted, allocate will reuse it 109 } 110 } 111 112 113 void JNIHandles::destroy_weak_global(jobject handle) { 114 if (handle != NULL) { 115 assert(!CheckJNICalls || is_weak_global_handle(handle), "Invalid delete of weak global JNI handle"); 116 *((oop*)handle) = deleted_handle(); // Mark the handle as deleted, allocate will reuse it 117 } 118 } 119 120 121 void JNIHandles::oops_do(OopClosure* f) { 122 f->do_oop(&_deleted_handle); 123 _global_handles->oops_do(f); 124 } 125 126 127 void JNIHandles::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) { 128 _weak_global_handles->weak_oops_do(is_alive, f); 129 } 130 131 132 void JNIHandles::initialize() { 133 _global_handles = JNIHandleBlock::allocate_block(); 134 _weak_global_handles = JNIHandleBlock::allocate_block(); 135 EXCEPTION_MARK; 136 // We will never reach the CATCH below since Exceptions::_throw will cause | 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "classfile/systemDictionary.hpp" 27 #include "oops/oop.inline.hpp" 28 #include "prims/jvmtiExport.hpp" 29 #include "runtime/jniHandles.hpp" 30 #include "runtime/mutexLocker.hpp" 31 #include "runtime/thread.inline.hpp" 32 #if INCLUDE_ALL_GCS 33 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" 34 #endif 35 36 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC 37 38 JNIHandleBlock* JNIHandles::_global_handles = NULL; 39 JNIHandleBlock* JNIHandles::_weak_global_handles = NULL; 40 oop JNIHandles::_deleted_handle = NULL; 41 42 43 jobject JNIHandles::make_local(oop obj) { 44 if (obj == NULL) { 45 return NULL; // ignore null handles 46 } else { 47 Thread* thread = Thread::current(); 48 assert(Universe::heap()->is_in_reserved(obj), "sanity check"); 49 return thread->active_handles()->allocate_handle(obj); 50 } 51 } 52 53 54 // optimized versions 72 return thread->active_handles()->allocate_handle(obj); 73 } 74 } 75 76 77 jobject JNIHandles::make_global(Handle obj) { 78 assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC"); 79 jobject res = NULL; 80 if (!obj.is_null()) { 81 // ignore null handles 82 MutexLocker ml(JNIGlobalHandle_lock); 83 assert(Universe::heap()->is_in_reserved(obj()), "sanity check"); 84 res = _global_handles->allocate_handle(obj()); 85 } else { 86 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); 87 } 88 89 return res; 90 } 91 92 jobject JNIHandles::make_weak_global(Handle obj) { 93 assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC"); 94 jobject res = NULL; 95 if (!obj.is_null()) { 96 // ignore null handles 97 { 98 MutexLocker ml(JNIGlobalHandle_lock); 99 assert(Universe::heap()->is_in_reserved(obj()), "sanity check"); 100 res = _weak_global_handles->allocate_handle(obj()); 101 } 102 // Add weak tag. 103 assert(is_ptr_aligned(res, weak_tag_alignment), "invariant"); 104 char* tptr = reinterpret_cast<char*>(res) + weak_tag_value; 105 res = reinterpret_cast<jobject>(tptr); 106 } else { 107 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); 108 } 109 return res; 110 } 111 112 template<bool external_guard> 113 oop JNIHandles::resolve_jweak(jweak handle) { 114 assert(is_jweak(handle), "precondition"); 115 oop result = jweak_ref(handle); 116 result = guard_value<external_guard>(result); 117 #if INCLUDE_ALL_GCS 118 if (result != NULL && UseG1GC) { 119 G1SATBCardTableModRefBS::enqueue(result); 120 } 121 #endif // INCLUDE_ALL_GCS 122 return result; 123 } 124 125 template oop JNIHandles::resolve_jweak<true>(jweak); 126 template oop JNIHandles::resolve_jweak<false>(jweak); 127 128 void JNIHandles::destroy_global(jobject handle) { 129 if (handle != NULL) { 130 assert(is_global_handle(handle), "Invalid delete of global JNI handle"); 131 jobject_ref(handle) = deleted_handle(); 132 } 133 } 134 135 void JNIHandles::destroy_weak_global(jobject handle) { 136 if (handle != NULL) { 137 jweak_ref(handle) = deleted_handle(); 138 } 139 } 140 141 142 void JNIHandles::oops_do(OopClosure* f) { 143 f->do_oop(&_deleted_handle); 144 _global_handles->oops_do(f); 145 } 146 147 148 void JNIHandles::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) { 149 _weak_global_handles->weak_oops_do(is_alive, f); 150 } 151 152 153 void JNIHandles::initialize() { 154 _global_handles = JNIHandleBlock::allocate_block(); 155 _weak_global_handles = JNIHandleBlock::allocate_block(); 156 EXCEPTION_MARK; 157 // We will never reach the CATCH below since Exceptions::_throw will cause |