Home | History | Annotate | Download | only in src
      1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #ifndef V8_SCOPEINFO_H_
     29 #define V8_SCOPEINFO_H_
     30 
     31 #include "variables.h"
     32 
     33 namespace v8 {
     34 namespace internal {
     35 
     36 // Scope information represents information about a functions's
     37 // scopes (currently only one, because we don't do any inlining)
     38 // and the allocation of the scope's variables. Scope information
     39 // is stored in a compressed form with Code objects and is used
     40 // at runtime (stack dumps, deoptimization, etc.).
     41 //
     42 // Historical note: In other VMs built by this team, ScopeInfo was
     43 // usually called DebugInfo since the information was used (among
     44 // other things) for on-demand debugging (Self, Smalltalk). However,
     45 // DebugInfo seems misleading, since this information is primarily used
     46 // in debugging-unrelated contexts.
     47 
     48 // Forward defined as
     49 // template <class Allocator = FreeStoreAllocationPolicy> class ScopeInfo;
     50 template<class Allocator>
     51 class ScopeInfo BASE_EMBEDDED {
     52  public:
     53   // Create a ScopeInfo instance from a scope.
     54   explicit ScopeInfo(Scope* scope);
     55 
     56   // Create a ScopeInfo instance from a Code object.
     57   explicit ScopeInfo(Code* code);
     58 
     59   // Write the ScopeInfo data into a Code object, and returns the
     60   // amount of space that was needed. If no Code object is provided
     61   // (NULL handle), Serialize() only returns the amount of space needed.
     62   //
     63   // This operations requires that the Code object has the correct amount
     64   // of space for the ScopeInfo data; otherwise the operation fails (fatal
     65   // error). Any existing scope info in the Code object is simply overwritten.
     66   int Serialize(Code* code);
     67 
     68   // Garbage collection support for scope info embedded in Code objects.
     69   // This code is in ScopeInfo because only here we should have to know
     70   // about the encoding.
     71   static void IterateScopeInfo(Code* code, ObjectVisitor* v);
     72 
     73 
     74   // --------------------------------------------------------------------------
     75   // Lookup
     76 
     77   Handle<String> function_name() const  { return function_name_; }
     78 
     79   Handle<String> parameter_name(int i) const  { return parameters_[i]; }
     80   int number_of_parameters() const  { return parameters_.length(); }
     81 
     82   Handle<String> stack_slot_name(int i) const  { return stack_slots_[i]; }
     83   int number_of_stack_slots() const  { return stack_slots_.length(); }
     84 
     85   Handle<String> context_slot_name(int i) const {
     86     return context_slots_[i - Context::MIN_CONTEXT_SLOTS];
     87   }
     88   int number_of_context_slots() const {
     89     int l = context_slots_.length();
     90     return l == 0 ? 0 : l + Context::MIN_CONTEXT_SLOTS;
     91   }
     92 
     93   Handle<String> LocalName(int i) const;
     94   int NumberOfLocals() const;
     95 
     96   // --------------------------------------------------------------------------
     97   // The following functions provide quick access to scope info details
     98   // for runtime routines w/o the need to explicitly create a ScopeInfo
     99   // object.
    100   //
    101   // ScopeInfo is the only class which should have to know about the
    102   // encoding of it's information in a Code object, which is why these
    103   // functions are in this class.
    104 
    105   // Does this scope call eval.
    106   static bool CallsEval(Code* code);
    107 
    108   // Return the number of stack slots for code.
    109   static int NumberOfStackSlots(Code* code);
    110 
    111   // Return the number of context slots for code.
    112   static int NumberOfContextSlots(Code* code);
    113 
    114   // Lookup support for scope info embedded in Code objects. Returns
    115   // the stack slot index for a given slot name if the slot is
    116   // present; otherwise returns a value < 0. The name must be a symbol
    117   // (canonicalized).
    118   static int StackSlotIndex(Code* code, String* name);
    119 
    120   // Lookup support for scope info embedded in Code objects. Returns the
    121   // context slot index for a given slot name if the slot is present; otherwise
    122   // returns a value < 0. The name must be a symbol (canonicalized).
    123   // If the slot is present and mode != NULL, sets *mode to the corresponding
    124   // mode for that variable.
    125   static int ContextSlotIndex(Code* code, String* name, Variable::Mode* mode);
    126 
    127   // Lookup support for scope info embedded in Code objects. Returns the
    128   // parameter index for a given parameter name if the parameter is present;
    129   // otherwise returns a value < 0. The name must be a symbol (canonicalized).
    130   static int ParameterIndex(Code* code, String* name);
    131 
    132   // Lookup support for scope info embedded in Code objects. Returns the
    133   // function context slot index if the function name is present (named
    134   // function expressions, only), otherwise returns a value < 0. The name
    135   // must be a symbol (canonicalized).
    136   static int FunctionContextSlotIndex(Code* code, String* name);
    137 
    138   // --------------------------------------------------------------------------
    139   // Debugging support
    140 
    141 #ifdef DEBUG
    142   void Print();
    143 #endif
    144 
    145  private:
    146   Handle<String> function_name_;
    147   bool calls_eval_;
    148   List<Handle<String>, Allocator > parameters_;
    149   List<Handle<String>, Allocator > stack_slots_;
    150   List<Handle<String>, Allocator > context_slots_;
    151   List<Variable::Mode, Allocator > context_modes_;
    152 };
    153 
    154 class ZoneScopeInfo: public ScopeInfo<ZoneListAllocationPolicy> {
    155  public:
    156   // Create a ZoneScopeInfo instance from a scope.
    157   explicit ZoneScopeInfo(Scope* scope)
    158       : ScopeInfo<ZoneListAllocationPolicy>(scope) {}
    159 
    160   // Create a ZoneScopeInfo instance from a Code object.
    161   explicit ZoneScopeInfo(Code* code)
    162       :  ScopeInfo<ZoneListAllocationPolicy>(code) {}
    163 };
    164 
    165 
    166 // Cache for mapping (code, property name) into context slot index.
    167 // The cache contains both positive and negative results.
    168 // Slot index equals -1 means the property is absent.
    169 // Cleared at startup and prior to mark sweep collection.
    170 class ContextSlotCache {
    171  public:
    172   // Lookup context slot index for (code, name).
    173   // If absent, kNotFound is returned.
    174   static int Lookup(Code* code,
    175                     String* name,
    176                     Variable::Mode* mode);
    177 
    178   // Update an element in the cache.
    179   static void Update(Code* code,
    180                      String* name,
    181                      Variable::Mode mode,
    182                      int slot_index);
    183 
    184   // Clear the cache.
    185   static void Clear();
    186 
    187   static const int kNotFound = -2;
    188  private:
    189   inline static int Hash(Code* code, String* name);
    190 
    191 #ifdef DEBUG
    192   static void ValidateEntry(Code* code,
    193                             String* name,
    194                             Variable::Mode mode,
    195                             int slot_index);
    196 #endif
    197 
    198   static const int kLength = 256;
    199   struct Key {
    200     Code* code;
    201     String* name;
    202   };
    203 
    204   struct Value {
    205     Value(Variable::Mode mode, int index) {
    206       ASSERT(ModeField::is_valid(mode));
    207       ASSERT(IndexField::is_valid(index));
    208       value_ = ModeField::encode(mode) | IndexField::encode(index);
    209       ASSERT(mode == this->mode());
    210       ASSERT(index == this->index());
    211     }
    212 
    213     inline Value(uint32_t value) : value_(value) {}
    214 
    215     uint32_t raw() { return value_; }
    216 
    217     Variable::Mode mode() { return ModeField::decode(value_); }
    218 
    219     int index() { return IndexField::decode(value_); }
    220 
    221     // Bit fields in value_ (type, shift, size). Must be public so the
    222     // constants can be embedded in generated code.
    223     class ModeField:  public BitField<Variable::Mode, 0, 3> {};
    224     class IndexField: public BitField<int,            3, 32-3> {};
    225    private:
    226     uint32_t value_;
    227   };
    228 
    229   static Key keys_[kLength];
    230   static uint32_t values_[kLength];
    231 };
    232 
    233 
    234 } }  // namespace v8::internal
    235 
    236 #endif  // V8_SCOPEINFO_H_
    237