1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/runtime/jniHandles.hpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,199 @@ 1.4 +/* 1.5 + * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#ifndef SHARE_VM_RUNTIME_JNIHANDLES_HPP 1.29 +#define SHARE_VM_RUNTIME_JNIHANDLES_HPP 1.30 + 1.31 +#include "runtime/handles.hpp" 1.32 +#include "utilities/top.hpp" 1.33 + 1.34 +class JNIHandleBlock; 1.35 + 1.36 + 1.37 +// Interface for creating and resolving local/global JNI handles 1.38 + 1.39 +class JNIHandles : AllStatic { 1.40 + friend class VMStructs; 1.41 + private: 1.42 + static JNIHandleBlock* _global_handles; // First global handle block 1.43 + static JNIHandleBlock* _weak_global_handles; // First weak global handle block 1.44 + static oop _deleted_handle; // Sentinel marking deleted handles 1.45 + 1.46 + public: 1.47 + // Resolve handle into oop 1.48 + inline static oop resolve(jobject handle); 1.49 + // Resolve externally provided handle into oop with some guards 1.50 + inline static oop resolve_external_guard(jobject handle); 1.51 + // Resolve handle into oop, result guaranteed not to be null 1.52 + inline static oop resolve_non_null(jobject handle); 1.53 + 1.54 + // Local handles 1.55 + static jobject make_local(oop obj); 1.56 + static jobject make_local(JNIEnv* env, oop obj); // Fast version when env is known 1.57 + static jobject make_local(Thread* thread, oop obj); // Even faster version when current thread is known 1.58 + inline static void destroy_local(jobject handle); 1.59 + 1.60 + // Global handles 1.61 + static jobject make_global(Handle obj); 1.62 + static void destroy_global(jobject handle); 1.63 + 1.64 + // Weak global handles 1.65 + static jobject make_weak_global(Handle obj); 1.66 + static void destroy_weak_global(jobject handle); 1.67 + 1.68 + // Sentinel marking deleted handles in block. Note that we cannot store NULL as 1.69 + // the sentinel, since clearing weak global JNI refs are done by storing NULL in 1.70 + // the handle. The handle may not be reused before destroy_weak_global is called. 1.71 + static oop deleted_handle() { return _deleted_handle; } 1.72 + 1.73 + // Initialization 1.74 + static void initialize(); 1.75 + 1.76 + // Debugging 1.77 + static void print_on(outputStream* st); 1.78 + static void print() { print_on(tty); } 1.79 + static void verify(); 1.80 + static bool is_local_handle(Thread* thread, jobject handle); 1.81 + static bool is_frame_handle(JavaThread* thr, jobject obj); 1.82 + static bool is_global_handle(jobject handle); 1.83 + static bool is_weak_global_handle(jobject handle); 1.84 + static long global_handle_memory_usage(); 1.85 + static long weak_global_handle_memory_usage(); 1.86 + 1.87 + // Garbage collection support(global handles only, local handles are traversed from thread) 1.88 + // Traversal of regular global handles 1.89 + static void oops_do(OopClosure* f); 1.90 + // Traversal of weak global handles. Unreachable oops are cleared. 1.91 + static void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f); 1.92 +}; 1.93 + 1.94 + 1.95 + 1.96 +// JNI handle blocks holding local/global JNI handles 1.97 + 1.98 +class JNIHandleBlock : public CHeapObj<mtInternal> { 1.99 + friend class VMStructs; 1.100 + friend class CppInterpreter; 1.101 + 1.102 + private: 1.103 + enum SomeConstants { 1.104 + block_size_in_oops = 32 // Number of handles per handle block 1.105 + }; 1.106 + 1.107 + oop _handles[block_size_in_oops]; // The handles 1.108 + int _top; // Index of next unused handle 1.109 + JNIHandleBlock* _next; // Link to next block 1.110 + 1.111 + // The following instance variables are only used by the first block in a chain. 1.112 + // Having two types of blocks complicates the code and the space overhead in negligble. 1.113 + JNIHandleBlock* _last; // Last block in use 1.114 + JNIHandleBlock* _pop_frame_link; // Block to restore on PopLocalFrame call 1.115 + oop* _free_list; // Handle free list 1.116 + int _allocate_before_rebuild; // Number of blocks to allocate before rebuilding free list 1.117 + 1.118 + #ifndef PRODUCT 1.119 + JNIHandleBlock* _block_list_link; // Link for list below 1.120 + static JNIHandleBlock* _block_list; // List of all allocated blocks (for debugging only) 1.121 + #endif 1.122 + 1.123 + static JNIHandleBlock* _block_free_list; // Free list of currently unused blocks 1.124 + static int _blocks_allocated; // For debugging/printing 1.125 + 1.126 + // Fill block with bad_handle values 1.127 + void zap(); 1.128 + 1.129 + protected: 1.130 + // No more handles in the both the current and following blocks 1.131 + void clear() { _top = 0; } 1.132 + 1.133 + private: 1.134 + // Free list computation 1.135 + void rebuild_free_list(); 1.136 + 1.137 + public: 1.138 + // Handle allocation 1.139 + jobject allocate_handle(oop obj); 1.140 + 1.141 + // Block allocation and block free list management 1.142 + static JNIHandleBlock* allocate_block(Thread* thread = NULL); 1.143 + static void release_block(JNIHandleBlock* block, Thread* thread = NULL); 1.144 + 1.145 + // JNI PushLocalFrame/PopLocalFrame support 1.146 + JNIHandleBlock* pop_frame_link() const { return _pop_frame_link; } 1.147 + void set_pop_frame_link(JNIHandleBlock* block) { _pop_frame_link = block; } 1.148 + 1.149 + // Stub generator support 1.150 + static int top_offset_in_bytes() { return offset_of(JNIHandleBlock, _top); } 1.151 + 1.152 + // Garbage collection support 1.153 + // Traversal of regular handles 1.154 + void oops_do(OopClosure* f); 1.155 + // Traversal of weak handles. Unreachable oops are cleared. 1.156 + void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f); 1.157 + 1.158 + // Debugging 1.159 + bool chain_contains(jobject handle) const; // Does this block or following blocks contain handle 1.160 + bool contains(jobject handle) const; // Does this block contain handle 1.161 + int length() const; // Length of chain starting with this block 1.162 + long memory_usage() const; 1.163 + #ifndef PRODUCT 1.164 + static bool any_contains(jobject handle); // Does any block currently in use contain handle 1.165 + static void print_statistics(); 1.166 + #endif 1.167 +}; 1.168 + 1.169 + 1.170 +inline oop JNIHandles::resolve(jobject handle) { 1.171 + oop result = (handle == NULL ? (oop)NULL : *(oop*)handle); 1.172 + assert(result != NULL || (handle == NULL || !CheckJNICalls || is_weak_global_handle(handle)), "Invalid value read from jni handle"); 1.173 + assert(result != badJNIHandle, "Pointing to zapped jni handle area"); 1.174 + return result; 1.175 +}; 1.176 + 1.177 + 1.178 +inline oop JNIHandles::resolve_external_guard(jobject handle) { 1.179 + if (handle == NULL) return NULL; 1.180 + oop result = *(oop*)handle; 1.181 + if (result == NULL || result == badJNIHandle) return NULL; 1.182 + return result; 1.183 +}; 1.184 + 1.185 + 1.186 +inline oop JNIHandles::resolve_non_null(jobject handle) { 1.187 + assert(handle != NULL, "JNI handle should not be null"); 1.188 + oop result = *(oop*)handle; 1.189 + assert(result != NULL, "Invalid value read from jni handle"); 1.190 + assert(result != badJNIHandle, "Pointing to zapped jni handle area"); 1.191 + // Don't let that private _deleted_handle object escape into the wild. 1.192 + assert(result != deleted_handle(), "Used a deleted global handle."); 1.193 + return result; 1.194 +}; 1.195 + 1.196 +inline void JNIHandles::destroy_local(jobject handle) { 1.197 + if (handle != NULL) { 1.198 + *((oop*)handle) = deleted_handle(); // Mark the handle as deleted, allocate will reuse it 1.199 + } 1.200 +} 1.201 + 1.202 +#endif // SHARE_VM_RUNTIME_JNIHANDLES_HPP