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

Side by Side Diff: src/scopeinfo.cc

Issue 981203003: Stack allocate lexical locals + hoist stack slots (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Feedback + rebased Created 5 years, 8 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
« no previous file with comments | « src/runtime/runtime-debug.cc ('k') | src/scopes.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/scopeinfo.h" 9 #include "src/scopeinfo.h"
10 #include "src/scopes.h" 10 #include "src/scopes.h"
11 11
12 namespace v8 { 12 namespace v8 {
13 namespace internal { 13 namespace internal {
14 14
15 15
16 Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, 16 Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
17 Scope* scope) { 17 Scope* scope) {
18 // Collect stack and context locals. 18 // Collect stack and context locals.
19 ZoneList<Variable*> stack_locals(scope->StackLocalCount(), zone); 19 ZoneList<Variable*> stack_locals(scope->StackLocalCount(), zone);
20 ZoneList<Variable*> context_locals(scope->ContextLocalCount(), zone); 20 ZoneList<Variable*> context_locals(scope->ContextLocalCount(), zone);
21 ZoneList<Variable*> strong_mode_free_variables(0, zone); 21 ZoneList<Variable*> strong_mode_free_variables(0, zone);
22 22
23 scope->CollectStackAndContextLocals(&stack_locals, &context_locals, 23 scope->CollectStackAndContextLocals(&stack_locals, &context_locals,
24 &strong_mode_free_variables); 24 &strong_mode_free_variables);
25 const int stack_local_count = stack_locals.length(); 25 const int stack_local_count = stack_locals.length();
26 const int context_local_count = context_locals.length(); 26 const int context_local_count = context_locals.length();
27 const int strong_mode_free_variable_count = 27 const int strong_mode_free_variable_count =
28 strong_mode_free_variables.length(); 28 strong_mode_free_variables.length();
29 // Make sure we allocate the correct amount. 29 // Make sure we allocate the correct amount.
30 DCHECK(scope->StackLocalCount() == stack_local_count);
31 DCHECK(scope->ContextLocalCount() == context_local_count); 30 DCHECK(scope->ContextLocalCount() == context_local_count);
32 31
33 bool simple_parameter_list = 32 bool simple_parameter_list =
34 scope->is_function_scope() ? scope->is_simple_parameter_list() : true; 33 scope->is_function_scope() ? scope->is_simple_parameter_list() : true;
35 34
36 // Determine use and location of the function variable if it is present. 35 // Determine use and location of the function variable if it is present.
37 FunctionVariableInfo function_name_info; 36 FunctionVariableInfo function_name_info;
38 VariableMode function_variable_mode; 37 VariableMode function_variable_mode;
39 if (scope->is_function_scope() && scope->function() != NULL) { 38 if (scope->is_function_scope() && scope->function() != NULL) {
40 Variable* var = scope->function()->proxy()->var(); 39 Variable* var = scope->function()->proxy()->var();
41 if (!var->is_used()) { 40 if (!var->is_used()) {
42 function_name_info = UNUSED; 41 function_name_info = UNUSED;
43 } else if (var->IsContextSlot()) { 42 } else if (var->IsContextSlot()) {
44 function_name_info = CONTEXT; 43 function_name_info = CONTEXT;
45 } else { 44 } else {
46 DCHECK(var->IsStackLocal()); 45 DCHECK(var->IsStackLocal());
47 function_name_info = STACK; 46 function_name_info = STACK;
48 } 47 }
49 function_variable_mode = var->mode(); 48 function_variable_mode = var->mode();
50 } else { 49 } else {
51 function_name_info = NONE; 50 function_name_info = NONE;
52 function_variable_mode = VAR; 51 function_variable_mode = VAR;
53 } 52 }
54 53
55 const bool has_function_name = function_name_info != NONE; 54 const bool has_function_name = function_name_info != NONE;
56 const int parameter_count = scope->num_parameters(); 55 const int parameter_count = scope->num_parameters();
57 const int length = kVariablePartIndex + parameter_count + stack_local_count + 56 const int length = kVariablePartIndex + parameter_count +
58 2 * context_local_count + 57 (1 + stack_local_count) + 2 * context_local_count +
59 3 * strong_mode_free_variable_count + 58 3 * strong_mode_free_variable_count +
60 (has_function_name ? 2 : 0); 59 (has_function_name ? 2 : 0);
61 60
62 Factory* factory = isolate->factory(); 61 Factory* factory = isolate->factory();
63 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); 62 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
64 63
65 // Encode the flags. 64 // Encode the flags.
66 int flags = ScopeTypeField::encode(scope->scope_type()) | 65 int flags = ScopeTypeField::encode(scope->scope_type()) |
67 CallsEvalField::encode(scope->calls_eval()) | 66 CallsEvalField::encode(scope->calls_eval()) |
68 LanguageModeField::encode(scope->language_mode()) | 67 LanguageModeField::encode(scope->language_mode()) |
(...skipping 13 matching lines...) Expand all
82 int index = kVariablePartIndex; 81 int index = kVariablePartIndex;
83 // Add parameters. 82 // Add parameters.
84 DCHECK(index == scope_info->ParameterEntriesIndex()); 83 DCHECK(index == scope_info->ParameterEntriesIndex());
85 for (int i = 0; i < parameter_count; ++i) { 84 for (int i = 0; i < parameter_count; ++i) {
86 scope_info->set(index++, *scope->parameter(i)->name()); 85 scope_info->set(index++, *scope->parameter(i)->name());
87 } 86 }
88 87
89 // Add stack locals' names. We are assuming that the stack locals' 88 // Add stack locals' names. We are assuming that the stack locals'
90 // slots are allocated in increasing order, so we can simply add 89 // slots are allocated in increasing order, so we can simply add
91 // them to the ScopeInfo object. 90 // them to the ScopeInfo object.
91 int first_slot_index;
92 if (stack_local_count > 0) {
93 first_slot_index = stack_locals[0]->index();
94 } else {
95 first_slot_index = 0;
96 }
97 DCHECK(index == scope_info->StackLocalFirstSlotIndex());
98 scope_info->set(index++, Smi::FromInt(first_slot_index));
92 DCHECK(index == scope_info->StackLocalEntriesIndex()); 99 DCHECK(index == scope_info->StackLocalEntriesIndex());
93 for (int i = 0; i < stack_local_count; ++i) { 100 for (int i = 0; i < stack_local_count; ++i) {
94 DCHECK(stack_locals[i]->index() == i); 101 DCHECK(stack_locals[i]->index() == first_slot_index + i);
95 scope_info->set(index++, *stack_locals[i]->name()); 102 scope_info->set(index++, *stack_locals[i]->name());
96 } 103 }
97 104
98 // Due to usage analysis, context-allocated locals are not necessarily in 105 // Due to usage analysis, context-allocated locals are not necessarily in
99 // increasing order: Some of them may be parameters which are allocated before 106 // increasing order: Some of them may be parameters which are allocated before
100 // the non-parameter locals. When the non-parameter locals are sorted 107 // the non-parameter locals. When the non-parameter locals are sorted
101 // according to usage, the allocated slot indices may not be in increasing 108 // according to usage, the allocated slot indices may not be in increasing
102 // order with the variable list anymore. Thus, we first need to sort them by 109 // order with the variable list anymore. Thus, we first need to sort them by
103 // context slot index before adding them to the ScopeInfo object. 110 // context slot index before adding them to the ScopeInfo object.
104 context_locals.Sort(&Variable::CompareIndex); 111 context_locals.Sort(&Variable::CompareIndex);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 ->strong_mode_reference_end_position())); 145 ->strong_mode_reference_end_position()));
139 scope_info->set(index++, *end_position); 146 scope_info->set(index++, *end_position);
140 } 147 }
141 148
142 // If present, add the function variable name and its index. 149 // If present, add the function variable name and its index.
143 DCHECK(index == scope_info->FunctionNameEntryIndex()); 150 DCHECK(index == scope_info->FunctionNameEntryIndex());
144 if (has_function_name) { 151 if (has_function_name) {
145 int var_index = scope->function()->proxy()->var()->index(); 152 int var_index = scope->function()->proxy()->var()->index();
146 scope_info->set(index++, *scope->function()->proxy()->name()); 153 scope_info->set(index++, *scope->function()->proxy()->name());
147 scope_info->set(index++, Smi::FromInt(var_index)); 154 scope_info->set(index++, Smi::FromInt(var_index));
148 DCHECK(function_name_info != STACK ||
149 (var_index == scope_info->StackLocalCount() &&
150 var_index == scope_info->StackSlotCount() - 1));
151 DCHECK(function_name_info != CONTEXT || 155 DCHECK(function_name_info != CONTEXT ||
152 var_index == scope_info->ContextLength() - 1); 156 var_index == scope_info->ContextLength() - 1);
153 } 157 }
154 158
155 DCHECK(index == scope_info->length()); 159 DCHECK(index == scope_info->length());
156 DCHECK(scope->num_parameters() == scope_info->ParameterCount()); 160 DCHECK(scope->num_parameters() == scope_info->ParameterCount());
157 DCHECK(scope->num_stack_slots() == scope_info->StackSlotCount());
158 DCHECK(scope->num_heap_slots() == scope_info->ContextLength() || 161 DCHECK(scope->num_heap_slots() == scope_info->ContextLength() ||
159 (scope->num_heap_slots() == kVariablePartIndex && 162 (scope->num_heap_slots() == kVariablePartIndex &&
160 scope_info->ContextLength() == 0)); 163 scope_info->ContextLength() == 0));
161 return scope_info; 164 return scope_info;
162 } 165 }
163 166
164 167
165 ScopeInfo* ScopeInfo::Empty(Isolate* isolate) { 168 ScopeInfo* ScopeInfo::Empty(Isolate* isolate) {
166 return reinterpret_cast<ScopeInfo*>(isolate->heap()->empty_fixed_array()); 169 return reinterpret_cast<ScopeInfo*>(isolate->heap()->empty_fixed_array());
167 } 170 }
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 } 265 }
263 266
264 267
265 String* ScopeInfo::StackLocalName(int var) { 268 String* ScopeInfo::StackLocalName(int var) {
266 DCHECK(0 <= var && var < StackLocalCount()); 269 DCHECK(0 <= var && var < StackLocalCount());
267 int info_index = StackLocalEntriesIndex() + var; 270 int info_index = StackLocalEntriesIndex() + var;
268 return String::cast(get(info_index)); 271 return String::cast(get(info_index));
269 } 272 }
270 273
271 274
275 int ScopeInfo::StackLocalIndex(int var) {
276 DCHECK(0 <= var && var < StackLocalCount());
277 int first_slot_index = Smi::cast(get(StackLocalFirstSlotIndex()))->value();
278 return first_slot_index + var;
279 }
280
281
272 String* ScopeInfo::ContextLocalName(int var) { 282 String* ScopeInfo::ContextLocalName(int var) {
273 DCHECK(0 <= var && var < ContextLocalCount()); 283 DCHECK(0 <= var && var < ContextLocalCount());
274 int info_index = ContextLocalNameEntriesIndex() + var; 284 int info_index = ContextLocalNameEntriesIndex() + var;
275 return String::cast(get(info_index)); 285 return String::cast(get(info_index));
276 } 286 }
277 287
278 288
279 VariableMode ScopeInfo::ContextLocalMode(int var) { 289 VariableMode ScopeInfo::ContextLocalMode(int var) {
280 DCHECK(0 <= var && var < ContextLocalCount()); 290 DCHECK(0 <= var && var < ContextLocalCount());
281 int info_index = ContextLocalInfoEntriesIndex() + var; 291 int info_index = ContextLocalInfoEntriesIndex() + var;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 bool ok = get(info_index)->ToInt32(&value); 346 bool ok = get(info_index)->ToInt32(&value);
337 USE(ok); 347 USE(ok);
338 DCHECK(ok); 348 DCHECK(ok);
339 return value; 349 return value;
340 } 350 }
341 351
342 352
343 int ScopeInfo::StackSlotIndex(String* name) { 353 int ScopeInfo::StackSlotIndex(String* name) {
344 DCHECK(name->IsInternalizedString()); 354 DCHECK(name->IsInternalizedString());
345 if (length() > 0) { 355 if (length() > 0) {
356 int first_slot_index = Smi::cast(get(StackLocalFirstSlotIndex()))->value();
346 int start = StackLocalEntriesIndex(); 357 int start = StackLocalEntriesIndex();
347 int end = StackLocalEntriesIndex() + StackLocalCount(); 358 int end = StackLocalEntriesIndex() + StackLocalCount();
348 for (int i = start; i < end; ++i) { 359 for (int i = start; i < end; ++i) {
349 if (name == get(i)) { 360 if (name == get(i)) {
350 return i - start; 361 return i - start + first_slot_index;
351 } 362 }
352 } 363 }
353 } 364 }
354 return -1; 365 return -1;
355 } 366 }
356 367
357 368
358 int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info, 369 int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info,
359 Handle<String> name, VariableMode* mode, 370 Handle<String> name, VariableMode* mode,
360 InitializationFlag* init_flag, 371 InitializationFlag* init_flag,
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 Isolate* isolate = scope_info->GetIsolate(); 457 Isolate* isolate = scope_info->GetIsolate();
447 int local_count = scope_info->ContextLocalCount(); 458 int local_count = scope_info->ContextLocalCount();
448 if (local_count == 0) return true; 459 if (local_count == 0) return true;
449 // Fill all context locals to the context extension. 460 // Fill all context locals to the context extension.
450 int first_context_var = scope_info->StackLocalCount(); 461 int first_context_var = scope_info->StackLocalCount();
451 int start = scope_info->ContextLocalNameEntriesIndex(); 462 int start = scope_info->ContextLocalNameEntriesIndex();
452 for (int i = 0; i < local_count; ++i) { 463 for (int i = 0; i < local_count; ++i) {
453 if (scope_info->LocalIsSynthetic(first_context_var + i)) continue; 464 if (scope_info->LocalIsSynthetic(first_context_var + i)) continue;
454 int context_index = Context::MIN_CONTEXT_SLOTS + i; 465 int context_index = Context::MIN_CONTEXT_SLOTS + i;
455 Handle<Object> value = Handle<Object>(context->get(context_index), isolate); 466 Handle<Object> value = Handle<Object>(context->get(context_index), isolate);
456 // Do not reflect variables under TDZ in scope object. 467 // Reflect variables under TDZ as undefined in scope object.
457 if (value->IsTheHole()) continue; 468 if (value->IsTheHole()) continue;
458 RETURN_ON_EXCEPTION_VALUE( 469 RETURN_ON_EXCEPTION_VALUE(
459 isolate, Runtime::DefineObjectProperty( 470 isolate, Runtime::DefineObjectProperty(
460 scope_object, 471 scope_object,
461 Handle<String>(String::cast(scope_info->get(i + start))), 472 Handle<String>(String::cast(scope_info->get(i + start))),
462 value, ::NONE), 473 value, ::NONE),
463 false); 474 false);
464 } 475 }
465 return true; 476 return true;
466 } 477 }
467 478
468 479
469 int ScopeInfo::ParameterEntriesIndex() { 480 int ScopeInfo::ParameterEntriesIndex() {
470 DCHECK(length() > 0); 481 DCHECK(length() > 0);
471 return kVariablePartIndex; 482 return kVariablePartIndex;
472 } 483 }
473 484
474 485
486 int ScopeInfo::StackLocalFirstSlotIndex() {
487 return ParameterEntriesIndex() + ParameterCount();
488 }
489
490
475 int ScopeInfo::StackLocalEntriesIndex() { 491 int ScopeInfo::StackLocalEntriesIndex() {
476 return ParameterEntriesIndex() + ParameterCount(); 492 return StackLocalFirstSlotIndex() + 1;
477 } 493 }
478 494
479 495
480 int ScopeInfo::ContextLocalNameEntriesIndex() { 496 int ScopeInfo::ContextLocalNameEntriesIndex() {
481 return StackLocalEntriesIndex() + StackLocalCount(); 497 return StackLocalEntriesIndex() + StackLocalCount();
482 } 498 }
483 499
484 500
485 int ScopeInfo::ContextLocalInfoEntriesIndex() { 501 int ScopeInfo::ContextLocalInfoEntriesIndex() {
486 return ContextLocalNameEntriesIndex() + ContextLocalCount(); 502 return ContextLocalNameEntriesIndex() + ContextLocalCount();
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 info->set_name(i, *(it.export_name()->string())); 659 info->set_name(i, *(it.export_name()->string()));
644 info->set_mode(i, var->mode()); 660 info->set_mode(i, var->mode());
645 DCHECK(var->index() >= 0); 661 DCHECK(var->index() >= 0);
646 info->set_index(i, var->index()); 662 info->set_index(i, var->index());
647 } 663 }
648 DCHECK(i == info->length()); 664 DCHECK(i == info->length());
649 return info; 665 return info;
650 } 666 }
651 667
652 } } // namespace v8::internal 668 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime/runtime-debug.cc ('k') | src/scopes.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698