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