blob: 02b4323980f30218e51059a5ebc287fd64c72b09 [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#include <stdlib.h>
29
30#include "v8.h"
31
32#include "scopeinfo.h"
33#include "scopes.h"
34
whesse@chromium.org030d38e2011-07-13 13:23:34 +000035#include "allocation-inl.h"
36
kasperl@chromium.org71affb52009-05-26 05:44:31 +000037namespace v8 {
38namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000039
40
mmassi@chromium.org7028c052012-06-13 11:51:58 +000041Handle<ScopeInfo> ScopeInfo::Create(Scope* scope, Zone* zone) {
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000042 // Collect stack and context locals.
mmassi@chromium.org7028c052012-06-13 11:51:58 +000043 ZoneList<Variable*> stack_locals(scope->StackLocalCount(), zone);
44 ZoneList<Variable*> context_locals(scope->ContextLocalCount(), zone);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000045 scope->CollectStackAndContextLocals(&stack_locals, &context_locals);
46 const int stack_local_count = stack_locals.length();
47 const int context_local_count = context_locals.length();
48 // Make sure we allocate the correct amount.
49 ASSERT(scope->StackLocalCount() == stack_local_count);
50 ASSERT(scope->ContextLocalCount() == context_local_count);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000051
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000052 // Determine use and location of the function variable if it is present.
53 FunctionVariableInfo function_name_info;
54 VariableMode function_variable_mode;
55 if (scope->is_function_scope() && scope->function() != NULL) {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +000056 Variable* var = scope->function()->proxy()->var();
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000057 if (!var->is_used()) {
58 function_name_info = UNUSED;
59 } else if (var->IsContextSlot()) {
60 function_name_info = CONTEXT;
61 } else {
62 ASSERT(var->IsStackLocal());
63 function_name_info = STACK;
64 }
65 function_variable_mode = var->mode();
66 } else {
67 function_name_info = NONE;
68 function_variable_mode = VAR;
69 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000070
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000071 const bool has_function_name = function_name_info != NONE;
72 const int parameter_count = scope->num_parameters();
73 const int length = kVariablePartIndex
74 + parameter_count + stack_local_count + 2 * context_local_count
75 + (has_function_name ? 2 : 0);
76
77 Handle<ScopeInfo> scope_info = FACTORY->NewScopeInfo(length);
78
79 // Encode the flags.
80 int flags = TypeField::encode(scope->type()) |
81 CallsEvalField::encode(scope->calls_eval()) |
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +000082 LanguageModeField::encode(scope->language_mode()) |
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000083 FunctionVariableField::encode(function_name_info) |
84 FunctionVariableMode::encode(function_variable_mode);
85 scope_info->SetFlags(flags);
86 scope_info->SetParameterCount(parameter_count);
87 scope_info->SetStackLocalCount(stack_local_count);
88 scope_info->SetContextLocalCount(context_local_count);
89
90 int index = kVariablePartIndex;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000091 // Add parameters.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000092 ASSERT(index == scope_info->ParameterEntriesIndex());
93 for (int i = 0; i < parameter_count; ++i) {
94 scope_info->set(index++, *scope->parameter(i)->name());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000095 }
96
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000097 // Add stack locals' names. We are assuming that the stack locals'
98 // slots are allocated in increasing order, so we can simply add
99 // them to the ScopeInfo object.
100 ASSERT(index == scope_info->StackLocalEntriesIndex());
101 for (int i = 0; i < stack_local_count; ++i) {
102 ASSERT(stack_locals[i]->index() == i);
103 scope_info->set(index++, *stack_locals[i]->name());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000104 }
105
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000106 // Due to usage analysis, context-allocated locals are not necessarily in
107 // increasing order: Some of them may be parameters which are allocated before
108 // the non-parameter locals. When the non-parameter locals are sorted
109 // according to usage, the allocated slot indices may not be in increasing
110 // order with the variable list anymore. Thus, we first need to sort them by
111 // context slot index before adding them to the ScopeInfo object.
112 context_locals.Sort(&Variable::CompareIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000113
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000114 // Add context locals' names.
115 ASSERT(index == scope_info->ContextLocalNameEntriesIndex());
116 for (int i = 0; i < context_local_count; ++i) {
117 scope_info->set(index++, *context_locals[i]->name());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000118 }
119
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000120 // Add context locals' info.
121 ASSERT(index == scope_info->ContextLocalInfoEntriesIndex());
122 for (int i = 0; i < context_local_count; ++i) {
123 Variable* var = context_locals[i];
124 uint32_t value = ContextLocalMode::encode(var->mode()) |
125 ContextLocalInitFlag::encode(var->initialization_flag());
126 scope_info->set(index++, Smi::FromInt(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000127 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000128
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000129 // If present, add the function variable name and its index.
130 ASSERT(index == scope_info->FunctionNameEntryIndex());
131 if (has_function_name) {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000132 int var_index = scope->function()->proxy()->var()->index();
133 scope_info->set(index++, *scope->function()->proxy()->name());
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000134 scope_info->set(index++, Smi::FromInt(var_index));
135 ASSERT(function_name_info != STACK ||
136 (var_index == scope_info->StackLocalCount() &&
137 var_index == scope_info->StackSlotCount() - 1));
138 ASSERT(function_name_info != CONTEXT ||
139 var_index == scope_info->ContextLength() - 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000140 }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000141
142 ASSERT(index == scope_info->length());
143 ASSERT(scope->num_parameters() == scope_info->ParameterCount());
144 ASSERT(scope->num_stack_slots() == scope_info->StackSlotCount());
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000145 ASSERT(scope->num_heap_slots() == scope_info->ContextLength() ||
146 (scope->num_heap_slots() == kVariablePartIndex &&
147 scope_info->ContextLength() == 0));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000148 return scope_info;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000149}
150
151
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000152ScopeInfo* ScopeInfo::Empty() {
153 return reinterpret_cast<ScopeInfo*>(HEAP->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000154}
155
156
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000157ScopeType ScopeInfo::Type() {
ager@chromium.orgb5737492010-07-15 09:29:43 +0000158 ASSERT(length() > 0);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000159 return TypeField::decode(Flags());
ager@chromium.orgb5737492010-07-15 09:29:43 +0000160}
161
162
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000163bool ScopeInfo::CallsEval() {
164 return length() > 0 && CallsEvalField::decode(Flags());
ager@chromium.orgb5737492010-07-15 09:29:43 +0000165}
166
167
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000168LanguageMode ScopeInfo::language_mode() {
169 return length() > 0 ? LanguageModeField::decode(Flags()) : CLASSIC_MODE;
ager@chromium.orgb5737492010-07-15 09:29:43 +0000170}
171
172
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000173int ScopeInfo::LocalCount() {
174 return StackLocalCount() + ContextLocalCount();
175}
176
177
178int ScopeInfo::StackSlotCount() {
ager@chromium.orgb5737492010-07-15 09:29:43 +0000179 if (length() > 0) {
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000180 bool function_name_stack_slot =
181 FunctionVariableField::decode(Flags()) == STACK;
182 return StackLocalCount() + (function_name_stack_slot ? 1 : 0);
ager@chromium.orgb5737492010-07-15 09:29:43 +0000183 }
184 return 0;
185}
186
187
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000188int ScopeInfo::ContextLength() {
ager@chromium.orgb5737492010-07-15 09:29:43 +0000189 if (length() > 0) {
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000190 int context_locals = ContextLocalCount();
191 bool function_name_context_slot =
192 FunctionVariableField::decode(Flags()) == CONTEXT;
193 bool has_context = context_locals > 0 ||
194 function_name_context_slot ||
195 Type() == WITH_SCOPE ||
danno@chromium.org81cac2b2012-07-10 11:28:27 +0000196 (Type() == FUNCTION_SCOPE && CallsEval()) ||
197 Type() == MODULE_SCOPE;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000198 if (has_context) {
199 return Context::MIN_CONTEXT_SLOTS + context_locals +
200 (function_name_context_slot ? 1 : 0);
201 }
ager@chromium.orgb5737492010-07-15 09:29:43 +0000202 }
203 return 0;
204}
205
206
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000207bool ScopeInfo::HasFunctionName() {
ager@chromium.orgb5737492010-07-15 09:29:43 +0000208 if (length() > 0) {
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000209 return NONE != FunctionVariableField::decode(Flags());
210 } else {
211 return false;
ager@chromium.orgb5737492010-07-15 09:29:43 +0000212 }
ager@chromium.orgb5737492010-07-15 09:29:43 +0000213}
214
215
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000216bool ScopeInfo::HasHeapAllocatedLocals() {
217 if (length() > 0) {
218 return ContextLocalCount() > 0;
219 } else {
220 return false;
221 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000222}
223
224
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000225bool ScopeInfo::HasContext() {
danno@chromium.org81cac2b2012-07-10 11:28:27 +0000226 return ContextLength() > 0;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000227}
228
229
230String* ScopeInfo::FunctionName() {
231 ASSERT(HasFunctionName());
232 return String::cast(get(FunctionNameEntryIndex()));
233}
234
235
236String* ScopeInfo::ParameterName(int var) {
237 ASSERT(0 <= var && var < ParameterCount());
238 int info_index = ParameterEntriesIndex() + var;
239 return String::cast(get(info_index));
240}
241
242
243String* ScopeInfo::LocalName(int var) {
244 ASSERT(0 <= var && var < LocalCount());
245 ASSERT(StackLocalEntriesIndex() + StackLocalCount() ==
246 ContextLocalNameEntriesIndex());
247 int info_index = StackLocalEntriesIndex() + var;
248 return String::cast(get(info_index));
249}
250
251
252String* ScopeInfo::StackLocalName(int var) {
253 ASSERT(0 <= var && var < StackLocalCount());
254 int info_index = StackLocalEntriesIndex() + var;
255 return String::cast(get(info_index));
256}
257
258
259String* ScopeInfo::ContextLocalName(int var) {
260 ASSERT(0 <= var && var < ContextLocalCount());
261 int info_index = ContextLocalNameEntriesIndex() + var;
262 return String::cast(get(info_index));
263}
264
265
266VariableMode ScopeInfo::ContextLocalMode(int var) {
267 ASSERT(0 <= var && var < ContextLocalCount());
268 int info_index = ContextLocalInfoEntriesIndex() + var;
269 int value = Smi::cast(get(info_index))->value();
270 return ContextLocalMode::decode(value);
271}
272
273
274InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) {
275 ASSERT(0 <= var && var < ContextLocalCount());
276 int info_index = ContextLocalInfoEntriesIndex() + var;
277 int value = Smi::cast(get(info_index))->value();
278 return ContextLocalInitFlag::decode(value);
279}
280
281
282int ScopeInfo::StackSlotIndex(String* name) {
ager@chromium.orgb5737492010-07-15 09:29:43 +0000283 ASSERT(name->IsSymbol());
284 if (length() > 0) {
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000285 int start = StackLocalEntriesIndex();
286 int end = StackLocalEntriesIndex() + StackLocalCount();
287 for (int i = start; i < end; ++i) {
288 if (name == get(i)) {
289 return i - start;
290 }
ager@chromium.orgb5737492010-07-15 09:29:43 +0000291 }
292 }
293 return -1;
294}
295
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000296
297int ScopeInfo::ContextSlotIndex(String* name,
298 VariableMode* mode,
299 InitializationFlag* init_flag) {
ager@chromium.orgb5737492010-07-15 09:29:43 +0000300 ASSERT(name->IsSymbol());
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000301 ASSERT(mode != NULL);
302 ASSERT(init_flag != NULL);
ager@chromium.orgb5737492010-07-15 09:29:43 +0000303 if (length() > 0) {
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000304 ContextSlotCache* context_slot_cache = GetIsolate()->context_slot_cache();
305 int result = context_slot_cache->Lookup(this, name, mode, init_flag);
306 if (result != ContextSlotCache::kNotFound) {
307 ASSERT(result < ContextLength());
308 return result;
309 }
310
311 int start = ContextLocalNameEntriesIndex();
312 int end = ContextLocalNameEntriesIndex() + ContextLocalCount();
313 for (int i = start; i < end; ++i) {
314 if (name == get(i)) {
315 int var = i - start;
316 *mode = ContextLocalMode(var);
317 *init_flag = ContextLocalInitFlag(var);
318 result = Context::MIN_CONTEXT_SLOTS + var;
319 context_slot_cache->Update(this, name, *mode, *init_flag, result);
320 ASSERT(result < ContextLength());
ager@chromium.orgb5737492010-07-15 09:29:43 +0000321 return result;
322 }
ager@chromium.orgb5737492010-07-15 09:29:43 +0000323 }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000324 context_slot_cache->Update(this, name, INTERNAL, kNeedsInitialization, -1);
ager@chromium.orgb5737492010-07-15 09:29:43 +0000325 }
ager@chromium.orgb5737492010-07-15 09:29:43 +0000326 return -1;
327}
328
329
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000330int ScopeInfo::ParameterIndex(String* name) {
ager@chromium.orgb5737492010-07-15 09:29:43 +0000331 ASSERT(name->IsSymbol());
332 if (length() > 0) {
333 // We must read parameters from the end since for
334 // multiply declared parameters the value of the
335 // last declaration of that parameter is used
336 // inside a function (and thus we need to look
337 // at the last index). Was bug# 1110337.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000338 int start = ParameterEntriesIndex();
339 int end = ParameterEntriesIndex() + ParameterCount();
340 for (int i = end - 1; i >= start; --i) {
341 if (name == get(i)) {
342 return i - start;
343 }
ager@chromium.orgb5737492010-07-15 09:29:43 +0000344 }
345 }
346 return -1;
347}
348
349
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000350int ScopeInfo::FunctionContextSlotIndex(String* name, VariableMode* mode) {
ager@chromium.orgb5737492010-07-15 09:29:43 +0000351 ASSERT(name->IsSymbol());
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000352 ASSERT(mode != NULL);
ager@chromium.orgb5737492010-07-15 09:29:43 +0000353 if (length() > 0) {
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000354 if (FunctionVariableField::decode(Flags()) == CONTEXT &&
355 FunctionName() == name) {
356 *mode = FunctionVariableMode::decode(Flags());
357 return Smi::cast(get(FunctionNameEntryIndex() + 1))->value();
ager@chromium.orgb5737492010-07-15 09:29:43 +0000358 }
359 }
360 return -1;
361}
362
363
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000364int ScopeInfo::ParameterEntriesIndex() {
365 ASSERT(length() > 0);
366 return kVariablePartIndex;
367}
368
369
370int ScopeInfo::StackLocalEntriesIndex() {
371 return ParameterEntriesIndex() + ParameterCount();
372}
373
374
375int ScopeInfo::ContextLocalNameEntriesIndex() {
376 return StackLocalEntriesIndex() + StackLocalCount();
377}
378
379
380int ScopeInfo::ContextLocalInfoEntriesIndex() {
381 return ContextLocalNameEntriesIndex() + ContextLocalCount();
382}
383
384
385int ScopeInfo::FunctionNameEntryIndex() {
386 return ContextLocalInfoEntriesIndex() + ContextLocalCount();
387}
388
389
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000390int ContextSlotCache::Hash(Object* data, String* name) {
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000391 // Uses only lower 32 bits if pointers are larger.
392 uintptr_t addr_hash =
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000393 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2;
fschneider@chromium.orgb95b98b2010-02-23 10:34:29 +0000394 return static_cast<int>((addr_hash ^ name->Hash()) % kLength);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000395}
396
397
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000398int ContextSlotCache::Lookup(Object* data,
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000399 String* name,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000400 VariableMode* mode,
401 InitializationFlag* init_flag) {
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000402 int index = Hash(data, name);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000403 Key& key = keys_[index];
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000404 if ((key.data == data) && key.name->Equals(name)) {
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000405 Value result(values_[index]);
406 if (mode != NULL) *mode = result.mode();
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000407 if (init_flag != NULL) *init_flag = result.initialization_flag();
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000408 return result.index() + kNotFound;
409 }
410 return kNotFound;
411}
412
413
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000414void ContextSlotCache::Update(Object* data,
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000415 String* name,
rossberg@chromium.orgb4b2aa62011-10-13 09:49:59 +0000416 VariableMode mode,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000417 InitializationFlag init_flag,
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000418 int slot_index) {
419 String* symbol;
420 ASSERT(slot_index > kNotFound);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000421 if (HEAP->LookupSymbolIfExists(name, &symbol)) {
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000422 int index = Hash(data, symbol);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000423 Key& key = keys_[index];
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000424 key.data = data;
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000425 key.name = symbol;
426 // Please note value only takes a uint as index.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000427 values_[index] = Value(mode, init_flag, slot_index - kNotFound).raw();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000428#ifdef DEBUG
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000429 ValidateEntry(data, name, mode, init_flag, slot_index);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000430#endif
431 }
432}
433
434
435void ContextSlotCache::Clear() {
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000436 for (int index = 0; index < kLength; index++) keys_[index].data = NULL;
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000437}
438
439
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000440#ifdef DEBUG
441
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000442void ContextSlotCache::ValidateEntry(Object* data,
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000443 String* name,
rossberg@chromium.orgb4b2aa62011-10-13 09:49:59 +0000444 VariableMode mode,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000445 InitializationFlag init_flag,
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000446 int slot_index) {
447 String* symbol;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000448 if (HEAP->LookupSymbolIfExists(name, &symbol)) {
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000449 int index = Hash(data, name);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000450 Key& key = keys_[index];
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000451 ASSERT(key.data == data);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000452 ASSERT(key.name->Equals(name));
453 Value result(values_[index]);
454 ASSERT(result.mode() == mode);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000455 ASSERT(result.initialization_flag() == init_flag);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000456 ASSERT(result.index() + kNotFound == slot_index);
457 }
458}
459
460
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000461static void PrintList(const char* list_name,
462 int nof_internal_slots,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000463 int start,
464 int end,
465 ScopeInfo* scope_info) {
466 if (start < end) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000467 PrintF("\n // %s\n", list_name);
468 if (nof_internal_slots > 0) {
469 PrintF(" %2d - %2d [internal slots]\n", 0 , nof_internal_slots - 1);
470 }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000471 for (int i = nof_internal_slots; start < end; ++i, ++start) {
472 PrintF(" %2d ", i);
473 String::cast(scope_info->get(start))->ShortPrint();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000474 PrintF("\n");
475 }
476 }
477}
478
479
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000480void ScopeInfo::Print() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000481 PrintF("ScopeInfo ");
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000482 if (HasFunctionName()) {
483 FunctionName()->ShortPrint();
484 } else {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000485 PrintF("/* no function name */");
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000486 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000487 PrintF("{");
488
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000489 PrintList("parameters", 0,
490 ParameterEntriesIndex(),
491 ParameterEntriesIndex() + ParameterCount(),
492 this);
493 PrintList("stack slots", 0,
494 StackLocalEntriesIndex(),
495 StackLocalEntriesIndex() + StackLocalCount(),
496 this);
497 PrintList("context slots",
498 Context::MIN_CONTEXT_SLOTS,
499 ContextLocalNameEntriesIndex(),
500 ContextLocalNameEntriesIndex() + ContextLocalCount(),
501 this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000502
503 PrintF("}\n");
504}
505#endif // DEBUG
506
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000507} } // namespace v8::internal