< prev index next >
src/hotspot/share/code/icBuffer.cpp
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();
}
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();
}
***************
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());
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());
***************
// 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));
// 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 >