1 /*
   2  * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   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 "code/codeCache.hpp"
  27 #include "code/compiledIC.hpp"
  28 #include "code/icBuffer.hpp"
  29 #include "code/nmethod.hpp"
  30 #include "code/scopeDesc.hpp"
  31 #include "gc/shared/collectedHeap.inline.hpp"
  32 #include "interpreter/interpreter.hpp"
  33 #include "interpreter/linkResolver.hpp"
  34 #include "memory/resourceArea.hpp"
  35 #include "oops/method.hpp"
  36 #include "oops/oop.inline.hpp"
  37 #include "runtime/handles.inline.hpp"
  38 #include "runtime/mutexLocker.inline.hpp"
  39 #include "runtime/stubRoutines.hpp"
  40 #include "runtime/thread.hpp"
  41 
  42 DEF_STUB_INTERFACE(ICStub);
  43 
  44 StubQueue* InlineCacheBuffer::_buffer    = NULL;
  45 
  46 CompiledICHolder* InlineCacheBuffer::_pending_released = NULL;
  47 int InlineCacheBuffer::_pending_count = 0;
  48 
  49 #ifdef ASSERT
  50 ICRefillVerifier::ICRefillVerifier()
  51   : _refill_requested(false),
  52     _refill_remembered(false)
  53 {
  54   Thread* thread = Thread::current();
  55   assert(thread->missed_ic_stub_refill_verifier() == NULL, "nesting not supported");
  56   thread->set_missed_ic_stub_refill_verifier(this);
  57 }
  58 
  59 ICRefillVerifier::~ICRefillVerifier() {
  60   assert(!_refill_requested || _refill_remembered,
  61          "Forgot to refill IC stubs after failed IC transition");
  62   Thread::current()->set_missed_ic_stub_refill_verifier(NULL);
  63 }
  64 
  65 ICRefillVerifierMark::ICRefillVerifierMark(ICRefillVerifier* verifier) {
  66   Thread* thread = Thread::current();
  67   assert(thread->missed_ic_stub_refill_verifier() == NULL, "nesting not supported");
  68   thread->set_missed_ic_stub_refill_verifier(verifier);
  69 }
  70 
  71 ICRefillVerifierMark::~ICRefillVerifierMark() {
  72   Thread::current()->set_missed_ic_stub_refill_verifier(NULL);
  73 }
  74 
  75 static ICRefillVerifier* current_ic_refill_verifier() {
  76   Thread* current = Thread::current();
  77   ICRefillVerifier* verifier = current->missed_ic_stub_refill_verifier();
  78   assert(verifier != NULL, "need a verifier for safety");
  79   return verifier;
  80 }
  81 #endif
  82 
  83 void ICStub::finalize() {
  84   if (!is_empty()) {
  85     ResourceMark rm;
  86     CompiledIC *ic = CompiledIC_at(CodeCache::find_compiled(ic_site()), ic_site());
  87     assert(CodeCache::find_compiled(ic->instruction_address()) != NULL, "inline cache in non-compiled?");
  88 
  89     assert(this == ICStub_from_destination_address(ic->stub_address()), "wrong owner of ic buffer");
  90     ic->set_ic_destination_and_value(destination(), cached_value());
  91   }
  92 }
  93 
  94 
  95 address ICStub::destination() const {
  96   return InlineCacheBuffer::ic_buffer_entry_point(code_begin());
  97 }
  98 
  99 void* ICStub::cached_value() const {
 100   return InlineCacheBuffer::ic_buffer_cached_value(code_begin());
 101 }
 102 
 103 
 104 void ICStub::set_stub(CompiledIC *ic, void* cached_val, address dest_addr) {
 105   // We cannot store a pointer to the 'ic' object, since it is resource allocated. Instead we
 106   // store the location of the inline cache. Then we have enough information recreate the CompiledIC
 107   // object when we need to remove the stub.
 108   _ic_site = ic->instruction_address();
 109 
 110   // Assemble new stub
 111   InlineCacheBuffer::assemble_ic_buffer_code(code_begin(), cached_val, dest_addr);
 112   assert(destination() == dest_addr,   "can recover destination");
 113   assert(cached_value() == cached_val, "can recover destination");
 114 }
 115 
 116 
 117 void ICStub::clear() {
 118   if (CompiledIC::is_icholder_entry(destination())) {
 119     InlineCacheBuffer::queue_for_release((CompiledICHolder*)cached_value());
 120   }
 121   _ic_site = NULL;
 122 }
 123 
 124 
 125 #ifndef PRODUCT
 126 // anybody calling to this stub will trap
 127 
 128 void ICStub::verify() {
 129 }
 130 
 131 void ICStub::print() {
 132   tty->print_cr("ICStub: site: " INTPTR_FORMAT, p2i(_ic_site));
 133 }
 134 #endif
 135 
 136 //-----------------------------------------------------------------------------------------------
 137 // Implementation of InlineCacheBuffer
 138 
 139 
 140 void InlineCacheBuffer::initialize() {
 141   if (_buffer != NULL) return; // already initialized
 142   _buffer = new StubQueue(new ICStubInterface, 10*K, InlineCacheBuffer_lock, "InlineCacheBuffer");
 143   assert (_buffer != NULL, "cannot allocate InlineCacheBuffer");
 144 }
 145 
 146 
 147 ICStub* InlineCacheBuffer::new_ic_stub() {
 148   return (ICStub*)buffer()->request_committed(ic_stub_code_size());
 149 }
 150 
 151 
 152 void InlineCacheBuffer::refill_ic_stubs() {
 153 #ifdef ASSERT
 154   ICRefillVerifier* verifier = current_ic_refill_verifier();
 155   verifier->request_remembered();
 156 #endif
 157   // we ran out of inline cache buffer space; must enter safepoint.
 158   // We do this by forcing a safepoint
 159   EXCEPTION_MARK;
 160 
 161   VM_ICBufferFull ibf;
 162   VMThread::execute(&ibf);
 163   // We could potential get an async. exception at this point.
 164   // In that case we will rethrow it to ourselvs.
 165   if (HAS_PENDING_EXCEPTION) {
 166     oop exception = PENDING_EXCEPTION;
 167     CLEAR_PENDING_EXCEPTION;
 168     Thread::send_async_exception(JavaThread::current()->threadObj(), exception);
 169   }
 170 }
 171 
 172 
 173 void InlineCacheBuffer::update_inline_caches() {
 174   if (buffer()->number_of_stubs() > 0) {
 175     if (TraceICBuffer) {
 176       tty->print_cr("[updating inline caches with %d stubs]", buffer()->number_of_stubs());
 177     }
 178     buffer()->remove_all();
 179   }
 180   release_pending_icholders();
 181 }
 182 
 183 
 184 bool InlineCacheBuffer::contains(address instruction_address) {
 185   return buffer()->contains(instruction_address);
 186 }
 187 
 188 
 189 bool InlineCacheBuffer::is_empty() {
 190   return buffer()->number_of_stubs() == 0;
 191 }
 192 
 193 
 194 void InlineCacheBuffer_init() {
 195   InlineCacheBuffer::initialize();
 196 }
 197 
 198 bool InlineCacheBuffer::create_transition_stub(CompiledIC *ic, void* cached_value, address entry) {
 199   assert(!SafepointSynchronize::is_at_safepoint(), "should not be called during a safepoint");
 200   assert(CompiledICLocker::is_safe(ic->instruction_address()), "mt unsafe call");
 201   if (TraceICBuffer) {
 202     tty->print_cr("  create transition stub for " INTPTR_FORMAT " destination " INTPTR_FORMAT " cached value " INTPTR_FORMAT,
 203                   p2i(ic->instruction_address()), p2i(entry), p2i(cached_value));
 204   }
 205 
 206   // allocate and initialize new "out-of-line" inline-cache
 207   ICStub* ic_stub = new_ic_stub();
 208   if (ic_stub == NULL) {
 209 #ifdef ASSERT
 210     ICRefillVerifier* verifier = current_ic_refill_verifier();
 211     verifier->request_refill();
 212 #endif
 213     return false;
 214   }
 215 
 216   // If an transition stub is already associate with the inline cache, then we remove the association.
 217   if (ic->is_in_transition_state()) {
 218     ICStub* old_stub = ICStub_from_destination_address(ic->stub_address());
 219     old_stub->clear();
 220   }
 221 
 222   ic_stub->set_stub(ic, cached_value, entry);
 223 
 224   // Update inline cache in nmethod to point to new "out-of-line" allocated inline cache
 225   ic->set_ic_destination(ic_stub);
 226   return true;
 227 }
 228 
 229 
 230 address InlineCacheBuffer::ic_destination_for(CompiledIC *ic) {
 231   ICStub* stub = ICStub_from_destination_address(ic->stub_address());
 232   return stub->destination();
 233 }
 234 
 235 
 236 void* InlineCacheBuffer::cached_value_for(CompiledIC *ic) {
 237   ICStub* stub = ICStub_from_destination_address(ic->stub_address());
 238   return stub->cached_value();
 239 }
 240 
 241 
 242 // Free CompiledICHolder*s that are no longer in use
 243 void InlineCacheBuffer::release_pending_icholders() {
 244   assert(SafepointSynchronize::is_at_safepoint(), "should only be called during a safepoint");
 245   CompiledICHolder* holder = _pending_released;
 246   _pending_released = NULL;
 247   while (holder != NULL) {
 248     CompiledICHolder* next = holder->next();
 249     delete holder;
 250     holder = next;
 251     _pending_count--;
 252   }
 253   assert(_pending_count == 0, "wrong count");
 254 }
 255 
 256 // Enqueue this icholder for release during the next safepoint.  It's
 257 // not safe to free them until them since they might be visible to
 258 // another thread.
 259 void InlineCacheBuffer::queue_for_release(CompiledICHolder* icholder) {
 260   MutexLocker mex(InlineCacheBuffer_lock, Mutex::_no_safepoint_check_flag);
 261   icholder->set_next(_pending_released);
 262   _pending_released = icholder;
 263   _pending_count++;
 264   if (TraceICBuffer) {
 265     tty->print_cr("enqueueing icholder " INTPTR_FORMAT " to be freed", p2i(icholder));
 266   }
 267 }