8224814: Remove dead JNIHandleBlock freelist code
Reviewed-by: stefank, tschatzl, kbarrett
This commit is contained in:
parent
d25350462e
commit
50e2aa7306
@ -396,10 +396,8 @@ JNIHandleBlock* JNIHandleBlock::allocate_block(Thread* thread) {
|
|||||||
block->_next = NULL;
|
block->_next = NULL;
|
||||||
block->_pop_frame_link = NULL;
|
block->_pop_frame_link = NULL;
|
||||||
block->_planned_capacity = block_size_in_oops;
|
block->_planned_capacity = block_size_in_oops;
|
||||||
// _last, _free_list & _allocate_before_rebuild initialized in allocate_handle
|
// _last initialized in allocate_handle
|
||||||
debug_only(block->_last = NULL);
|
debug_only(block->_last = NULL);
|
||||||
debug_only(block->_free_list = NULL);
|
|
||||||
debug_only(block->_allocate_before_rebuild = -1);
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,12 +458,7 @@ void JNIHandleBlock::oops_do(OopClosure* f) {
|
|||||||
"only blocks first in chain should have pop frame link set");
|
"only blocks first in chain should have pop frame link set");
|
||||||
for (int index = 0; index < current->_top; index++) {
|
for (int index = 0; index < current->_top; index++) {
|
||||||
oop* root = &(current->_handles)[index];
|
oop* root = &(current->_handles)[index];
|
||||||
oop value = *root;
|
f->do_oop(root);
|
||||||
// traverse heap pointers only, not deleted handles or free list
|
|
||||||
// pointers
|
|
||||||
if (value != NULL && Universe::heap()->is_in_reserved(value)) {
|
|
||||||
f->do_oop(root);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// the next handle block is valid only if current block is full
|
// the next handle block is valid only if current block is full
|
||||||
if (current->_top < block_size_in_oops) {
|
if (current->_top < block_size_in_oops) {
|
||||||
@ -486,8 +479,6 @@ jobject JNIHandleBlock::allocate_handle(oop obj) {
|
|||||||
for (JNIHandleBlock* current = _next; current != NULL;
|
for (JNIHandleBlock* current = _next; current != NULL;
|
||||||
current = current->_next) {
|
current = current->_next) {
|
||||||
assert(current->_last == NULL, "only first block should have _last set");
|
assert(current->_last == NULL, "only first block should have _last set");
|
||||||
assert(current->_free_list == NULL,
|
|
||||||
"only first block should have _free_list set");
|
|
||||||
if (current->_top == 0) {
|
if (current->_top == 0) {
|
||||||
// All blocks after the first clear trailing block are already cleared.
|
// All blocks after the first clear trailing block are already cleared.
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
@ -501,8 +492,6 @@ jobject JNIHandleBlock::allocate_handle(oop obj) {
|
|||||||
current->zap();
|
current->zap();
|
||||||
}
|
}
|
||||||
// Clear initial block
|
// Clear initial block
|
||||||
_free_list = NULL;
|
|
||||||
_allocate_before_rebuild = 0;
|
|
||||||
_last = this;
|
_last = this;
|
||||||
zap();
|
zap();
|
||||||
}
|
}
|
||||||
@ -514,13 +503,6 @@ jobject JNIHandleBlock::allocate_handle(oop obj) {
|
|||||||
return (jobject) handle;
|
return (jobject) handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try free list
|
|
||||||
if (_free_list != NULL) {
|
|
||||||
oop* handle = _free_list;
|
|
||||||
_free_list = (oop*) *_free_list;
|
|
||||||
NativeAccess<IS_DEST_UNINITIALIZED>::oop_store(handle, obj);
|
|
||||||
return (jobject) handle;
|
|
||||||
}
|
|
||||||
// Check if unused block follow last
|
// Check if unused block follow last
|
||||||
if (_last->_next != NULL) {
|
if (_last->_next != NULL) {
|
||||||
// update last and retry
|
// update last and retry
|
||||||
@ -528,51 +510,16 @@ jobject JNIHandleBlock::allocate_handle(oop obj) {
|
|||||||
return allocate_handle(obj);
|
return allocate_handle(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
// No space available, we have to rebuild free list or expand
|
// Append new block
|
||||||
if (_allocate_before_rebuild == 0) {
|
Thread* thread = Thread::current();
|
||||||
rebuild_free_list(); // updates _allocate_before_rebuild counter
|
Handle obj_handle(thread, obj);
|
||||||
} else {
|
// This can block, so we need to preserve obj across call.
|
||||||
// Append new block
|
_last->_next = JNIHandleBlock::allocate_block(thread);
|
||||||
Thread* thread = Thread::current();
|
_last = _last->_next;
|
||||||
Handle obj_handle(thread, obj);
|
obj = obj_handle();
|
||||||
// This can block, so we need to preserve obj across call.
|
|
||||||
_last->_next = JNIHandleBlock::allocate_block(thread);
|
|
||||||
_last = _last->_next;
|
|
||||||
_allocate_before_rebuild--;
|
|
||||||
obj = obj_handle();
|
|
||||||
}
|
|
||||||
return allocate_handle(obj); // retry
|
return allocate_handle(obj); // retry
|
||||||
}
|
}
|
||||||
|
|
||||||
void JNIHandleBlock::rebuild_free_list() {
|
|
||||||
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) {
|
|
||||||
// this handle was cleared out by a delete call, reuse it
|
|
||||||
*handle = (oop) _free_list;
|
|
||||||
_free_list = handle;
|
|
||||||
free++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// we should not rebuild free list if there are unused handles at the end
|
|
||||||
assert(current->_top == block_size_in_oops, "just checking");
|
|
||||||
blocks++;
|
|
||||||
}
|
|
||||||
// Heuristic: if more than half of the handles are free we rebuild next time
|
|
||||||
// as well, otherwise we append a corresponding number of new blocks before
|
|
||||||
// attempting a free list rebuild again.
|
|
||||||
int total = blocks * block_size_in_oops;
|
|
||||||
int extra = total - 2*free;
|
|
||||||
if (extra > 0) {
|
|
||||||
// Not as many free handles as we would like - compute number of new blocks to append
|
|
||||||
_allocate_before_rebuild = (extra + block_size_in_oops - 1) / block_size_in_oops;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool JNIHandleBlock::contains(jobject handle) const {
|
bool JNIHandleBlock::contains(jobject handle) const {
|
||||||
return ((jobject)&_handles[0] <= handle && handle<(jobject)&_handles[_top]);
|
return ((jobject)&_handles[0] <= handle && handle<(jobject)&_handles[_top]);
|
||||||
|
@ -148,8 +148,6 @@ class JNIHandleBlock : public CHeapObj<mtInternal> {
|
|||||||
// Having two types of blocks complicates the code and the space overhead in negligible.
|
// Having two types of blocks complicates the code and the space overhead in negligible.
|
||||||
JNIHandleBlock* _last; // Last block in use
|
JNIHandleBlock* _last; // Last block in use
|
||||||
JNIHandleBlock* _pop_frame_link; // Block to restore on PopLocalFrame call
|
JNIHandleBlock* _pop_frame_link; // Block to restore on PopLocalFrame call
|
||||||
oop* _free_list; // Handle free list
|
|
||||||
int _allocate_before_rebuild; // Number of blocks to allocate before rebuilding free list
|
|
||||||
|
|
||||||
// Check JNI, "planned capacity" for current frame (or push/ensure)
|
// Check JNI, "planned capacity" for current frame (or push/ensure)
|
||||||
size_t _planned_capacity;
|
size_t _planned_capacity;
|
||||||
@ -165,9 +163,6 @@ class JNIHandleBlock : public CHeapObj<mtInternal> {
|
|||||||
// Fill block with bad_handle values
|
// Fill block with bad_handle values
|
||||||
void zap() NOT_DEBUG_RETURN;
|
void zap() NOT_DEBUG_RETURN;
|
||||||
|
|
||||||
// Free list computation
|
|
||||||
void rebuild_free_list();
|
|
||||||
|
|
||||||
// No more handles in the both the current and following blocks
|
// No more handles in the both the current and following blocks
|
||||||
void clear() { _top = 0; }
|
void clear() { _top = 0; }
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user