< prev index next > src/hotspot/share/runtime/jniHandles.cpp
Print this page
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;
// 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) {
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) {
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
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) {
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 >