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

Side by Side Diff: src/scopes.cc

Issue 149245: Allow variable proxies for the same global variable to share the same... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 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 | Annotate | Revision Log
« no previous file with comments | « src/scopes.h ('k') | src/variables.h » ('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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 static bool Match(void* key1, void* key2) { 64 static bool Match(void* key1, void* key2) {
65 String* name1 = *reinterpret_cast<String**>(key1); 65 String* name1 = *reinterpret_cast<String**>(key1);
66 String* name2 = *reinterpret_cast<String**>(key2); 66 String* name2 = *reinterpret_cast<String**>(key2);
67 ASSERT(name1->IsSymbol()); 67 ASSERT(name1->IsSymbol());
68 ASSERT(name2->IsSymbol()); 68 ASSERT(name2->IsSymbol());
69 return name1 == name2; 69 return name1 == name2;
70 } 70 }
71 71
72 72
73 // Dummy constructor 73 // Dummy constructor
74 LocalsMap::LocalsMap(bool gotta_love_static_overloading) : HashMap() {} 74 VariableMap::VariableMap(bool gotta_love_static_overloading) : HashMap() {}
75 75
76 LocalsMap::LocalsMap() : HashMap(Match, &LocalsMapAllocator, 8) {} 76 VariableMap::VariableMap() : HashMap(Match, &LocalsMapAllocator, 8) {}
77 LocalsMap::~LocalsMap() {} 77 VariableMap::~VariableMap() {}
78 78
79 79
80 Variable* LocalsMap::Declare(Scope* scope, 80 Variable* VariableMap::Declare(Scope* scope,
81 Handle<String> name, 81 Handle<String> name,
82 Variable::Mode mode, 82 Variable::Mode mode,
83 bool is_valid_LHS, 83 bool is_valid_lhs,
84 Variable::Kind kind) { 84 Variable::Kind kind) {
85 HashMap::Entry* p = HashMap::Lookup(name.location(), name->Hash(), true); 85 HashMap::Entry* p = HashMap::Lookup(name.location(), name->Hash(), true);
86 if (p->value == NULL) { 86 if (p->value == NULL) {
87 // The variable has not been declared yet -> insert it. 87 // The variable has not been declared yet -> insert it.
88 ASSERT(p->key == name.location()); 88 ASSERT(p->key == name.location());
89 p->value = new Variable(scope, name, mode, is_valid_LHS, kind); 89 p->value = new Variable(scope, name, mode, is_valid_lhs, kind);
90 } 90 }
91 return reinterpret_cast<Variable*>(p->value); 91 return reinterpret_cast<Variable*>(p->value);
92 } 92 }
93 93
94 94
95 Variable* LocalsMap::Lookup(Handle<String> name) { 95 Variable* VariableMap::Lookup(Handle<String> name) {
96 HashMap::Entry* p = HashMap::Lookup(name.location(), name->Hash(), false); 96 HashMap::Entry* p = HashMap::Lookup(name.location(), name->Hash(), false);
97 if (p != NULL) { 97 if (p != NULL) {
98 ASSERT(*reinterpret_cast<String**>(p->key) == *name); 98 ASSERT(*reinterpret_cast<String**>(p->key) == *name);
99 ASSERT(p->value != NULL); 99 ASSERT(p->value != NULL);
100 return reinterpret_cast<Variable*>(p->value); 100 return reinterpret_cast<Variable*>(p->value);
101 } 101 }
102 return NULL; 102 return NULL;
103 } 103 }
104 104
105 105
106 // ---------------------------------------------------------------------------- 106 // ----------------------------------------------------------------------------
107 // Implementation of Scope 107 // Implementation of Scope
108 108
109 109
110 // Dummy constructor 110 // Dummy constructor
111 Scope::Scope() 111 Scope::Scope()
112 : inner_scopes_(0), 112 : inner_scopes_(0),
113 locals_(false), 113 variables_(false),
114 temps_(0), 114 temps_(0),
115 params_(0), 115 params_(0),
116 dynamics_(NULL), 116 dynamics_(NULL),
117 unresolved_(0), 117 unresolved_(0),
118 decls_(0) { 118 decls_(0) {
119 } 119 }
120 120
121 121
122 Scope::Scope(Scope* outer_scope, Type type) 122 Scope::Scope(Scope* outer_scope, Type type)
123 : outer_scope_(outer_scope), 123 : outer_scope_(outer_scope),
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 } 161 }
162 162
163 // Declare convenience variables. 163 // Declare convenience variables.
164 // Declare and allocate receiver (even for the global scope, and even 164 // Declare and allocate receiver (even for the global scope, and even
165 // if naccesses_ == 0). 165 // if naccesses_ == 0).
166 // NOTE: When loading parameters in the global scope, we must take 166 // NOTE: When loading parameters in the global scope, we must take
167 // care not to access them as properties of the global object, but 167 // care not to access them as properties of the global object, but
168 // instead load them directly from the stack. Currently, the only 168 // instead load them directly from the stack. Currently, the only
169 // such parameter is 'this' which is passed on the stack when 169 // such parameter is 'this' which is passed on the stack when
170 // invoking scripts 170 // invoking scripts
171 { Variable* var = 171 Variable* var =
172 locals_.Declare(this, Factory::this_symbol(), Variable::VAR, 172 variables_.Declare(this, Factory::this_symbol(), Variable::VAR,
173 false, Variable::THIS); 173 false, Variable::THIS);
174 var->rewrite_ = new Slot(var, Slot::PARAMETER, -1); 174 var->rewrite_ = new Slot(var, Slot::PARAMETER, -1);
175 receiver_ = new VariableProxy(Factory::this_symbol(), true, false); 175 receiver_ = new VariableProxy(Factory::this_symbol(), true, false);
176 receiver_->BindTo(var); 176 receiver_->BindTo(var);
177 }
178 177
179 if (is_function_scope()) { 178 if (is_function_scope()) {
180 // Declare 'arguments' variable which exists in all functions. 179 // Declare 'arguments' variable which exists in all functions.
181 // Note that it may never be accessed, in which case it won't 180 // Note that it might never be accessed, in which case it won't be
182 // be allocated during variable allocation. 181 // allocated during variable allocation.
183 locals_.Declare(this, Factory::arguments_symbol(), Variable::VAR, 182 variables_.Declare(this, Factory::arguments_symbol(), Variable::VAR,
184 true, Variable::ARGUMENTS); 183 true, Variable::ARGUMENTS);
185 } 184 }
186 } 185 }
187 186
188 187
189 188
190 Variable* Scope::LookupLocal(Handle<String> name) { 189 Variable* Scope::LocalLookup(Handle<String> name) {
191 return locals_.Lookup(name); 190 return variables_.Lookup(name);
192 } 191 }
193 192
194 193
195 Variable* Scope::Lookup(Handle<String> name) { 194 Variable* Scope::Lookup(Handle<String> name) {
196 for (Scope* scope = this; 195 for (Scope* scope = this;
197 scope != NULL; 196 scope != NULL;
198 scope = scope->outer_scope()) { 197 scope = scope->outer_scope()) {
199 Variable* var = scope->LookupLocal(name); 198 Variable* var = scope->LocalLookup(name);
200 if (var != NULL) return var; 199 if (var != NULL) return var;
201 } 200 }
202 return NULL; 201 return NULL;
203 } 202 }
204 203
205 204
206 Variable* Scope::DeclareFunctionVar(Handle<String> name) { 205 Variable* Scope::DeclareFunctionVar(Handle<String> name) {
207 ASSERT(is_function_scope() && function_ == NULL); 206 ASSERT(is_function_scope() && function_ == NULL);
208 function_ = new Variable(this, name, Variable::CONST, true, Variable::NORMAL); 207 function_ = new Variable(this, name, Variable::CONST, true, Variable::NORMAL);
209 return function_; 208 return function_;
210 } 209 }
211 210
212 211
213 Variable* Scope::Declare(Handle<String> name, Variable::Mode mode) { 212 Variable* Scope::DeclareLocal(Handle<String> name, Variable::Mode mode) {
214 // DYNAMIC variables are introduces during variable allocation, 213 // DYNAMIC variables are introduces during variable allocation,
215 // INTERNAL variables are allocated explicitly, and TEMPORARY 214 // INTERNAL variables are allocated explicitly, and TEMPORARY
216 // variables are allocated via NewTemporary(). 215 // variables are allocated via NewTemporary().
217 ASSERT(mode == Variable::VAR || mode == Variable::CONST); 216 ASSERT(mode == Variable::VAR || mode == Variable::CONST);
218 return locals_.Declare(this, name, mode, true, Variable::NORMAL); 217 return variables_.Declare(this, name, mode, true, Variable::NORMAL);
218 }
219
220
221 Variable* Scope::DeclareGlobal(Handle<String> name) {
222 ASSERT(is_global_scope());
223 return variables_.Declare(this, name, Variable::DYNAMIC, true,
224 Variable::NORMAL);
219 } 225 }
220 226
221 227
222 void Scope::AddParameter(Variable* var) { 228 void Scope::AddParameter(Variable* var) {
223 ASSERT(is_function_scope()); 229 ASSERT(is_function_scope());
224 ASSERT(LookupLocal(var->name()) == var); 230 ASSERT(LocalLookup(var->name()) == var);
225 params_.Add(var); 231 params_.Add(var);
226 } 232 }
227 233
228 234
229 VariableProxy* Scope::NewUnresolved(Handle<String> name, bool inside_with) { 235 VariableProxy* Scope::NewUnresolved(Handle<String> name, bool inside_with) {
230 // Note that we must not share the unresolved variables with 236 // Note that we must not share the unresolved variables with
231 // the same name because they may be removed selectively via 237 // the same name because they may be removed selectively via
232 // RemoveUnresolved(). 238 // RemoveUnresolved().
233 VariableProxy* proxy = new VariableProxy(name, false, inside_with); 239 VariableProxy* proxy = new VariableProxy(name, false, inside_with);
234 unresolved_.Add(proxy); 240 unresolved_.Add(proxy);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 // Collect variables in this scope. 290 // Collect variables in this scope.
285 // Note that the function_ variable - if present - is not 291 // Note that the function_ variable - if present - is not
286 // collected here but handled separately in ScopeInfo 292 // collected here but handled separately in ScopeInfo
287 // which is the current user of this function). 293 // which is the current user of this function).
288 for (int i = 0; i < temps_.length(); i++) { 294 for (int i = 0; i < temps_.length(); i++) {
289 Variable* var = temps_[i]; 295 Variable* var = temps_[i];
290 if (var->var_uses()->is_used()) { 296 if (var->var_uses()->is_used()) {
291 locals->Add(var); 297 locals->Add(var);
292 } 298 }
293 } 299 }
294 for (LocalsMap::Entry* p = locals_.Start(); p != NULL; p = locals_.Next(p)) { 300 for (VariableMap::Entry* p = variables_.Start();
301 p != NULL;
302 p = variables_.Next(p)) {
295 Variable* var = reinterpret_cast<Variable*>(p->value); 303 Variable* var = reinterpret_cast<Variable*>(p->value);
296 if (var->var_uses()->is_used()) { 304 if (var->var_uses()->is_used()) {
297 locals->Add(var); 305 locals->Add(var);
298 } 306 }
299 } 307 }
300 } 308 }
301 309
302 310
303 // Make sure the method gets instantiated by the template system. 311 // Make sure the method gets instantiated by the template system.
304 template void Scope::CollectUsedVariables( 312 template void Scope::CollectUsedVariables(
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 if (var->is_accessed_from_inner_scope()) PrintF("inner scope access, "); 411 if (var->is_accessed_from_inner_scope()) PrintF("inner scope access, ");
404 PrintF("var "); 412 PrintF("var ");
405 var->var_uses()->Print(); 413 var->var_uses()->Print();
406 PrintF(", obj "); 414 PrintF(", obj ");
407 var->obj_uses()->Print(); 415 var->obj_uses()->Print();
408 PrintF("\n"); 416 PrintF("\n");
409 } 417 }
410 } 418 }
411 419
412 420
413 static void PrintMap(PrettyPrinter* printer, int indent, LocalsMap* map) { 421 static void PrintMap(PrettyPrinter* printer, int indent, VariableMap* map) {
414 for (LocalsMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) { 422 for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) {
415 Variable* var = reinterpret_cast<Variable*>(p->value); 423 Variable* var = reinterpret_cast<Variable*>(p->value);
416 PrintVar(printer, indent, var); 424 PrintVar(printer, indent, var);
417 } 425 }
418 } 426 }
419 427
420 428
421 void Scope::Print(int n) { 429 void Scope::Print(int n) {
422 int n0 = (n > 0 ? n : 0); 430 int n0 = (n > 0 ? n : 0);
423 int n1 = n0 + 2; // indentation 431 int n1 = n0 + 2; // indentation
424 432
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 if (function_ != NULL) { 479 if (function_ != NULL) {
472 PrintVar(&printer, n1, function_); 480 PrintVar(&printer, n1, function_);
473 } 481 }
474 482
475 Indent(n1, "// temporary vars\n"); 483 Indent(n1, "// temporary vars\n");
476 for (int i = 0; i < temps_.length(); i++) { 484 for (int i = 0; i < temps_.length(); i++) {
477 PrintVar(&printer, n1, temps_[i]); 485 PrintVar(&printer, n1, temps_[i]);
478 } 486 }
479 487
480 Indent(n1, "// local vars\n"); 488 Indent(n1, "// local vars\n");
481 PrintMap(&printer, n1, &locals_); 489 PrintMap(&printer, n1, &variables_);
482 490
483 Indent(n1, "// dynamic vars\n"); 491 Indent(n1, "// dynamic vars\n");
484 if (dynamics_ != NULL) { 492 if (dynamics_ != NULL) {
485 PrintMap(&printer, n1, dynamics_->GetMap(Variable::DYNAMIC)); 493 PrintMap(&printer, n1, dynamics_->GetMap(Variable::DYNAMIC));
486 PrintMap(&printer, n1, dynamics_->GetMap(Variable::DYNAMIC_LOCAL)); 494 PrintMap(&printer, n1, dynamics_->GetMap(Variable::DYNAMIC_LOCAL));
487 PrintMap(&printer, n1, dynamics_->GetMap(Variable::DYNAMIC_GLOBAL)); 495 PrintMap(&printer, n1, dynamics_->GetMap(Variable::DYNAMIC_GLOBAL));
488 } 496 }
489 497
490 // Print inner scopes (disable by providing negative n). 498 // Print inner scopes (disable by providing negative n).
491 if (n >= 0) { 499 if (n >= 0) {
492 for (int i = 0; i < inner_scopes_.length(); i++) { 500 for (int i = 0; i < inner_scopes_.length(); i++) {
493 PrintF("\n"); 501 PrintF("\n");
494 inner_scopes_[i]->Print(n1); 502 inner_scopes_[i]->Print(n1);
495 } 503 }
496 } 504 }
497 505
498 Indent(n0, "}\n"); 506 Indent(n0, "}\n");
499 } 507 }
500 #endif // DEBUG 508 #endif // DEBUG
501 509
502 510
503 Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) { 511 Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) {
504 if (dynamics_ == NULL) dynamics_ = new DynamicScopePart(); 512 if (dynamics_ == NULL) dynamics_ = new DynamicScopePart();
505 LocalsMap* map = dynamics_->GetMap(mode); 513 VariableMap* map = dynamics_->GetMap(mode);
506 Variable* var = map->Lookup(name); 514 Variable* var = map->Lookup(name);
507 if (var == NULL) { 515 if (var == NULL) {
508 // Declare a new non-local. 516 // Declare a new non-local.
509 var = map->Declare(NULL, name, mode, true, Variable::NORMAL); 517 var = map->Declare(NULL, name, mode, true, Variable::NORMAL);
510 // Allocate it by giving it a dynamic lookup. 518 // Allocate it by giving it a dynamic lookup.
511 var->rewrite_ = new Slot(var, Slot::LOOKUP, -1); 519 var->rewrite_ = new Slot(var, Slot::LOOKUP, -1);
512 } 520 }
513 return var; 521 return var;
514 } 522 }
515 523
516 524
517 // Lookup a variable starting with this scope. The result is either 525 // Lookup a variable starting with this scope. The result is either
518 // the statically resolved (local!) variable belonging to an outer scope, 526 // the statically resolved (local!) variable belonging to an outer scope,
519 // or NULL. It may be NULL because a) we couldn't find a variable, or b) 527 // or NULL. It may be NULL because a) we couldn't find a variable, or b)
520 // because the variable is just a guess (and may be shadowed by another 528 // because the variable is just a guess (and may be shadowed by another
521 // variable that is introduced dynamically via an 'eval' call or a 'with' 529 // variable that is introduced dynamically via an 'eval' call or a 'with'
522 // statement). 530 // statement).
523 Variable* Scope::LookupRecursive(Handle<String> name, 531 Variable* Scope::LookupRecursive(Handle<String> name,
524 bool inner_lookup, 532 bool inner_lookup,
525 Variable** invalidated_local) { 533 Variable** invalidated_local) {
526 // If we find a variable, but the current scope calls 'eval', the found 534 // If we find a variable, but the current scope calls 'eval', the found
527 // variable may not be the correct one (the 'eval' may introduce a 535 // variable may not be the correct one (the 'eval' may introduce a
528 // property with the same name). In that case, remember that the variable 536 // property with the same name). In that case, remember that the variable
529 // found is just a guess. 537 // found is just a guess.
530 bool guess = scope_calls_eval_; 538 bool guess = scope_calls_eval_;
531 539
532 // Try to find the variable in this scope. 540 // Try to find the variable in this scope.
533 Variable* var = LookupLocal(name); 541 Variable* var = LocalLookup(name);
534 542
535 if (var != NULL) { 543 if (var != NULL) {
536 // We found a variable. If this is not an inner lookup, we are done. 544 // We found a variable. If this is not an inner lookup, we are done.
537 // (Even if there is an 'eval' in this scope which introduces the 545 // (Even if there is an 'eval' in this scope which introduces the
538 // same variable again, the resulting variable remains the same. 546 // same variable again, the resulting variable remains the same.
539 // Note that enclosing 'with' statements are handled at the call site.) 547 // Note that enclosing 'with' statements are handled at the call site.)
540 if (!inner_lookup) 548 if (!inner_lookup)
541 return var; 549 return var;
542 550
543 } else { 551 } else {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 // are outside a 'with' statement) or if there is no way 622 // are outside a 'with' statement) or if there is no way
615 // that the variable might be introduced dynamically (through 623 // that the variable might be introduced dynamically (through
616 // a local or outer eval() call, or an outer 'with' statement), 624 // a local or outer eval() call, or an outer 'with' statement),
617 // or we don't know about the outer scope (because we are 625 // or we don't know about the outer scope (because we are
618 // in an eval scope). 626 // in an eval scope).
619 if (is_global_scope() || 627 if (is_global_scope() ||
620 !(scope_inside_with_ || outer_scope_is_eval_scope_ || 628 !(scope_inside_with_ || outer_scope_is_eval_scope_ ||
621 scope_calls_eval_ || outer_scope_calls_eval_)) { 629 scope_calls_eval_ || outer_scope_calls_eval_)) {
622 // We must have a global variable. 630 // We must have a global variable.
623 ASSERT(global_scope != NULL); 631 ASSERT(global_scope != NULL);
624 var = new Variable(global_scope, proxy->name(), 632 var = global_scope->DeclareGlobal(proxy->name());
625 Variable::DYNAMIC, true, Variable::NORMAL);
626 633
627 } else if (scope_inside_with_) { 634 } else if (scope_inside_with_) {
628 // If we are inside a with statement we give up and look up 635 // If we are inside a with statement we give up and look up
629 // the variable at runtime. 636 // the variable at runtime.
630 var = NonLocal(proxy->name(), Variable::DYNAMIC); 637 var = NonLocal(proxy->name(), Variable::DYNAMIC);
631 638
632 } else if (invalidated_local != NULL) { 639 } else if (invalidated_local != NULL) {
633 // No with statements are involved and we found a local 640 // No with statements are involved and we found a local
634 // variable that might be shadowed by eval introduced 641 // variable that might be shadowed by eval introduced
635 // variables. 642 // variables.
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 if (inner_scope->force_eager_compilation_) { 706 if (inner_scope->force_eager_compilation_) {
700 force_eager_compilation_ = true; 707 force_eager_compilation_ = true;
701 } 708 }
702 } 709 }
703 710
704 return scope_calls_eval_ || inner_scope_calls_eval_; 711 return scope_calls_eval_ || inner_scope_calls_eval_;
705 } 712 }
706 713
707 714
708 bool Scope::MustAllocate(Variable* var) { 715 bool Scope::MustAllocate(Variable* var) {
709 // Give var a read/write use if there is a chance it might be 716 // Give var a read/write use if there is a chance it might be accessed
710 // accessed via an eval() call, or if it is a global variable. 717 // via an eval() call. This is only possible if the variable has a
711 // This is only possible if the variable has a visible name. 718 // visible name.
712 if ((var->is_this() || var->name()->length() > 0) && 719 if ((var->is_this() || var->name()->length() > 0) &&
713 (var->is_accessed_from_inner_scope_ || 720 (var->is_accessed_from_inner_scope_ ||
714 scope_calls_eval_ || inner_scope_calls_eval_ || 721 scope_calls_eval_ || inner_scope_calls_eval_ ||
715 scope_contains_with_ || var->is_global())) { 722 scope_contains_with_)) {
716 var->var_uses()->RecordAccess(1); 723 var->var_uses()->RecordAccess(1);
717 } 724 }
718 return var->var_uses()->is_used(); 725 // Global variables do not need to be allocated.
726 return !var->is_global() && var->var_uses()->is_used();
719 } 727 }
720 728
721 729
722 bool Scope::MustAllocateInContext(Variable* var) { 730 bool Scope::MustAllocateInContext(Variable* var) {
723 // If var is accessed from an inner scope, or if there is a 731 // If var is accessed from an inner scope, or if there is a
724 // possibility that it might be accessed from the current or 732 // possibility that it might be accessed from the current or an inner
725 // an inner scope (through an eval() call), it must be allocated 733 // scope (through an eval() call), it must be allocated in the
726 // in the context. 734 // context. Exception: temporary variables are not allocated in the
727 // Exceptions: Global variables and temporary variables must 735 // context.
728 // never be allocated in the (FixedArray part of the) context.
729 return 736 return
730 var->mode() != Variable::TEMPORARY && 737 var->mode() != Variable::TEMPORARY &&
731 (var->is_accessed_from_inner_scope_ || 738 (var->is_accessed_from_inner_scope_ ||
732 scope_calls_eval_ || inner_scope_calls_eval_ || 739 scope_calls_eval_ || inner_scope_calls_eval_ ||
733 scope_contains_with_ || var->is_global()); 740 scope_contains_with_ || var->is_global());
734 } 741 }
735 742
736 743
737 bool Scope::HasArgumentsParameter() { 744 bool Scope::HasArgumentsParameter() {
738 for (int i = 0; i < params_.length(); i++) { 745 for (int i = 0; i < params_.length(); i++) {
739 if (params_[i]->name().is_identical_to(Factory::arguments_symbol())) 746 if (params_[i]->name().is_identical_to(Factory::arguments_symbol()))
740 return true; 747 return true;
741 } 748 }
742 return false; 749 return false;
743 } 750 }
744 751
745 752
746 void Scope::AllocateStackSlot(Variable* var) { 753 void Scope::AllocateStackSlot(Variable* var) {
747 var->rewrite_ = new Slot(var, Slot::LOCAL, num_stack_slots_++); 754 var->rewrite_ = new Slot(var, Slot::LOCAL, num_stack_slots_++);
748 } 755 }
749 756
750 757
751 void Scope::AllocateHeapSlot(Variable* var) { 758 void Scope::AllocateHeapSlot(Variable* var) {
752 var->rewrite_ = new Slot(var, Slot::CONTEXT, num_heap_slots_++); 759 var->rewrite_ = new Slot(var, Slot::CONTEXT, num_heap_slots_++);
753 } 760 }
754 761
755 762
756 void Scope::AllocateParameterLocals() { 763 void Scope::AllocateParameterLocals() {
757 ASSERT(is_function_scope()); 764 ASSERT(is_function_scope());
758 Variable* arguments = LookupLocal(Factory::arguments_symbol()); 765 Variable* arguments = LocalLookup(Factory::arguments_symbol());
759 ASSERT(arguments != NULL); // functions have 'arguments' declared implicitly 766 ASSERT(arguments != NULL); // functions have 'arguments' declared implicitly
760 if (MustAllocate(arguments) && !HasArgumentsParameter()) { 767 if (MustAllocate(arguments) && !HasArgumentsParameter()) {
761 // 'arguments' is used. Unless there is also a parameter called 768 // 'arguments' is used. Unless there is also a parameter called
762 // 'arguments', we must be conservative and access all parameters via 769 // 'arguments', we must be conservative and access all parameters via
763 // the arguments object: The i'th parameter is rewritten into 770 // the arguments object: The i'th parameter is rewritten into
764 // '.arguments[i]' (*). If we have a parameter named 'arguments', a 771 // '.arguments[i]' (*). If we have a parameter named 'arguments', a
765 // (new) value is always assigned to it via the function 772 // (new) value is always assigned to it via the function
766 // invocation. Then 'arguments' denotes that specific parameter value 773 // invocation. Then 'arguments' denotes that specific parameter value
767 // and cannot be used to access the parameters, which is why we don't 774 // and cannot be used to access the parameters, which is why we don't
768 // need to rewrite in that case. 775 // need to rewrite in that case.
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
858 } 865 }
859 } 866 }
860 } 867 }
861 868
862 869
863 void Scope::AllocateNonParameterLocal(Variable* var) { 870 void Scope::AllocateNonParameterLocal(Variable* var) {
864 ASSERT(var->scope() == this); 871 ASSERT(var->scope() == this);
865 ASSERT(var->rewrite_ == NULL || 872 ASSERT(var->rewrite_ == NULL ||
866 (!var->IsVariable(Factory::result_symbol())) || 873 (!var->IsVariable(Factory::result_symbol())) ||
867 (var->slot() == NULL || var->slot()->type() != Slot::LOCAL)); 874 (var->slot() == NULL || var->slot()->type() != Slot::LOCAL));
868 if (MustAllocate(var) && var->rewrite_ == NULL) { 875 if (var->rewrite_ == NULL && MustAllocate(var)) {
869 if (MustAllocateInContext(var)) { 876 if (MustAllocateInContext(var)) {
870 AllocateHeapSlot(var); 877 AllocateHeapSlot(var);
871 } else { 878 } else {
872 AllocateStackSlot(var); 879 AllocateStackSlot(var);
873 } 880 }
874 } 881 }
875 } 882 }
876 883
877 884
878 void Scope::AllocateNonParameterLocals() { 885 void Scope::AllocateNonParameterLocals() {
879 // Each variable occurs exactly once in the locals_ list; all 886 // All variables that have no rewrite yet are non-parameter locals.
880 // variables that have no rewrite yet are non-parameter locals.
881
882 // Sort them according to use such that the locals with more uses
883 // get allocated first.
884 if (FLAG_usage_computation) {
885 // This is currently not implemented.
886 }
887
888 for (int i = 0; i < temps_.length(); i++) { 887 for (int i = 0; i < temps_.length(); i++) {
889 AllocateNonParameterLocal(temps_[i]); 888 AllocateNonParameterLocal(temps_[i]);
890 } 889 }
891 890
892 for (LocalsMap::Entry* p = locals_.Start(); p != NULL; p = locals_.Next(p)) { 891 for (VariableMap::Entry* p = variables_.Start();
892 p != NULL;
893 p = variables_.Next(p)) {
893 Variable* var = reinterpret_cast<Variable*>(p->value); 894 Variable* var = reinterpret_cast<Variable*>(p->value);
894 AllocateNonParameterLocal(var); 895 AllocateNonParameterLocal(var);
895 } 896 }
896 897
897 // Note: For now, function_ must be allocated at the very end. If 898 // For now, function_ must be allocated at the very end. If it gets
898 // it gets allocated in the context, it must be the last slot in the 899 // allocated in the context, it must be the last slot in the context,
899 // context, because of the current ScopeInfo implementation (see 900 // because of the current ScopeInfo implementation (see
900 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). 901 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
901 if (function_ != NULL) { 902 if (function_ != NULL) {
902 AllocateNonParameterLocal(function_); 903 AllocateNonParameterLocal(function_);
903 } 904 }
904 } 905 }
905 906
906 907
907 void Scope::AllocateVariablesRecursively() { 908 void Scope::AllocateVariablesRecursively() {
908 // The number of slots required for variables. 909 // The number of slots required for variables.
909 num_stack_slots_ = 0; 910 num_stack_slots_ = 0;
(...skipping 25 matching lines...) Expand all
935 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && 936 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS &&
936 !must_have_local_context) { 937 !must_have_local_context) {
937 num_heap_slots_ = 0; 938 num_heap_slots_ = 0;
938 } 939 }
939 940
940 // Allocation done. 941 // Allocation done.
941 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); 942 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
942 } 943 }
943 944
944 } } // namespace v8::internal 945 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/scopes.h ('k') | src/variables.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698