< prev index next >

src/share/vm/runtime/jniHandles.hpp

Print this page
rev 12906 : [mq]: gc_interface

*** 38,55 **** private: static JNIHandleBlock* _global_handles; // First global handle block static JNIHandleBlock* _weak_global_handles; // First weak global handle block static oop _deleted_handle; // Sentinel marking deleted handles inline static bool is_jweak(jobject handle); - inline static oop& jobject_ref(jobject handle); // NOT jweak! - inline static oop& jweak_ref(jobject handle); template<bool external_guard> inline static oop guard_value(oop value); template<bool external_guard> inline static oop resolve_impl(jobject handle); template<bool external_guard> static oop resolve_jweak(jweak handle); 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 // be able to distinguish jweak values from other jobjects, and // is_weak_global_handle is unsuitable for performance reasons. To --- 38,117 ---- private: static JNIHandleBlock* _global_handles; // First global handle block static JNIHandleBlock* _weak_global_handles; // First weak global handle block static oop _deleted_handle; // Sentinel marking deleted handles + inline static oop* oop_addr(jobject handle); inline static bool is_jweak(jobject handle); template<bool external_guard> inline static oop guard_value(oop value); template<bool external_guard> inline static oop resolve_impl(jobject handle); template<bool external_guard> static oop resolve_jweak(jweak handle); + static oop resolve_handle(jobject handle); + + enum ResolveType { + DEFAULT, + EXTERNAL_GUARD, + NOT_NULL + }; + + template <ResolveType type> + class JNIHandleResolver: public StackObj { + oop _value; + + bool is_not_null() const { + return type == NOT_NULL; + } + + bool is_external_guard() const { + return type == EXTERNAL_GUARD; + } + + bool is_default() const { + return type == DEFAULT; + } + + bool is_dead(oop value) const { + return value == NULL || value == badJNIHandle || value == deleted_handle(); + } + + void assert_not_dead(oop value) const { + if (!is_external_guard()) { + assert(value != badJNIHandle, "Pointing to zapped jni handle area"); + assert(value == NULL || value != deleted_handle(), "Used a deleted global handle"); + } + } + + public: + JNIHandleResolver(jobject handle) { + oop value; + assert(!is_not_null() || handle != NULL, "JNI handle should not be null"); + if (!is_not_null() && handle == NULL) { + value = NULL; + } else { + value = *oop_addr(handle); + assert_not_dead(value); + if (is_external_guard() && is_dead(value)) { + value = NULL; + } else { + value = resolve_handle(handle); + } + } + _value = value; + } + + oop value() const { + return _value; + } + + ~JNIHandleResolver() { + assert_not_dead(_value); + assert(!is_not_null() || _value != NULL, "NULL read from jni handle"); + } + }; + 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 // be able to distinguish jweak values from other jobjects, and // is_weak_global_handle is unsuitable for performance reasons. To
*** 201,282 **** STATIC_ASSERT(weak_tag_size == 1); STATIC_ASSERT(weak_tag_value == 1); return (reinterpret_cast<uintptr_t>(handle) & weak_tag_mask) != 0; } ! inline oop& JNIHandles::jobject_ref(jobject handle) { ! assert(!is_jweak(handle), "precondition"); ! return *reinterpret_cast<oop*>(handle); ! } ! ! inline oop& JNIHandles::jweak_ref(jobject handle) { ! assert(is_jweak(handle), "precondition"); ! char* ptr = reinterpret_cast<char*>(handle) - weak_tag_value; ! return *reinterpret_cast<oop*>(ptr); ! } ! ! // external_guard is true if called from resolve_external_guard. ! // Treat deleted (and possibly zapped) as NULL for external_guard, ! // else as (asserted) error. ! template<bool external_guard> ! inline oop JNIHandles::guard_value(oop value) { ! if (!external_guard) { ! assert(value != badJNIHandle, "Pointing to zapped jni handle area"); ! assert(value != deleted_handle(), "Used a deleted global handle"); ! } else if ((value == badJNIHandle) || (value == deleted_handle())) { ! value = NULL; ! } ! return value; ! } ! ! // external_guard is true if called from resolve_external_guard. ! template<bool external_guard> ! inline oop JNIHandles::resolve_impl(jobject handle) { ! assert(handle != NULL, "precondition"); ! oop result; ! if (is_jweak(handle)) { // Unlikely ! result = resolve_jweak<external_guard>(handle); ! } else { ! result = jobject_ref(handle); ! // Construction of jobjects canonicalize a null value into a null ! // jobject, so for non-jweak the pointee should never be null. ! assert(external_guard || result != NULL, ! "Invalid value read from jni handle"); ! result = guard_value<external_guard>(result); ! } ! return result; } inline oop JNIHandles::resolve(jobject handle) { ! oop result = NULL; ! if (handle != NULL) { ! result = resolve_impl<false /* external_guard */ >(handle); ! } ! return result; } // Resolve some erroneous cases to NULL, rather than treating them as // possibly unchecked errors. In particular, deleted handles are // treated as NULL (though a deleted and later reallocated handle // isn't detected). inline oop JNIHandles::resolve_external_guard(jobject handle) { ! oop result = NULL; ! if (handle != NULL) { ! result = resolve_impl<true /* external_guard */ >(handle); ! } ! return result; } inline oop JNIHandles::resolve_non_null(jobject handle) { ! assert(handle != NULL, "JNI handle should not be null"); ! oop result = resolve_impl<false /* external_guard */ >(handle); ! assert(result != NULL, "NULL read from jni handle"); ! return result; } inline void JNIHandles::destroy_local(jobject handle) { if (handle != NULL) { ! jobject_ref(handle) = deleted_handle(); } } #endif // SHARE_VM_RUNTIME_JNIHANDLES_HPP --- 263,294 ---- STATIC_ASSERT(weak_tag_size == 1); STATIC_ASSERT(weak_tag_value == 1); return (reinterpret_cast<uintptr_t>(handle) & weak_tag_mask) != 0; } ! inline oop* JNIHandles::oop_addr(jobject handle) { ! return (oop*)(reinterpret_cast<uintptr_t>(handle) & ~(weak_tag_mask)); } inline oop JNIHandles::resolve(jobject handle) { ! return JNIHandleResolver<DEFAULT>(handle).value(); } // Resolve some erroneous cases to NULL, rather than treating them as // possibly unchecked errors. In particular, deleted handles are // treated as NULL (though a deleted and later reallocated handle // isn't detected). inline oop JNIHandles::resolve_external_guard(jobject handle) { ! return JNIHandleResolver<EXTERNAL_GUARD>(handle).value(); } inline oop JNIHandles::resolve_non_null(jobject handle) { ! return JNIHandleResolver<NOT_NULL>(handle).value(); } inline void JNIHandles::destroy_local(jobject handle) { if (handle != NULL) { ! *oop_addr(handle) = deleted_handle(); } } #endif // SHARE_VM_RUNTIME_JNIHANDLES_HPP
< prev index next >