blob: 86c33f61ffaf3a1bd38bc8d38665a83ec0181c41 [file] [log] [blame]
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001// Copyright 2011 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// 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
lrn@chromium.org1c092762011-05-09 09:42:16 +000031#include "allocation.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000032#include "variables.h"
ager@chromium.orgce5e87b2010-03-10 10:24:18 +000033#include "zone-inl.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000034
kasperl@chromium.org71affb52009-05-26 05:44:31 +000035namespace v8 {
36namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000037
38// Scope information represents information about a functions's
39// scopes (currently only one, because we don't do any inlining)
40// and the allocation of the scope's variables. Scope information
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +000041// is stored in a compressed form in FixedArray objects and is used
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000042// at runtime (stack dumps, deoptimization, etc.).
43//
44// Historical note: In other VMs built by this team, ScopeInfo was
45// usually called DebugInfo since the information was used (among
46// other things) for on-demand debugging (Self, Smalltalk). However,
47// DebugInfo seems misleading, since this information is primarily used
48// in debugging-unrelated contexts.
49
50// Forward defined as
51// template <class Allocator = FreeStoreAllocationPolicy> class ScopeInfo;
52template<class Allocator>
53class ScopeInfo BASE_EMBEDDED {
54 public:
55 // Create a ScopeInfo instance from a scope.
56 explicit ScopeInfo(Scope* scope);
57
ager@chromium.orgb5737492010-07-15 09:29:43 +000058 // Create a ScopeInfo instance from SerializedScopeInfo.
59 explicit ScopeInfo(SerializedScopeInfo* data);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000060
ager@chromium.orgb5737492010-07-15 09:29:43 +000061 // Creates a SerializedScopeInfo holding the serialized scope info.
62 Handle<SerializedScopeInfo> Serialize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000063
64 // --------------------------------------------------------------------------
65 // Lookup
66
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +000067 Handle<String> function_name() const { return function_name_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000068
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +000069 Handle<String> parameter_name(int i) const { return parameters_[i]; }
70 int number_of_parameters() const { return parameters_.length(); }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000071
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +000072 Handle<String> stack_slot_name(int i) const { return stack_slots_[i]; }
73 int number_of_stack_slots() const { return stack_slots_.length(); }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000074
75 Handle<String> context_slot_name(int i) const {
76 return context_slots_[i - Context::MIN_CONTEXT_SLOTS];
77 }
78 int number_of_context_slots() const {
79 int l = context_slots_.length();
80 return l == 0 ? 0 : l + Context::MIN_CONTEXT_SLOTS;
81 }
82
83 Handle<String> LocalName(int i) const;
84 int NumberOfLocals() const;
85
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000086 // --------------------------------------------------------------------------
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000087 // Debugging support
88
89#ifdef DEBUG
90 void Print();
91#endif
92
93 private:
94 Handle<String> function_name_;
ager@chromium.org381abbb2009-02-25 13:23:22 +000095 bool calls_eval_;
karlklose@chromium.org83a47282011-05-11 11:54:09 +000096 bool is_strict_mode_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000097 List<Handle<String>, Allocator > parameters_;
98 List<Handle<String>, Allocator > stack_slots_;
99 List<Handle<String>, Allocator > context_slots_;
100 List<Variable::Mode, Allocator > context_modes_;
101};
102
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000103
ager@chromium.orgb5737492010-07-15 09:29:43 +0000104// This object provides quick access to scope info details for runtime
105// routines w/o the need to explicitly create a ScopeInfo object.
106class SerializedScopeInfo : public FixedArray {
107 public :
108
109 static SerializedScopeInfo* cast(Object* object) {
110 ASSERT(object->IsFixedArray());
111 return reinterpret_cast<SerializedScopeInfo*>(object);
112 }
113
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000114 // Does this scope call eval?
ager@chromium.orgb5737492010-07-15 09:29:43 +0000115 bool CallsEval();
116
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000117 // Is this scope a strict mode scope?
118 bool IsStrictMode();
119
ager@chromium.orgb5737492010-07-15 09:29:43 +0000120 // 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
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000168// Cache for mapping (data, property name) into context slot index.
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000169// 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.
172class ContextSlotCache {
173 public:
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000174 // Lookup context slot index for (data, name).
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000175 // If absent, kNotFound is returned.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000176 int Lookup(Object* data,
177 String* name,
178 Variable::Mode* mode);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000179
180 // Update an element in the cache.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000181 void Update(Object* data,
182 String* name,
183 Variable::Mode mode,
184 int slot_index);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000185
186 // Clear the cache.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000187 void Clear();
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000188
189 static const int kNotFound = -2;
190 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000191 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
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000199 inline static int Hash(Object* data, String* name);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000200
201#ifdef DEBUG
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000202 void ValidateEntry(Object* data,
203 String* name,
204 Variable::Mode mode,
205 int slot_index);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000206#endif
207
208 static const int kLength = 256;
209 struct Key {
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000210 Object* data;
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000211 String* name;
212 };
213
214 struct Value {
215 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
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000223 explicit inline Value(uint32_t value) : value_(value) {}
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000224
225 uint32_t raw() { return value_; }
226
227 Variable::Mode mode() { return ModeField::decode(value_); }
228
229 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
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000239 Key keys_[kLength];
240 uint32_t values_[kLength];
241
242 friend class Isolate;
243 DISALLOW_COPY_AND_ASSIGN(ContextSlotCache);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000244};
245
246
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000247} } // namespace v8::internal
248
249#endif // V8_SCOPEINFO_H_