jumpTable.hpp

Go to the documentation of this file.
00001 /* Copyright 1994, LongView Technologies L.L.C. $Revision: 1.17 $ */
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 // The jumpTable constitutes the interface between interpreter code and optimized code.
00025 // This indirection makes it possible to invalidate optimized code without 
00026 //  - keeping track of dependencies between sends in methodsOops and optimized code, or 
00027 //  - traverse all methodOops. 
00028 // If optimized code has become invalid the jump table entry is simply snapped.
00029 // In addition the jumpTable serves as a dispatch table for block closures for optimized code.
00030 
00031 // %implementation note:
00032 //   make jumpTable growable
00033 
00034 #ifdef DELTA_COMPILER
00035 
00036 class jumpTableEntry;
00037 class jumpTable;
00038 
00039 class jumpTableID : ValueObj {
00040   u_short _major;
00041   u_short _minor;
00042   friend class jumpTable;
00043 
00044   enum { max_value = nthMask(16) };
00045 
00046  public:
00047   jumpTableID()                             : _major(max_value), _minor(max_value) {}
00048   jumpTableID(u_short major)                : _major(major),     _minor(max_value) {}
00049   jumpTableID(u_short major, u_short minor) : _major(major),     _minor(minor)     {}
00050   bool has_minor() const                { return _minor != max_value; }
00051   bool is_block() const                 { return _minor > 0;          }
00052   bool is_valid() const                 { return _major != max_value; }
00053   u_short major() const                 { return _major; }
00054   u_short minor() const                 { return _minor; }
00055   jumpTableID sub(u_short minor) const  { return jumpTableID(_major, minor); }
00056 };
00057 
00058 
00059 class jumpTable : public ValueObj {
00060  protected:
00061   int firstFree;        // index of first free elem
00062   static char*           allocate_jump_entries(int size);
00063   static jumpTableEntry* jump_entry_for_at(char* entries, int index);
00064   jumpTableEntry*        major_at(u_short index);
00065  public:
00066   char* entries;
00067   int length;           // max. number of IDs
00068   int usedIDs;          // # of used ID
00069 
00070  public:
00071   jumpTable();
00072   ~jumpTable();
00073 
00074   void  init();
00075 
00076   // Allocates a block of adjacent jump table entries.
00077   jumpTableID allocate(int number_of_entries);
00078 
00079   // returns the jumptable entry for id
00080   jumpTableEntry* at(jumpTableID id);
00081 
00082   int newID();             // return a new ID
00083   int peekID();            // return value which would be returned by newID,
00084                            // but don't actually allocate the ID
00085   void freeID(int index); // index is unused again
00086 
00087   void verify();
00088   void print();
00089 
00090   // compilation of blocks
00091   static char*    compile_new_block(blockClosureOop blk);     // create nmethod, return entry point
00092   static nmethod* compile_block(blockClosureOop blk);         // (re)compile block nmethod
00093 
00094   friend class jumpTableEntry;
00095 };
00096 
00097 
00098 // implementation note: jumpTableEntry should be an abstract class with two
00099 // subclasses for nmethod and block entries, but these classes are combined
00100 // in order to save space (no vtbl pointer needed)
00101 class jumpTableEntry : public ValueObj {
00102  private:
00103   char* jump_inst_addr() const          { assert(oop(this)->is_smi(), "misaligned"); return (char*) this; }
00104   char* state_addr() const              { return ((char*) this) + sizeof(char) + sizeof(int); }
00105   char  state() const                   { return *state_addr(); }
00106   void fill_entry(char instr, char* dest, char state);
00107   void initialize_as_unused(int index);
00108   void initialize_as_link(char* link);
00109   void initialize_nmethod_stub(char* dest);
00110   void initialize_block_closure_stub();
00111   inline jumpTableEntry* previous_stub() const;
00112   inline jumpTableEntry* next_stub() const;
00113   jumpTableEntry* parent_entry(int& index) const;
00114   void report_verify_error(char* message);
00115  public:
00116    // testing operations            LARS: please add comments explaining what the 4 cases are  -Urs 4/96
00117   bool is_nmethod_stub() const;
00118   bool is_block_closure_stub() const;
00119   bool is_link() const;
00120   bool is_unused() const;
00121 
00122   // entry point
00123   char* entry_point() const             { return jump_inst_addr(); }
00124 
00125   // destination
00126   char** destination_addr() const;      // the address of the destination
00127   char*  destination() const;           // current destination
00128   void   set_destination(char* dest);   // sets the destination
00129 
00130   // operations for link stubs
00131   char* link() const;
00132 
00133   // operations for unused
00134   int next_free() const;
00135 
00136   // operations for nmethod stubs (is_nmethod_stub() == true)
00137   nmethod* method() const;        // NULL if not pointing to a method
00138 
00139   // operations for block stubs (is_block_closure_stub() == true)
00140   bool      block_has_nmethod() const;
00141   nmethod*  block_nmethod() const;      // block nmethod (or NULL if not compiled yet)
00142   methodOop block_method() const;       // block method
00143   // nmethod creating the blockClosureOops pointing to this entry
00144   // index is set to the distance |parent_entry - this|
00145   nmethod*  parent_nmethod(int& index) const; 
00146 
00147   // printing
00148   void print();
00149   void verify();
00150 
00151   // size of jump table entry
00152   static int size()                     { return 8; }
00153 
00154   friend class jumpTable;
00155 };
00156 
00157 #endif

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