< prev index next >

src/hotspot/share/code/icBuffer.cpp


*** 107,156 **** ICStub* ic_stub = (ICStub*)buffer()->request_committed (ic_stub_code_size()); assert (ic_stub != NULL, "no room for a single stub"); set_next_stub(ic_stub); } void InlineCacheBuffer::initialize() { if (_buffer != NULL) return; // already initialized _buffer = new StubQueue(new ICStubInterface, 10*K, InlineCacheBuffer_lock, "InlineCacheBuffer"); assert (_buffer != NULL, "cannot allocate InlineCacheBuffer"); - init_next_stub(); } ICStub* InlineCacheBuffer::new_ic_stub() { ! while (true) { ! ICStub* ic_stub = (ICStub*)buffer()->request_committed(ic_stub_code_size()); ! if (ic_stub != NULL) { ! return ic_stub; ! } ! // we ran out of inline cache buffer space; must enter safepoint. ! // We do this by forcing a safepoint ! EXCEPTION_MARK; ! ! VM_ICBufferFull ibf; ! VMThread::execute(&ibf); ! // We could potential get an async. exception at this point. ! // In that case we will rethrow it to ourselvs. ! if (HAS_PENDING_EXCEPTION) { ! oop exception = PENDING_EXCEPTION; ! CLEAR_PENDING_EXCEPTION; ! Thread::send_async_exception(JavaThread::current()->threadObj(), exception); ! } } - ShouldNotReachHere(); - return NULL; } void InlineCacheBuffer::update_inline_caches() { ! if (buffer()->number_of_stubs() > 1) { if (TraceICBuffer) { tty->print_cr("[updating inline caches with %d stubs]", buffer()->number_of_stubs()); } buffer()->remove_all(); - init_next_stub(); } release_pending_icholders(); } --- 107,152 ---- ICStub* ic_stub = (ICStub*)buffer()->request_committed (ic_stub_code_size()); assert (ic_stub != NULL, "no room for a single stub"); set_next_stub(ic_stub); } + void InlineCacheBuffer::initialize() { if (_buffer != NULL) return; // already initialized _buffer = new StubQueue(new ICStubInterface, 10*K, InlineCacheBuffer_lock, "InlineCacheBuffer"); assert (_buffer != NULL, "cannot allocate InlineCacheBuffer"); } ICStub* InlineCacheBuffer::new_ic_stub() { ! return (ICStub*)buffer()->request_committed(ic_stub_code_size()); ! } ! ! ! void InlineCacheBuffer::refill_ic_stubs() { ! // we ran out of inline cache buffer space; must enter safepoint. ! // We do this by forcing a safepoint ! EXCEPTION_MARK; ! ! VM_ICBufferFull ibf; ! VMThread::execute(&ibf); ! // We could potential get an async. exception at this point. ! // In that case we will rethrow it to ourselvs. ! if (HAS_PENDING_EXCEPTION) { ! oop exception = PENDING_EXCEPTION; ! CLEAR_PENDING_EXCEPTION; ! Thread::send_async_exception(JavaThread::current()->threadObj(), exception); } } void InlineCacheBuffer::update_inline_caches() { ! if (buffer()->number_of_stubs() > 0) { if (TraceICBuffer) { tty->print_cr("[updating inline caches with %d stubs]", buffer()->number_of_stubs()); } buffer()->remove_all(); } release_pending_icholders(); } ***************
*** 158,199 **** return buffer()->contains(instruction_address); } bool InlineCacheBuffer::is_empty() { ! return buffer()->number_of_stubs() == 1; // always has sentinel } void InlineCacheBuffer_init() { InlineCacheBuffer::initialize(); } ! void InlineCacheBuffer::create_transition_stub(CompiledIC *ic, void* cached_value, address entry) { ! MutexLockerEx ml(CompiledIC_lock->owned_by_self() ? NULL : CompiledIC_lock); assert(!SafepointSynchronize::is_at_safepoint(), "should not be called during a safepoint"); assert(CompiledICLocker::is_safe(ic->instruction_address()), "mt unsafe call"); if (TraceICBuffer) { tty->print_cr(" create transition stub for " INTPTR_FORMAT " destination " INTPTR_FORMAT " cached value " INTPTR_FORMAT, p2i(ic->instruction_address()), p2i(entry), p2i(cached_value)); } // If an transition stub is already associate with the inline cache, then we remove the association. if (ic->is_in_transition_state()) { ICStub* old_stub = ICStub_from_destination_address(ic->stub_address()); old_stub->clear(); } - // allocate and initialize new "out-of-line" inline-cache - ICStub* ic_stub = get_next_stub(); ic_stub->set_stub(ic, cached_value, entry); // Update inline cache in nmethod to point to new "out-of-line" allocated inline cache ic->set_ic_destination(ic_stub); ! ! set_next_stub(new_ic_stub()); // can cause safepoint synchronization } address InlineCacheBuffer::ic_destination_for(CompiledIC *ic) { ICStub* stub = ICStub_from_destination_address(ic->stub_address()); --- 154,197 ---- return buffer()->contains(instruction_address); } bool InlineCacheBuffer::is_empty() { ! return buffer()->number_of_stubs() == 0; // always has sentinel } void InlineCacheBuffer_init() { InlineCacheBuffer::initialize(); } ! bool InlineCacheBuffer::create_transition_stub(CompiledIC *ic, void* cached_value, address entry) { assert(!SafepointSynchronize::is_at_safepoint(), "should not be called during a safepoint"); assert(CompiledICLocker::is_safe(ic->instruction_address()), "mt unsafe call"); if (TraceICBuffer) { tty->print_cr(" create transition stub for " INTPTR_FORMAT " destination " INTPTR_FORMAT " cached value " INTPTR_FORMAT, p2i(ic->instruction_address()), p2i(entry), p2i(cached_value)); } + // allocate and initialize new "out-of-line" inline-cache + ICStub* ic_stub = new_ic_stub(); + if (ic_stub == NULL) { + return false; + } + // If an transition stub is already associate with the inline cache, then we remove the association. if (ic->is_in_transition_state()) { ICStub* old_stub = ICStub_from_destination_address(ic->stub_address()); old_stub->clear(); } ic_stub->set_stub(ic, cached_value, entry); // Update inline cache in nmethod to point to new "out-of-line" allocated inline cache ic->set_ic_destination(ic_stub); ! return true; } address InlineCacheBuffer::ic_destination_for(CompiledIC *ic) { ICStub* stub = ICStub_from_destination_address(ic->stub_address()); ***************
*** 223,235 **** // Enqueue this icholder for release during the next safepoint. It's // not safe to free them until them since they might be visible to // another thread. void InlineCacheBuffer::queue_for_release(CompiledICHolder* icholder) { ! MutexLockerEx mex1((CompiledIC_lock->owned_by_self() || ! SafepointSynchronize::is_at_safepoint()) ? NULL : CompiledIC_lock); ! MutexLockerEx mex2(InlineCacheBuffer_lock); icholder->set_next(_pending_released); _pending_released = icholder; _pending_count++; if (TraceICBuffer) { tty->print_cr("enqueueing icholder " INTPTR_FORMAT " to be freed", p2i(icholder)); --- 221,231 ---- // Enqueue this icholder for release during the next safepoint. It's // not safe to free them until them since they might be visible to // another thread. void InlineCacheBuffer::queue_for_release(CompiledICHolder* icholder) { ! MutexLockerEx mex(InlineCacheBuffer_lock, Mutex::_no_safepoint_check_flag); icholder->set_next(_pending_released); _pending_released = icholder; _pending_count++; if (TraceICBuffer) { tty->print_cr("enqueueing icholder " INTPTR_FORMAT " to be freed", p2i(icholder));
< prev index next >