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