Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(185)

Side by Side Diff: src/scopeinfo.cc

Issue 1218783005: Support for global var shortcuts in script contexts. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stdlib.h> 5 #include <stdlib.h>
6 6
7 #include "src/v8.h" 7 #include "src/v8.h"
8 8
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/scopeinfo.h" 10 #include "src/scopeinfo.h"
11 #include "src/scopes.h" 11 #include "src/scopes.h"
12 12
13 namespace v8 { 13 namespace v8 {
14 namespace internal { 14 namespace internal {
15 15
16 16
17 Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, 17 Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
18 Scope* scope) { 18 Scope* scope) {
19 // Collect stack and context locals. 19 // Collect stack and context locals.
20 ZoneList<Variable*> stack_locals(scope->StackLocalCount(), zone); 20 ZoneList<Variable*> stack_locals(scope->StackLocalCount(), zone);
21 ZoneList<Variable*> context_locals(scope->ContextLocalCount(), zone); 21 ZoneList<Variable*> context_locals(scope->ContextLocalCount(), zone);
22 ZoneList<Variable*> context_globals(scope->ContextGlobalCount(), zone);
22 ZoneList<Variable*> strong_mode_free_variables(0, zone); 23 ZoneList<Variable*> strong_mode_free_variables(0, zone);
23 24
24 scope->CollectStackAndContextLocals(&stack_locals, &context_locals, 25 scope->CollectStackAndContextLocals(&stack_locals, &context_locals,
26 &context_globals,
25 &strong_mode_free_variables); 27 &strong_mode_free_variables);
26 const int stack_local_count = stack_locals.length(); 28 const int stack_local_count = stack_locals.length();
27 const int context_local_count = context_locals.length(); 29 const int context_local_count = context_locals.length();
30 const int context_global_count = context_globals.length();
28 const int strong_mode_free_variable_count = 31 const int strong_mode_free_variable_count =
29 strong_mode_free_variables.length(); 32 strong_mode_free_variables.length();
30 // Make sure we allocate the correct amount. 33 // Make sure we allocate the correct amount.
31 DCHECK(scope->ContextLocalCount() == context_local_count); 34 DCHECK_EQ(scope->ContextLocalCount(), context_local_count);
35 DCHECK_EQ(scope->ContextGlobalCount(), context_global_count);
32 36
33 bool simple_parameter_list = 37 bool simple_parameter_list =
34 scope->is_function_scope() ? scope->is_simple_parameter_list() : true; 38 scope->is_function_scope() ? scope->is_simple_parameter_list() : true;
35 39
36 // Determine use and location of the "this" binding if it is present. 40 // Determine use and location of the "this" binding if it is present.
37 VariableAllocationInfo receiver_info; 41 VariableAllocationInfo receiver_info;
38 if (scope->has_this_declaration()) { 42 if (scope->has_this_declaration()) {
39 Variable* var = scope->receiver(); 43 Variable* var = scope->receiver();
40 if (!var->is_used()) { 44 if (!var->is_used()) {
41 receiver_info = UNUSED; 45 receiver_info = UNUSED;
(...skipping 18 matching lines...) Expand all
60 function_name_info = CONTEXT; 64 function_name_info = CONTEXT;
61 } else { 65 } else {
62 DCHECK(var->IsStackLocal()); 66 DCHECK(var->IsStackLocal());
63 function_name_info = STACK; 67 function_name_info = STACK;
64 } 68 }
65 function_variable_mode = var->mode(); 69 function_variable_mode = var->mode();
66 } else { 70 } else {
67 function_name_info = NONE; 71 function_name_info = NONE;
68 function_variable_mode = VAR; 72 function_variable_mode = VAR;
69 } 73 }
74 DCHECK(context_global_count == 0 || scope->scope_type() == SCRIPT_SCOPE);
70 75
71 const bool has_function_name = function_name_info != NONE; 76 const bool has_function_name = function_name_info != NONE;
72 const bool has_receiver = receiver_info == STACK || receiver_info == CONTEXT; 77 const bool has_receiver = receiver_info == STACK || receiver_info == CONTEXT;
73 const int parameter_count = scope->num_parameters(); 78 const int parameter_count = scope->num_parameters();
74 const int length = kVariablePartIndex + parameter_count + 79 const int length = kVariablePartIndex + parameter_count +
75 (1 + stack_local_count) + 2 * context_local_count + 80 (1 + stack_local_count) + 2 * context_local_count +
81 2 * context_global_count +
76 3 * strong_mode_free_variable_count + 82 3 * strong_mode_free_variable_count +
77 (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0); 83 (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0);
78 84
79 Factory* factory = isolate->factory(); 85 Factory* factory = isolate->factory();
80 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); 86 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
81 87
82 // Encode the flags. 88 // Encode the flags.
83 int flags = ScopeTypeField::encode(scope->scope_type()) | 89 int flags = ScopeTypeField::encode(scope->scope_type()) |
84 CallsEvalField::encode(scope->calls_eval()) | 90 CallsEvalField::encode(scope->calls_eval()) |
85 LanguageModeField::encode(scope->language_mode()) | 91 LanguageModeField::encode(scope->language_mode()) |
86 ReceiverVariableField::encode(receiver_info) | 92 ReceiverVariableField::encode(receiver_info) |
87 FunctionVariableField::encode(function_name_info) | 93 FunctionVariableField::encode(function_name_info) |
88 FunctionVariableMode::encode(function_variable_mode) | 94 FunctionVariableMode::encode(function_variable_mode) |
89 AsmModuleField::encode(scope->asm_module()) | 95 AsmModuleField::encode(scope->asm_module()) |
90 AsmFunctionField::encode(scope->asm_function()) | 96 AsmFunctionField::encode(scope->asm_function()) |
91 IsSimpleParameterListField::encode(simple_parameter_list) | 97 IsSimpleParameterListField::encode(simple_parameter_list) |
92 BlockScopeIsClassScopeField::encode(scope->is_class_scope()) | 98 BlockScopeIsClassScopeField::encode(scope->is_class_scope()) |
93 FunctionKindField::encode(scope->function_kind()); 99 FunctionKindField::encode(scope->function_kind());
94 scope_info->SetFlags(flags); 100 scope_info->SetFlags(flags);
95 scope_info->SetParameterCount(parameter_count); 101 scope_info->SetParameterCount(parameter_count);
96 scope_info->SetStackLocalCount(stack_local_count); 102 scope_info->SetStackLocalCount(stack_local_count);
97 scope_info->SetContextLocalCount(context_local_count); 103 scope_info->SetContextLocalCount(context_local_count);
104 scope_info->SetContextGlobalCount(context_global_count);
98 scope_info->SetStrongModeFreeVariableCount(strong_mode_free_variable_count); 105 scope_info->SetStrongModeFreeVariableCount(strong_mode_free_variable_count);
99 106
100 int index = kVariablePartIndex; 107 int index = kVariablePartIndex;
101 // Add parameters. 108 // Add parameters.
102 DCHECK(index == scope_info->ParameterEntriesIndex()); 109 DCHECK(index == scope_info->ParameterEntriesIndex());
103 for (int i = 0; i < parameter_count; ++i) { 110 for (int i = 0; i < parameter_count; ++i) {
104 scope_info->set(index++, *scope->parameter(i)->name()); 111 scope_info->set(index++, *scope->parameter(i)->name());
105 } 112 }
106 113
107 // Add stack locals' names. We are assuming that the stack locals' 114 // Add stack locals' names. We are assuming that the stack locals'
(...skipping 20 matching lines...) Expand all
128 // order with the variable list anymore. Thus, we first need to sort them by 135 // order with the variable list anymore. Thus, we first need to sort them by
129 // context slot index before adding them to the ScopeInfo object. 136 // context slot index before adding them to the ScopeInfo object.
130 context_locals.Sort(&Variable::CompareIndex); 137 context_locals.Sort(&Variable::CompareIndex);
131 138
132 // Add context locals' names. 139 // Add context locals' names.
133 DCHECK(index == scope_info->ContextLocalNameEntriesIndex()); 140 DCHECK(index == scope_info->ContextLocalNameEntriesIndex());
134 for (int i = 0; i < context_local_count; ++i) { 141 for (int i = 0; i < context_local_count; ++i) {
135 scope_info->set(index++, *context_locals[i]->name()); 142 scope_info->set(index++, *context_locals[i]->name());
136 } 143 }
137 144
145 // Add context globals' names.
146 DCHECK(index == scope_info->ContextGlobalNameEntriesIndex());
147 for (int i = 0; i < context_global_count; ++i) {
148 scope_info->set(index++, *context_globals[i]->name());
149 }
150
138 // Add context locals' info. 151 // Add context locals' info.
139 DCHECK(index == scope_info->ContextLocalInfoEntriesIndex()); 152 DCHECK(index == scope_info->ContextLocalInfoEntriesIndex());
140 for (int i = 0; i < context_local_count; ++i) { 153 for (int i = 0; i < context_local_count; ++i) {
141 Variable* var = context_locals[i]; 154 Variable* var = context_locals[i];
142 uint32_t value = 155 uint32_t value =
143 ContextLocalMode::encode(var->mode()) | 156 ContextLocalMode::encode(var->mode()) |
144 ContextLocalInitFlag::encode(var->initialization_flag()) | 157 ContextLocalInitFlag::encode(var->initialization_flag()) |
145 ContextLocalMaybeAssignedFlag::encode(var->maybe_assigned()); 158 ContextLocalMaybeAssignedFlag::encode(var->maybe_assigned());
146 scope_info->set(index++, Smi::FromInt(value)); 159 scope_info->set(index++, Smi::FromInt(value));
147 } 160 }
148 161
162 // Add context globals' info.
163 DCHECK(index == scope_info->ContextGlobalInfoEntriesIndex());
164 for (int i = 0; i < context_global_count; ++i) {
165 Variable* var = context_globals[i];
166 // TODO(ishell): do we need this kind of info for globals here?
167 uint32_t value =
168 ContextLocalMode::encode(var->mode()) |
169 ContextLocalInitFlag::encode(var->initialization_flag()) |
170 ContextLocalMaybeAssignedFlag::encode(var->maybe_assigned());
171 scope_info->set(index++, Smi::FromInt(value));
172 }
173
149 DCHECK(index == scope_info->StrongModeFreeVariableNameEntriesIndex()); 174 DCHECK(index == scope_info->StrongModeFreeVariableNameEntriesIndex());
150 for (int i = 0; i < strong_mode_free_variable_count; ++i) { 175 for (int i = 0; i < strong_mode_free_variable_count; ++i) {
151 scope_info->set(index++, *strong_mode_free_variables[i]->name()); 176 scope_info->set(index++, *strong_mode_free_variables[i]->name());
152 } 177 }
153 178
154 DCHECK(index == scope_info->StrongModeFreeVariablePositionEntriesIndex()); 179 DCHECK(index == scope_info->StrongModeFreeVariablePositionEntriesIndex());
155 for (int i = 0; i < strong_mode_free_variable_count; ++i) { 180 for (int i = 0; i < strong_mode_free_variable_count; ++i) {
156 // Unfortunately, the source code positions are stored as int even though 181 // Unfortunately, the source code positions are stored as int even though
157 // int32_t would be enough (given the maximum source code length). 182 // int32_t would be enough (given the maximum source code length).
158 Handle<Object> start_position = factory->NewNumberFromInt( 183 Handle<Object> start_position = factory->NewNumberFromInt(
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 scope_info->ContextLength() == 0)); 216 scope_info->ContextLength() == 0));
192 return scope_info; 217 return scope_info;
193 } 218 }
194 219
195 220
196 Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) { 221 Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) {
197 DCHECK(isolate->bootstrapper()->IsActive()); 222 DCHECK(isolate->bootstrapper()->IsActive());
198 223
199 const int stack_local_count = 0; 224 const int stack_local_count = 0;
200 const int context_local_count = 1; 225 const int context_local_count = 1;
226 const int context_global_count = 0;
201 const int strong_mode_free_variable_count = 0; 227 const int strong_mode_free_variable_count = 0;
202 const bool simple_parameter_list = true; 228 const bool simple_parameter_list = true;
203 const VariableAllocationInfo receiver_info = CONTEXT; 229 const VariableAllocationInfo receiver_info = CONTEXT;
204 const VariableAllocationInfo function_name_info = NONE; 230 const VariableAllocationInfo function_name_info = NONE;
205 const VariableMode function_variable_mode = VAR; 231 const VariableMode function_variable_mode = VAR;
206 const bool has_function_name = false; 232 const bool has_function_name = false;
207 const bool has_receiver = true; 233 const bool has_receiver = true;
208 const int parameter_count = 0; 234 const int parameter_count = 0;
209 const int length = kVariablePartIndex + parameter_count + 235 const int length = kVariablePartIndex + parameter_count +
210 (1 + stack_local_count) + 2 * context_local_count + 236 (1 + stack_local_count) + 2 * context_local_count +
237 2 * context_global_count +
211 3 * strong_mode_free_variable_count + 238 3 * strong_mode_free_variable_count +
212 (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0); 239 (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0);
213 240
214 Factory* factory = isolate->factory(); 241 Factory* factory = isolate->factory();
215 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); 242 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
216 243
217 // Encode the flags. 244 // Encode the flags.
218 int flags = ScopeTypeField::encode(SCRIPT_SCOPE) | 245 int flags = ScopeTypeField::encode(SCRIPT_SCOPE) |
219 CallsEvalField::encode(false) | 246 CallsEvalField::encode(false) |
220 LanguageModeField::encode(SLOPPY) | 247 LanguageModeField::encode(SLOPPY) |
221 ReceiverVariableField::encode(receiver_info) | 248 ReceiverVariableField::encode(receiver_info) |
222 FunctionVariableField::encode(function_name_info) | 249 FunctionVariableField::encode(function_name_info) |
223 FunctionVariableMode::encode(function_variable_mode) | 250 FunctionVariableMode::encode(function_variable_mode) |
224 AsmModuleField::encode(false) | AsmFunctionField::encode(false) | 251 AsmModuleField::encode(false) | AsmFunctionField::encode(false) |
225 IsSimpleParameterListField::encode(simple_parameter_list) | 252 IsSimpleParameterListField::encode(simple_parameter_list) |
226 BlockScopeIsClassScopeField::encode(false) | 253 BlockScopeIsClassScopeField::encode(false) |
227 FunctionKindField::encode(FunctionKind::kNormalFunction); 254 FunctionKindField::encode(FunctionKind::kNormalFunction);
228 scope_info->SetFlags(flags); 255 scope_info->SetFlags(flags);
229 scope_info->SetParameterCount(parameter_count); 256 scope_info->SetParameterCount(parameter_count);
230 scope_info->SetStackLocalCount(stack_local_count); 257 scope_info->SetStackLocalCount(stack_local_count);
231 scope_info->SetContextLocalCount(context_local_count); 258 scope_info->SetContextLocalCount(context_local_count);
259 scope_info->SetContextGlobalCount(context_global_count);
232 scope_info->SetStrongModeFreeVariableCount(strong_mode_free_variable_count); 260 scope_info->SetStrongModeFreeVariableCount(strong_mode_free_variable_count);
233 261
234 int index = kVariablePartIndex; 262 int index = kVariablePartIndex;
235 const int first_slot_index = 0; 263 const int first_slot_index = 0;
236 DCHECK(index == scope_info->StackLocalFirstSlotIndex()); 264 DCHECK(index == scope_info->StackLocalFirstSlotIndex());
237 scope_info->set(index++, Smi::FromInt(first_slot_index)); 265 scope_info->set(index++, Smi::FromInt(first_slot_index));
238 DCHECK(index == scope_info->StackLocalEntriesIndex()); 266 DCHECK(index == scope_info->StackLocalEntriesIndex());
239 267
240 // Here we add info for context-allocated "this". 268 // Here we add info for context-allocated "this".
241 DCHECK(index == scope_info->ContextLocalNameEntriesIndex()); 269 DCHECK(index == scope_info->ContextLocalNameEntriesIndex());
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 FunctionVariableField::decode(Flags()) == STACK; 324 FunctionVariableField::decode(Flags()) == STACK;
297 return StackLocalCount() + (function_name_stack_slot ? 1 : 0); 325 return StackLocalCount() + (function_name_stack_slot ? 1 : 0);
298 } 326 }
299 return 0; 327 return 0;
300 } 328 }
301 329
302 330
303 int ScopeInfo::ContextLength() { 331 int ScopeInfo::ContextLength() {
304 if (length() > 0) { 332 if (length() > 0) {
305 int context_locals = ContextLocalCount(); 333 int context_locals = ContextLocalCount();
334 int context_globals = ContextGlobalCount();
306 bool function_name_context_slot = 335 bool function_name_context_slot =
307 FunctionVariableField::decode(Flags()) == CONTEXT; 336 FunctionVariableField::decode(Flags()) == CONTEXT;
308 bool has_context = context_locals > 0 || function_name_context_slot || 337 bool has_context = context_locals > 0 || context_globals > 0 ||
338 function_name_context_slot ||
309 scope_type() == WITH_SCOPE || 339 scope_type() == WITH_SCOPE ||
310 (scope_type() == ARROW_SCOPE && CallsSloppyEval()) || 340 (scope_type() == ARROW_SCOPE && CallsSloppyEval()) ||
311 (scope_type() == FUNCTION_SCOPE && CallsSloppyEval()) || 341 (scope_type() == FUNCTION_SCOPE && CallsSloppyEval()) ||
312 scope_type() == MODULE_SCOPE; 342 scope_type() == MODULE_SCOPE;
343
313 if (has_context) { 344 if (has_context) {
314 return Context::MIN_CONTEXT_SLOTS + context_locals + 345 return Context::MIN_CONTEXT_SLOTS + context_locals + 2 * context_globals +
315 (function_name_context_slot ? 1 : 0); 346 (function_name_context_slot ? 1 : 0);
316 } 347 }
317 } 348 }
318 return 0; 349 return 0;
319 } 350 }
320 351
321 352
322 bool ScopeInfo::HasReceiver() { 353 bool ScopeInfo::HasReceiver() {
323 if (length() > 0) { 354 if (length() > 0) {
324 return NONE != ReceiverVariableField::decode(Flags()); 355 return NONE != ReceiverVariableField::decode(Flags());
325 } else { 356 } else {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 422
392 423
393 int ScopeInfo::StackLocalIndex(int var) { 424 int ScopeInfo::StackLocalIndex(int var) {
394 DCHECK(0 <= var && var < StackLocalCount()); 425 DCHECK(0 <= var && var < StackLocalCount());
395 int first_slot_index = Smi::cast(get(StackLocalFirstSlotIndex()))->value(); 426 int first_slot_index = Smi::cast(get(StackLocalFirstSlotIndex()))->value();
396 return first_slot_index + var; 427 return first_slot_index + var;
397 } 428 }
398 429
399 430
400 String* ScopeInfo::ContextLocalName(int var) { 431 String* ScopeInfo::ContextLocalName(int var) {
401 DCHECK(0 <= var && var < ContextLocalCount()); 432 DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount());
402 int info_index = ContextLocalNameEntriesIndex() + var; 433 int info_index = ContextLocalNameEntriesIndex() + var;
403 return String::cast(get(info_index)); 434 return String::cast(get(info_index));
404 } 435 }
405 436
406 437
407 VariableMode ScopeInfo::ContextLocalMode(int var) { 438 VariableMode ScopeInfo::ContextLocalMode(int var) {
408 DCHECK(0 <= var && var < ContextLocalCount()); 439 DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount());
409 int info_index = ContextLocalInfoEntriesIndex() + var; 440 int info_index = ContextLocalInfoEntriesIndex() + var;
410 int value = Smi::cast(get(info_index))->value(); 441 int value = Smi::cast(get(info_index))->value();
411 return ContextLocalMode::decode(value); 442 return ContextLocalMode::decode(value);
412 } 443 }
413 444
414 445
415 InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) { 446 InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) {
416 DCHECK(0 <= var && var < ContextLocalCount()); 447 DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount());
417 int info_index = ContextLocalInfoEntriesIndex() + var; 448 int info_index = ContextLocalInfoEntriesIndex() + var;
418 int value = Smi::cast(get(info_index))->value(); 449 int value = Smi::cast(get(info_index))->value();
419 return ContextLocalInitFlag::decode(value); 450 return ContextLocalInitFlag::decode(value);
420 } 451 }
421 452
422 453
423 MaybeAssignedFlag ScopeInfo::ContextLocalMaybeAssignedFlag(int var) { 454 MaybeAssignedFlag ScopeInfo::ContextLocalMaybeAssignedFlag(int var) {
424 DCHECK(0 <= var && var < ContextLocalCount()); 455 DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount());
425 int info_index = ContextLocalInfoEntriesIndex() + var; 456 int info_index = ContextLocalInfoEntriesIndex() + var;
426 int value = Smi::cast(get(info_index))->value(); 457 int value = Smi::cast(get(info_index))->value();
427 return ContextLocalMaybeAssignedFlag::decode(value); 458 return ContextLocalMaybeAssignedFlag::decode(value);
428 } 459 }
429 460
430 461
431 bool ScopeInfo::LocalIsSynthetic(int var) { 462 bool ScopeInfo::LocalIsSynthetic(int var) {
432 DCHECK(0 <= var && var < LocalCount()); 463 DCHECK(0 <= var && var < LocalCount());
433 // There's currently no flag stored on the ScopeInfo to indicate that a 464 // There's currently no flag stored on the ScopeInfo to indicate that a
434 // variable is a compiler-introduced temporary. However, to avoid conflict 465 // variable is a compiler-introduced temporary. However, to avoid conflict
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 return i - start + first_slot_index; 511 return i - start + first_slot_index;
481 } 512 }
482 } 513 }
483 } 514 }
484 return -1; 515 return -1;
485 } 516 }
486 517
487 518
488 int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info, 519 int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info,
489 Handle<String> name, VariableMode* mode, 520 Handle<String> name, VariableMode* mode,
521 ContextSlotKindFlag* context_slot_kind,
490 InitializationFlag* init_flag, 522 InitializationFlag* init_flag,
491 MaybeAssignedFlag* maybe_assigned_flag) { 523 MaybeAssignedFlag* maybe_assigned_flag) {
492 DCHECK(name->IsInternalizedString()); 524 DCHECK(name->IsInternalizedString());
493 DCHECK(mode != NULL); 525 DCHECK(mode != NULL);
526 DCHECK(context_slot_kind != NULL);
494 DCHECK(init_flag != NULL); 527 DCHECK(init_flag != NULL);
495 if (scope_info->length() > 0) { 528 if (scope_info->length() > 0) {
496 ContextSlotCache* context_slot_cache = 529 ContextSlotCache* context_slot_cache =
497 scope_info->GetIsolate()->context_slot_cache(); 530 scope_info->GetIsolate()->context_slot_cache();
498 int result = context_slot_cache->Lookup(*scope_info, *name, mode, init_flag, 531 int result =
499 maybe_assigned_flag); 532 context_slot_cache->Lookup(*scope_info, *name, mode, context_slot_kind,
533 init_flag, maybe_assigned_flag);
500 if (result != ContextSlotCache::kNotFound) { 534 if (result != ContextSlotCache::kNotFound) {
501 DCHECK(result < scope_info->ContextLength()); 535 DCHECK(result < scope_info->ContextLength());
502 return result; 536 return result;
503 } 537 }
504 538
539 DCHECK_EQ(scope_info->ContextGlobalNameEntriesIndex(),
540 scope_info->ContextLocalNameEntriesIndex() +
541 scope_info->ContextLocalCount());
505 int start = scope_info->ContextLocalNameEntriesIndex(); 542 int start = scope_info->ContextLocalNameEntriesIndex();
506 int end = scope_info->ContextLocalNameEntriesIndex() + 543 int end = scope_info->ContextGlobalNameEntriesIndex() +
507 scope_info->ContextLocalCount(); 544 scope_info->ContextGlobalCount();
508 for (int i = start; i < end; ++i) { 545 for (int i = start; i < end; ++i) {
509 if (*name == scope_info->get(i)) { 546 if (*name == scope_info->get(i)) {
510 int var = i - start; 547 int var = i - start;
511 *mode = scope_info->ContextLocalMode(var); 548 *mode = scope_info->ContextLocalMode(var);
512 *init_flag = scope_info->ContextLocalInitFlag(var); 549 *init_flag = scope_info->ContextLocalInitFlag(var);
513 *maybe_assigned_flag = scope_info->ContextLocalMaybeAssignedFlag(var); 550 *maybe_assigned_flag = scope_info->ContextLocalMaybeAssignedFlag(var);
514 result = Context::MIN_CONTEXT_SLOTS + var; 551
515 context_slot_cache->Update(scope_info, name, *mode, *init_flag, 552 if (var < scope_info->ContextLocalCount()) {
516 *maybe_assigned_flag, result); 553 *context_slot_kind = ContextSlotKindFlag::kLocal;
554 result = Context::MIN_CONTEXT_SLOTS + var;
555 } else {
556 var -= scope_info->ContextLocalCount();
557 *context_slot_kind = ContextSlotKindFlag::kGlobal;
558 result = Context::MIN_CONTEXT_SLOTS +
559 scope_info->ContextLocalCount() + 2 * var;
560 }
561
562 context_slot_cache->Update(scope_info, name, *mode, *context_slot_kind,
563 *init_flag, *maybe_assigned_flag, result);
517 DCHECK(result < scope_info->ContextLength()); 564 DCHECK(result < scope_info->ContextLength());
518 return result; 565 return result;
519 } 566 }
520 } 567 }
521 // Cache as not found. Mode, init flag and maybe assigned flag don't matter. 568 // Cache as not found. Mode, init flag and maybe assigned flag don't matter.
522 context_slot_cache->Update(scope_info, name, INTERNAL, kNeedsInitialization, 569 context_slot_cache->Update(scope_info, name, INTERNAL,
523 kNotAssigned, -1); 570 ContextSlotKindFlag::kLocal,
571 kNeedsInitialization, kNotAssigned, -1);
524 } 572 }
525 return -1; 573 return -1;
526 } 574 }
527 575
528 576
529 int ScopeInfo::ParameterIndex(String* name) { 577 int ScopeInfo::ParameterIndex(String* name) {
530 DCHECK(name->IsInternalizedString()); 578 DCHECK(name->IsInternalizedString());
531 if (length() > 0) { 579 if (length() > 0) {
532 // We must read parameters from the end since for 580 // We must read parameters from the end since for
533 // multiply declared parameters the value of the 581 // multiply declared parameters the value of the
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 int ScopeInfo::StackLocalEntriesIndex() { 663 int ScopeInfo::StackLocalEntriesIndex() {
616 return StackLocalFirstSlotIndex() + 1; 664 return StackLocalFirstSlotIndex() + 1;
617 } 665 }
618 666
619 667
620 int ScopeInfo::ContextLocalNameEntriesIndex() { 668 int ScopeInfo::ContextLocalNameEntriesIndex() {
621 return StackLocalEntriesIndex() + StackLocalCount(); 669 return StackLocalEntriesIndex() + StackLocalCount();
622 } 670 }
623 671
624 672
673 int ScopeInfo::ContextGlobalNameEntriesIndex() {
674 return ContextLocalNameEntriesIndex() + ContextLocalCount();
675 }
676
677
625 int ScopeInfo::ContextLocalInfoEntriesIndex() { 678 int ScopeInfo::ContextLocalInfoEntriesIndex() {
626 return ContextLocalNameEntriesIndex() + ContextLocalCount(); 679 return ContextGlobalNameEntriesIndex() + ContextGlobalCount();
680 }
681
682
683 int ScopeInfo::ContextGlobalInfoEntriesIndex() {
684 return ContextLocalInfoEntriesIndex() + ContextLocalCount();
627 } 685 }
628 686
629 687
630 int ScopeInfo::StrongModeFreeVariableNameEntriesIndex() { 688 int ScopeInfo::StrongModeFreeVariableNameEntriesIndex() {
631 return ContextLocalInfoEntriesIndex() + ContextLocalCount(); 689 return ContextGlobalInfoEntriesIndex() + ContextGlobalCount();
632 } 690 }
633 691
634 692
635 int ScopeInfo::StrongModeFreeVariablePositionEntriesIndex() { 693 int ScopeInfo::StrongModeFreeVariablePositionEntriesIndex() {
636 return StrongModeFreeVariableNameEntriesIndex() + 694 return StrongModeFreeVariableNameEntriesIndex() +
637 StrongModeFreeVariableCount(); 695 StrongModeFreeVariableCount();
638 } 696 }
639 697
640 698
641 int ScopeInfo::ReceiverEntryIndex() { 699 int ScopeInfo::ReceiverEntryIndex() {
642 return StrongModeFreeVariablePositionEntriesIndex() + 700 return StrongModeFreeVariablePositionEntriesIndex() +
643 2 * StrongModeFreeVariableCount(); 701 2 * StrongModeFreeVariableCount();
644 } 702 }
645 703
646 704
647 int ScopeInfo::FunctionNameEntryIndex() { 705 int ScopeInfo::FunctionNameEntryIndex() {
648 return ReceiverEntryIndex() + (HasAllocatedReceiver() ? 1 : 0); 706 return ReceiverEntryIndex() + (HasAllocatedReceiver() ? 1 : 0);
649 } 707 }
650 708
651 709
652 int ContextSlotCache::Hash(Object* data, String* name) { 710 int ContextSlotCache::Hash(Object* data, String* name) {
653 // Uses only lower 32 bits if pointers are larger. 711 // Uses only lower 32 bits if pointers are larger.
654 uintptr_t addr_hash = 712 uintptr_t addr_hash =
655 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2; 713 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2;
656 return static_cast<int>((addr_hash ^ name->Hash()) % kLength); 714 return static_cast<int>((addr_hash ^ name->Hash()) % kLength);
657 } 715 }
658 716
659 717
660 int ContextSlotCache::Lookup(Object* data, String* name, VariableMode* mode, 718 int ContextSlotCache::Lookup(Object* data, String* name, VariableMode* mode,
719 ContextSlotKindFlag* context_slot_kind,
661 InitializationFlag* init_flag, 720 InitializationFlag* init_flag,
662 MaybeAssignedFlag* maybe_assigned_flag) { 721 MaybeAssignedFlag* maybe_assigned_flag) {
663 int index = Hash(data, name); 722 int index = Hash(data, name);
664 Key& key = keys_[index]; 723 Key& key = keys_[index];
665 if ((key.data == data) && key.name->Equals(name)) { 724 if ((key.data == data) && key.name->Equals(name)) {
666 Value result(values_[index]); 725 Value result(values_[index]);
667 if (mode != NULL) *mode = result.mode(); 726 if (mode != NULL) *mode = result.mode();
727 if (context_slot_kind != NULL)
728 *context_slot_kind = result.context_slot_kind();
668 if (init_flag != NULL) *init_flag = result.initialization_flag(); 729 if (init_flag != NULL) *init_flag = result.initialization_flag();
669 if (maybe_assigned_flag != NULL) 730 if (maybe_assigned_flag != NULL)
670 *maybe_assigned_flag = result.maybe_assigned_flag(); 731 *maybe_assigned_flag = result.maybe_assigned_flag();
671 return result.index() + kNotFound; 732 return result.index() + kNotFound;
672 } 733 }
673 return kNotFound; 734 return kNotFound;
674 } 735 }
675 736
676 737
677 void ContextSlotCache::Update(Handle<Object> data, Handle<String> name, 738 void ContextSlotCache::Update(Handle<Object> data, Handle<String> name,
678 VariableMode mode, InitializationFlag init_flag, 739 VariableMode mode,
740 ContextSlotKindFlag context_slot_kind,
741 InitializationFlag init_flag,
679 MaybeAssignedFlag maybe_assigned_flag, 742 MaybeAssignedFlag maybe_assigned_flag,
680 int slot_index) { 743 int slot_index) {
681 DisallowHeapAllocation no_gc; 744 DisallowHeapAllocation no_gc;
682 Handle<String> internalized_name; 745 Handle<String> internalized_name;
683 DCHECK(slot_index > kNotFound); 746 DCHECK(slot_index > kNotFound);
684 if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name). 747 if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name).
685 ToHandle(&internalized_name)) { 748 ToHandle(&internalized_name)) {
686 int index = Hash(*data, *internalized_name); 749 int index = Hash(*data, *internalized_name);
687 Key& key = keys_[index]; 750 Key& key = keys_[index];
688 key.data = *data; 751 key.data = *data;
689 key.name = *internalized_name; 752 key.name = *internalized_name;
690 // Please note value only takes a uint as index. 753 // Please note value only takes a uint as index.
691 values_[index] = Value(mode, init_flag, maybe_assigned_flag, 754 values_[index] = Value(mode, context_slot_kind, init_flag,
692 slot_index - kNotFound).raw(); 755 maybe_assigned_flag, slot_index - kNotFound).raw();
693 #ifdef DEBUG 756 #ifdef DEBUG
694 ValidateEntry(data, name, mode, init_flag, maybe_assigned_flag, slot_index); 757 ValidateEntry(data, name, mode, context_slot_kind, init_flag,
758 maybe_assigned_flag, slot_index);
695 #endif 759 #endif
696 } 760 }
697 } 761 }
698 762
699 763
700 void ContextSlotCache::Clear() { 764 void ContextSlotCache::Clear() {
701 for (int index = 0; index < kLength; index++) keys_[index].data = NULL; 765 for (int index = 0; index < kLength; index++) keys_[index].data = NULL;
702 } 766 }
703 767
704 768
705 #ifdef DEBUG 769 #ifdef DEBUG
706 770
707 void ContextSlotCache::ValidateEntry(Handle<Object> data, Handle<String> name, 771 void ContextSlotCache::ValidateEntry(Handle<Object> data, Handle<String> name,
708 VariableMode mode, 772 VariableMode mode,
773 ContextSlotKindFlag context_slot_kind,
709 InitializationFlag init_flag, 774 InitializationFlag init_flag,
710 MaybeAssignedFlag maybe_assigned_flag, 775 MaybeAssignedFlag maybe_assigned_flag,
711 int slot_index) { 776 int slot_index) {
712 DisallowHeapAllocation no_gc; 777 DisallowHeapAllocation no_gc;
713 Handle<String> internalized_name; 778 Handle<String> internalized_name;
714 if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name). 779 if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name).
715 ToHandle(&internalized_name)) { 780 ToHandle(&internalized_name)) {
716 int index = Hash(*data, *name); 781 int index = Hash(*data, *name);
717 Key& key = keys_[index]; 782 Key& key = keys_[index];
718 DCHECK(key.data == *data); 783 DCHECK(key.data == *data);
719 DCHECK(key.name->Equals(*name)); 784 DCHECK(key.name->Equals(*name));
720 Value result(values_[index]); 785 Value result(values_[index]);
721 DCHECK(result.mode() == mode); 786 DCHECK(result.mode() == mode);
787 DCHECK(result.context_slot_kind() == context_slot_kind);
722 DCHECK(result.initialization_flag() == init_flag); 788 DCHECK(result.initialization_flag() == init_flag);
723 DCHECK(result.maybe_assigned_flag() == maybe_assigned_flag); 789 DCHECK(result.maybe_assigned_flag() == maybe_assigned_flag);
724 DCHECK(result.index() + kNotFound == slot_index); 790 DCHECK(result.index() + kNotFound == slot_index);
725 } 791 }
726 } 792 }
727 793
728 794
729 static void PrintList(const char* list_name, 795 static void PrintList(const char* list_name,
730 int nof_internal_slots, 796 int nof_internal_slots,
731 int start, 797 int start,
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
789 info->set_mode(i, var->mode()); 855 info->set_mode(i, var->mode());
790 DCHECK(var->index() >= 0); 856 DCHECK(var->index() >= 0);
791 info->set_index(i, var->index()); 857 info->set_index(i, var->index());
792 } 858 }
793 DCHECK(i == info->length()); 859 DCHECK(i == info->length());
794 return info; 860 return info;
795 } 861 }
796 862
797 } // namespace internal 863 } // namespace internal
798 } // namespace v8 864 } // namespace v8
OLDNEW
« src/runtime/runtime-scopes.cc ('K') | « src/scopeinfo.h ('k') | src/scopes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698