< prev index next >

src/hotspot/share/runtime/jniHandles.cpp

Print this page
@@ -345,10 +345,21 @@
  JNIHandleBlock* JNIHandleBlock::_block_free_list      = NULL;
  #ifndef PRODUCT
  JNIHandleBlock* JNIHandleBlock::_block_list           = NULL;
  #endif
  
+ static inline bool is_tagged_free_list(uintptr_t value) {
+   return (value & 1u) != 0;
+ }
+ 
+ static inline uintptr_t tag_free_list(uintptr_t value) {
+   return value | 1u;
+ }
+ 
+ static inline uintptr_t untag_free_list(uintptr_t value) {
+   return value & ~(uintptr_t)1u;
+ }
  
  #ifdef ASSERT
  void JNIHandleBlock::zap() {
    // Zap block values
    _top = 0;

@@ -353,11 +364,11 @@
    // Zap block values
    _top = 0;
    for (int index = 0; index < block_size_in_oops; index++) {
      // NOT using Access here; just bare clobbering to NULL, since the
      // block no longer contains valid oops.
-     _handles[index] = NULL;
+     _handles[index] = 0;
    }
  }
  #endif // ASSERT
  
  JNIHandleBlock* JNIHandleBlock::allocate_block(Thread* thread)  {

@@ -457,15 +468,16 @@
      for (JNIHandleBlock* current = current_chain; current != NULL;
           current = current->_next) {
        assert(current == current_chain || current->pop_frame_link() == NULL,
          "only blocks first in chain should have pop frame link set");
        for (int index = 0; index < current->_top; index++) {
-         oop* root = &(current->_handles)[index];
-         oop value = *root;
-         // traverse heap pointers only, not deleted handles or free list
-         // pointers
-         if (value != NULL && Universe::heap()->is_in_reserved(value)) {
+         uintptr_t* addr = &(current->_handles)[index];
+         uintptr_t value = *addr;
+         if (value != 0 && !is_tagged_free_list(value)) {
+           // traverse heap pointers only, not deleted handles or free list
+           // pointers
+           oop* root = (oop*)addr;
            f->do_oop(root);
          }
        }
        // the next handle block is valid only if current block is full
        if (current->_top < block_size_in_oops) {

@@ -507,11 +519,11 @@
      zap();
    }
  
    // Try last block
    if (_last->_top < block_size_in_oops) {
-     oop* handle = &(_last->_handles)[_last->_top++];
+     oop* handle = (oop*)&(_last->_handles)[_last->_top++];
      NativeAccess<IS_DEST_UNINITIALIZED>::oop_store(handle, obj);
      return (jobject) handle;
    }
  
    // Try free list

@@ -514,12 +526,12 @@
      return (jobject) handle;
    }
  
    // Try free list
    if (_free_list != NULL) {
-     oop* handle = _free_list;
-     _free_list = (oop*) *_free_list;
+     oop* handle = (oop*)_free_list;
+     _free_list = (uintptr_t*) untag_free_list(*_free_list);
      NativeAccess<IS_DEST_UNINITIALIZED>::oop_store(handle, obj);
      return (jobject) handle;
    }
    // Check if unused block follow last
    if (_last->_next != NULL) {

@@ -548,14 +560,14 @@
    assert(_allocate_before_rebuild == 0 && _free_list == NULL, "just checking");
    int free = 0;
    int blocks = 0;
    for (JNIHandleBlock* current = this; current != NULL; current = current->_next) {
      for (int index = 0; index < current->_top; index++) {
-       oop* handle = &(current->_handles)[index];
-       if (*handle == NULL) {
+       uintptr_t* handle = &(current->_handles)[index];
+       if (*handle == 0) {
          // this handle was cleared out by a delete call, reuse it
-         *handle = (oop) _free_list;
+         *handle = _free_list == NULL ? 0 : tag_free_list((uintptr_t)_free_list);
          _free_list = handle;
          free++;
        }
      }
      // we should not rebuild free list if there are unused handles at the end
< prev index next >