blob: dd49a4e08250405a756d155ac4dd39c3dfe184f9 [file] [log] [blame]
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001// Copyright 2006-2008 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
31#include "variables.h"
ager@chromium.orgce5e87b2010-03-10 10:24:18 +000032#include "zone-inl.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000033
kasperl@chromium.org71affb52009-05-26 05:44:31 +000034namespace v8 {
35namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000036
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
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +000040// is stored in a compressed form in FixedArray objects and is used
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000041// 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;
51template<class Allocator>
52class ScopeInfo BASE_EMBEDDED {
53 public:
54 // Create a ScopeInfo instance from a scope.
55 explicit ScopeInfo(Scope* scope);
56
ager@chromium.orgb5737492010-07-15 09:29:43 +000057 // Create a ScopeInfo instance from SerializedScopeInfo.
58 explicit ScopeInfo(SerializedScopeInfo* data);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000059
ager@chromium.orgb5737492010-07-15 09:29:43 +000060 // Creates a SerializedScopeInfo holding the serialized scope info.
61 Handle<SerializedScopeInfo> Serialize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000062
63 // --------------------------------------------------------------------------
64 // Lookup
65
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +000066 Handle<String> function_name() const { return function_name_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000067
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +000068 Handle<String> parameter_name(int i) const { return parameters_[i]; }
69 int number_of_parameters() const { return parameters_.length(); }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000070
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +000071 Handle<String> stack_slot_name(int i) const { return stack_slots_[i]; }
72 int number_of_stack_slots() const { return stack_slots_.length(); }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000073
74 Handle<String> context_slot_name(int i) const {
75 return context_slots_[i - Context::MIN_CONTEXT_SLOTS];
76 }
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
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000085 // --------------------------------------------------------------------------
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000086 // Debugging support
87
88#ifdef DEBUG
89 void Print();
90#endif
91
92 private:
93 Handle<String> function_name_;
ager@chromium.org381abbb2009-02-25 13:23:22 +000094 bool calls_eval_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000095 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
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000101
ager@chromium.orgb5737492010-07-15 09:29:43 +0000102// This object provides quick access to scope info details for runtime
103// routines w/o the need to explicitly create a ScopeInfo object.
104class SerializedScopeInfo : public FixedArray {
105 public :
106
107 static SerializedScopeInfo* cast(Object* object) {
108 ASSERT(object->IsFixedArray());
109 return reinterpret_cast<SerializedScopeInfo*>(object);
110 }
111
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000112 // Does this scope call eval?
ager@chromium.orgb5737492010-07-15 09:29:43 +0000113 bool CallsEval();
114
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000115 // Does this scope have an arguments shadow?
116 bool HasArgumentsShadow() {
117 return StackSlotIndex(Heap::arguments_shadow_symbol()) >= 0;
118 }
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.
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000176 static int Lookup(Object* data,
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000177 String* name,
178 Variable::Mode* mode);
179
180 // Update an element in the cache.
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000181 static void Update(Object* data,
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000182 String* name,
183 Variable::Mode mode,
184 int slot_index);
185
186 // Clear the cache.
187 static void Clear();
188
189 static const int kNotFound = -2;
190 private:
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000191 inline static int Hash(Object* data, String* name);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000192
193#ifdef DEBUG
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000194 static void ValidateEntry(Object* data,
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000195 String* name,
196 Variable::Mode mode,
197 int slot_index);
198#endif
199
200 static const int kLength = 256;
201 struct Key {
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000202 Object* data;
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000203 String* name;
204 };
205
206 struct Value {
207 Value(Variable::Mode mode, int index) {
208 ASSERT(ModeField::is_valid(mode));
209 ASSERT(IndexField::is_valid(index));
210 value_ = ModeField::encode(mode) | IndexField::encode(index);
211 ASSERT(mode == this->mode());
212 ASSERT(index == this->index());
213 }
214
215 inline Value(uint32_t value) : value_(value) {}
216
217 uint32_t raw() { return value_; }
218
219 Variable::Mode mode() { return ModeField::decode(value_); }
220
221 int index() { return IndexField::decode(value_); }
222
223 // Bit fields in value_ (type, shift, size). Must be public so the
224 // constants can be embedded in generated code.
225 class ModeField: public BitField<Variable::Mode, 0, 3> {};
226 class IndexField: public BitField<int, 3, 32-3> {};
227 private:
228 uint32_t value_;
229 };
230
231 static Key keys_[kLength];
232 static uint32_t values_[kLength];
233};
234
235
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000236} } // namespace v8::internal
237
238#endif // V8_SCOPEINFO_H_