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