< prev index next >

src/share/vm/runtime/jniHandles.cpp

Print this page
rev 11777 : [mq]: gcinterface.patch


  25 #include "precompiled.hpp"
  26 #include "classfile/systemDictionary.hpp"
  27 #include "logging/log.hpp"
  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 
  35 JNIHandleBlock* JNIHandles::_global_handles       = NULL;
  36 JNIHandleBlock* JNIHandles::_weak_global_handles  = NULL;
  37 oop             JNIHandles::_deleted_handle       = NULL;
  38 
  39 
  40 jobject JNIHandles::make_local(oop obj) {
  41   if (obj == NULL) {
  42     return NULL;                // ignore null handles
  43   } else {
  44     Thread* thread = Thread::current();
  45     assert(Universe::heap()->is_in_reserved(obj), "sanity check");
  46     return thread->active_handles()->allocate_handle(obj);
  47   }
  48 }
  49 
  50 
  51 // optimized versions
  52 
  53 jobject JNIHandles::make_local(Thread* thread, oop obj) {
  54   if (obj == NULL) {
  55     return NULL;                // ignore null handles
  56   } else {
  57     assert(Universe::heap()->is_in_reserved(obj), "sanity check");
  58     return thread->active_handles()->allocate_handle(obj);
  59   }
  60 }
  61 
  62 
  63 jobject JNIHandles::make_local(JNIEnv* env, oop obj) {
  64   if (obj == NULL) {
  65     return NULL;                // ignore null handles
  66   } else {
  67     JavaThread* thread = JavaThread::thread_from_jni_environment(env);
  68     assert(Universe::heap()->is_in_reserved(obj), "sanity check");
  69     return thread->active_handles()->allocate_handle(obj);
  70   }
  71 }
  72 
  73 
  74 jobject JNIHandles::make_global(Handle obj) {
  75   assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC");
  76   jobject res = NULL;
  77   if (!obj.is_null()) {
  78     // ignore null handles
  79     MutexLocker ml(JNIGlobalHandle_lock);
  80     assert(Universe::heap()->is_in_reserved(obj()), "sanity check");
  81     res = _global_handles->allocate_handle(obj());
  82   } else {
  83     CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
  84   }
  85 
  86   return res;
  87 }
  88 
  89 
  90 jobject JNIHandles::make_weak_global(Handle obj) {
  91   assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC");
  92   jobject res = NULL;
  93   if (!obj.is_null()) {
  94     // ignore null handles
  95     MutexLocker ml(JNIGlobalHandle_lock);
  96     assert(Universe::heap()->is_in_reserved(obj()), "sanity check");
  97     res = _weak_global_handles->allocate_handle(obj());
  98   } else {
  99     CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
 100   }
 101   return res;
 102 }
 103 
 104 
 105 void JNIHandles::destroy_global(jobject handle) {
 106   if (handle != NULL) {
 107     assert(is_global_handle(handle), "Invalid delete of global JNI handle");
 108     *((oop*)handle) = deleted_handle(); // Mark the handle as deleted, allocate will reuse it
 109   }
 110 }
 111 
 112 
 113 void JNIHandles::destroy_weak_global(jobject handle) {
 114   if (handle != NULL) {
 115     assert(!CheckJNICalls || is_weak_global_handle(handle), "Invalid delete of weak global JNI handle");
 116     *((oop*)handle) = deleted_handle(); // Mark the handle as deleted, allocate will reuse it


 344     // correct number of times).
 345     release_block(pop_frame_link, thread);
 346   }
 347 }
 348 
 349 
 350 void JNIHandleBlock::oops_do(OopClosure* f) {
 351   JNIHandleBlock* current_chain = this;
 352   // Iterate over chain of blocks, followed by chains linked through the
 353   // pop frame links.
 354   while (current_chain != NULL) {
 355     for (JNIHandleBlock* current = current_chain; current != NULL;
 356          current = current->_next) {
 357       assert(current == current_chain || current->pop_frame_link() == NULL,
 358         "only blocks first in chain should have pop frame link set");
 359       for (int index = 0; index < current->_top; index++) {
 360         oop* root = &(current->_handles)[index];
 361         oop value = *root;
 362         // traverse heap pointers only, not deleted handles or free list
 363         // pointers
 364         if (value != NULL && Universe::heap()->is_in_reserved(value)) {
 365           f->do_oop(root);
 366         }
 367       }
 368       // the next handle block is valid only if current block is full
 369       if (current->_top < block_size_in_oops) {
 370         break;
 371       }
 372     }
 373     current_chain = current_chain->pop_frame_link();
 374   }
 375 }
 376 
 377 
 378 void JNIHandleBlock::weak_oops_do(BoolObjectClosure* is_alive,
 379                                   OopClosure* f) {
 380   for (JNIHandleBlock* current = this; current != NULL; current = current->_next) {
 381     assert(current->pop_frame_link() == NULL,
 382       "blocks holding weak global JNI handles should not have pop frame link set");
 383     for (int index = 0; index < current->_top; index++) {
 384       oop* root = &(current->_handles)[index];
 385       oop value = *root;
 386       // traverse heap pointers only, not deleted handles or free list pointers
 387       if (value != NULL && Universe::heap()->is_in_reserved(value)) {
 388         if (is_alive->do_object_b(value)) {
 389           // The weakly referenced object is alive, update pointer
 390           f->do_oop(root);
 391         } else {
 392           // The weakly referenced object is not alive, clear the reference by storing NULL
 393           log_develop_trace(gc, ref)("Clearing JNI weak reference (" INTPTR_FORMAT ")", p2i(root));
 394           *root = NULL;
 395         }
 396       }
 397     }
 398     // the next handle block is valid only if current block is full
 399     if (current->_top < block_size_in_oops) {
 400       break;
 401     }
 402   }
 403 
 404   /*
 405    * JVMTI data structures may also contain weak oops.  The iteration of them
 406    * is placed here so that we don't need to add it to each of the collectors.
 407    */
 408   JvmtiExport::weak_oops_do(is_alive, f);
 409 }
 410 
 411 
 412 jobject JNIHandleBlock::allocate_handle(oop obj) {
 413   assert(Universe::heap()->is_in_reserved(obj), "sanity check");
 414   if (_top == 0) {
 415     // This is the first allocation or the initial block got zapped when
 416     // entering a native function. If we have any following blocks they are
 417     // not valid anymore.
 418     for (JNIHandleBlock* current = _next; current != NULL;
 419          current = current->_next) {
 420       assert(current->_last == NULL, "only first block should have _last set");
 421       assert(current->_free_list == NULL,
 422              "only first block should have _free_list set");
 423       current->_top = 0;
 424       if (ZapJNIHandleArea) current->zap();
 425     }
 426     // Clear initial block
 427     _free_list = NULL;
 428     _allocate_before_rebuild = 0;
 429     _last = this;
 430     if (ZapJNIHandleArea) zap();
 431   }
 432 
 433   // Try last block




  25 #include "precompiled.hpp"
  26 #include "classfile/systemDictionary.hpp"
  27 #include "logging/log.hpp"
  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 
  35 JNIHandleBlock* JNIHandles::_global_handles       = NULL;
  36 JNIHandleBlock* JNIHandles::_weak_global_handles  = NULL;
  37 oop             JNIHandles::_deleted_handle       = NULL;
  38 
  39 
  40 jobject JNIHandles::make_local(oop obj) {
  41   if (obj == NULL) {
  42     return NULL;                // ignore null handles
  43   } else {
  44     Thread* thread = Thread::current();
  45     assert(GC::gc()->heap()->is_in_reserved(obj), "sanity check");
  46     return thread->active_handles()->allocate_handle(obj);
  47   }
  48 }
  49 
  50 
  51 // optimized versions
  52 
  53 jobject JNIHandles::make_local(Thread* thread, oop obj) {
  54   if (obj == NULL) {
  55     return NULL;                // ignore null handles
  56   } else {
  57     assert(GC::gc()->heap()->is_in_reserved(obj), "sanity check");
  58     return thread->active_handles()->allocate_handle(obj);
  59   }
  60 }
  61 
  62 
  63 jobject JNIHandles::make_local(JNIEnv* env, oop obj) {
  64   if (obj == NULL) {
  65     return NULL;                // ignore null handles
  66   } else {
  67     JavaThread* thread = JavaThread::thread_from_jni_environment(env);
  68     assert(GC::gc()->heap()->is_in_reserved(obj), "sanity check");
  69     return thread->active_handles()->allocate_handle(obj);
  70   }
  71 }
  72 
  73 
  74 jobject JNIHandles::make_global(Handle obj) {
  75   assert(!GC::gc()->heap()->is_gc_active(), "can't extend the root set during GC");
  76   jobject res = NULL;
  77   if (!obj.is_null()) {
  78     // ignore null handles
  79     MutexLocker ml(JNIGlobalHandle_lock);
  80     assert(GC::gc()->heap()->is_in_reserved(obj()), "sanity check");
  81     res = _global_handles->allocate_handle(obj());
  82   } else {
  83     CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
  84   }
  85 
  86   return res;
  87 }
  88 
  89 
  90 jobject JNIHandles::make_weak_global(Handle obj) {
  91   assert(!GC::gc()->heap()->is_gc_active(), "can't extend the root set during GC");
  92   jobject res = NULL;
  93   if (!obj.is_null()) {
  94     // ignore null handles
  95     MutexLocker ml(JNIGlobalHandle_lock);
  96     assert(GC::gc()->heap()->is_in_reserved(obj()), "sanity check");
  97     res = _weak_global_handles->allocate_handle(obj());
  98   } else {
  99     CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
 100   }
 101   return res;
 102 }
 103 
 104 
 105 void JNIHandles::destroy_global(jobject handle) {
 106   if (handle != NULL) {
 107     assert(is_global_handle(handle), "Invalid delete of global JNI handle");
 108     *((oop*)handle) = deleted_handle(); // Mark the handle as deleted, allocate will reuse it
 109   }
 110 }
 111 
 112 
 113 void JNIHandles::destroy_weak_global(jobject handle) {
 114   if (handle != NULL) {
 115     assert(!CheckJNICalls || is_weak_global_handle(handle), "Invalid delete of weak global JNI handle");
 116     *((oop*)handle) = deleted_handle(); // Mark the handle as deleted, allocate will reuse it


 344     // correct number of times).
 345     release_block(pop_frame_link, thread);
 346   }
 347 }
 348 
 349 
 350 void JNIHandleBlock::oops_do(OopClosure* f) {
 351   JNIHandleBlock* current_chain = this;
 352   // Iterate over chain of blocks, followed by chains linked through the
 353   // pop frame links.
 354   while (current_chain != NULL) {
 355     for (JNIHandleBlock* current = current_chain; current != NULL;
 356          current = current->_next) {
 357       assert(current == current_chain || current->pop_frame_link() == NULL,
 358         "only blocks first in chain should have pop frame link set");
 359       for (int index = 0; index < current->_top; index++) {
 360         oop* root = &(current->_handles)[index];
 361         oop value = *root;
 362         // traverse heap pointers only, not deleted handles or free list
 363         // pointers
 364         if (value != NULL && GC::gc()->heap()->is_in_reserved(value)) {
 365           f->do_oop(root);
 366         }
 367       }
 368       // the next handle block is valid only if current block is full
 369       if (current->_top < block_size_in_oops) {
 370         break;
 371       }
 372     }
 373     current_chain = current_chain->pop_frame_link();
 374   }
 375 }
 376 
 377 
 378 void JNIHandleBlock::weak_oops_do(BoolObjectClosure* is_alive,
 379                                   OopClosure* f) {
 380   for (JNIHandleBlock* current = this; current != NULL; current = current->_next) {
 381     assert(current->pop_frame_link() == NULL,
 382       "blocks holding weak global JNI handles should not have pop frame link set");
 383     for (int index = 0; index < current->_top; index++) {
 384       oop* root = &(current->_handles)[index];
 385       oop value = *root;
 386       // traverse heap pointers only, not deleted handles or free list pointers
 387       if (value != NULL && GC::gc()->heap()->is_in_reserved(value)) {
 388         if (is_alive->do_object_b(value)) {
 389           // The weakly referenced object is alive, update pointer
 390           f->do_oop(root);
 391         } else {
 392           // The weakly referenced object is not alive, clear the reference by storing NULL
 393           log_develop_trace(gc, ref)("Clearing JNI weak reference (" INTPTR_FORMAT ")", p2i(root));
 394           *root = NULL;
 395         }
 396       }
 397     }
 398     // the next handle block is valid only if current block is full
 399     if (current->_top < block_size_in_oops) {
 400       break;
 401     }
 402   }
 403 
 404   /*
 405    * JVMTI data structures may also contain weak oops.  The iteration of them
 406    * is placed here so that we don't need to add it to each of the collectors.
 407    */
 408   JvmtiExport::weak_oops_do(is_alive, f);
 409 }
 410 
 411 
 412 jobject JNIHandleBlock::allocate_handle(oop obj) {
 413   assert(GC::gc()->heap()->is_in_reserved(obj), "sanity check");
 414   if (_top == 0) {
 415     // This is the first allocation or the initial block got zapped when
 416     // entering a native function. If we have any following blocks they are
 417     // not valid anymore.
 418     for (JNIHandleBlock* current = _next; current != NULL;
 419          current = current->_next) {
 420       assert(current->_last == NULL, "only first block should have _last set");
 421       assert(current->_free_list == NULL,
 422              "only first block should have _free_list set");
 423       current->_top = 0;
 424       if (ZapJNIHandleArea) current->zap();
 425     }
 426     // Clear initial block
 427     _free_list = NULL;
 428     _allocate_before_rebuild = 0;
 429     _last = this;
 430     if (ZapJNIHandleArea) zap();
 431   }
 432 
 433   // Try last block


< prev index next >