src/share/vm/code/compiledIC.hpp

changeset 435
a61af66fc99e
child 1907
c18cbe5936b8
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/code/compiledIC.hpp	Sat Dec 01 00:00:00 2007 +0000
     1.3 @@ -0,0 +1,241 @@
     1.4 +/*
     1.5 + * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.
    1.11 + *
    1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.15 + * version 2 for more details (a copy is included in the LICENSE file that
    1.16 + * accompanied this code).
    1.17 + *
    1.18 + * You should have received a copy of the GNU General Public License version
    1.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 + *
    1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
    1.24 + * have any questions.
    1.25 + *
    1.26 + */
    1.27 +
    1.28 +//-----------------------------------------------------------------------------
    1.29 +// The CompiledIC represents a compiled inline cache.
    1.30 +//
    1.31 +// In order to make patching of the inline cache MT-safe, we only allow the following
    1.32 +// transitions (when not at a safepoint):
    1.33 +//
    1.34 +//
    1.35 +//         [1] --<--  Clean -->---  [1]
    1.36 +//            /       (null)      \
    1.37 +//           /                     \      /-<-\
    1.38 +//          /          [2]          \    /     \
    1.39 +//      Interpreted  ---------> Monomorphic     | [3]
    1.40 +//  (compiledICHolderOop)        (klassOop)     |
    1.41 +//          \                        /   \     /
    1.42 +//       [4] \                      / [4] \->-/
    1.43 +//            \->-  Megamorphic -<-/
    1.44 +//                  (methodOop)
    1.45 +//
    1.46 +// The text in paranteses () refere to the value of the inline cache receiver (mov instruction)
    1.47 +//
    1.48 +// The numbers in square brackets refere to the kind of transition:
    1.49 +// [1]: Initial fixup. Receiver it found from debug information
    1.50 +// [2]: Compilation of a method
    1.51 +// [3]: Recompilation of a method (note: only entry is changed. The klassOop must stay the same)
    1.52 +// [4]: Inline cache miss. We go directly to megamorphic call.
    1.53 +//
    1.54 +// The class automatically inserts transition stubs (using the InlineCacheBuffer) when an MT-unsafe
    1.55 +// transition is made to a stub.
    1.56 +//
    1.57 +class CompiledIC;
    1.58 +
    1.59 +class CompiledICInfo {
    1.60 +  friend class CompiledIC;
    1.61 + private:
    1.62 +  address _entry;              // entry point for call
    1.63 +  Handle  _cached_oop;         // Value of cached_oop (either in stub or inline cache)
    1.64 +  bool    _is_optimized;       // it is an optimized virtual call (i.e., can be statically bound)
    1.65 +  bool    _to_interpreter;     // Call it to interpreter
    1.66 + public:
    1.67 +  address entry() const        { return _entry; }
    1.68 +  Handle  cached_oop() const   { return _cached_oop; }
    1.69 +  bool    is_optimized() const { return _is_optimized; }
    1.70 +};
    1.71 +
    1.72 +class CompiledIC: public ResourceObj {
    1.73 +  friend class InlineCacheBuffer;
    1.74 +  friend class ICStub;
    1.75 +
    1.76 +
    1.77 + private:
    1.78 +  NativeCall*   _ic_call;       // the call instruction
    1.79 +  oop*          _oop_addr;      // patchable oop cell for this IC
    1.80 +  RelocIterator _oops;          // iteration over any and all set-oop instructions
    1.81 +  bool          _is_optimized;  // an optimized virtual call (i.e., no compiled IC)
    1.82 +
    1.83 +  CompiledIC(NativeCall* ic_call);
    1.84 +  CompiledIC(Relocation* ic_reloc);    // Must be of virtual_call_type/opt_virtual_call_type
    1.85 +
    1.86 +  // low-level inline-cache manipulation. Cannot be accessed directly, since it might not be MT-safe
    1.87 +  // to change an inline-cache. These changes the underlying inline-cache directly. They *newer* make
    1.88 +  // changes to a transition stub.
    1.89 +  void set_ic_destination(address entry_point);
    1.90 +  void set_cached_oop(oop cache);
    1.91 +
    1.92 +  // Reads the location of the transition stub. This will fail with an assertion, if no transition stub is
    1.93 +  // associated with the inline cache.
    1.94 +  address stub_address() const;
    1.95 +  bool is_in_transition_state() const;  // Use InlineCacheBuffer
    1.96 +
    1.97 + public:
    1.98 +  // conversion (machine PC to CompiledIC*)
    1.99 +  friend CompiledIC* CompiledIC_before(address return_addr);
   1.100 +  friend CompiledIC* CompiledIC_at(address call_site);
   1.101 +  friend CompiledIC* CompiledIC_at(Relocation* call_site);
   1.102 +
   1.103 +  // Return the cached_oop/destination associated with this inline cache. If the cache currently points
   1.104 +  // to a transition stub, it will read the values from the transition stub.
   1.105 +  oop  cached_oop() const;
   1.106 +  address ic_destination() const;
   1.107 +
   1.108 +  bool is_optimized() const   { return _is_optimized; }
   1.109 +
   1.110 +  // State
   1.111 +  bool is_clean() const;
   1.112 +  bool is_megamorphic() const;
   1.113 +  bool is_call_to_compiled() const;
   1.114 +  bool is_call_to_interpreted() const;
   1.115 +
   1.116 +  address end_of_call() { return  _ic_call->return_address(); }
   1.117 +
   1.118 +  // MT-safe patching of inline caches. Note: Only safe to call is_xxx when holding the CompiledIC_ock
   1.119 +  // so you are guaranteed that no patching takes place. The same goes for verify.
   1.120 +  //
   1.121 +  // Note: We do not provide any direct access to the stub code, to prevent parts of the code
   1.122 +  // to manipulate the inline cache in MT-unsafe ways.
   1.123 +  //
   1.124 +  // They all takes a TRAP argument, since they can cause a GC if the inline-cache buffer is full.
   1.125 +  //
   1.126 +  void set_to_clean();  // Can only be called during a safepoint operation
   1.127 +  void set_to_monomorphic(const CompiledICInfo& info);
   1.128 +  void set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS);
   1.129 +
   1.130 +  static void compute_monomorphic_entry(methodHandle method, KlassHandle receiver_klass,
   1.131 +                                        bool is_optimized, bool static_bound, CompiledICInfo& info, TRAPS);
   1.132 +
   1.133 +  // Location
   1.134 +  address instruction_address() const { return _ic_call->instruction_address(); }
   1.135 +
   1.136 +  // Misc
   1.137 +  void print()             PRODUCT_RETURN;
   1.138 +  void print_compiled_ic() PRODUCT_RETURN;
   1.139 +  void verify()            PRODUCT_RETURN;
   1.140 +};
   1.141 +
   1.142 +inline CompiledIC* CompiledIC_before(address return_addr) {
   1.143 +  CompiledIC* c_ic = new CompiledIC(nativeCall_before(return_addr));
   1.144 +  c_ic->verify();
   1.145 +  return c_ic;
   1.146 +}
   1.147 +
   1.148 +inline CompiledIC* CompiledIC_at(address call_site) {
   1.149 +  CompiledIC* c_ic = new CompiledIC(nativeCall_at(call_site));
   1.150 +  c_ic->verify();
   1.151 +  return c_ic;
   1.152 +}
   1.153 +
   1.154 +inline CompiledIC* CompiledIC_at(Relocation* call_site) {
   1.155 +  CompiledIC* c_ic = new CompiledIC(call_site);
   1.156 +  c_ic->verify();
   1.157 +  return c_ic;
   1.158 +}
   1.159 +
   1.160 +
   1.161 +//-----------------------------------------------------------------------------
   1.162 +// The CompiledStaticCall represents a call to a static method in the compiled
   1.163 +//
   1.164 +// Transition diagram of a static call site is somewhat simpler than for an inlined cache:
   1.165 +//
   1.166 +//
   1.167 +//           -----<----- Clean ----->-----
   1.168 +//          /                             \
   1.169 +//         /                               \
   1.170 +//    compilled code <------------> interpreted code
   1.171 +//
   1.172 +//  Clean:            Calls directly to runtime method for fixup
   1.173 +//  Compiled code:    Calls directly to compiled code
   1.174 +//  Interpreted code: Calls to stub that set methodOop reference
   1.175 +//
   1.176 +//
   1.177 +class CompiledStaticCall;
   1.178 +
   1.179 +class StaticCallInfo {
   1.180 + private:
   1.181 +  address      _entry;          // Entrypoint
   1.182 +  methodHandle _callee;         // Callee (used when calling interpreter)
   1.183 +  bool         _to_interpreter; // call to interpreted method (otherwise compiled)
   1.184 +
   1.185 +  friend class CompiledStaticCall;
   1.186 + public:
   1.187 +  address      entry() const    { return _entry;  }
   1.188 +  methodHandle callee() const   { return _callee; }
   1.189 +};
   1.190 +
   1.191 +
   1.192 +class CompiledStaticCall: public NativeCall {
   1.193 +  friend class CompiledIC;
   1.194 +
   1.195 +  // Also used by CompiledIC
   1.196 +  void set_to_interpreted(methodHandle callee, address entry);
   1.197 +  bool is_optimized_virtual();
   1.198 +
   1.199 + public:
   1.200 +  friend CompiledStaticCall* compiledStaticCall_before(address return_addr);
   1.201 +  friend CompiledStaticCall* compiledStaticCall_at(address native_call);
   1.202 +  friend CompiledStaticCall* compiledStaticCall_at(Relocation* call_site);
   1.203 +
   1.204 +  // State
   1.205 +  bool is_clean() const;
   1.206 +  bool is_call_to_compiled() const;
   1.207 +  bool is_call_to_interpreted() const;
   1.208 +
   1.209 +  // Clean static call (will force resolving on next use)
   1.210 +  void set_to_clean();
   1.211 +
   1.212 +  // Set state. The entry must be the same, as computed by compute_entry.
   1.213 +  // Computation and setting is split up, since the actions are separate during
   1.214 +  // a OptoRuntime::resolve_xxx.
   1.215 +  void set(const StaticCallInfo& info);
   1.216 +
   1.217 +  // Compute entry point given a method
   1.218 +  static void compute_entry(methodHandle m, StaticCallInfo& info);
   1.219 +
   1.220 +  // Stub support
   1.221 +  address find_stub();
   1.222 +  static void set_stub_to_clean(static_stub_Relocation* static_stub);
   1.223 +
   1.224 +  // Misc.
   1.225 +  void print()  PRODUCT_RETURN;
   1.226 +  void verify() PRODUCT_RETURN;
   1.227 +};
   1.228 +
   1.229 +
   1.230 +inline CompiledStaticCall* compiledStaticCall_before(address return_addr) {
   1.231 +  CompiledStaticCall* st = (CompiledStaticCall*)nativeCall_before(return_addr);
   1.232 +  st->verify();
   1.233 +  return st;
   1.234 +}
   1.235 +
   1.236 +inline CompiledStaticCall* compiledStaticCall_at(address native_call) {
   1.237 +  CompiledStaticCall* st = (CompiledStaticCall*)native_call;
   1.238 +  st->verify();
   1.239 +  return st;
   1.240 +}
   1.241 +
   1.242 +inline CompiledStaticCall* compiledStaticCall_at(Relocation* call_site) {
   1.243 +  return compiledStaticCall_at(call_site->addr());
   1.244 +}

mercurial