icBuffer.cpp revision 6412:53a41e7cbe05
11541Srgrimes/*
21541Srgrimes * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
31541Srgrimes * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
41541Srgrimes *
51541Srgrimes * This code is free software; you can redistribute it and/or modify it
61541Srgrimes * under the terms of the GNU General Public License version 2 only, as
71541Srgrimes * published by the Free Software Foundation.
81541Srgrimes *
91541Srgrimes * This code is distributed in the hope that it will be useful, but WITHOUT
101541Srgrimes * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
111541Srgrimes * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
121541Srgrimes * version 2 for more details (a copy is included in the LICENSE file that
131541Srgrimes * accompanied this code).
141541Srgrimes *
151541Srgrimes * You should have received a copy of the GNU General Public License version
161541Srgrimes * 2 along with this work; if not, write to the Free Software Foundation,
171541Srgrimes * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
181541Srgrimes *
191541Srgrimes * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
201541Srgrimes * or visit www.oracle.com if you need additional information or have any
211541Srgrimes * questions.
221541Srgrimes *
231541Srgrimes */
241541Srgrimes
251541Srgrimes#include "precompiled.hpp"
261541Srgrimes#include "code/codeCache.hpp"
271541Srgrimes#include "code/compiledIC.hpp"
281541Srgrimes#include "code/icBuffer.hpp"
291541Srgrimes#include "code/nmethod.hpp"
301541Srgrimes#include "code/scopeDesc.hpp"
311541Srgrimes#include "gc_interface/collectedHeap.inline.hpp"
321541Srgrimes#include "interpreter/interpreter.hpp"
331541Srgrimes#include "interpreter/linkResolver.hpp"
3444510Swollman#include "memory/resourceArea.hpp"
351541Srgrimes#include "memory/universe.inline.hpp"
361541Srgrimes#include "oops/method.hpp"
37116182Sobrien#include "oops/oop.inline.hpp"
38116182Sobrien#include "oops/oop.inline2.hpp"
39116182Sobrien#include "runtime/mutexLocker.hpp"
401541Srgrimes#include "runtime/stubRoutines.hpp"
411541Srgrimes
4233392SphkPRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
43127969Scperciva
441541SrgrimesDEF_STUB_INTERFACE(ICStub);
45133229Srwatson
4674914SjhbStubQueue* InlineCacheBuffer::_buffer    = NULL;
4768840SjhbICStub*    InlineCacheBuffer::_next_stub = NULL;
48150188Sjhb
49115810SphkCompiledICHolder* InlineCacheBuffer::_pending_released = NULL;
501541Srgrimesint InlineCacheBuffer::_pending_count = 0;
51115810Sphk
52115810Sphkvoid ICStub::finalize() {
53115810Sphk  if (!is_empty()) {
54115810Sphk    ResourceMark rm;
55115810Sphk    CompiledIC *ic = CompiledIC_at(CodeCache::find_nmethod(ic_site()), ic_site());
56115810Sphk    assert(CodeCache::find_nmethod(ic->instruction_address()) != NULL, "inline cache in non-nmethod?");
57141428Siedowse
58141428Siedowse    assert(this == ICStub_from_destination_address(ic->stub_address()), "wrong owner of ic buffer");
59141428Siedowse    ic->set_ic_destination_and_value(destination(), cached_value());
60115810Sphk  }
61115810Sphk}
62115810Sphk
6333392Sphk
6433392Sphkaddress ICStub::destination() const {
6533392Sphk  return InlineCacheBuffer::ic_buffer_entry_point(code_begin());
6633392Sphk}
6733392Sphk
6833392Sphkvoid* ICStub::cached_value() const {
6929680Sgibbs  return InlineCacheBuffer::ic_buffer_cached_value(code_begin());
7029680Sgibbs}
7129680Sgibbs
7229680Sgibbs
7333392Sphkvoid ICStub::set_stub(CompiledIC *ic, void* cached_val, address dest_addr) {
74116606Sphk  // We cannot store a pointer to the 'ic' object, since it is resource allocated. Instead we
752112Swollman  // store the location of the inline cache. Then we have enough information recreate the CompiledIC
7629680Sgibbs  // object when we need to remove the stub.
77128024Scperciva  _ic_site = ic->instruction_address();
78139831Scperciva
79127969Scperciva  // Assemble new stub
80127969Scperciva  InlineCacheBuffer::assemble_ic_buffer_code(code_begin(), cached_val, dest_addr);
81155957Sjhb  assert(destination() == dest_addr,   "can recover destination");
82155957Sjhb  assert(cached_value() == cached_val, "can recover destination");
83127969Scperciva}
84141428Siedowse
85141428Siedowse
86141428Siedowsevoid ICStub::clear() {
87141428Siedowse  if (CompiledIC::is_icholder_entry(destination())) {
88155957Sjhb    InlineCacheBuffer::queue_for_release((CompiledICHolder*)cached_value());
89141428Siedowse  }
90155957Sjhb  _ic_site = NULL;
91155957Sjhb}
92128024Scperciva
93127969Scperciva
94127969Scperciva#ifndef PRODUCT
95141428Siedowse// anybody calling to this stub will trap
96155957Sjhb
97128024Scpercivavoid ICStub::verify() {
981541Srgrimes}
9982127Sdillon
10082127Sdillonvoid ICStub::print() {
10182127Sdillon  tty->print_cr("ICStub: site: " INTPTR_FORMAT, _ic_site);
10282127Sdillon}
10382127Sdillon#endif
10482127Sdillon
10582127Sdillon//-----------------------------------------------------------------------------------------------
10682127Sdillon// Implementation of InlineCacheBuffer
10782127Sdillon
10882127Sdillonvoid InlineCacheBuffer::init_next_stub() {
10982127Sdillon  ICStub* ic_stub = (ICStub*)buffer()->request_committed (ic_stub_code_size());
11082127Sdillon  assert (ic_stub != NULL, "no room for a single stub");
11182127Sdillon  set_next_stub(ic_stub);
11282127Sdillon}
11382127Sdillon
11482127Sdillonvoid InlineCacheBuffer::initialize() {
11582127Sdillon  if (_buffer != NULL) return; // already initialized
11682127Sdillon  _buffer = new StubQueue(new ICStubInterface, 10*K, InlineCacheBuffer_lock, "InlineCacheBuffer");
11782127Sdillon  assert (_buffer != NULL, "cannot allocate InlineCacheBuffer");
11882127Sdillon  init_next_stub();
11982127Sdillon}
12082127Sdillon
12182127Sdillon
12282127SdillonICStub* InlineCacheBuffer::new_ic_stub() {
12382127Sdillon  while (true) {
12482127Sdillon    ICStub* ic_stub = (ICStub*)buffer()->request_committed(ic_stub_code_size());
12582127Sdillon    if (ic_stub != NULL) {
12682127Sdillon      return ic_stub;
12782127Sdillon    }
12882127Sdillon    // we ran out of inline cache buffer space; must enter safepoint.
12982127Sdillon    // We do this by forcing a safepoint
13082127Sdillon    EXCEPTION_MARK;
13182127Sdillon
13282127Sdillon    VM_ForceSafepoint vfs;
13382127Sdillon    VMThread::execute(&vfs);
13482127Sdillon    // We could potential get an async. exception at this point.
13582127Sdillon    // In that case we will rethrow it to ourselvs.
13682127Sdillon    if (HAS_PENDING_EXCEPTION) {
13782127Sdillon      oop exception = PENDING_EXCEPTION;
13882127Sdillon      CLEAR_PENDING_EXCEPTION;
13982127Sdillon      Thread::send_async_exception(JavaThread::current()->threadObj(), exception);
14082127Sdillon    }
14182127Sdillon  }
14282127Sdillon  ShouldNotReachHere();
14382127Sdillon  return NULL;
14493818Sjhb}
14582127Sdillon
14682127Sdillon
14782127Sdillonvoid InlineCacheBuffer::update_inline_caches() {
14829680Sgibbs  if (buffer()->number_of_stubs() > 1) {
14929680Sgibbs    if (TraceICBuffer) {
15029680Sgibbs      tty->print_cr("[updating inline caches with %d stubs]", buffer()->number_of_stubs());
15129680Sgibbs    }
152128630Shmp    buffer()->remove_all();
15329680Sgibbs    init_next_stub();
15429680Sgibbs  }
15529680Sgibbs  release_pending_icholders();
15629680Sgibbs}
15729680Sgibbs
15832388Sphk
15929680Sgibbsbool InlineCacheBuffer::contains(address instruction_address) {
1601541Srgrimes  return buffer()->contains(instruction_address);
1611541Srgrimes}
1621541Srgrimes
1631541Srgrimes
16467551Sjhbbool InlineCacheBuffer::is_empty() {
1651541Srgrimes  return buffer()->number_of_stubs() == 1;    // always has sentinel
166102936Sphk}
167102936Sphk
168102936Sphk
169102936Sphkvoid InlineCacheBuffer_init() {
170115810Sphk  InlineCacheBuffer::initialize();
171115810Sphk}
172141428Siedowse
173115810Sphk
174122585Smckusickvoid InlineCacheBuffer::create_transition_stub(CompiledIC *ic, void* cached_value, address entry) {
175122585Smckusick  assert(!SafepointSynchronize::is_at_safepoint(), "should not be called during a safepoint");
176122585Smckusick  assert (CompiledIC_lock->is_locked(), "");
177122585Smckusick  if (TraceICBuffer) {
178123254Sphk    tty->print_cr("  create transition stub for " INTPTR_FORMAT " destination " INTPTR_FORMAT " cached value " INTPTR_FORMAT,
179122585Smckusick                  ic->instruction_address(), entry, cached_value);
1801541Srgrimes  }
18133392Sphk
18233392Sphk  // If an transition stub is already associate with the inline cache, then we remove the association.
18333392Sphk  if (ic->is_in_transition_state()) {
18429680Sgibbs    ICStub* old_stub = ICStub_from_destination_address(ic->stub_address());
185115810Sphk    old_stub->clear();
186141428Siedowse  }
187115810Sphk
188115810Sphk  // allocate and initialize new "out-of-line" inline-cache
18929680Sgibbs  ICStub* ic_stub = get_next_stub();
19072200Sbmilekic  ic_stub->set_stub(ic, cached_value, entry);
19129680Sgibbs
19229805Sgibbs  // Update inline cache in nmethod to point to new "out-of-line" allocated inline cache
19329805Sgibbs  ic->set_ic_destination(ic_stub);
19429805Sgibbs
19529805Sgibbs  set_next_stub(new_ic_stub()); // can cause safepoint synchronization
19629805Sgibbs}
19729805Sgibbs
19829805Sgibbs
19929805Sgibbsaddress InlineCacheBuffer::ic_destination_for(CompiledIC *ic) {
20029680Sgibbs  ICStub* stub = ICStub_from_destination_address(ic->stub_address());
201115810Sphk  return stub->destination();
20229805Sgibbs}
20329680Sgibbs
20429680Sgibbs
20529680Sgibbsvoid* InlineCacheBuffer::cached_value_for(CompiledIC *ic) {
20629680Sgibbs  ICStub* stub = ICStub_from_destination_address(ic->stub_address());
20729805Sgibbs  return stub->cached_value();
20872200Sbmilekic}
20981370Sjhb
21072200Sbmilekic
21129680Sgibbs// Free CompiledICHolder*s that are no longer in use
21229680Sgibbsvoid InlineCacheBuffer::release_pending_icholders() {
21329680Sgibbs  assert(SafepointSynchronize::is_at_safepoint(), "should only be called during a safepoint");
21429680Sgibbs  CompiledICHolder* holder = _pending_released;
21529680Sgibbs  _pending_released = NULL;
21629680Sgibbs  while (holder != NULL) {
217141428Siedowse    CompiledICHolder* next = holder->next();
21868889Sjake    delete holder;
21929680Sgibbs    holder = next;
22029680Sgibbs    _pending_count--;
22129805Sgibbs  }
22229680Sgibbs  assert(_pending_count == 0, "wrong count");
22329680Sgibbs}
224141428Siedowse
22568889Sjake// Enqueue this icholder for release during the next safepoint.  It's
22644510Swollman// not safe to free them until them since they might be visible to
227140489Scperciva// another thread.
22844510Swollmanvoid InlineCacheBuffer::queue_for_release(CompiledICHolder* icholder) {
22944510Swollman  MutexLockerEx mex(InlineCacheBuffer_lock);
23044510Swollman  icholder->set_next(_pending_released);
231141674Siedowse  _pending_released = icholder;
23244510Swollman  _pending_count++;
23344510Swollman  if (TraceICBuffer) {
23450673Sjlemon    tty->print_cr("enqueueing icholder " INTPTR_FORMAT " to be freed", icholder);
235141674Siedowse  }
23644510Swollman}
237141428Siedowse