< 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 >