9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc/shared/oopStorage.inline.hpp"
27 #include "logging/log.hpp"
28 #include "memory/iterator.hpp"
29 #include "oops/oop.inline.hpp"
30 #include "runtime/handles.inline.hpp"
31 #include "runtime/jniHandles.inline.hpp"
32 #include "runtime/mutexLocker.hpp"
33 #include "runtime/thread.inline.hpp"
34 #include "trace/traceMacros.hpp"
35 #include "utilities/align.hpp"
36 #include "utilities/debug.hpp"
37 #if INCLUDE_ALL_GCS
38 #include "gc/g1/g1BarrierSet.hpp"
39 #endif
40
41 OopStorage* JNIHandles::_global_handles = NULL;
42 OopStorage* JNIHandles::_weak_global_handles = NULL;
43
44
45 jobject JNIHandles::make_local(oop obj) {
46 if (obj == NULL) {
47 return NULL; // ignore null handles
48 } else {
49 Thread* thread = Thread::current();
50 assert(oopDesc::is_oop(obj), "not an oop");
51 assert(!current_thread_in_native(), "must not be in native");
52 return thread->active_handles()->allocate_handle(obj);
53 }
54 }
55
56
57 // optimized versions
58
59 jobject JNIHandles::make_local(Thread* thread, oop obj) {
84 const char* handle_kind) {
85 if (alloc_failmode == AllocFailStrategy::EXIT_OOM) {
86 // Fake size value, since we don't know the min allocation size here.
87 vm_exit_out_of_memory(sizeof(oop), OOM_MALLOC_ERROR,
88 "Cannot create %s JNI handle", handle_kind);
89 } else {
90 assert(alloc_failmode == AllocFailStrategy::RETURN_NULL, "invariant");
91 }
92 }
93
94 jobject JNIHandles::make_global(Handle obj, AllocFailType alloc_failmode) {
95 assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC");
96 assert(!current_thread_in_native(), "must not be in native");
97 jobject res = NULL;
98 if (!obj.is_null()) {
99 // ignore null handles
100 assert(oopDesc::is_oop(obj()), "not an oop");
101 oop* ptr = _global_handles->allocate();
102 // Return NULL on allocation failure.
103 if (ptr != NULL) {
104 *ptr = obj();
105 res = reinterpret_cast<jobject>(ptr);
106 } else {
107 report_handle_allocation_failure(alloc_failmode, "global");
108 }
109 } else {
110 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
111 }
112
113 return res;
114 }
115
116
117 jobject JNIHandles::make_weak_global(Handle obj, AllocFailType alloc_failmode) {
118 assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC");
119 assert(!current_thread_in_native(), "must not be in native");
120 jobject res = NULL;
121 if (!obj.is_null()) {
122 // ignore null handles
123 assert(oopDesc::is_oop(obj()), "not an oop");
124 oop* ptr = _weak_global_handles->allocate();
125 // Return NULL on allocation failure.
126 if (ptr != NULL) {
127 *ptr = obj();
128 char* tptr = reinterpret_cast<char*>(ptr) + weak_tag_value;
129 res = reinterpret_cast<jobject>(tptr);
130 } else {
131 report_handle_allocation_failure(alloc_failmode, "weak global");
132 }
133 } else {
134 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
135 }
136 return res;
137 }
138
139 // Resolve some erroneous cases to NULL, rather than treating them as
140 // possibly unchecked errors. In particular, deleted handles are
141 // treated as NULL (though a deleted and later reallocated handle
142 // isn't detected).
143 oop JNIHandles::resolve_external_guard(jobject handle) {
144 oop result = NULL;
145 if (handle != NULL) {
146 result = resolve_impl<true /* external_guard */ >(handle);
147 }
148 return result;
149 }
150
151 oop JNIHandles::resolve_jweak(jweak handle) {
152 assert(handle != NULL, "precondition");
153 assert(is_jweak(handle), "precondition");
154 oop result = jweak_ref(handle);
155 #if INCLUDE_ALL_GCS
156 if (result != NULL && UseG1GC) {
157 G1BarrierSet::enqueue(result);
158 }
159 #endif // INCLUDE_ALL_GCS
160 return result;
161 }
162
163 bool JNIHandles::is_global_weak_cleared(jweak handle) {
164 assert(handle != NULL, "precondition");
165 assert(is_jweak(handle), "not a weak handle");
166 return jweak_ref(handle) == NULL;
167 }
168
169 void JNIHandles::destroy_global(jobject handle) {
170 if (handle != NULL) {
171 assert(!is_jweak(handle), "wrong method for detroying jweak");
172 jobject_ref(handle) = NULL;
173 _global_handles->release(&jobject_ref(handle));
174 }
175 }
176
177
178 void JNIHandles::destroy_weak_global(jobject handle) {
179 if (handle != NULL) {
180 assert(is_jweak(handle), "JNI handle not jweak");
181 jweak_ref(handle) = NULL;
182 _weak_global_handles->release(&jweak_ref(handle));
183 }
184 }
185
186
187 void JNIHandles::oops_do(OopClosure* f) {
188 _global_handles->oops_do(f);
189 }
190
191
192 void JNIHandles::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
193 _weak_global_handles->weak_oops_do(is_alive, f);
194 }
195
196
197 void JNIHandles::weak_oops_do(OopClosure* f) {
198 _weak_global_handles->weak_oops_do(f);
199 }
200
201
202 void JNIHandles::initialize() {
203 _global_handles = new OopStorage("JNI Global",
204 JNIGlobalAlloc_lock,
205 JNIGlobalActive_lock);
206 _weak_global_handles = new OopStorage("JNI Weak",
207 JNIWeakAlloc_lock,
208 JNIWeakActive_lock);
209 }
210
211
212 inline bool is_storage_handle(const OopStorage* storage, const oop* ptr) {
213 return storage->allocation_status(ptr) == OopStorage::ALLOCATED_ENTRY;
214 }
215
216
217 jobjectRefType JNIHandles::handle_type(Thread* thread, jobject handle) {
218 assert(handle != NULL, "precondition");
219 jobjectRefType result = JNIInvalidRefType;
220 if (is_jweak(handle)) {
221 if (is_storage_handle(_weak_global_handles, &jweak_ref(handle))) {
222 result = JNIWeakGlobalRefType;
223 }
224 } else {
225 switch (_global_handles->allocation_status(&jobject_ref(handle))) {
226 case OopStorage::ALLOCATED_ENTRY:
227 result = JNIGlobalRefType;
228 break;
229
230 case OopStorage::UNALLOCATED_ENTRY:
231 break; // Invalid global handle
232
233 case OopStorage::INVALID_ENTRY:
234 // Not in global storage. Might be a local handle.
235 if (is_local_handle(thread, handle) ||
236 (thread->is_Java_thread() &&
237 is_frame_handle((JavaThread*)thread, handle))) {
238 result = JNILocalRefType;
239 }
240 break;
241
242 default:
243 ShouldNotReachHere();
244 }
245 }
262 }
263
264
265 // Determine if the handle is somewhere in the current thread's stack.
266 // We easily can't isolate any particular stack frame the handle might
267 // come from, so we'll check the whole stack.
268
269 bool JNIHandles::is_frame_handle(JavaThread* thr, jobject handle) {
270 assert(handle != NULL, "precondition");
271 // If there is no java frame, then this must be top level code, such
272 // as the java command executable, in which case, this type of handle
273 // is not permitted.
274 return (thr->has_last_Java_frame() &&
275 (void*)handle < (void*)thr->stack_base() &&
276 (void*)handle >= (void*)thr->last_Java_sp());
277 }
278
279
280 bool JNIHandles::is_global_handle(jobject handle) {
281 assert(handle != NULL, "precondition");
282 return !is_jweak(handle) && is_storage_handle(_global_handles, &jobject_ref(handle));
283 }
284
285
286 bool JNIHandles::is_weak_global_handle(jobject handle) {
287 assert(handle != NULL, "precondition");
288 return is_jweak(handle) && is_storage_handle(_weak_global_handles, &jweak_ref(handle));
289 }
290
291 size_t JNIHandles::global_handle_memory_usage() {
292 return _global_handles->total_memory_usage();
293 }
294
295 size_t JNIHandles::weak_global_handle_memory_usage() {
296 return _weak_global_handles->total_memory_usage();
297 }
298
299
300 // We assume this is called at a safepoint: no lock is needed.
301 void JNIHandles::print_on(outputStream* st) {
302 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
303 assert(_global_handles != NULL && _weak_global_handles != NULL,
304 "JNIHandles not initialized");
305
306 st->print_cr("JNI global refs: " SIZE_FORMAT ", weak refs: " SIZE_FORMAT,
307 _global_handles->allocation_count(),
308 _weak_global_handles->allocation_count());
334 }
335
336
337 void jni_handles_init() {
338 JNIHandles::initialize();
339 }
340
341
342 int JNIHandleBlock::_blocks_allocated = 0;
343 JNIHandleBlock* JNIHandleBlock::_block_free_list = NULL;
344 #ifndef PRODUCT
345 JNIHandleBlock* JNIHandleBlock::_block_list = NULL;
346 #endif
347
348
349 #ifdef ASSERT
350 void JNIHandleBlock::zap() {
351 // Zap block values
352 _top = 0;
353 for (int index = 0; index < block_size_in_oops; index++) {
354 _handles[index] = NULL;
355 }
356 }
357 #endif // ASSERT
358
359 JNIHandleBlock* JNIHandleBlock::allocate_block(Thread* thread) {
360 assert(thread == NULL || thread == Thread::current(), "sanity check");
361 JNIHandleBlock* block;
362 // Check the thread-local free list for a block so we don't
363 // have to acquire a mutex.
364 if (thread != NULL && thread->free_handle_block() != NULL) {
365 block = thread->free_handle_block();
366 thread->set_free_handle_block(block->_next);
367 }
368 else {
369 // locking with safepoint checking introduces a potential deadlock:
370 // - we would hold JNIHandleBlockFreeList_lock and then Threads_lock
371 // - another would hold Threads_lock (jni_AttachCurrentThread) and then
372 // JNIHandleBlockFreeList_lock (JNIHandleBlock::allocate_block)
373 MutexLockerEx ml(JNIHandleBlockFreeList_lock,
489 #ifdef ASSERT
490 for (current = current->_next; current != NULL; current = current->_next) {
491 assert(current->_top == 0, "trailing blocks must already be cleared");
492 }
493 #endif
494 break;
495 }
496 current->_top = 0;
497 current->zap();
498 }
499 // Clear initial block
500 _free_list = NULL;
501 _allocate_before_rebuild = 0;
502 _last = this;
503 zap();
504 }
505
506 // Try last block
507 if (_last->_top < block_size_in_oops) {
508 oop* handle = &(_last->_handles)[_last->_top++];
509 *handle = obj;
510 return (jobject) handle;
511 }
512
513 // Try free list
514 if (_free_list != NULL) {
515 oop* handle = _free_list;
516 _free_list = (oop*) *_free_list;
517 *handle = obj;
518 return (jobject) handle;
519 }
520 // Check if unused block follow last
521 if (_last->_next != NULL) {
522 // update last and retry
523 _last = _last->_next;
524 return allocate_handle(obj);
525 }
526
527 // No space available, we have to rebuild free list or expand
528 if (_allocate_before_rebuild == 0) {
529 rebuild_free_list(); // updates _allocate_before_rebuild counter
530 } else {
531 // Append new block
532 Thread* thread = Thread::current();
533 Handle obj_handle(thread, obj);
534 // This can block, so we need to preserve obj across call.
535 _last->_next = JNIHandleBlock::allocate_block(thread);
536 _last = _last->_next;
537 _allocate_before_rebuild--;
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc/shared/oopStorage.inline.hpp"
27 #include "logging/log.hpp"
28 #include "memory/iterator.hpp"
29 #include "oops/access.inline.hpp"
30 #include "oops/oop.inline.hpp"
31 #include "runtime/handles.inline.hpp"
32 #include "runtime/jniHandles.inline.hpp"
33 #include "runtime/mutexLocker.hpp"
34 #include "runtime/thread.inline.hpp"
35 #include "trace/traceMacros.hpp"
36 #include "utilities/align.hpp"
37 #include "utilities/debug.hpp"
38
39 OopStorage* JNIHandles::_global_handles = NULL;
40 OopStorage* JNIHandles::_weak_global_handles = NULL;
41
42
43 jobject JNIHandles::make_local(oop obj) {
44 if (obj == NULL) {
45 return NULL; // ignore null handles
46 } else {
47 Thread* thread = Thread::current();
48 assert(oopDesc::is_oop(obj), "not an oop");
49 assert(!current_thread_in_native(), "must not be in native");
50 return thread->active_handles()->allocate_handle(obj);
51 }
52 }
53
54
55 // optimized versions
56
57 jobject JNIHandles::make_local(Thread* thread, oop obj) {
82 const char* handle_kind) {
83 if (alloc_failmode == AllocFailStrategy::EXIT_OOM) {
84 // Fake size value, since we don't know the min allocation size here.
85 vm_exit_out_of_memory(sizeof(oop), OOM_MALLOC_ERROR,
86 "Cannot create %s JNI handle", handle_kind);
87 } else {
88 assert(alloc_failmode == AllocFailStrategy::RETURN_NULL, "invariant");
89 }
90 }
91
92 jobject JNIHandles::make_global(Handle obj, AllocFailType alloc_failmode) {
93 assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC");
94 assert(!current_thread_in_native(), "must not be in native");
95 jobject res = NULL;
96 if (!obj.is_null()) {
97 // ignore null handles
98 assert(oopDesc::is_oop(obj()), "not an oop");
99 oop* ptr = _global_handles->allocate();
100 // Return NULL on allocation failure.
101 if (ptr != NULL) {
102 assert(*ptr == NULL, "invariant");
103 RootAccess<IN_CONCURRENT_ROOT>::oop_store(ptr, obj());
104 res = reinterpret_cast<jobject>(ptr);
105 } else {
106 report_handle_allocation_failure(alloc_failmode, "global");
107 }
108 } else {
109 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
110 }
111
112 return res;
113 }
114
115
116 jobject JNIHandles::make_weak_global(Handle obj, AllocFailType alloc_failmode) {
117 assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC");
118 assert(!current_thread_in_native(), "must not be in native");
119 jobject res = NULL;
120 if (!obj.is_null()) {
121 // ignore null handles
122 assert(oopDesc::is_oop(obj()), "not an oop");
123 oop* ptr = _weak_global_handles->allocate();
124 // Return NULL on allocation failure.
125 if (ptr != NULL) {
126 assert(*ptr == NULL, "invariant");
127 RootAccess<ON_PHANTOM_OOP_REF>::oop_store(ptr, obj());
128 char* tptr = reinterpret_cast<char*>(ptr) + weak_tag_value;
129 res = reinterpret_cast<jobject>(tptr);
130 } else {
131 report_handle_allocation_failure(alloc_failmode, "weak global");
132 }
133 } else {
134 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
135 }
136 return res;
137 }
138
139 // Resolve some erroneous cases to NULL, rather than treating them as
140 // possibly unchecked errors. In particular, deleted handles are
141 // treated as NULL (though a deleted and later reallocated handle
142 // isn't detected).
143 oop JNIHandles::resolve_external_guard(jobject handle) {
144 oop result = NULL;
145 if (handle != NULL) {
146 result = resolve_impl<true /* external_guard */ >(handle);
147 }
148 return result;
149 }
150
151 oop JNIHandles::resolve_jweak(jweak handle) {
152 assert(handle != NULL, "precondition");
153 assert(is_jweak(handle), "precondition");
154 return RootAccess<ON_PHANTOM_OOP_REF>::oop_load(jweak_ptr(handle));
155 }
156
157 bool JNIHandles::is_global_weak_cleared(jweak handle) {
158 assert(handle != NULL, "precondition");
159 assert(is_jweak(handle), "not a weak handle");
160 oop* oop_ptr = jweak_ptr(handle);
161 oop value = RootAccess<ON_PHANTOM_OOP_REF | AS_NO_KEEPALIVE>::oop_load(oop_ptr);
162 return value == NULL;
163 }
164
165 void JNIHandles::destroy_global(jobject handle) {
166 if (handle != NULL) {
167 assert(!is_jweak(handle), "wrong method for detroying jweak");
168 oop* oop_ptr = jobject_ptr(handle);
169 RootAccess<IN_CONCURRENT_ROOT>::oop_store(oop_ptr, (oop)NULL);
170 _global_handles->release(oop_ptr);
171 }
172 }
173
174
175 void JNIHandles::destroy_weak_global(jobject handle) {
176 if (handle != NULL) {
177 assert(is_jweak(handle), "JNI handle not jweak");
178 oop* oop_ptr = jweak_ptr(handle);
179 RootAccess<ON_PHANTOM_OOP_REF>::oop_store(oop_ptr, (oop)NULL);
180 _weak_global_handles->release(oop_ptr);
181 }
182 }
183
184
185 void JNIHandles::oops_do(OopClosure* f) {
186 _global_handles->oops_do(f);
187 }
188
189
190 void JNIHandles::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
191 _weak_global_handles->weak_oops_do(is_alive, f);
192 }
193
194
195 void JNIHandles::weak_oops_do(OopClosure* f) {
196 _weak_global_handles->weak_oops_do(f);
197 }
198
199
200 void JNIHandles::initialize() {
201 _global_handles = new OopStorage("JNI Global",
202 JNIGlobalAlloc_lock,
203 JNIGlobalActive_lock);
204 _weak_global_handles = new OopStorage("JNI Weak",
205 JNIWeakAlloc_lock,
206 JNIWeakActive_lock);
207 }
208
209
210 inline bool is_storage_handle(const OopStorage* storage, const oop* ptr) {
211 return storage->allocation_status(ptr) == OopStorage::ALLOCATED_ENTRY;
212 }
213
214
215 jobjectRefType JNIHandles::handle_type(Thread* thread, jobject handle) {
216 assert(handle != NULL, "precondition");
217 jobjectRefType result = JNIInvalidRefType;
218 if (is_jweak(handle)) {
219 if (is_storage_handle(_weak_global_handles, jweak_ptr(handle))) {
220 result = JNIWeakGlobalRefType;
221 }
222 } else {
223 switch (_global_handles->allocation_status(jobject_ptr(handle))) {
224 case OopStorage::ALLOCATED_ENTRY:
225 result = JNIGlobalRefType;
226 break;
227
228 case OopStorage::UNALLOCATED_ENTRY:
229 break; // Invalid global handle
230
231 case OopStorage::INVALID_ENTRY:
232 // Not in global storage. Might be a local handle.
233 if (is_local_handle(thread, handle) ||
234 (thread->is_Java_thread() &&
235 is_frame_handle((JavaThread*)thread, handle))) {
236 result = JNILocalRefType;
237 }
238 break;
239
240 default:
241 ShouldNotReachHere();
242 }
243 }
260 }
261
262
263 // Determine if the handle is somewhere in the current thread's stack.
264 // We easily can't isolate any particular stack frame the handle might
265 // come from, so we'll check the whole stack.
266
267 bool JNIHandles::is_frame_handle(JavaThread* thr, jobject handle) {
268 assert(handle != NULL, "precondition");
269 // If there is no java frame, then this must be top level code, such
270 // as the java command executable, in which case, this type of handle
271 // is not permitted.
272 return (thr->has_last_Java_frame() &&
273 (void*)handle < (void*)thr->stack_base() &&
274 (void*)handle >= (void*)thr->last_Java_sp());
275 }
276
277
278 bool JNIHandles::is_global_handle(jobject handle) {
279 assert(handle != NULL, "precondition");
280 return !is_jweak(handle) && is_storage_handle(_global_handles, jobject_ptr(handle));
281 }
282
283
284 bool JNIHandles::is_weak_global_handle(jobject handle) {
285 assert(handle != NULL, "precondition");
286 return is_jweak(handle) && is_storage_handle(_weak_global_handles, jweak_ptr(handle));
287 }
288
289 size_t JNIHandles::global_handle_memory_usage() {
290 return _global_handles->total_memory_usage();
291 }
292
293 size_t JNIHandles::weak_global_handle_memory_usage() {
294 return _weak_global_handles->total_memory_usage();
295 }
296
297
298 // We assume this is called at a safepoint: no lock is needed.
299 void JNIHandles::print_on(outputStream* st) {
300 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
301 assert(_global_handles != NULL && _weak_global_handles != NULL,
302 "JNIHandles not initialized");
303
304 st->print_cr("JNI global refs: " SIZE_FORMAT ", weak refs: " SIZE_FORMAT,
305 _global_handles->allocation_count(),
306 _weak_global_handles->allocation_count());
332 }
333
334
335 void jni_handles_init() {
336 JNIHandles::initialize();
337 }
338
339
340 int JNIHandleBlock::_blocks_allocated = 0;
341 JNIHandleBlock* JNIHandleBlock::_block_free_list = NULL;
342 #ifndef PRODUCT
343 JNIHandleBlock* JNIHandleBlock::_block_list = NULL;
344 #endif
345
346
347 #ifdef ASSERT
348 void JNIHandleBlock::zap() {
349 // Zap block values
350 _top = 0;
351 for (int index = 0; index < block_size_in_oops; index++) {
352 // NOT using Access here; just bare clobbering to NULL, since the
353 // block no longer contains valid oops.
354 _handles[index] = NULL;
355 }
356 }
357 #endif // ASSERT
358
359 JNIHandleBlock* JNIHandleBlock::allocate_block(Thread* thread) {
360 assert(thread == NULL || thread == Thread::current(), "sanity check");
361 JNIHandleBlock* block;
362 // Check the thread-local free list for a block so we don't
363 // have to acquire a mutex.
364 if (thread != NULL && thread->free_handle_block() != NULL) {
365 block = thread->free_handle_block();
366 thread->set_free_handle_block(block->_next);
367 }
368 else {
369 // locking with safepoint checking introduces a potential deadlock:
370 // - we would hold JNIHandleBlockFreeList_lock and then Threads_lock
371 // - another would hold Threads_lock (jni_AttachCurrentThread) and then
372 // JNIHandleBlockFreeList_lock (JNIHandleBlock::allocate_block)
373 MutexLockerEx ml(JNIHandleBlockFreeList_lock,
489 #ifdef ASSERT
490 for (current = current->_next; current != NULL; current = current->_next) {
491 assert(current->_top == 0, "trailing blocks must already be cleared");
492 }
493 #endif
494 break;
495 }
496 current->_top = 0;
497 current->zap();
498 }
499 // Clear initial block
500 _free_list = NULL;
501 _allocate_before_rebuild = 0;
502 _last = this;
503 zap();
504 }
505
506 // Try last block
507 if (_last->_top < block_size_in_oops) {
508 oop* handle = &(_last->_handles)[_last->_top++];
509 RootAccess<AS_DEST_NOT_INITIALIZED>::oop_store(handle, obj);
510 return (jobject) handle;
511 }
512
513 // Try free list
514 if (_free_list != NULL) {
515 oop* handle = _free_list;
516 _free_list = (oop*) *_free_list;
517 RootAccess<AS_DEST_NOT_INITIALIZED>::oop_store(handle, obj);
518 return (jobject) handle;
519 }
520 // Check if unused block follow last
521 if (_last->_next != NULL) {
522 // update last and retry
523 _last = _last->_next;
524 return allocate_handle(obj);
525 }
526
527 // No space available, we have to rebuild free list or expand
528 if (_allocate_before_rebuild == 0) {
529 rebuild_free_list(); // updates _allocate_before_rebuild counter
530 } else {
531 // Append new block
532 Thread* thread = Thread::current();
533 Handle obj_handle(thread, obj);
534 // This can block, so we need to preserve obj across call.
535 _last->_next = JNIHandleBlock::allocate_block(thread);
536 _last = _last->_next;
537 _allocate_before_rebuild--;
|