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:
ContextSlotCache()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 {
ValueValue61     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 
ValueValue76     explicit inline Value(uint32_t value) : value_(value) {}
77 
rawValue78     uint32_t raw() { return value_; }
79 
modeValue80     VariableMode mode() { return ModeField::decode(value_); }
81 
initialization_flagValue82     InitializationFlag initialization_flag() {
83       return InitField::decode(value_);
84     }
85 
maybe_assigned_flagValue86     MaybeAssignedFlag maybe_assigned_flag() {
87       return MaybeAssignedField::decode(value_);
88     }
89 
indexValue90     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:
cast(Object * description)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.
host_index()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.
name(int i)135   String* name(int i) { return String::cast(get(name_offset(i))); }
mode(int i)136   VariableMode mode(int i) {
137     return static_cast<VariableMode>(Smi::cast(get(mode_offset(i)))->value());
138   }
index(int i)139   int index(int i) { return Smi::cast(get(index_offset(i)))->value(); }
140 
length()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   };
name_offset(int i)153   inline int name_offset(int i) { return NAME_OFFSET + i * ITEM_SIZE; }
mode_offset(int i)154   inline int mode_offset(int i) { return MODE_OFFSET + i * ITEM_SIZE; }
index_offset(int i)155   inline int index_offset(int i) { return INDEX_OFFSET + i * ITEM_SIZE; }
156 
Allocate(Isolate * isolate,int length)157   static Handle<ModuleInfo> Allocate(Isolate* isolate, int length) {
158     return Handle<ModuleInfo>::cast(
159         isolate->factory()->NewFixedArray(HEADER_SIZE + ITEM_SIZE * length));
160   }
set_host_index(int index)161   void set_host_index(int index) { set(HOST_OFFSET, Smi::FromInt(index)); }
set_name(int i,String * name)162   void set_name(int i, String* name) { set(name_offset(i), name); }
set_mode(int i,VariableMode mode)163   void set_mode(int i, VariableMode mode) {
164     set(mode_offset(i), Smi::FromInt(mode));
165   }
set_index(int i,int index)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