28 #include "memory/iterator.hpp"
29 #include "oops/oop.inline.hpp"
30 #include "prims/jvmtiExport.hpp"
31 #include "runtime/jniHandles.hpp"
32 #include "runtime/mutexLocker.hpp"
33 #include "runtime/thread.inline.hpp"
34 #if INCLUDE_ALL_GCS
35 #include "gc/g1/g1SATBCardTableModRefBS.hpp"
36 #endif
37
38 JNIHandleBlock* JNIHandles::_global_handles = NULL;
39 JNIHandleBlock* JNIHandles::_weak_global_handles = NULL;
40 oop JNIHandles::_deleted_handle = NULL;
41
42
43 jobject JNIHandles::make_local(oop obj) {
44 if (obj == NULL) {
45 return NULL; // ignore null handles
46 } else {
47 Thread* thread = Thread::current();
48 assert(Universe::heap()->is_in_reserved(obj), "sanity check");
49 return thread->active_handles()->allocate_handle(obj);
50 }
51 }
52
53
54 // optimized versions
55
56 jobject JNIHandles::make_local(Thread* thread, oop obj) {
57 if (obj == NULL) {
58 return NULL; // ignore null handles
59 } else {
60 assert(Universe::heap()->is_in_reserved(obj), "sanity check");
61 return thread->active_handles()->allocate_handle(obj);
62 }
63 }
64
65
66 jobject JNIHandles::make_local(JNIEnv* env, oop obj) {
67 if (obj == NULL) {
68 return NULL; // ignore null handles
69 } else {
70 JavaThread* thread = JavaThread::thread_from_jni_environment(env);
71 assert(Universe::heap()->is_in_reserved(obj), "sanity check");
72 return thread->active_handles()->allocate_handle(obj);
73 }
74 }
75
76
77 jobject JNIHandles::make_global(Handle obj) {
78 assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC");
79 jobject res = NULL;
80 if (!obj.is_null()) {
81 // ignore null handles
82 MutexLocker ml(JNIGlobalHandle_lock);
83 assert(Universe::heap()->is_in_reserved(obj()), "sanity check");
84 res = _global_handles->allocate_handle(obj());
85 } else {
86 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
87 }
88
89 return res;
90 }
91
92
93 jobject JNIHandles::make_weak_global(Handle obj) {
94 assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC");
95 jobject res = NULL;
96 if (!obj.is_null()) {
97 // ignore null handles
98 {
99 MutexLocker ml(JNIGlobalHandle_lock);
100 assert(Universe::heap()->is_in_reserved(obj()), "sanity check");
101 res = _weak_global_handles->allocate_handle(obj());
102 }
103 // Add weak tag.
104 assert(is_ptr_aligned(res, weak_tag_alignment), "invariant");
105 char* tptr = reinterpret_cast<char*>(res) + weak_tag_value;
106 res = reinterpret_cast<jobject>(tptr);
107 } else {
108 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
109 }
110 return res;
111 }
112
113 template<bool external_guard>
114 oop JNIHandles::resolve_jweak(jweak handle) {
115 assert(is_jweak(handle), "precondition");
116 oop result = jweak_ref(handle);
117 result = guard_value<external_guard>(result);
118 #if INCLUDE_ALL_GCS
119 if (result != NULL && UseG1GC) {
120 G1SATBCardTableModRefBS::enqueue(result);
367 // correct number of times).
368 release_block(pop_frame_link, thread);
369 }
370 }
371
372
373 void JNIHandleBlock::oops_do(OopClosure* f) {
374 JNIHandleBlock* current_chain = this;
375 // Iterate over chain of blocks, followed by chains linked through the
376 // pop frame links.
377 while (current_chain != NULL) {
378 for (JNIHandleBlock* current = current_chain; current != NULL;
379 current = current->_next) {
380 assert(current == current_chain || current->pop_frame_link() == NULL,
381 "only blocks first in chain should have pop frame link set");
382 for (int index = 0; index < current->_top; index++) {
383 oop* root = &(current->_handles)[index];
384 oop value = *root;
385 // traverse heap pointers only, not deleted handles or free list
386 // pointers
387 if (value != NULL && Universe::heap()->is_in_reserved(value)) {
388 f->do_oop(root);
389 }
390 }
391 // the next handle block is valid only if current block is full
392 if (current->_top < block_size_in_oops) {
393 break;
394 }
395 }
396 current_chain = current_chain->pop_frame_link();
397 }
398 }
399
400
401 void JNIHandleBlock::weak_oops_do(BoolObjectClosure* is_alive,
402 OopClosure* f) {
403 for (JNIHandleBlock* current = this; current != NULL; current = current->_next) {
404 assert(current->pop_frame_link() == NULL,
405 "blocks holding weak global JNI handles should not have pop frame link set");
406 for (int index = 0; index < current->_top; index++) {
407 oop* root = &(current->_handles)[index];
408 oop value = *root;
409 // traverse heap pointers only, not deleted handles or free list pointers
410 if (value != NULL && Universe::heap()->is_in_reserved(value)) {
411 if (is_alive->do_object_b(value)) {
412 // The weakly referenced object is alive, update pointer
413 f->do_oop(root);
414 } else {
415 // The weakly referenced object is not alive, clear the reference by storing NULL
416 log_develop_trace(gc, ref)("Clearing JNI weak reference (" INTPTR_FORMAT ")", p2i(root));
417 *root = NULL;
418 }
419 }
420 }
421 // the next handle block is valid only if current block is full
422 if (current->_top < block_size_in_oops) {
423 break;
424 }
425 }
426
427 /*
428 * JVMTI data structures may also contain weak oops. The iteration of them
429 * is placed here so that we don't need to add it to each of the collectors.
430 */
431 JvmtiExport::weak_oops_do(is_alive, f);
432 }
433
434
435 jobject JNIHandleBlock::allocate_handle(oop obj) {
436 assert(Universe::heap()->is_in_reserved(obj), "sanity check");
437 if (_top == 0) {
438 // This is the first allocation or the initial block got zapped when
439 // entering a native function. If we have any following blocks they are
440 // not valid anymore.
441 for (JNIHandleBlock* current = _next; current != NULL;
442 current = current->_next) {
443 assert(current->_last == NULL, "only first block should have _last set");
444 assert(current->_free_list == NULL,
445 "only first block should have _free_list set");
446 current->_top = 0;
447 if (ZapJNIHandleArea) current->zap();
448 }
449 // Clear initial block
450 _free_list = NULL;
451 _allocate_before_rebuild = 0;
452 _last = this;
453 if (ZapJNIHandleArea) zap();
454 }
455
456 // Try last block
|
28 #include "memory/iterator.hpp"
29 #include "oops/oop.inline.hpp"
30 #include "prims/jvmtiExport.hpp"
31 #include "runtime/jniHandles.hpp"
32 #include "runtime/mutexLocker.hpp"
33 #include "runtime/thread.inline.hpp"
34 #if INCLUDE_ALL_GCS
35 #include "gc/g1/g1SATBCardTableModRefBS.hpp"
36 #endif
37
38 JNIHandleBlock* JNIHandles::_global_handles = NULL;
39 JNIHandleBlock* JNIHandles::_weak_global_handles = NULL;
40 oop JNIHandles::_deleted_handle = NULL;
41
42
43 jobject JNIHandles::make_local(oop obj) {
44 if (obj == NULL) {
45 return NULL; // ignore null handles
46 } else {
47 Thread* thread = Thread::current();
48 assert(GC::gc()->heap()->is_in_reserved(obj), "sanity check");
49 return thread->active_handles()->allocate_handle(obj);
50 }
51 }
52
53
54 // optimized versions
55
56 jobject JNIHandles::make_local(Thread* thread, oop obj) {
57 if (obj == NULL) {
58 return NULL; // ignore null handles
59 } else {
60 assert(GC::gc()->heap()->is_in_reserved(obj), "sanity check");
61 return thread->active_handles()->allocate_handle(obj);
62 }
63 }
64
65
66 jobject JNIHandles::make_local(JNIEnv* env, oop obj) {
67 if (obj == NULL) {
68 return NULL; // ignore null handles
69 } else {
70 JavaThread* thread = JavaThread::thread_from_jni_environment(env);
71 assert(GC::gc()->heap()->is_in_reserved(obj), "sanity check");
72 return thread->active_handles()->allocate_handle(obj);
73 }
74 }
75
76
77 jobject JNIHandles::make_global(Handle obj) {
78 assert(!GC::gc()->heap()->is_gc_active(), "can't extend the root set during GC");
79 jobject res = NULL;
80 if (!obj.is_null()) {
81 // ignore null handles
82 MutexLocker ml(JNIGlobalHandle_lock);
83 assert(GC::gc()->heap()->is_in_reserved(obj()), "sanity check");
84 res = _global_handles->allocate_handle(obj());
85 } else {
86 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
87 }
88
89 return res;
90 }
91
92
93 jobject JNIHandles::make_weak_global(Handle obj) {
94 assert(!GC::gc()->heap()->is_gc_active(), "can't extend the root set during GC");
95 jobject res = NULL;
96 if (!obj.is_null()) {
97 // ignore null handles
98 {
99 MutexLocker ml(JNIGlobalHandle_lock);
100 assert(GC::gc()->heap()->is_in_reserved(obj()), "sanity check");
101 res = _weak_global_handles->allocate_handle(obj());
102 }
103 // Add weak tag.
104 assert(is_ptr_aligned(res, weak_tag_alignment), "invariant");
105 char* tptr = reinterpret_cast<char*>(res) + weak_tag_value;
106 res = reinterpret_cast<jobject>(tptr);
107 } else {
108 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
109 }
110 return res;
111 }
112
113 template<bool external_guard>
114 oop JNIHandles::resolve_jweak(jweak handle) {
115 assert(is_jweak(handle), "precondition");
116 oop result = jweak_ref(handle);
117 result = guard_value<external_guard>(result);
118 #if INCLUDE_ALL_GCS
119 if (result != NULL && UseG1GC) {
120 G1SATBCardTableModRefBS::enqueue(result);
367 // correct number of times).
368 release_block(pop_frame_link, thread);
369 }
370 }
371
372
373 void JNIHandleBlock::oops_do(OopClosure* f) {
374 JNIHandleBlock* current_chain = this;
375 // Iterate over chain of blocks, followed by chains linked through the
376 // pop frame links.
377 while (current_chain != NULL) {
378 for (JNIHandleBlock* current = current_chain; current != NULL;
379 current = current->_next) {
380 assert(current == current_chain || current->pop_frame_link() == NULL,
381 "only blocks first in chain should have pop frame link set");
382 for (int index = 0; index < current->_top; index++) {
383 oop* root = &(current->_handles)[index];
384 oop value = *root;
385 // traverse heap pointers only, not deleted handles or free list
386 // pointers
387 if (value != NULL && GC::gc()->heap()->is_in_reserved(value)) {
388 f->do_oop(root);
389 }
390 }
391 // the next handle block is valid only if current block is full
392 if (current->_top < block_size_in_oops) {
393 break;
394 }
395 }
396 current_chain = current_chain->pop_frame_link();
397 }
398 }
399
400
401 void JNIHandleBlock::weak_oops_do(BoolObjectClosure* is_alive,
402 OopClosure* f) {
403 for (JNIHandleBlock* current = this; current != NULL; current = current->_next) {
404 assert(current->pop_frame_link() == NULL,
405 "blocks holding weak global JNI handles should not have pop frame link set");
406 for (int index = 0; index < current->_top; index++) {
407 oop* root = &(current->_handles)[index];
408 oop value = *root;
409 // traverse heap pointers only, not deleted handles or free list pointers
410 if (value != NULL && GC::gc()->heap()->is_in_reserved(value)) {
411 if (is_alive->do_object_b(value)) {
412 // The weakly referenced object is alive, update pointer
413 f->do_oop(root);
414 } else {
415 // The weakly referenced object is not alive, clear the reference by storing NULL
416 log_develop_trace(gc, ref)("Clearing JNI weak reference (" INTPTR_FORMAT ")", p2i(root));
417 *root = NULL;
418 }
419 }
420 }
421 // the next handle block is valid only if current block is full
422 if (current->_top < block_size_in_oops) {
423 break;
424 }
425 }
426
427 /*
428 * JVMTI data structures may also contain weak oops. The iteration of them
429 * is placed here so that we don't need to add it to each of the collectors.
430 */
431 JvmtiExport::weak_oops_do(is_alive, f);
432 }
433
434
435 jobject JNIHandleBlock::allocate_handle(oop obj) {
436 assert(GC::gc()->heap()->is_in_reserved(obj), "sanity check");
437 if (_top == 0) {
438 // This is the first allocation or the initial block got zapped when
439 // entering a native function. If we have any following blocks they are
440 // not valid anymore.
441 for (JNIHandleBlock* current = _next; current != NULL;
442 current = current->_next) {
443 assert(current->_last == NULL, "only first block should have _last set");
444 assert(current->_free_list == NULL,
445 "only first block should have _free_list set");
446 current->_top = 0;
447 if (ZapJNIHandleArea) current->zap();
448 }
449 // Clear initial block
450 _free_list = NULL;
451 _allocate_before_rebuild = 0;
452 _last = this;
453 if (ZapJNIHandleArea) zap();
454 }
455
456 // Try last block
|