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