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

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: More cleanup 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
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); 30 // DCHECK(scope->StackLocalCount() >= stack_local_count);
rossberg 2015/04/17 15:16:27 What about this?
Dmitry Lomov (no reviews) 2015/04/20 11:53:21 These are incorrect
31 DCHECK(scope->ContextLocalCount() == context_local_count); 31 DCHECK(scope->ContextLocalCount() == context_local_count);
32 32
33 bool simple_parameter_list = 33 bool simple_parameter_list =
34 scope->is_function_scope() ? scope->is_simple_parameter_list() : true; 34 scope->is_function_scope() ? scope->is_simple_parameter_list() : true;
35 35
36 // Determine use and location of the function variable if it is present. 36 // Determine use and location of the function variable if it is present.
37 FunctionVariableInfo function_name_info; 37 FunctionVariableInfo function_name_info;
38 VariableMode function_variable_mode; 38 VariableMode function_variable_mode;
39 if (scope->is_function_scope() && scope->function() != NULL) { 39 if (scope->is_function_scope() && scope->function() != NULL) {
40 Variable* var = scope->function()->proxy()->var(); 40 Variable* var = scope->function()->proxy()->var();
41 if (!var->is_used()) { 41 if (!var->is_used()) {
42 function_name_info = UNUSED; 42 function_name_info = UNUSED;
43 } else if (var->IsContextSlot()) { 43 } else if (var->IsContextSlot()) {
44 function_name_info = CONTEXT; 44 function_name_info = CONTEXT;
45 } else { 45 } else {
46 DCHECK(var->IsStackLocal()); 46 DCHECK(var->IsStackLocal());
47 function_name_info = STACK; 47 function_name_info = STACK;
48 } 48 }
49 function_variable_mode = var->mode(); 49 function_variable_mode = var->mode();
50 } else { 50 } else {
51 function_name_info = NONE; 51 function_name_info = NONE;
52 function_variable_mode = VAR; 52 function_variable_mode = VAR;
53 } 53 }
54 54
55 const bool has_function_name = function_name_info != NONE; 55 const bool has_function_name = function_name_info != NONE;
56 const int parameter_count = scope->num_parameters(); 56 const int parameter_count = scope->num_parameters();
57 const int length = kVariablePartIndex + parameter_count + stack_local_count + 57 const int length = kVariablePartIndex + parameter_count +
58 2 * context_local_count + 58 (1 + stack_local_count) + 2 * context_local_count +
59 3 * strong_mode_free_variable_count + 59 3 * strong_mode_free_variable_count +
60 (has_function_name ? 2 : 0); 60 (has_function_name ? 2 : 0);
61 61
62 Factory* factory = isolate->factory(); 62 Factory* factory = isolate->factory();
63 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); 63 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
64 64
65 // Encode the flags. 65 // Encode the flags.
66 int flags = ScopeTypeField::encode(scope->scope_type()) | 66 int flags = ScopeTypeField::encode(scope->scope_type()) |
67 CallsEvalField::encode(scope->calls_eval()) | 67 CallsEvalField::encode(scope->calls_eval()) |
68 LanguageModeField::encode(scope->language_mode()) | 68 LanguageModeField::encode(scope->language_mode()) |
(...skipping 13 matching lines...) Expand all
82 int index = kVariablePartIndex; 82 int index = kVariablePartIndex;
83 // Add parameters. 83 // Add parameters.
84 DCHECK(index == scope_info->ParameterEntriesIndex()); 84 DCHECK(index == scope_info->ParameterEntriesIndex());
85 for (int i = 0; i < parameter_count; ++i) { 85 for (int i = 0; i < parameter_count; ++i) {
86 scope_info->set(index++, *scope->parameter(i)->name()); 86 scope_info->set(index++, *scope->parameter(i)->name());
87 } 87 }
88 88
89 // Add stack locals' names. We are assuming that the stack locals' 89 // Add stack locals' names. We are assuming that the stack locals'
90 // slots are allocated in increasing order, so we can simply add 90 // slots are allocated in increasing order, so we can simply add
91 // them to the ScopeInfo object. 91 // them to the ScopeInfo object.
92 int first_slot_index;
93 if (stack_local_count > 0) {
94 first_slot_index = stack_locals[0]->index();
95 } else {
96 first_slot_index = 0;
97 }
98 DCHECK(index == scope_info->StackLocalFirstSlotIndex());
99 scope_info->set(index++, Smi::FromInt(first_slot_index));
92 DCHECK(index == scope_info->StackLocalEntriesIndex()); 100 DCHECK(index == scope_info->StackLocalEntriesIndex());
93 for (int i = 0; i < stack_local_count; ++i) { 101 for (int i = 0; i < stack_local_count; ++i) {
94 DCHECK(stack_locals[i]->index() == i); 102 DCHECK(stack_locals[i]->index() == first_slot_index + i);
95 scope_info->set(index++, *stack_locals[i]->name()); 103 scope_info->set(index++, *stack_locals[i]->name());
96 } 104 }
97 105
98 // Due to usage analysis, context-allocated locals are not necessarily in 106 // Due to usage analysis, context-allocated locals are not necessarily in
99 // increasing order: Some of them may be parameters which are allocated before 107 // increasing order: Some of them may be parameters which are allocated before
100 // the non-parameter locals. When the non-parameter locals are sorted 108 // the non-parameter locals. When the non-parameter locals are sorted
101 // according to usage, the allocated slot indices may not be in increasing 109 // 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 110 // 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. 111 // context slot index before adding them to the ScopeInfo object.
104 context_locals.Sort(&Variable::CompareIndex); 112 context_locals.Sort(&Variable::CompareIndex);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 ->strong_mode_reference_end_position())); 146 ->strong_mode_reference_end_position()));
139 scope_info->set(index++, *end_position); 147 scope_info->set(index++, *end_position);
140 } 148 }
141 149
142 // If present, add the function variable name and its index. 150 // If present, add the function variable name and its index.
143 DCHECK(index == scope_info->FunctionNameEntryIndex()); 151 DCHECK(index == scope_info->FunctionNameEntryIndex());
144 if (has_function_name) { 152 if (has_function_name) {
145 int var_index = scope->function()->proxy()->var()->index(); 153 int var_index = scope->function()->proxy()->var()->index();
146 scope_info->set(index++, *scope->function()->proxy()->name()); 154 scope_info->set(index++, *scope->function()->proxy()->name());
147 scope_info->set(index++, Smi::FromInt(var_index)); 155 scope_info->set(index++, Smi::FromInt(var_index));
156 /*
rossberg 2015/04/17 15:16:27 TODO?
Dmitry Lomov (no reviews) 2015/04/20 11:53:20 Done.
148 DCHECK(function_name_info != STACK || 157 DCHECK(function_name_info != STACK ||
149 (var_index == scope_info->StackLocalCount() && 158 (var_index == scope_info->StackLocalCount() &&
150 var_index == scope_info->StackSlotCount() - 1)); 159 var_index == scope_info->StackSlotCount() - 1));
160 */
151 DCHECK(function_name_info != CONTEXT || 161 DCHECK(function_name_info != CONTEXT ||
152 var_index == scope_info->ContextLength() - 1); 162 var_index == scope_info->ContextLength() - 1);
153 } 163 }
154 164
155 DCHECK(index == scope_info->length()); 165 DCHECK(index == scope_info->length());
156 DCHECK(scope->num_parameters() == scope_info->ParameterCount()); 166 DCHECK(scope->num_parameters() == scope_info->ParameterCount());
157 DCHECK(scope->num_stack_slots() == scope_info->StackSlotCount()); 167 // DCHECK(scope->is_block_scope() || scope->num_stack_slots() ==
rossberg 2015/04/17 15:16:27 TODO?
Dmitry Lomov (no reviews) 2015/04/20 11:53:21 Done.
168 // scope_info->StackSlotCount());
158 DCHECK(scope->num_heap_slots() == scope_info->ContextLength() || 169 DCHECK(scope->num_heap_slots() == scope_info->ContextLength() ||
159 (scope->num_heap_slots() == kVariablePartIndex && 170 (scope->num_heap_slots() == kVariablePartIndex &&
160 scope_info->ContextLength() == 0)); 171 scope_info->ContextLength() == 0));
161 return scope_info; 172 return scope_info;
162 } 173 }
163 174
164 175
165 ScopeInfo* ScopeInfo::Empty(Isolate* isolate) { 176 ScopeInfo* ScopeInfo::Empty(Isolate* isolate) {
166 return reinterpret_cast<ScopeInfo*>(isolate->heap()->empty_fixed_array()); 177 return reinterpret_cast<ScopeInfo*>(isolate->heap()->empty_fixed_array());
167 } 178 }
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 } 273 }
263 274
264 275
265 String* ScopeInfo::StackLocalName(int var) { 276 String* ScopeInfo::StackLocalName(int var) {
266 DCHECK(0 <= var && var < StackLocalCount()); 277 DCHECK(0 <= var && var < StackLocalCount());
267 int info_index = StackLocalEntriesIndex() + var; 278 int info_index = StackLocalEntriesIndex() + var;
268 return String::cast(get(info_index)); 279 return String::cast(get(info_index));
269 } 280 }
270 281
271 282
283 int ScopeInfo::StackLocalIndex(int var) {
284 DCHECK(0 <= var && var < StackLocalCount());
285 int first_slot_index = Smi::cast(get(StackLocalFirstSlotIndex()))->value();
286 return first_slot_index + var;
287 }
288
289
272 String* ScopeInfo::ContextLocalName(int var) { 290 String* ScopeInfo::ContextLocalName(int var) {
273 DCHECK(0 <= var && var < ContextLocalCount()); 291 DCHECK(0 <= var && var < ContextLocalCount());
274 int info_index = ContextLocalNameEntriesIndex() + var; 292 int info_index = ContextLocalNameEntriesIndex() + var;
275 return String::cast(get(info_index)); 293 return String::cast(get(info_index));
276 } 294 }
277 295
278 296
279 VariableMode ScopeInfo::ContextLocalMode(int var) { 297 VariableMode ScopeInfo::ContextLocalMode(int var) {
280 DCHECK(0 <= var && var < ContextLocalCount()); 298 DCHECK(0 <= var && var < ContextLocalCount());
281 int info_index = ContextLocalInfoEntriesIndex() + var; 299 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); 354 bool ok = get(info_index)->ToInt32(&value);
337 USE(ok); 355 USE(ok);
338 DCHECK(ok); 356 DCHECK(ok);
339 return value; 357 return value;
340 } 358 }
341 359
342 360
343 int ScopeInfo::StackSlotIndex(String* name) { 361 int ScopeInfo::StackSlotIndex(String* name) {
344 DCHECK(name->IsInternalizedString()); 362 DCHECK(name->IsInternalizedString());
345 if (length() > 0) { 363 if (length() > 0) {
364 int first_slot_index = Smi::cast(get(StackLocalFirstSlotIndex()))->value();
346 int start = StackLocalEntriesIndex(); 365 int start = StackLocalEntriesIndex();
347 int end = StackLocalEntriesIndex() + StackLocalCount(); 366 int end = StackLocalEntriesIndex() + StackLocalCount();
348 for (int i = start; i < end; ++i) { 367 for (int i = start; i < end; ++i) {
349 if (name == get(i)) { 368 if (name == get(i)) {
350 return i - start; 369 return i - start + first_slot_index;
351 } 370 }
352 } 371 }
353 } 372 }
354 return -1; 373 return -1;
355 } 374 }
356 375
357 376
358 int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info, 377 int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info,
359 Handle<String> name, VariableMode* mode, 378 Handle<String> name, VariableMode* mode,
360 InitializationFlag* init_flag, 379 InitializationFlag* init_flag,
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 int local_count = scope_info->ContextLocalCount(); 466 int local_count = scope_info->ContextLocalCount();
448 if (local_count == 0) return true; 467 if (local_count == 0) return true;
449 // Fill all context locals to the context extension. 468 // Fill all context locals to the context extension.
450 int first_context_var = scope_info->StackLocalCount(); 469 int first_context_var = scope_info->StackLocalCount();
451 int start = scope_info->ContextLocalNameEntriesIndex(); 470 int start = scope_info->ContextLocalNameEntriesIndex();
452 for (int i = 0; i < local_count; ++i) { 471 for (int i = 0; i < local_count; ++i) {
453 if (scope_info->LocalIsSynthetic(first_context_var + i)) continue; 472 if (scope_info->LocalIsSynthetic(first_context_var + i)) continue;
454 int context_index = Context::MIN_CONTEXT_SLOTS + i; 473 int context_index = Context::MIN_CONTEXT_SLOTS + i;
455 Handle<Object> value = Handle<Object>(context->get(context_index), isolate); 474 Handle<Object> value = Handle<Object>(context->get(context_index), isolate);
456 // Do not reflect variables under TDZ in scope object. 475 // Do not reflect variables under TDZ in scope object.
457 if (value->IsTheHole()) continue; 476 if (value->IsTheHole()) {
477 value = isolate->factory()->undefined_value();
rossberg 2015/04/17 15:16:27 Same as earlier (also, the comment now is out of s
Dmitry Lomov (no reviews) 2015/04/20 11:53:21 Removed. This is not needed.
478 }
458 RETURN_ON_EXCEPTION_VALUE( 479 RETURN_ON_EXCEPTION_VALUE(
459 isolate, Runtime::DefineObjectProperty( 480 isolate, Runtime::DefineObjectProperty(
460 scope_object, 481 scope_object,
461 Handle<String>(String::cast(scope_info->get(i + start))), 482 Handle<String>(String::cast(scope_info->get(i + start))),
462 value, ::NONE), 483 value, ::NONE),
463 false); 484 false);
464 } 485 }
465 return true; 486 return true;
466 } 487 }
467 488
468 489
469 int ScopeInfo::ParameterEntriesIndex() { 490 int ScopeInfo::ParameterEntriesIndex() {
470 DCHECK(length() > 0); 491 DCHECK(length() > 0);
471 return kVariablePartIndex; 492 return kVariablePartIndex;
472 } 493 }
473 494
474 495
496 int ScopeInfo::StackLocalFirstSlotIndex() {
497 return ParameterEntriesIndex() + ParameterCount();
498 }
499
500
475 int ScopeInfo::StackLocalEntriesIndex() { 501 int ScopeInfo::StackLocalEntriesIndex() {
476 return ParameterEntriesIndex() + ParameterCount(); 502 return StackLocalFirstSlotIndex() + 1;
477 } 503 }
478 504
479 505
480 int ScopeInfo::ContextLocalNameEntriesIndex() { 506 int ScopeInfo::ContextLocalNameEntriesIndex() {
481 return StackLocalEntriesIndex() + StackLocalCount(); 507 return StackLocalEntriesIndex() + StackLocalCount();
482 } 508 }
483 509
484 510
485 int ScopeInfo::ContextLocalInfoEntriesIndex() { 511 int ScopeInfo::ContextLocalInfoEntriesIndex() {
486 return ContextLocalNameEntriesIndex() + ContextLocalCount(); 512 return ContextLocalNameEntriesIndex() + ContextLocalCount();
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 info->set_name(i, *(it.export_name()->string())); 669 info->set_name(i, *(it.export_name()->string()));
644 info->set_mode(i, var->mode()); 670 info->set_mode(i, var->mode());
645 DCHECK(var->index() >= 0); 671 DCHECK(var->index() >= 0);
646 info->set_index(i, var->index()); 672 info->set_index(i, var->index());
647 } 673 }
648 DCHECK(i == info->length()); 674 DCHECK(i == info->length());
649 return info; 675 return info;
650 } 676 }
651 677
652 } } // namespace v8::internal 678 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698