hotspot Udiff src/share/vm/runtime/jniHandles.hpp (original) (raw)
rev 12541 : imported patch weak_tag rev 12551 : imported patch always_tag
@@ -1,7 +1,7 @@ /*
- Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
- Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
- DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- This code is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License version 2 only, as
- published by the Free Software Foundation.
@@ -25,10 +25,13 @@ #ifndef SHARE_VM_RUNTIME_JNIHANDLES_HPP #define SHARE_VM_RUNTIME_JNIHANDLES_HPP
#include "memory/allocation.hpp" #include "runtime/handles.hpp" +#if INCLUDE_ALL_GCS +#include "gc/g1/g1SATBCardTableModRefBS.hpp" +#endif
class JNIHandleBlock;
// Interface for creating and resolving local/global JNI handles
@@ -38,11 +41,24 @@ 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 inline static oop guard_value(oop value);
- template inline static oop resolve_impl(jobject handle);
- public:
- // Low tag bit in jobject used to distinguish a jweak.
- static const uintptr_t weak_tag_size = 1;
- static const uintptr_t weak_tag_alignment = (1u << weak_tag_size);
- static const uintptr_t weak_tag_mask = weak_tag_alignment - 1;
- static const int weak_tag_value = 1;
- // Resolve handle into oop inline static oop resolve(jobject handle); // Resolve externally provided handle into oop with some guards inline static oop resolve_external_guard(jobject handle); // Resolve handle into oop, result guaranteed not to be null
@@ -174,39 +190,86 @@ static bool any_contains(jobject handle); // Does any block currently in use contain handle static void print_statistics(); #endif }; +inline bool JNIHandles::is_jweak(jobject handle) { + STATIC_ASSERT(weak_tag_size == 1); + STATIC_ASSERT(weak_tag_value == 1); + return (reinterpret_cast(handle) & weak_tag_mask) != 0; +} -inline oop JNIHandles::resolve(jobject handle) { - oop result = (handle == NULL ? (oop)NULL : (oop)handle); - assert(result != NULL || (handle == NULL || !CheckJNICalls || is_weak_global_handle(handle)), "Invalid value read from jni handle"); - assert(result != badJNIHandle, "Pointing to zapped jni handle area"); +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); +} + +template +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; +} + +template +inline oop JNIHandles::resolve_impl(jobject handle) { + assert(handle != NULL, "precondition"); + oop result; + if (is_jweak(handle)) { // Unlikely + result = jweak_ref(handle); + result = guard_value(result); +#if INCLUDE_ALL_GCS + if (result != NULL && UseG1GC) { + G1SATBCardTableModRefBS::enqueue(result); + } +#endif // INCLUDE_ALL_GCS + } 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(result); + } return result; -}; +} +inline oop JNIHandles::resolve(jobject handle) { + oop result = NULL; + if (handle != NULL) { + result = resolve_impl<false /* external_guard */ >(handle); + } + return result; +} inline oop JNIHandles::resolve_external_guard(jobject handle) { - if (handle == NULL) return NULL; - oop result = (oop)handle; - if (result == NULL || result == badJNIHandle) return NULL; + 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 = (oop)handle;
- assert(result != NULL, "Invalid value read from jni handle");
- assert(result != badJNIHandle, "Pointing to zapped jni handle area");
- // Don't let that private _deleted_handle object escape into the wild.
- assert(result != deleted_handle(), "Used a deleted global handle.");
- 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) {
- ((oop)handle) = deleted_handle(); // Mark the handle as deleted, allocate will reuse it
- jobject_ref(handle) = deleted_handle();
} }
#endif // SHARE_VM_RUNTIME_JNIHANDLES_HPP