interpretedIC.hpp

Go to the documentation of this file.
00001 /* Copyright 1994 - 1996, LongView Technologies, L.L.C. $Revision: 1.12 $ */
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 
00025 // The InterpretedIC describes the contents of an inline cache in the
00026 // byte codes of a method. The inline cache holds a combination of
00027 // selector/method and 0/class oops and is read and modified during
00028 // execution.
00029 //
00030 //
00031 // An InterpretedIC can have four different states:
00032 //
00033 // 1) empty                                     {selector,         0} 
00034 // 2) filled with a call to interpreted code    {method,           klass}
00035 // 3) filled with an interpreter PIC            {selector,         objArrayObj}
00036 // 4) filled with a call to compiled code       {jump table entry, klass}
00037 //
00038 //
00039 // Layout:
00040 //
00041 //    send byte code                    <-----  send_code_addr()
00042 //    ...
00043 //    halt byte codes for alignment
00044 //    ...
00045 // 0: selector/method/jump table entry  <-----  first_word_addr()
00046 // 4: 0/klass/objArray                  <-----  second_word_addr()
00047 // 8: ...
00048 
00049 class InterpretedIC: ValueObj {
00050  public:
00051   enum {
00052     size               = 8,                     // inline cache size in words
00053     first_word_offset  = 0,                     // layout info: first word
00054     second_word_offset = 4,                     // layout info: second word
00055   } InterpretedICConstants;
00056 
00057   // Conversion (Bytecode* -> InterpretedIC*)
00058   friend InterpretedIC* as_InterpretedIC(char* address_of_next_instr);
00059 
00060   // find send bytecode, given address of selector; return NULL/IllegalBCI if not in a send
00061   static u_char* findStartOfSend(u_char* selector_addr);
00062   static int findStartOfSend(methodOop m, int bci);
00063 
00064  private:
00065   // field access
00066   char*   addr_at(int offset) const             { return (char*)this + offset; }
00067   oop*    first_word_addr() const               { return (oop*)addr_at(first_word_offset); }
00068   oop*    second_word_addr() const              { return (oop*)addr_at(second_word_offset); }
00069   void    set(Bytecodes::Code send_code, oop first_word, oop second_word);
00070 
00071  public:
00072   // Raw inline cache access
00073   u_char* send_code_addr() const                { return findStartOfSend((u_char*)this); }
00074   Bytecodes::Code send_code() const             { return Bytecodes::Code(*send_code_addr()); }
00075   oop             first_word() const            { return *first_word_addr(); }
00076   oop             second_word() const           { return *second_word_addr(); }
00077   
00078   // Returns the polymorphic inline cache array. Assert fails if no pic is present.
00079   objArrayOop pic_array();
00080 
00081   // Inline cache information
00082   bool            is_empty() const              { return second_word() == NULL; }
00083   symbolOop       selector() const;             // the selector
00084   jumpTableEntry* jump_table_entry() const;     // only legal to call if compiled send
00085 
00086   int             nof_arguments() const;        // the number of arguments
00087   Bytecodes::SendType     send_type() const;    // the send type
00088   Bytecodes::ArgumentSpec argument_spec() const;// the argument spec
00089 
00090   // Manipulation
00091   void clear();                                 // clears the inline cache
00092   void cleanup();                               // cleanup the inline cache
00093   void clear_without_deallocation_pic();        // clears the inline cache without deallocating the pic
00094   void replace(nmethod* nm);                    // replaces the appropriate target with a nm
00095   void replace(LookupResult result, klassOop receiver_klass); // replaces the inline cache with a lookup result
00096 
00097   // Debugging
00098   void print();
00099 
00100   // Cache miss
00101   static void inline_cache_miss();              // the inline cache miss handler
00102 
00103  private:
00104   // helpers for inline_cache_miss
00105   static void update_inline_cache(InterpretedIC* ic, frame* f, Bytecodes::Code send_code, klassOop klass, LookupResult result);
00106   static void does_not_understand(oop receiver, InterpretedIC* ic, frame* f);
00107   static void trace_inline_cache_miss(InterpretedIC* ic, klassOop klass, LookupResult result);
00108 };
00109 
00110 
00111 // Interpreter_PICs handles the allocation and deallocation of interpreter PICs.
00112 
00113 static const int size_of_smallest_interpreterPIC = 2;
00114 static const int size_of_largest_interpreterPIC  = 5;
00115 static const int number_of_interpreterPIC_sizes  = size_of_largest_interpreterPIC - size_of_smallest_interpreterPIC + 1;
00116 
00117 
00118 // An InterpretedIC_Iterator is used to iterate through the entries of
00119 // an inline cache in a methodOop. Whenever possible, one should use this
00120 // abstraction instead of the (raw) InterpretedIC.
00121 
00122 class InterpretedIC_Iterator: public IC_Iterator {
00123  private:
00124   InterpretedIC* _ic;                           // the inline cache
00125   objArrayOop   _pic;                           // the PIC if there is one
00126 
00127   // state machine
00128   int           _number_of_targets;             // the no. of IC entries
00129   IC_Shape      _info;                          // send site information
00130   int           _index;                         // the current entry no.
00131   klassOop      _klass;                         // the current klass
00132   methodOop     _method;                        // the current method
00133   nmethod*      _nm;                            // current nmethod (NULL if none)
00134 
00135   void set_method(oop m);                       // set _method and _nmethod
00136   void set_klass(oop k);                        // don't assign to _klass directly
00137 
00138  public:
00139   InterpretedIC_Iterator(InterpretedIC* ic);
00140 
00141   // IC information
00142   int           number_of_targets() const       { return _number_of_targets; }
00143   IC_Shape      shape() const                   { return _info; }
00144   symbolOop     selector() const                { return _ic->selector(); }
00145   bool          is_interpreted_ic() const       { return true; }
00146   bool          is_super_send() const;
00147   InterpretedIC* interpreted_ic() const         { return _ic; }
00148 
00149 
00150   // Iterating through entries
00151   void          init_iteration();
00152   void          advance();
00153   bool          at_end() const                  { return _index >= number_of_targets(); }
00154 
00155   // Accessing entries
00156   klassOop      klass() const                   { return _klass; }
00157 
00158   // answer whether current target method is compiled or interpreted
00159   bool          is_interpreted() const          { return _nm == NULL; }
00160   bool          is_compiled() const             { return _nm != NULL; }
00161 
00162   methodOop     interpreted_method() const;
00163   nmethod*      compiled_method() const;
00164 
00165   // Debugging
00166   void          print();
00167 };

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