compiledIC.hpp revision 6760:22b98ab2a69f
1/* 2 * Copyright (c) 1997, 2014, 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 "code/nativeInst.hpp" 29#include "interpreter/linkResolver.hpp" 30#include "oops/compiledICHolder.hpp" 31 32//----------------------------------------------------------------------------- 33// The CompiledIC represents a compiled inline cache. 34// 35// In order to make patching of the inline cache MT-safe, we only allow the following 36// transitions (when not at a safepoint): 37// 38// 39// [1] --<-- Clean -->--- [1] 40// / (null) \ 41// / \ /-<-\ 42// / [2] \ / \ 43// Interpreted ---------> Monomorphic | [3] 44// (CompiledICHolder*) (Klass*) | 45// \ / \ / 46// [4] \ / [4] \->-/ 47// \->- Megamorphic -<-/ 48// (Method*) 49// 50// The text in paranteses () refere to the value of the inline cache receiver (mov instruction) 51// 52// The numbers in square brackets refere to the kind of transition: 53// [1]: Initial fixup. Receiver it found from debug information 54// [2]: Compilation of a method 55// [3]: Recompilation of a method (note: only entry is changed. The Klass* must stay the same) 56// [4]: Inline cache miss. We go directly to megamorphic call. 57// 58// The class automatically inserts transition stubs (using the InlineCacheBuffer) when an MT-unsafe 59// transition is made to a stub. 60// 61class CompiledIC; 62class ICStub; 63 64class CompiledICInfo : public StackObj { 65 private: 66 address _entry; // entry point for call 67 void* _cached_value; // Value of cached_value (either in stub or inline cache) 68 bool _is_icholder; // Is the cached value a CompiledICHolder* 69 bool _is_optimized; // it is an optimized virtual call (i.e., can be statically bound) 70 bool _to_interpreter; // Call it to interpreter 71 bool _release_icholder; 72 public: 73 address entry() const { return _entry; } 74 Metadata* cached_metadata() const { assert(!_is_icholder, ""); return (Metadata*)_cached_value; } 75 CompiledICHolder* claim_cached_icholder() { 76 assert(_is_icholder, ""); 77 assert(_cached_value != NULL, "must be non-NULL"); 78 _release_icholder = false; 79 CompiledICHolder* icholder = (CompiledICHolder*)_cached_value; 80 icholder->claim(); 81 return icholder; 82 } 83 bool is_optimized() const { return _is_optimized; } 84 bool to_interpreter() const { return _to_interpreter; } 85 86 void set_compiled_entry(address entry, Klass* klass, bool is_optimized) { 87 _entry = entry; 88 _cached_value = (void*)klass; 89 _to_interpreter = false; 90 _is_icholder = false; 91 _is_optimized = is_optimized; 92 _release_icholder = false; 93 } 94 95 void set_interpreter_entry(address entry, Method* method) { 96 _entry = entry; 97 _cached_value = (void*)method; 98 _to_interpreter = true; 99 _is_icholder = false; 100 _is_optimized = true; 101 _release_icholder = false; 102 } 103 104 void set_icholder_entry(address entry, CompiledICHolder* icholder) { 105 _entry = entry; 106 _cached_value = (void*)icholder; 107 _to_interpreter = true; 108 _is_icholder = true; 109 _is_optimized = false; 110 _release_icholder = true; 111 } 112 113 CompiledICInfo(): _entry(NULL), _cached_value(NULL), _is_icholder(false), 114 _to_interpreter(false), _is_optimized(false), _release_icholder(false) { 115 } 116 ~CompiledICInfo() { 117 // In rare cases the info is computed but not used, so release any 118 // CompiledICHolder* that was created 119 if (_release_icholder) { 120 assert(_is_icholder, "must be"); 121 CompiledICHolder* icholder = (CompiledICHolder*)_cached_value; 122 icholder->claim(); 123 delete icholder; 124 } 125 } 126}; 127 128class CompiledIC: public ResourceObj { 129 friend class InlineCacheBuffer; 130 friend class ICStub; 131 132 133 private: 134 NativeCall* _ic_call; // the call instruction 135 NativeMovConstReg* _value; // patchable value cell for this IC 136 bool _is_optimized; // an optimized virtual call (i.e., no compiled IC) 137 138 CompiledIC(nmethod* nm, NativeCall* ic_call); 139 140 static bool is_icholder_entry(address entry); 141 142 // low-level inline-cache manipulation. Cannot be accessed directly, since it might not be MT-safe 143 // to change an inline-cache. These changes the underlying inline-cache directly. They *newer* make 144 // changes to a transition stub. 145 void internal_set_ic_destination(address entry_point, bool is_icstub, void* cache, bool is_icholder); 146 void set_ic_destination(ICStub* stub); 147 void set_ic_destination(address entry_point) { 148 assert(_is_optimized, "use set_ic_destination_and_value instead"); 149 internal_set_ic_destination(entry_point, false, NULL, false); 150 } 151 // This only for use by ICStubs where the type of the value isn't known 152 void set_ic_destination_and_value(address entry_point, void* value) { 153 internal_set_ic_destination(entry_point, false, value, is_icholder_entry(entry_point)); 154 } 155 void set_ic_destination_and_value(address entry_point, Metadata* value) { 156 internal_set_ic_destination(entry_point, false, value, false); 157 } 158 void set_ic_destination_and_value(address entry_point, CompiledICHolder* value) { 159 internal_set_ic_destination(entry_point, false, value, true); 160 } 161 162 // Reads the location of the transition stub. This will fail with an assertion, if no transition stub is 163 // associated with the inline cache. 164 address stub_address() const; 165 bool is_in_transition_state() const; // Use InlineCacheBuffer 166 167 public: 168 // conversion (machine PC to CompiledIC*) 169 friend CompiledIC* CompiledIC_before(nmethod* nm, address return_addr); 170 friend CompiledIC* CompiledIC_at(nmethod* nm, address call_site); 171 friend CompiledIC* CompiledIC_at(Relocation* call_site); 172 173 // This is used to release CompiledICHolder*s from nmethods that 174 // are about to be freed. The callsite might contain other stale 175 // values of other kinds so it must be careful. 176 static void cleanup_call_site(virtual_call_Relocation* call_site); 177 static bool is_icholder_call_site(virtual_call_Relocation* call_site); 178 179 // Return the cached_metadata/destination associated with this inline cache. If the cache currently points 180 // to a transition stub, it will read the values from the transition stub. 181 void* cached_value() const; 182 CompiledICHolder* cached_icholder() const { 183 assert(is_icholder_call(), "must be"); 184 return (CompiledICHolder*) cached_value(); 185 } 186 Metadata* cached_metadata() const { 187 assert(!is_icholder_call(), "must be"); 188 return (Metadata*) cached_value(); 189 } 190 191 address ic_destination() const; 192 193 bool is_optimized() const { return _is_optimized; } 194 195 // State 196 bool is_clean() const; 197 bool is_megamorphic() const; 198 bool is_call_to_compiled() const; 199 bool is_call_to_interpreted() const; 200 201 bool is_icholder_call() const; 202 203 address end_of_call() { return _ic_call->return_address(); } 204 205 // MT-safe patching of inline caches. Note: Only safe to call is_xxx when holding the CompiledIC_ock 206 // so you are guaranteed that no patching takes place. The same goes for verify. 207 // 208 // Note: We do not provide any direct access to the stub code, to prevent parts of the code 209 // to manipulate the inline cache in MT-unsafe ways. 210 // 211 // They all takes a TRAP argument, since they can cause a GC if the inline-cache buffer is full. 212 // 213 void set_to_clean(); // Can only be called during a safepoint operation 214 void set_to_monomorphic(CompiledICInfo& info); 215 216 // Returns true if successful and false otherwise. The call can fail if memory 217 // allocation in the code cache fails. 218 bool set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS); 219 220 static void compute_monomorphic_entry(methodHandle method, KlassHandle receiver_klass, 221 bool is_optimized, bool static_bound, CompiledICInfo& info, TRAPS); 222 223 // Location 224 address instruction_address() const { return _ic_call->instruction_address(); } 225 226 // Misc 227 void print() PRODUCT_RETURN; 228 void print_compiled_ic() PRODUCT_RETURN; 229 void verify() PRODUCT_RETURN; 230}; 231 232inline CompiledIC* CompiledIC_before(nmethod* nm, address return_addr) { 233 CompiledIC* c_ic = new CompiledIC(nm, nativeCall_before(return_addr)); 234 c_ic->verify(); 235 return c_ic; 236} 237 238inline CompiledIC* CompiledIC_at(nmethod* nm, address call_site) { 239 CompiledIC* c_ic = new CompiledIC(nm, nativeCall_at(call_site)); 240 c_ic->verify(); 241 return c_ic; 242} 243 244inline CompiledIC* CompiledIC_at(Relocation* call_site) { 245 assert(call_site->type() == relocInfo::virtual_call_type || 246 call_site->type() == relocInfo::opt_virtual_call_type, "wrong reloc. info"); 247 CompiledIC* c_ic = new CompiledIC(call_site->code(), nativeCall_at(call_site->addr())); 248 c_ic->verify(); 249 return c_ic; 250} 251 252 253//----------------------------------------------------------------------------- 254// The CompiledStaticCall represents a call to a static method in the compiled 255// 256// Transition diagram of a static call site is somewhat simpler than for an inlined cache: 257// 258// 259// -----<----- Clean ----->----- 260// / \ 261// / \ 262// compilled code <------------> interpreted code 263// 264// Clean: Calls directly to runtime method for fixup 265// Compiled code: Calls directly to compiled code 266// Interpreted code: Calls to stub that set Method* reference 267// 268// 269class CompiledStaticCall; 270 271class StaticCallInfo { 272 private: 273 address _entry; // Entrypoint 274 methodHandle _callee; // Callee (used when calling interpreter) 275 bool _to_interpreter; // call to interpreted method (otherwise compiled) 276 277 friend class CompiledStaticCall; 278 public: 279 address entry() const { return _entry; } 280 methodHandle callee() const { return _callee; } 281}; 282 283 284class CompiledStaticCall: public NativeCall { 285 friend class CompiledIC; 286 287 // Also used by CompiledIC 288 void set_to_interpreted(methodHandle callee, address entry); 289 bool is_optimized_virtual(); 290 291 public: 292 friend CompiledStaticCall* compiledStaticCall_before(address return_addr); 293 friend CompiledStaticCall* compiledStaticCall_at(address native_call); 294 friend CompiledStaticCall* compiledStaticCall_at(Relocation* call_site); 295 296 // Code 297 static void emit_to_interp_stub(CodeBuffer &cbuf); 298 static int to_interp_stub_size(); 299 static int reloc_to_interp_stub(); 300 301 // State 302 bool is_clean() const; 303 bool is_call_to_compiled() const; 304 bool is_call_to_interpreted() const; 305 306 // Clean static call (will force resolving on next use) 307 void set_to_clean(); 308 309 // Set state. The entry must be the same, as computed by compute_entry. 310 // Computation and setting is split up, since the actions are separate during 311 // a OptoRuntime::resolve_xxx. 312 void set(const StaticCallInfo& info); 313 314 // Compute entry point given a method 315 static void compute_entry(methodHandle m, StaticCallInfo& info); 316 317 // Stub support 318 address find_stub(); 319 static void set_stub_to_clean(static_stub_Relocation* static_stub); 320 321 // Misc. 322 void print() PRODUCT_RETURN; 323 void verify() PRODUCT_RETURN; 324}; 325 326 327inline CompiledStaticCall* compiledStaticCall_before(address return_addr) { 328 CompiledStaticCall* st = (CompiledStaticCall*)nativeCall_before(return_addr); 329 st->verify(); 330 return st; 331} 332 333inline CompiledStaticCall* compiledStaticCall_at(address native_call) { 334 CompiledStaticCall* st = (CompiledStaticCall*)native_call; 335 st->verify(); 336 return st; 337} 338 339inline CompiledStaticCall* compiledStaticCall_at(Relocation* call_site) { 340 return compiledStaticCall_at(call_site->addr()); 341} 342 343#endif // SHARE_VM_CODE_COMPILEDIC_HPP 344