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