Home | History | Annotate | Download | only in src
      1 // Copyright 2011 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 "allocation.h"
     32 #include "variables.h"
     33 #include "zone-inl.h"
     34 
     35 namespace v8 {
     36 namespace internal {
     37 
     38 // Cache for mapping (data, property name) into context slot index.
     39 // The cache contains both positive and negative results.
     40 // Slot index equals -1 means the property is absent.
     41 // Cleared at startup and prior to mark sweep collection.
     42 class ContextSlotCache {
     43  public:
     44   // Lookup context slot index for (data, name).
     45   // If absent, kNotFound is returned.
     46   int Lookup(Object* data,
     47              String* name,
     48              VariableMode* mode,
     49              InitializationFlag* init_flag);
     50 
     51   // Update an element in the cache.
     52   void Update(Object* data,
     53               String* name,
     54               VariableMode mode,
     55               InitializationFlag init_flag,
     56               int slot_index);
     57 
     58   // Clear the cache.
     59   void Clear();
     60 
     61   static const int kNotFound = -2;
     62 
     63  private:
     64   ContextSlotCache() {
     65     for (int i = 0; i < kLength; ++i) {
     66       keys_[i].data = NULL;
     67       keys_[i].name = NULL;
     68       values_[i] = kNotFound;
     69     }
     70   }
     71 
     72   inline static int Hash(Object* data, String* name);
     73 
     74 #ifdef DEBUG
     75   void ValidateEntry(Object* data,
     76                      String* name,
     77                      VariableMode mode,
     78                      InitializationFlag init_flag,
     79                      int slot_index);
     80 #endif
     81 
     82   static const int kLength = 256;
     83   struct Key {
     84     Object* data;
     85     String* name;
     86   };
     87 
     88   struct Value {
     89     Value(VariableMode mode,
     90           InitializationFlag init_flag,
     91           int index) {
     92       ASSERT(ModeField::is_valid(mode));
     93       ASSERT(InitField::is_valid(init_flag));
     94       ASSERT(IndexField::is_valid(index));
     95       value_ = ModeField::encode(mode) |
     96           IndexField::encode(index) |
     97           InitField::encode(init_flag);
     98       ASSERT(mode == this->mode());
     99       ASSERT(init_flag == this->initialization_flag());
    100       ASSERT(index == this->index());
    101     }
    102 
    103     explicit inline Value(uint32_t value) : value_(value) {}
    104 
    105     uint32_t raw() { return value_; }
    106 
    107     VariableMode mode() { return ModeField::decode(value_); }
    108 
    109     InitializationFlag initialization_flag() {
    110       return InitField::decode(value_);
    111     }
    112 
    113     int index() { return IndexField::decode(value_); }
    114 
    115     // Bit fields in value_ (type, shift, size). Must be public so the
    116     // constants can be embedded in generated code.
    117     class ModeField:  public BitField<VariableMode,       0, 4> {};
    118     class InitField:  public BitField<InitializationFlag, 4, 1> {};
    119     class IndexField: public BitField<int,                5, 32-5> {};
    120 
    121    private:
    122     uint32_t value_;
    123   };
    124 
    125   Key keys_[kLength];
    126   uint32_t values_[kLength];
    127 
    128   friend class Isolate;
    129   DISALLOW_COPY_AND_ASSIGN(ContextSlotCache);
    130 };
    131 
    132 
    133 
    134 
    135 //---------------------------------------------------------------------------
    136 // Auxiliary class used for the description of module instances.
    137 // Used by Runtime_DeclareModules.
    138 
    139 class ModuleInfo: public FixedArray {
    140  public:
    141   static ModuleInfo* cast(Object* description) {
    142     return static_cast<ModuleInfo*>(FixedArray::cast(description));
    143   }
    144 
    145   static Handle<ModuleInfo> Create(
    146       Isolate* isolate, Interface* interface, Scope* scope);
    147 
    148   // Index of module's context in host context.
    149   int host_index() { return Smi::cast(get(HOST_OFFSET))->value(); }
    150 
    151   // Name, mode, and index of the i-th export, respectively.
    152   // For value exports, the index is the slot of the value in the module
    153   // context, for exported modules it is the slot index of the
    154   // referred module's context in the host context.
    155   // TODO(rossberg): This format cannot yet handle exports of modules declared
    156   // in earlier scripts.
    157   String* name(int i) { return String::cast(get(name_offset(i))); }
    158   VariableMode mode(int i) {
    159     return static_cast<VariableMode>(Smi::cast(get(mode_offset(i)))->value());
    160   }
    161   int index(int i) { return Smi::cast(get(index_offset(i)))->value(); }
    162 
    163   int length() { return (FixedArray::length() - HEADER_SIZE) / ITEM_SIZE; }
    164 
    165  private:
    166   // The internal format is: Index, (Name, VariableMode, Index)*
    167   enum {
    168     HOST_OFFSET,
    169     NAME_OFFSET,
    170     MODE_OFFSET,
    171     INDEX_OFFSET,
    172     HEADER_SIZE = NAME_OFFSET,
    173     ITEM_SIZE = INDEX_OFFSET - NAME_OFFSET + 1
    174   };
    175   inline int name_offset(int i) { return NAME_OFFSET + i * ITEM_SIZE; }
    176   inline int mode_offset(int i) { return MODE_OFFSET + i * ITEM_SIZE; }
    177   inline int index_offset(int i) { return INDEX_OFFSET + i * ITEM_SIZE; }
    178 
    179   static Handle<ModuleInfo> Allocate(Isolate* isolate, int length) {
    180     return Handle<ModuleInfo>::cast(
    181         isolate->factory()->NewFixedArray(HEADER_SIZE + ITEM_SIZE * length));
    182   }
    183   void set_host_index(int index) { set(HOST_OFFSET, Smi::FromInt(index)); }
    184   void set_name(int i, String* name) { set(name_offset(i), name); }
    185   void set_mode(int i, VariableMode mode) {
    186     set(mode_offset(i), Smi::FromInt(mode));
    187   }
    188   void set_index(int i, int index) {
    189     set(index_offset(i), Smi::FromInt(index));
    190   }
    191 };
    192 
    193 
    194 } }  // namespace v8::internal
    195 
    196 #endif  // V8_SCOPEINFO_H_
    197