65 static const uintptr_t weak_tag_mask = weak_tag_alignment - 1; |
65 static const uintptr_t weak_tag_mask = weak_tag_alignment - 1; |
66 static const int weak_tag_value = 1; |
66 static const int weak_tag_value = 1; |
67 |
67 |
68 // Resolve handle into oop |
68 // Resolve handle into oop |
69 inline static oop resolve(jobject handle); |
69 inline static oop resolve(jobject handle); |
70 // Resolve externally provided handle into oop with some guards |
|
71 inline static oop resolve_external_guard(jobject handle); |
|
72 // Resolve handle into oop, result guaranteed not to be null |
70 // Resolve handle into oop, result guaranteed not to be null |
73 inline static oop resolve_non_null(jobject handle); |
71 inline static oop resolve_non_null(jobject handle); |
|
72 // Resolve externally provided handle into oop with some guards |
|
73 static oop resolve_external_guard(jobject handle); |
74 |
74 |
75 // Local handles |
75 // Local handles |
76 static jobject make_local(oop obj); |
76 static jobject make_local(oop obj); |
77 static jobject make_local(JNIEnv* env, oop obj); // Fast version when env is known |
77 static jobject make_local(JNIEnv* env, oop obj); // Fast version when env is known |
78 static jobject make_local(Thread* thread, oop obj); // Even faster version when current thread is known |
78 static jobject make_local(Thread* thread, oop obj); // Even faster version when current thread is known |
196 static bool any_contains(jobject handle); // Does any block currently in use contain handle |
196 static bool any_contains(jobject handle); // Does any block currently in use contain handle |
197 static void print_statistics(); |
197 static void print_statistics(); |
198 #endif |
198 #endif |
199 }; |
199 }; |
200 |
200 |
201 inline bool JNIHandles::is_jweak(jobject handle) { |
|
202 STATIC_ASSERT(weak_tag_size == 1); |
|
203 STATIC_ASSERT(weak_tag_value == 1); |
|
204 return (reinterpret_cast<uintptr_t>(handle) & weak_tag_mask) != 0; |
|
205 } |
|
206 |
|
207 inline oop& JNIHandles::jobject_ref(jobject handle) { |
|
208 assert(!is_jweak(handle), "precondition"); |
|
209 return *reinterpret_cast<oop*>(handle); |
|
210 } |
|
211 |
|
212 inline oop& JNIHandles::jweak_ref(jobject handle) { |
|
213 assert(is_jweak(handle), "precondition"); |
|
214 char* ptr = reinterpret_cast<char*>(handle) - weak_tag_value; |
|
215 return *reinterpret_cast<oop*>(ptr); |
|
216 } |
|
217 |
|
218 // external_guard is true if called from resolve_external_guard. |
|
219 template<bool external_guard> |
|
220 inline oop JNIHandles::resolve_impl(jobject handle) { |
|
221 assert(handle != NULL, "precondition"); |
|
222 assert(!current_thread_in_native(), "must not be in native"); |
|
223 oop result; |
|
224 if (is_jweak(handle)) { // Unlikely |
|
225 result = resolve_jweak(handle); |
|
226 } else { |
|
227 result = jobject_ref(handle); |
|
228 // Construction of jobjects canonicalize a null value into a null |
|
229 // jobject, so for non-jweak the pointee should never be null. |
|
230 assert(external_guard || result != NULL, "Invalid JNI handle"); |
|
231 } |
|
232 return result; |
|
233 } |
|
234 |
|
235 inline oop JNIHandles::resolve(jobject handle) { |
|
236 oop result = NULL; |
|
237 if (handle != NULL) { |
|
238 result = resolve_impl<false /* external_guard */ >(handle); |
|
239 } |
|
240 return result; |
|
241 } |
|
242 |
|
243 // Resolve some erroneous cases to NULL, rather than treating them as |
|
244 // possibly unchecked errors. In particular, deleted handles are |
|
245 // treated as NULL (though a deleted and later reallocated handle |
|
246 // isn't detected). |
|
247 inline oop JNIHandles::resolve_external_guard(jobject handle) { |
|
248 oop result = NULL; |
|
249 if (handle != NULL) { |
|
250 result = resolve_impl<true /* external_guard */ >(handle); |
|
251 } |
|
252 return result; |
|
253 } |
|
254 |
|
255 inline oop JNIHandles::resolve_non_null(jobject handle) { |
|
256 assert(handle != NULL, "JNI handle should not be null"); |
|
257 oop result = resolve_impl<false /* external_guard */ >(handle); |
|
258 assert(result != NULL, "NULL read from jni handle"); |
|
259 return result; |
|
260 } |
|
261 |
|
262 inline void JNIHandles::destroy_local(jobject handle) { |
|
263 if (handle != NULL) { |
|
264 assert(!is_jweak(handle), "Invalid JNI local handle"); |
|
265 jobject_ref(handle) = NULL; |
|
266 } |
|
267 } |
|
268 |
|
269 #endif // SHARE_VM_RUNTIME_JNIHANDLES_HPP |
201 #endif // SHARE_VM_RUNTIME_JNIHANDLES_HPP |