|
@@ -58,15 +58,15 @@ jobject JNIHandles::make_local(oop obj) { |
|
|
return make_local(Thread::current(), obj); |
|
|
} |
|
|
|
|
|
|
|
|
jobject JNIHandles::make_local(Thread* thread, oop obj) { |
|
|
// Used by NewLocalRef which requires NULL on out-of-memory |
|
|
jobject JNIHandles::make_local(Thread* thread, oop obj, AllocFailType alloc_failmode) { |
|
|
if (obj == NULL) { |
|
|
return NULL; // ignore null handles |
|
|
} else { |
|
|
assert(oopDesc::is_oop(obj), "not an oop"); |
|
|
assert(thread->is_Java_thread(), "not a Java thread"); |
|
|
assert(!current_thread_in_native(), "must not be in native"); |
|
|
return thread->active_handles()->allocate_handle(obj); |
|
|
return thread->active_handles()->allocate_handle(obj, alloc_failmode); |
|
|
} |
|
|
} |
|
|
|
|
@@ -102,7 +102,6 @@ jobject JNIHandles::make_global(Handle obj, AllocFailType alloc_failmode) { |
|
|
return res; |
|
|
} |
|
|
|
|
|
|
|
|
jobject JNIHandles::make_weak_global(Handle obj, AllocFailType alloc_failmode) { |
|
|
assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC"); |
|
|
assert(!current_thread_in_native(), "must not be in native"); |
|
@@ -343,7 +342,7 @@ void JNIHandleBlock::zap() { |
|
|
} |
|
|
#endif // ASSERT |
|
|
|
|
|
JNIHandleBlock* JNIHandleBlock::allocate_block(Thread* thread) { |
|
|
JNIHandleBlock* JNIHandleBlock::allocate_block(Thread* thread, AllocFailType alloc_failmode) { |
|
|
assert(thread == NULL || thread == Thread::current(), "sanity check"); |
|
|
JNIHandleBlock* block; |
|
|
// Check the thread-local free list for a block so we don't |
|
@@ -361,7 +360,14 @@ JNIHandleBlock* JNIHandleBlock::allocate_block(Thread* thread) { |
|
|
Mutex::_no_safepoint_check_flag); |
|
|
if (_block_free_list == NULL) { |
|
|
// Allocate new block |
|
|
block = new JNIHandleBlock(); |
|
|
if (alloc_failmode == AllocFailStrategy::RETURN_NULL) { |
|
|
block = new (std::nothrow) JNIHandleBlock(); |
|
|
if (block == NULL) { |
|
|
return NULL; |
|
|
} |
|
|
} else { |
|
|
block = new JNIHandleBlock(); |
|
|
} |
|
|
_blocks_allocated++; |
|
|
block->zap(); |
|
|
#ifndef PRODUCT |
|
@@ -461,7 +467,7 @@ void JNIHandleBlock::oops_do(OopClosure* f) { |
|
|
} |
|
|
|
|
|
|
|
|
jobject JNIHandleBlock::allocate_handle(oop obj) { |
|
|
jobject JNIHandleBlock::allocate_handle(oop obj, AllocFailType alloc_failmode) { |
|
|
assert(Universe::heap()->is_in(obj), "sanity check"); |
|
|
if (_top == 0) { |
|
|
// This is the first allocation or the initial block got zapped when |
|
@@ -509,7 +515,7 @@ jobject JNIHandleBlock::allocate_handle(oop obj) { |
|
|
if (_last->_next != NULL) { |
|
|
// update last and retry |
|
|
_last = _last->_next; |
|
|
return allocate_handle(obj); |
|
|
return allocate_handle(obj, alloc_failmode); |
|
|
} |
|
|
|
|
|
// No space available, we have to rebuild free list or expand |
|
@@ -520,12 +526,15 @@ jobject JNIHandleBlock::allocate_handle(oop obj) { |
|
|
Thread* thread = Thread::current(); |
|
|
Handle obj_handle(thread, obj); |
|
|
// This can block, so we need to preserve obj across call. |
|
|
_last->_next = JNIHandleBlock::allocate_block(thread); |
|
|
_last->_next = JNIHandleBlock::allocate_block(thread, alloc_failmode); |
|
|
if (_last->_next == NULL) { |
|
|
return NULL; |
|
|
} |
|
|
_last = _last->_next; |
|
|
_allocate_before_rebuild--; |
|
|
obj = obj_handle(); |
|
|
} |
|
|
return allocate_handle(obj); // retry |
|
|
return allocate_handle(obj, alloc_failmode); // retry |
|
|
} |
|
|
|
|
|
void JNIHandleBlock::rebuild_free_list() { |
|
|