scopeinfo.h revision b0fe1620dcb4135ac3ab2d66ff93072373911299
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
34namespace v8 {
35namespace 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;
51template<class Allocator>
52class 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
66  Handle<String> function_name() const { return function_name_; }
67
68  Handle<String> parameter_name(int i) const { return parameters_[i]; }
69  int number_of_parameters() const { return parameters_.length(); }
70
71  Handle<String> stack_slot_name(int i) const { return stack_slots_[i]; }
72  int number_of_stack_slots() const { return stack_slots_.length(); }
73
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
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.
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
112  // Does this scope call eval?
113  bool CallsEval();
114
115  // Does this scope have an arguments shadow?
116  bool HasArgumentsShadow() {
117    return StackSlotIndex(Heap::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.
172class ContextSlotCache {
173 public:
174  // Lookup context slot index for (data, name).
175  // If absent, kNotFound is returned.
176  static int Lookup(Object* data,
177                    String* name,
178                    Variable::Mode* mode);
179
180  // Update an element in the cache.
181  static void Update(Object* data,
182                     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:
191  inline static int Hash(Object* data, String* name);
192
193#ifdef DEBUG
194  static void ValidateEntry(Object* data,
195                            String* name,
196                            Variable::Mode mode,
197                            int slot_index);
198#endif
199
200  static const int kLength = 256;
201  struct Key {
202    Object* data;
203    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
236} }  // namespace v8::internal
237
238#endif  // V8_SCOPEINFO_H_
239