compiledIC.hpp revision 1879:f95d63e2154a
1/* 2 * Copyright (c) 1997, 2010, 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_COMPILEDIC_HPP 26#define SHARE_VM_CODE_COMPILEDIC_HPP 27 28#include "interpreter/linkResolver.hpp" 29#include "oops/compiledICHolderKlass.hpp" 30#include "oops/compiledICHolderOop.hpp" 31#include "oops/klassOop.hpp" 32#ifdef TARGET_ARCH_x86 33# include "nativeInst_x86.hpp" 34#endif 35#ifdef TARGET_ARCH_sparc 36# include "nativeInst_sparc.hpp" 37#endif 38#ifdef TARGET_ARCH_zero 39# include "nativeInst_zero.hpp" 40#endif 41 42//----------------------------------------------------------------------------- 43// The CompiledIC represents a compiled inline cache. 44// 45// In order to make patching of the inline cache MT-safe, we only allow the following 46// transitions (when not at a safepoint): 47// 48// 49// [1] --<-- Clean -->--- [1] 50// / (null) \ 51// / \ /-<-\ 52// / [2] \ / \ 53// Interpreted ---------> Monomorphic | [3] 54// (compiledICHolderOop) (klassOop) | 55// \ / \ / 56// [4] \ / [4] \->-/ 57// \->- Megamorphic -<-/ 58// (methodOop) 59// 60// The text in paranteses () refere to the value of the inline cache receiver (mov instruction) 61// 62// The numbers in square brackets refere to the kind of transition: 63// [1]: Initial fixup. Receiver it found from debug information 64// [2]: Compilation of a method 65// [3]: Recompilation of a method (note: only entry is changed. The klassOop must stay the same) 66// [4]: Inline cache miss. We go directly to megamorphic call. 67// 68// The class automatically inserts transition stubs (using the InlineCacheBuffer) when an MT-unsafe 69// transition is made to a stub. 70// 71class CompiledIC; 72 73class CompiledICInfo { 74 friend class CompiledIC; 75 private: 76 address _entry; // entry point for call 77 Handle _cached_oop; // Value of cached_oop (either in stub or inline cache) 78 bool _is_optimized; // it is an optimized virtual call (i.e., can be statically bound) 79 bool _to_interpreter; // Call it to interpreter 80 public: 81 address entry() const { return _entry; } 82 Handle cached_oop() const { return _cached_oop; } 83 bool is_optimized() const { return _is_optimized; } 84}; 85 86class CompiledIC: public ResourceObj { 87 friend class InlineCacheBuffer; 88 friend class ICStub; 89 90 91 private: 92 NativeCall* _ic_call; // the call instruction 93 oop* _oop_addr; // patchable oop cell for this IC 94 RelocIterator _oops; // iteration over any and all set-oop instructions 95 bool _is_optimized; // an optimized virtual call (i.e., no compiled IC) 96 97 CompiledIC(NativeCall* ic_call); 98 CompiledIC(Relocation* ic_reloc); // Must be of virtual_call_type/opt_virtual_call_type 99 100 // low-level inline-cache manipulation. Cannot be accessed directly, since it might not be MT-safe 101 // to change an inline-cache. These changes the underlying inline-cache directly. They *newer* make 102 // changes to a transition stub. 103 void set_ic_destination(address entry_point); 104 void set_cached_oop(oop cache); 105 106 // Reads the location of the transition stub. This will fail with an assertion, if no transition stub is 107 // associated with the inline cache. 108 address stub_address() const; 109 bool is_in_transition_state() const; // Use InlineCacheBuffer 110 111 public: 112 // conversion (machine PC to CompiledIC*) 113 friend CompiledIC* CompiledIC_before(address return_addr); 114 friend CompiledIC* CompiledIC_at(address call_site); 115 friend CompiledIC* CompiledIC_at(Relocation* call_site); 116 117 // Return the cached_oop/destination associated with this inline cache. If the cache currently points 118 // to a transition stub, it will read the values from the transition stub. 119 oop cached_oop() const; 120 address ic_destination() const; 121 122 bool is_optimized() const { return _is_optimized; } 123 124 // State 125 bool is_clean() const; 126 bool is_megamorphic() const; 127 bool is_call_to_compiled() const; 128 bool is_call_to_interpreted() const; 129 130 address end_of_call() { return _ic_call->return_address(); } 131 132 // MT-safe patching of inline caches. Note: Only safe to call is_xxx when holding the CompiledIC_ock 133 // so you are guaranteed that no patching takes place. The same goes for verify. 134 // 135 // Note: We do not provide any direct access to the stub code, to prevent parts of the code 136 // to manipulate the inline cache in MT-unsafe ways. 137 // 138 // They all takes a TRAP argument, since they can cause a GC if the inline-cache buffer is full. 139 // 140 void set_to_clean(); // Can only be called during a safepoint operation 141 void set_to_monomorphic(const CompiledICInfo& info); 142 void set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS); 143 144 static void compute_monomorphic_entry(methodHandle method, KlassHandle receiver_klass, 145 bool is_optimized, bool static_bound, CompiledICInfo& info, TRAPS); 146 147 // Location 148 address instruction_address() const { return _ic_call->instruction_address(); } 149 150 // Misc 151 void print() PRODUCT_RETURN; 152 void print_compiled_ic() PRODUCT_RETURN; 153 void verify() PRODUCT_RETURN; 154}; 155 156inline CompiledIC* CompiledIC_before(address return_addr) { 157 CompiledIC* c_ic = new CompiledIC(nativeCall_before(return_addr)); 158 c_ic->verify(); 159 return c_ic; 160} 161 162inline CompiledIC* CompiledIC_at(address call_site) { 163 CompiledIC* c_ic = new CompiledIC(nativeCall_at(call_site)); 164 c_ic->verify(); 165 return c_ic; 166} 167 168inline CompiledIC* CompiledIC_at(Relocation* call_site) { 169 CompiledIC* c_ic = new CompiledIC(call_site); 170 c_ic->verify(); 171 return c_ic; 172} 173 174 175//----------------------------------------------------------------------------- 176// The CompiledStaticCall represents a call to a static method in the compiled 177// 178// Transition diagram of a static call site is somewhat simpler than for an inlined cache: 179// 180// 181// -----<----- Clean ----->----- 182// / \ 183// / \ 184// compilled code <------------> interpreted code 185// 186// Clean: Calls directly to runtime method for fixup 187// Compiled code: Calls directly to compiled code 188// Interpreted code: Calls to stub that set methodOop reference 189// 190// 191class CompiledStaticCall; 192 193class StaticCallInfo { 194 private: 195 address _entry; // Entrypoint 196 methodHandle _callee; // Callee (used when calling interpreter) 197 bool _to_interpreter; // call to interpreted method (otherwise compiled) 198 199 friend class CompiledStaticCall; 200 public: 201 address entry() const { return _entry; } 202 methodHandle callee() const { return _callee; } 203}; 204 205 206class CompiledStaticCall: public NativeCall { 207 friend class CompiledIC; 208 209 // Also used by CompiledIC 210 void set_to_interpreted(methodHandle callee, address entry); 211 bool is_optimized_virtual(); 212 213 public: 214 friend CompiledStaticCall* compiledStaticCall_before(address return_addr); 215 friend CompiledStaticCall* compiledStaticCall_at(address native_call); 216 friend CompiledStaticCall* compiledStaticCall_at(Relocation* call_site); 217 218 // State 219 bool is_clean() const; 220 bool is_call_to_compiled() const; 221 bool is_call_to_interpreted() const; 222 223 // Clean static call (will force resolving on next use) 224 void set_to_clean(); 225 226 // Set state. The entry must be the same, as computed by compute_entry. 227 // Computation and setting is split up, since the actions are separate during 228 // a OptoRuntime::resolve_xxx. 229 void set(const StaticCallInfo& info); 230 231 // Compute entry point given a method 232 static void compute_entry(methodHandle m, StaticCallInfo& info); 233 234 // Stub support 235 address find_stub(); 236 static void set_stub_to_clean(static_stub_Relocation* static_stub); 237 238 // Misc. 239 void print() PRODUCT_RETURN; 240 void verify() PRODUCT_RETURN; 241}; 242 243 244inline CompiledStaticCall* compiledStaticCall_before(address return_addr) { 245 CompiledStaticCall* st = (CompiledStaticCall*)nativeCall_before(return_addr); 246 st->verify(); 247 return st; 248} 249 250inline CompiledStaticCall* compiledStaticCall_at(address native_call) { 251 CompiledStaticCall* st = (CompiledStaticCall*)native_call; 252 st->verify(); 253 return st; 254} 255 256inline CompiledStaticCall* compiledStaticCall_at(Relocation* call_site) { 257 return compiledStaticCall_at(call_site->addr()); 258} 259 260#endif // SHARE_VM_CODE_COMPILEDIC_HPP 261