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 #include "zone-inl.h"
     33 
     34 namespace v8 {
     35 namespace internal {
     36 
     37 // Scope information represents information about a functions's
     38 // scopes (currently only one, because we don't do any inlining)
     39 // and the allocation of the scope's variables. Scope information
     40 // is stored in a compressed form in FixedArray objects and is used
     41 // at runtime (stack dumps, deoptimization, etc.).
     42 //
     43 // Historical note: In other VMs built by this team, ScopeInfo was
     44 // usually called DebugInfo since the information was used (among
     45 // other things) for on-demand debugging (Self, Smalltalk). However,
     46 // DebugInfo seems misleading, since this information is primarily used
     47 // in debugging-unrelated contexts.
     48 
     49 // Forward defined as
     50 // template <class Allocator = FreeStoreAllocationPolicy> class ScopeInfo;
     51 template<class Allocator>
     52 class ScopeInfo BASE_EMBEDDED {
     53  public:
     54   // Create a ScopeInfo instance from a scope.
     55   explicit ScopeInfo(Scope* scope);
     56 
     57   // Create a ScopeInfo instance from SerializedScopeInfo.
     58   explicit ScopeInfo(SerializedScopeInfo* data);
     59 
     60   // Creates a SerializedScopeInfo holding the serialized scope info.
     61   Handle<SerializedScopeInfo> Serialize();
     62 
     63   // --------------------------------------------------------------------------
     64   // Lookup
     65 
     66   Handle<String> function_name() const { return function_name_; }
     67 
     68   Handle<String> parameter_name(int i) const { return parameters_[i]; }
     69   int number_of_parameters() const { return parameters_.length(); }
     70 
     71   Handle<String> stack_slot_name(int i) const { return stack_slots_[i]; }
     72   int number_of_stack_slots() const { return stack_slots_.length(); }
     73 
     74   Handle<String> context_slot_name(int i) const {
     75     return context_slots_[i - Context::MIN_CONTEXT_SLOTS];
     76   }
     77   int number_of_context_slots() const {
     78     int l = context_slots_.length();
     79     return l == 0 ? 0 : l + Context::MIN_CONTEXT_SLOTS;
     80   }
     81 
     82   Handle<String> LocalName(int i) const;
     83   int NumberOfLocals() const;
     84 
     85   // --------------------------------------------------------------------------
     86   // Debugging support
     87 
     88 #ifdef DEBUG
     89   void Print();
     90 #endif
     91 
     92  private:
     93   Handle<String> function_name_;
     94   bool calls_eval_;
     95   List<Handle<String>, Allocator > parameters_;
     96   List<Handle<String>, Allocator > stack_slots_;
     97   List<Handle<String>, Allocator > context_slots_;
     98   List<Variable::Mode, Allocator > context_modes_;
     99 };
    100 
    101 
    102 // This object provides quick access to scope info details for runtime
    103 // routines w/o the need to explicitly create a ScopeInfo object.
    104 class SerializedScopeInfo : public FixedArray {
    105  public :
    106 
    107   static SerializedScopeInfo* cast(Object* object) {
    108     ASSERT(object->IsFixedArray());
    109     return reinterpret_cast<SerializedScopeInfo*>(object);
    110   }
    111 
    112   // Does this scope call eval?
    113   bool CallsEval();
    114 
    115   // Does this scope have an arguments shadow?
    116   bool HasArgumentsShadow() {
    117     return StackSlotIndex(GetHeap()->arguments_shadow_symbol()) >= 0;
    118   }
    119 
    120   // Return the number of stack slots for code.
    121   int NumberOfStackSlots();
    122 
    123   // Return the number of context slots for code.
    124   int NumberOfContextSlots();
    125 
    126   // Return if this has context slots besides MIN_CONTEXT_SLOTS;
    127   bool HasHeapAllocatedLocals();
    128 
    129   // Lookup support for serialized scope info. Returns the
    130   // the stack slot index for a given slot name if the slot is
    131   // present; otherwise returns a value < 0. The name must be a symbol
    132   // (canonicalized).
    133   int StackSlotIndex(String* name);
    134 
    135   // Lookup support for serialized scope info. Returns the
    136   // context slot index for a given slot name if the slot is present; otherwise
    137   // returns a value < 0. The name must be a symbol (canonicalized).
    138   // If the slot is present and mode != NULL, sets *mode to the corresponding
    139   // mode for that variable.
    140   int ContextSlotIndex(String* name, Variable::Mode* mode);
    141 
    142   // Lookup support for serialized scope info. Returns the
    143   // parameter index for a given parameter name if the parameter is present;
    144   // otherwise returns a value < 0. The name must be a symbol (canonicalized).
    145   int ParameterIndex(String* name);
    146 
    147   // Lookup support for serialized scope info. Returns the
    148   // function context slot index if the function name is present (named
    149   // function expressions, only), otherwise returns a value < 0. The name
    150   // must be a symbol (canonicalized).
    151   int FunctionContextSlotIndex(String* name);
    152 
    153   static Handle<SerializedScopeInfo> Create(Scope* scope);
    154 
    155   // Serializes empty scope info.
    156   static SerializedScopeInfo* Empty();
    157 
    158  private:
    159 
    160   inline Object** ContextEntriesAddr();
    161 
    162   inline Object** ParameterEntriesAddr();
    163 
    164   inline Object** StackSlotEntriesAddr();
    165 };
    166 
    167 
    168 // Cache for mapping (data, property name) into context slot index.
    169 // The cache contains both positive and negative results.
    170 // Slot index equals -1 means the property is absent.
    171 // Cleared at startup and prior to mark sweep collection.
    172 class ContextSlotCache {
    173  public:
    174   // Lookup context slot index for (data, name).
    175   // If absent, kNotFound is returned.
    176   int Lookup(Object* data,
    177              String* name,
    178              Variable::Mode* mode);
    179 
    180   // Update an element in the cache.
    181   void Update(Object* data,
    182               String* name,
    183               Variable::Mode mode,
    184               int slot_index);
    185 
    186   // Clear the cache.
    187   void Clear();
    188 
    189   static const int kNotFound = -2;
    190  private:
    191   ContextSlotCache() {
    192     for (int i = 0; i < kLength; ++i) {
    193       keys_[i].data = NULL;
    194       keys_[i].name = NULL;
    195       values_[i] = kNotFound;
    196     }
    197   }
    198 
    199   inline static int Hash(Object* data, String* name);
    200 
    201 #ifdef DEBUG
    202   void ValidateEntry(Object* data,
    203                      String* name,
    204                      Variable::Mode mode,
    205                      int slot_index);
    206 #endif
    207 
    208   static const int kLength = 256;
    209   struct Key {
    210     Object* data;
    211     String* name;
    212   };
    213 
    214   struct Value {
    215     Value(Variable::Mode mode, int index) {
    216       ASSERT(ModeField::is_valid(mode));
    217       ASSERT(IndexField::is_valid(index));
    218       value_ = ModeField::encode(mode) | IndexField::encode(index);
    219       ASSERT(mode == this->mode());
    220       ASSERT(index == this->index());
    221     }
    222 
    223     explicit inline Value(uint32_t value) : value_(value) {}
    224 
    225     uint32_t raw() { return value_; }
    226 
    227     Variable::Mode mode() { return ModeField::decode(value_); }
    228 
    229     int index() { return IndexField::decode(value_); }
    230 
    231     // Bit fields in value_ (type, shift, size). Must be public so the
    232     // constants can be embedded in generated code.
    233     class ModeField:  public BitField<Variable::Mode, 0, 3> {};
    234     class IndexField: public BitField<int,            3, 32-3> {};
    235    private:
    236     uint32_t value_;
    237   };
    238 
    239   Key keys_[kLength];
    240   uint32_t values_[kLength];
    241 
    242   friend class Isolate;
    243   DISALLOW_COPY_AND_ASSIGN(ContextSlotCache);
    244 };
    245 
    246 
    247 } }  // namespace v8::internal
    248 
    249 #endif  // V8_SCOPEINFO_H_
    250