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