• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
function_name()66   Handle<String> function_name() const { return function_name_; }
67 
parameter_name(int i)68   Handle<String> parameter_name(int i) const { return parameters_[i]; }
number_of_parameters()69   int number_of_parameters() const { return parameters_.length(); }
70 
stack_slot_name(int i)71   Handle<String> stack_slot_name(int i) const { return stack_slots_[i]; }
number_of_stack_slots()72   int number_of_stack_slots() const { return stack_slots_.length(); }
73 
context_slot_name(int i)74   Handle<String> context_slot_name(int i) const {
75     return context_slots_[i - Context::MIN_CONTEXT_SLOTS];
76   }
number_of_context_slots()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 
cast(Object * object)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?
HasArgumentsShadow()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:
ContextSlotCache()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 {
ValueValue215     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 
ValueValue223     explicit inline Value(uint32_t value) : value_(value) {}
224 
rawValue225     uint32_t raw() { return value_; }
226 
modeValue227     Variable::Mode mode() { return ModeField::decode(value_); }
228 
indexValue229     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