compiledPIC.hpp

Go to the documentation of this file.
00001 /* Copyright 1994 - 1996 LongView Technologies L.L.C. $Revision: 1.24 $ */
00002 /* Copyright (c) 2006, Sun Microsystems, Inc.
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 
00006 following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 
00010           disclaimer in the documentation and/or other materials provided with the distribution.
00011     * Neither the name of Sun Microsystems nor the names of its contributors may be used to endorse or promote products derived 
00012           from this software without specific prior written permission.
00013 
00014 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 
00015 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
00016 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
00017 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00018 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
00019 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00020 
00021 
00022 */
00023 
00024 #ifdef DELTA_COMPILER
00025 
00026 // A PIC implements a Polymorphic Inline Cache for compiled code.
00027 // It may be megamorphic, in which case it may cache only the last
00028 // method and do a lookup whenever there is a cache miss.
00029 
00030 class PIC_Iterator;
00031 class PIC_contents;
00032 
00033 class PIC {
00034  public:
00035   enum Consts {
00036     max_nof_entries             =  4,                   // the maximal number of PIC entries
00037 
00038     // PIC layout constants
00039     PIC_methodOop_only_offset   =  5,
00040     PIC_smi_nmethod_offset      =  4,
00041 
00042     PIC_nmethod_entry_offset    = 11,
00043     PIC_nmethod_entry_size      = 12,
00044     PIC_nmethod_klass_offset    =  2,
00045     PIC_nmethod_offset          =  8,
00046 
00047     PIC_methodOop_entry_offset  = 16,
00048     PIC_methodOop_entry_size    =  8,
00049     PIC_methodOop_klass_offset  =  0,
00050     PIC_methodOop_offset        =  4,
00051 
00052     // MIC layout constants
00053     MIC_selector_offset         =  5,
00054     MIC_code_size               =  9,
00055   };
00056 
00057  private:
00058   CompiledIC*   _ic;                            // the ic linked to this PIC
00059   short         _code_size;                     // size of code in bytes
00060   short         _number_of_targets;             // the total number of PIC entries, 0 indicates a MIC
00061 
00062   static int    nof_entries(char* pic_stub);    // the no. of methodOop entries for a given stub routine
00063 
00064   int           code_for_methodOops_only (char* entry, PIC_contents* c);
00065   int           code_for_polymorphic_case(char* entry, PIC_contents* c);
00066   int           code_for_megamorphic_case(char* entry);
00067 
00068   void          shrink_and_generate(PIC* pic, klassOop klass, void* method);
00069 
00070   bool          contains(char* addr)            { return entry() <= addr && addr < entry() + code_size(); }
00071 
00072   // Creation/access of PICs
00073   PIC(CompiledIC* ic, PIC_contents* contents, int allocated_code_size); // creation of PICs
00074   PIC(CompiledIC* ic);                                                  // creation of MICs
00075 
00076  public:
00077   void* operator new(size_t size, int code_size);
00078 
00079   // Deallocates this pic from the pic heap
00080   void operator delete (void* p);
00081 
00082   // Allocates and returns a new ready to execute pic.
00083   static PIC*   allocate(CompiledIC* ic, klassOop klass, LookupResult result);
00084 
00085   // Tells whether addr inside the PIC area
00086   static bool   in_heap(char* addr);
00087 
00088   // Returns the PIC containing addr, NULL otherwise
00089   static PIC*   find(char* addr);
00090 
00091   // Returns the code size of the PIC
00092   int           code_size() const               { return _code_size; }            
00093 
00094 
00095   // Retrieving PIC information
00096   CompiledIC*   compiled_ic() const             { return _ic;                           }
00097   int           number_of_targets() const       { return _number_of_targets;            }
00098   symbolOop     selector() const                { return compiled_ic()->selector();     }
00099   char*         entry() const                   { return (char*) (this+1);              }
00100   bool          is_monomorphic() const          { return number_of_targets() == 1;      }
00101   bool          is_polymorphic() const          { return number_of_targets() > 1;       }
00102   bool          is_megamorphic() const          { return number_of_targets() == 0;      }
00103 
00104   // For MICs (megamorphic PICs) only
00105   symbolOop*    MIC_selector_address() const;   // the address of the selector in the MIC cache
00106 
00107   // replace appropriate target (with key nm->key) by nm.
00108   // this is returned if we could patch the current PIC.
00109   // a new PIC is returned if we could not patch this PIC.
00110   PIC* replace(nmethod* nm);
00111 
00112   // Cleans up the pic and returns:
00113   //  1) A PIC                  (still polymorphic or megamorphic)
00114   //  2) A nmethod              (now   monomorphic)
00115   //  3) nothing                (now   anamorphic)
00116   PIC* cleanup(nmethod** nm);
00117 
00118   GrowableArray<klassOop>*      klasses() const;
00119 
00120   // Iterate over all oops in the pic
00121   void oops_do(void f(oop*));
00122 
00123   // printing operation
00124   void print();
00125 
00126   // verify operation
00127   void verify();
00128 
00129   friend class PIC_Iterator;
00130 };
00131 
00132 
00133 // A PIC_Iterator is used get information out of a PIC. It is used to
00134 // display PICs visually, to generate new PICs out of old ones and for
00135 // GC purposes. In case of a megamorphic IC (MIC), the PIC_Iterator will
00136 // be at_end after setup (no entries).
00137 
00138 class PIC_Iterator: public PrintableResourceObj {
00139  public:
00140   enum State {  at_smi_nmethod,
00141                 at_nmethod,
00142                 at_methodOop,
00143                 at_the_end
00144   };
00145 
00146  private:
00147   PIC*          _pic;                           // the PIC over which is iterated
00148   char*         _pos;                           // the current iterator position
00149   enum State    _state;                         // current iterator state
00150   int           _methodOop_counter;             // remaining no. of methodOop entries
00151 
00152   int*          nmethod_disp_addr() const;      // valid if state() in {at_smi_nmethod, at_nmethod}
00153   void          computeNextState();
00154 
00155  public:
00156   PIC_Iterator(PIC* pic);
00157 
00158   // Iterating through PIC entries
00159   void          advance();
00160   State         state() const                   { return _state; }
00161   bool          at_end() const                  { return state() == at_the_end; }
00162 
00163   // Accessing PIC entries
00164   klassOop      get_klass() const;
00165   char*         get_call_addr() const;
00166   bool          is_interpreted() const;
00167   bool          is_compiled() const;
00168 
00169   methodOop     interpreted_method() const;
00170   nmethod*      compiled_method() const;
00171 
00172   // Modifying PIC entries
00173   void          set_klass(klassOop klass);
00174   void          set_nmethod(nmethod* nm);
00175   void          set_methodOop(methodOop method);
00176 
00177   // Must be public for oops_do in CompiledPIC
00178   methodOop*    methodOop_addr() const;         // valid if state() is at_PIC_methodOop
00179   klassOop*     klass_addr() const;             // valid if state() in {at_nmethod, at_methodOop}
00180 
00181   // Debugging
00182   void          print();
00183 };
00184 
00185 
00186 class CompiledIC_Iterator: public IC_Iterator {
00187  private:
00188   CompiledIC*   _ic;
00189   PIC_Iterator* _picit;
00190 
00191   int           _number_of_targets;             // the no. of IC entries
00192   IC_Shape      _shape;                         // shape of inline cache
00193   int           _index;                         // the next entry no.
00194   
00195  public:
00196   CompiledIC_Iterator(CompiledIC* ic);
00197 
00198   // IC information
00199   bool          is_compiled_ic() const          { return true; }
00200   bool          is_super_send() const;
00201   int           number_of_targets() const       { return _number_of_targets; }
00202   IC_Shape      shape() const                   { return _shape; }
00203   symbolOop     selector() const                { return _ic->selector(); }
00204   CompiledIC*   compiled_ic() const             { return _ic; }
00205 
00206   // Iterating through entries
00207   void          init_iteration();
00208   void          advance();                      // advance iterator to next target
00209   bool          at_end() const                  { return _index >= number_of_targets(); }
00210 
00211   // Accessing entries
00212   klassOop      klass() const;                  // receiver klass of current target
00213 
00214   bool          is_interpreted() const;         // is current target interpreted?
00215   bool          is_compiled() const;
00216 
00217   methodOop     interpreted_method() const;     // current target method (whether compiled or not)
00218   nmethod*      compiled_method() const;        // current compiled target or NULL if interpreted
00219 
00220   // Debugging
00221   void          print();
00222 };
00223 
00224 
00225 #endif

Generated on Mon Oct 9 13:37:07 2006 for Strongtalk VM by  doxygen 1.4.7