1 /*
  2  * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 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 #ifndef SHARE_RUNTIME_JNIHANDLES_INLINE_HPP
 26 #define SHARE_RUNTIME_JNIHANDLES_INLINE_HPP
 27 
 28 #include "runtime/jniHandles.hpp"
 29 
 30 #include "oops/access.inline.hpp"
 31 #include "oops/oop.hpp"
 32 #include "utilities/debug.hpp"
 33 #include "utilities/globalDefinitions.hpp"
 34 
 35 inline bool JNIHandles::is_jweak(jobject handle) {
 36   STATIC_ASSERT(weak_tag_size == 1);
 37   STATIC_ASSERT(weak_tag_value == 1);
 38   return (reinterpret_cast<uintptr_t>(handle) & weak_tag_mask) != 0;
 39 }
 40 
 41 inline oop* JNIHandles::jobject_ptr(jobject handle) {
 42   assert(!is_jweak(handle), "precondition");
 43   return reinterpret_cast<oop*>(handle);
 44 }
 45 
 46 inline oop* JNIHandles::jweak_ptr(jobject handle) {
 47   assert(is_jweak(handle), "precondition");
 48   char* ptr = reinterpret_cast<char*>(handle) - weak_tag_value;
 49   return reinterpret_cast<oop*>(ptr);
 50 }
 51 
 52 // external_guard is true if called from resolve_external_guard.
 53 template <DecoratorSet decorators, bool external_guard>
 54 inline oop JNIHandles::resolve_impl(jobject handle) {
 55   assert(handle != NULL, "precondition");
 56   assert(!current_thread_in_native(), "must not be in native");
 57   oop result;
 58   if (is_jweak(handle)) {       // Unlikely
 59     result = NativeAccess<ON_PHANTOM_OOP_REF|decorators>::oop_load(jweak_ptr(handle));
 60   } else {
 61     result = NativeAccess<decorators>::oop_load(jobject_ptr(handle));
 62     // Construction of jobjects canonicalize a null value into a null
 63     // jobject, so for non-jweak the pointee should never be null.
 64     assert(external_guard || result != NULL, "Invalid JNI handle");
 65   }
 66   return result;
 67 }
 68 
 69 inline oop JNIHandles::resolve(jobject handle) {
 70   oop result = NULL;
 71   if (handle != NULL) {
 72     result = resolve_impl<DECORATORS_NONE, false /* external_guard */>(handle);
 73   }
 74   return result;
 75 }
 76 
 77 inline oop JNIHandles::resolve_no_keepalive(jobject handle) {
 78   oop result = NULL;
 79   if (handle != NULL) {
 80     result = resolve_impl<AS_NO_KEEPALIVE, false /* external_guard */>(handle);
 81   }
 82   return result;
 83 }
 84 
 85 inline bool JNIHandles::is_same_object(jobject handle1, jobject handle2) {
 86   oop obj1 = resolve_no_keepalive(handle1);
 87   oop obj2 = resolve_no_keepalive(handle2);
 88   return obj1 == obj2;
 89 }
 90 
 91 inline oop JNIHandles::resolve_non_null(jobject handle) {
 92   assert(handle != NULL, "JNI handle should not be null");
 93   oop result = resolve_impl<DECORATORS_NONE, false /* external_guard */>(handle);
 94   assert(result != NULL, "NULL read from jni handle");
 95   return result;
 96 }
 97 
 98 inline void JNIHandles::destroy_local(jobject handle) {
 99   if (handle != NULL) {
100     assert(!is_jweak(handle), "Invalid JNI local handle");
101     NativeAccess<>::oop_store(jobject_ptr(handle), (oop)NULL);
102   }
103 }
104 
105 #endif // SHARE_RUNTIME_JNIHANDLES_INLINE_HPP