1 /*
   2  * Copyright (c) 1997, 2012, 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 #ifndef SHARE_VM_CODE_ICBUFFER_HPP
  26 #define SHARE_VM_CODE_ICBUFFER_HPP
  27 
  28 #include "asm/codeBuffer.hpp"
  29 #include "code/stubs.hpp"
  30 #include "interpreter/bytecodes.hpp"
  31 #include "memory/allocation.hpp"
  32 
  33 //
  34 // For CompiledIC's:
  35 //
  36 // In cases where we do not have MT-safe state transformation,
  37 // we go to a transition state, using ICStubs. At a safepoint,
  38 // the inline caches are transferred from the transitional code:
  39 //
  40 //    instruction_address --> 01 set xxx_oop, Ginline_cache_klass
  41 //                            23 jump_to Gtemp, yyyy
  42 //                            4  nop
  43 
  44 class ICStub: public Stub {
  45  private:
  46   int                 _size;       // total size of the stub incl. code
  47   address             _ic_site;    // points at call instruction of owning ic-buffer
  48   /* stub code follows here */
  49  protected:
  50   friend class ICStubInterface;
  51   // This will be called only by ICStubInterface
  52   void    initialize(int size,
  53                      CodeStrings strings)        { _size = size; _ic_site = NULL; }
  54   void    finalize(); // called when a method is removed
  55 
  56   // General info
  57   int     size() const                           { return _size; }
  58   static  int code_size_to_size(int code_size)   { return round_to(sizeof(ICStub), CodeEntryAlignment) + code_size; }
  59 
  60  public:
  61   // Creation
  62   void set_stub(CompiledIC *ic, void* cached_value, address dest_addr);
  63 
  64   // Code info
  65   address code_begin() const                     { return (address)this + round_to(sizeof(ICStub), CodeEntryAlignment); }
  66   address code_end() const                       { return (address)this + size(); }
  67 
  68   // Call site info
  69   address ic_site() const                        { return _ic_site; }
  70   void    clear();
  71   bool    is_empty() const                       { return _ic_site == NULL; }
  72 
  73   // stub info
  74   address destination() const;  // destination of jump instruction
  75   void* cached_value() const;   // cached_value for stub
  76 
  77   // Debugging
  78   void    verify()            PRODUCT_RETURN;
  79   void    print()             PRODUCT_RETURN;
  80 
  81   // Creation
  82   friend ICStub* ICStub_from_destination_address(address destination_address);
  83 };
  84 
  85 // ICStub Creation
  86 inline ICStub* ICStub_from_destination_address(address destination_address) {
  87   ICStub* stub = (ICStub*) (destination_address - round_to(sizeof(ICStub), CodeEntryAlignment));
  88   #ifdef ASSERT
  89   stub->verify();
  90   #endif
  91   return stub;
  92 }
  93 
  94 class InlineCacheBuffer: public AllStatic {
  95  private:
  96   // friends
  97   friend class ICStub;
  98 
  99   static int ic_stub_code_size();
 100 
 101   static StubQueue* _buffer;
 102   static ICStub*    _next_stub;
 103 
 104   static CompiledICHolder* _pending_released;
 105   static int _pending_count;
 106 
 107   static StubQueue* buffer()                         { return _buffer;         }
 108   static void       set_next_stub(ICStub* next_stub) { _next_stub = next_stub; }
 109   static ICStub*    get_next_stub()                  { return _next_stub;      }
 110 
 111   static void       init_next_stub();
 112 
 113   static ICStub* new_ic_stub();
 114 
 115 
 116   // Machine-dependent implementation of ICBuffer
 117   static void    assemble_ic_buffer_code(address code_begin, void* cached_value, address entry_point);
 118   static address ic_buffer_entry_point  (address code_begin);
 119   static void*   ic_buffer_cached_value (address code_begin);
 120 
 121  public:
 122 
 123     // Initialization; must be called before first usage
 124   static void initialize();
 125 
 126   // Access
 127   static bool contains(address instruction_address);
 128 
 129     // removes the ICStubs after backpatching
 130   static void update_inline_caches();
 131 
 132   // for debugging
 133   static bool is_empty();
 134 
 135   static void release_pending_icholders();
 136   static void queue_for_release(CompiledICHolder* icholder);
 137   static int pending_icholder_count() { return _pending_count; }
 138 
 139   // New interface
 140   static void    create_transition_stub(CompiledIC *ic, void* cached_value, address entry);
 141   static address ic_destination_for(CompiledIC *ic);
 142   static void*   cached_value_for(CompiledIC *ic);
 143 };
 144 
 145 #endif // SHARE_VM_CODE_ICBUFFER_HPP