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

Side by Side Diff: src/scopes.cc

Issue 147075: Allocate arguments object on-demand instead of at function entry.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 6 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
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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 LocalsMap::LocalsMap(bool gotta_love_static_overloading) : HashMap() {} 74 LocalsMap::LocalsMap(bool gotta_love_static_overloading) : HashMap() {}
75 75
76 LocalsMap::LocalsMap() : HashMap(Match, &LocalsMapAllocator, 8) {} 76 LocalsMap::LocalsMap() : HashMap(Match, &LocalsMapAllocator, 8) {}
77 LocalsMap::~LocalsMap() {} 77 LocalsMap::~LocalsMap() {}
78 78
79 79
80 Variable* LocalsMap::Declare(Scope* scope, 80 Variable* LocalsMap::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 bool is_this) { 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, is_this); 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* LocalsMap::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);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
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, false, true); 172 locals_.Declare(this, Factory::this_symbol(), Variable::VAR,
173 false, Variable::THIS);
173 var->rewrite_ = new Slot(var, Slot::PARAMETER, -1); 174 var->rewrite_ = new Slot(var, Slot::PARAMETER, -1);
174 receiver_ = new VariableProxy(Factory::this_symbol(), true, false); 175 receiver_ = new VariableProxy(Factory::this_symbol(), true, false);
175 receiver_->BindTo(var); 176 receiver_->BindTo(var);
176 } 177 }
177 178
178 if (is_function_scope()) { 179 if (is_function_scope()) {
179 // Declare 'arguments' variable which exists in all functions. 180 // Declare 'arguments' variable which exists in all functions.
180 // Note that it may never be accessed, in which case it won't 181 // Note that it may never be accessed, in which case it won't
181 // be allocated during variable allocation. 182 // be allocated during variable allocation.
182 Declare(Factory::arguments_symbol(), Variable::VAR); 183 locals_.Declare(this, Factory::arguments_symbol(), Variable::VAR,
184 true, Variable::ARGUMENTS);
183 } 185 }
184 } 186 }
185 187
186 188
187 189
188 Variable* Scope::LookupLocal(Handle<String> name) { 190 Variable* Scope::LookupLocal(Handle<String> name) {
189 return locals_.Lookup(name); 191 return locals_.Lookup(name);
190 } 192 }
191 193
192 194
193 Variable* Scope::Lookup(Handle<String> name) { 195 Variable* Scope::Lookup(Handle<String> name) {
194 for (Scope* scope = this; 196 for (Scope* scope = this;
195 scope != NULL; 197 scope != NULL;
196 scope = scope->outer_scope()) { 198 scope = scope->outer_scope()) {
197 Variable* var = scope->LookupLocal(name); 199 Variable* var = scope->LookupLocal(name);
198 if (var != NULL) return var; 200 if (var != NULL) return var;
199 } 201 }
200 return NULL; 202 return NULL;
201 } 203 }
202 204
203 205
204 Variable* Scope::DeclareFunctionVar(Handle<String> name) { 206 Variable* Scope::DeclareFunctionVar(Handle<String> name) {
205 ASSERT(is_function_scope() && function_ == NULL); 207 ASSERT(is_function_scope() && function_ == NULL);
206 function_ = new Variable(this, name, Variable::CONST, true, false); 208 function_ = new Variable(this, name, Variable::CONST, true, Variable::NORMAL);
207 return function_; 209 return function_;
208 } 210 }
209 211
210 212
211 Variable* Scope::Declare(Handle<String> name, Variable::Mode mode) { 213 Variable* Scope::Declare(Handle<String> name, Variable::Mode mode) {
212 // DYNAMIC variables are introduces during variable allocation, 214 // DYNAMIC variables are introduces during variable allocation,
213 // INTERNAL variables are allocated explicitly, and TEMPORARY 215 // INTERNAL variables are allocated explicitly, and TEMPORARY
214 // variables are allocated via NewTemporary(). 216 // variables are allocated via NewTemporary().
215 ASSERT(mode == Variable::VAR || mode == Variable::CONST); 217 ASSERT(mode == Variable::VAR || mode == Variable::CONST);
216 return locals_.Declare(this, name, mode, true, false); 218 return locals_.Declare(this, name, mode, true, Variable::NORMAL);
217 } 219 }
218 220
219 221
220 void Scope::AddParameter(Variable* var) { 222 void Scope::AddParameter(Variable* var) {
221 ASSERT(is_function_scope()); 223 ASSERT(is_function_scope());
222 ASSERT(LookupLocal(var->name()) == var); 224 ASSERT(LookupLocal(var->name()) == var);
223 params_.Add(var); 225 params_.Add(var);
224 } 226 }
225 227
226 228
(...skipping 13 matching lines...) Expand all
240 for (int i = unresolved_.length(); i-- > 0;) { 242 for (int i = unresolved_.length(); i-- > 0;) {
241 if (unresolved_[i] == var) { 243 if (unresolved_[i] == var) {
242 unresolved_.Remove(i); 244 unresolved_.Remove(i);
243 return; 245 return;
244 } 246 }
245 } 247 }
246 } 248 }
247 249
248 250
249 VariableProxy* Scope::NewTemporary(Handle<String> name) { 251 VariableProxy* Scope::NewTemporary(Handle<String> name) {
250 Variable* var = new Variable(this, name, Variable::TEMPORARY, true, false); 252 Variable* var = new Variable(this, name, Variable::TEMPORARY, true,
253 Variable::NORMAL);
251 VariableProxy* tmp = new VariableProxy(name, false, false); 254 VariableProxy* tmp = new VariableProxy(name, false, false);
252 tmp->BindTo(var); 255 tmp->BindTo(var);
253 temps_.Add(var); 256 temps_.Add(var);
254 return tmp; 257 return tmp;
255 } 258 }
256 259
257 260
258 void Scope::AddDeclaration(Declaration* declaration) { 261 void Scope::AddDeclaration(Declaration* declaration) {
259 decls_.Add(declaration); 262 decls_.Add(declaration);
260 } 263 }
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 } 499 }
497 #endif // DEBUG 500 #endif // DEBUG
498 501
499 502
500 Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) { 503 Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) {
501 if (dynamics_ == NULL) dynamics_ = new DynamicScopePart(); 504 if (dynamics_ == NULL) dynamics_ = new DynamicScopePart();
502 LocalsMap* map = dynamics_->GetMap(mode); 505 LocalsMap* map = dynamics_->GetMap(mode);
503 Variable* var = map->Lookup(name); 506 Variable* var = map->Lookup(name);
504 if (var == NULL) { 507 if (var == NULL) {
505 // Declare a new non-local. 508 // Declare a new non-local.
506 var = map->Declare(NULL, name, mode, true, false); 509 var = map->Declare(NULL, name, mode, true, Variable::NORMAL);
507 // Allocate it by giving it a dynamic lookup. 510 // Allocate it by giving it a dynamic lookup.
508 var->rewrite_ = new Slot(var, Slot::LOOKUP, -1); 511 var->rewrite_ = new Slot(var, Slot::LOOKUP, -1);
509 } 512 }
510 return var; 513 return var;
511 } 514 }
512 515
513 516
514 // Lookup a variable starting with this scope. The result is either 517 // Lookup a variable starting with this scope. The result is either
515 // the statically resolved (local!) variable belonging to an outer scope, 518 // the statically resolved (local!) variable belonging to an outer scope,
516 // or NULL. It may be NULL because a) we couldn't find a variable, or b) 519 // or NULL. It may be NULL because a) we couldn't find a variable, or b)
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 // that the variable might be introduced dynamically (through 615 // that the variable might be introduced dynamically (through
613 // a local or outer eval() call, or an outer 'with' statement), 616 // a local or outer eval() call, or an outer 'with' statement),
614 // or we don't know about the outer scope (because we are 617 // or we don't know about the outer scope (because we are
615 // in an eval scope). 618 // in an eval scope).
616 if (is_global_scope() || 619 if (is_global_scope() ||
617 !(scope_inside_with_ || outer_scope_is_eval_scope_ || 620 !(scope_inside_with_ || outer_scope_is_eval_scope_ ||
618 scope_calls_eval_ || outer_scope_calls_eval_)) { 621 scope_calls_eval_ || outer_scope_calls_eval_)) {
619 // We must have a global variable. 622 // We must have a global variable.
620 ASSERT(global_scope != NULL); 623 ASSERT(global_scope != NULL);
621 var = new Variable(global_scope, proxy->name(), 624 var = new Variable(global_scope, proxy->name(),
622 Variable::DYNAMIC, true, false); 625 Variable::DYNAMIC, true, Variable::NORMAL);
623 626
624 } else if (scope_inside_with_) { 627 } else if (scope_inside_with_) {
625 // If we are inside a with statement we give up and look up 628 // If we are inside a with statement we give up and look up
626 // the variable at runtime. 629 // the variable at runtime.
627 var = NonLocal(proxy->name(), Variable::DYNAMIC); 630 var = NonLocal(proxy->name(), Variable::DYNAMIC);
628 631
629 } else if (invalidated_local != NULL) { 632 } else if (invalidated_local != NULL) {
630 // No with statements are involved and we found a local 633 // No with statements are involved and we found a local
631 // variable that might be shadowed by eval introduced 634 // variable that might be shadowed by eval introduced
632 // variables. 635 // variables.
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
790 // and bind the corresponding proxy. It's ok to declare it only now 793 // and bind the corresponding proxy. It's ok to declare it only now
791 // because it's a local variable that is allocated after the parameters 794 // because it's a local variable that is allocated after the parameters
792 // have been allocated. 795 // have been allocated.
793 // 796 //
794 // Note: This is "almost" at temporary variable but we cannot use 797 // Note: This is "almost" at temporary variable but we cannot use
795 // NewTemporary() because the mode needs to be INTERNAL since this 798 // NewTemporary() because the mode needs to be INTERNAL since this
796 // variable may be allocated in the heap-allocated context (temporaries 799 // variable may be allocated in the heap-allocated context (temporaries
797 // are never allocated in the context). 800 // are never allocated in the context).
798 Variable* arguments_shadow = 801 Variable* arguments_shadow =
799 new Variable(this, Factory::arguments_shadow_symbol(), 802 new Variable(this, Factory::arguments_shadow_symbol(),
800 Variable::INTERNAL, true, false); 803 Variable::INTERNAL, true, Variable::ARGUMENTS);
801 arguments_shadow_ = 804 arguments_shadow_ =
802 new VariableProxy(Factory::arguments_shadow_symbol(), false, false); 805 new VariableProxy(Factory::arguments_shadow_symbol(), false, false);
803 arguments_shadow_->BindTo(arguments_shadow); 806 arguments_shadow_->BindTo(arguments_shadow);
804 temps_.Add(arguments_shadow); 807 temps_.Add(arguments_shadow);
805 808
806 // Allocate the parameters by rewriting them into '.arguments[i]' accesses. 809 // Allocate the parameters by rewriting them into '.arguments[i]' accesses.
807 for (int i = 0; i < params_.length(); i++) { 810 for (int i = 0; i < params_.length(); i++) {
808 Variable* var = params_[i]; 811 Variable* var = params_[i];
809 ASSERT(var->scope() == this); 812 ASSERT(var->scope() == this);
810 if (MustAllocate(var)) { 813 if (MustAllocate(var)) {
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
932 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && 935 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS &&
933 !must_have_local_context) { 936 !must_have_local_context) {
934 num_heap_slots_ = 0; 937 num_heap_slots_ = 0;
935 } 938 }
936 939
937 // Allocation done. 940 // Allocation done.
938 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); 941 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
939 } 942 }
940 943
941 } } // namespace v8::internal 944 } } // namespace v8::internal
OLDNEW
« src/ia32/codegen-ia32.cc ('K') | « src/scopes.h ('k') | src/variables.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698