• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
ContextSlotCache()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 {
ValueValue89     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 
ValueValue103     explicit inline Value(uint32_t value) : value_(value) {}
104 
rawValue105     uint32_t raw() { return value_; }
106 
modeValue107     VariableMode mode() { return ModeField::decode(value_); }
108 
initialization_flagValue109     InitializationFlag initialization_flag() {
110       return InitField::decode(value_);
111     }
112 
indexValue113     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:
cast(Object * description)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.
host_index()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.
name(int i)157   String* name(int i) { return String::cast(get(name_offset(i))); }
mode(int i)158   VariableMode mode(int i) {
159     return static_cast<VariableMode>(Smi::cast(get(mode_offset(i)))->value());
160   }
index(int i)161   int index(int i) { return Smi::cast(get(index_offset(i)))->value(); }
162 
length()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   };
name_offset(int i)175   inline int name_offset(int i) { return NAME_OFFSET + i * ITEM_SIZE; }
mode_offset(int i)176   inline int mode_offset(int i) { return MODE_OFFSET + i * ITEM_SIZE; }
index_offset(int i)177   inline int index_offset(int i) { return INDEX_OFFSET + i * ITEM_SIZE; }
178 
Allocate(Isolate * isolate,int length)179   static Handle<ModuleInfo> Allocate(Isolate* isolate, int length) {
180     return Handle<ModuleInfo>::cast(
181         isolate->factory()->NewFixedArray(HEADER_SIZE + ITEM_SIZE * length));
182   }
set_host_index(int index)183   void set_host_index(int index) { set(HOST_OFFSET, Smi::FromInt(index)); }
set_name(int i,String * name)184   void set_name(int i, String* name) { set(name_offset(i), name); }
set_mode(int i,VariableMode mode)185   void set_mode(int i, VariableMode mode) {
186     set(mode_offset(i), Smi::FromInt(mode));
187   }
set_index(int i,int index)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