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

Side by Side Diff: src/scopes.cc

Issue 114024: Avoid linear search for non-locals in the scope code... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 7 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') | no next file » | 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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 // ---------------------------------------------------------------------------- 105 // ----------------------------------------------------------------------------
106 // Implementation of Scope 106 // Implementation of Scope
107 107
108 108
109 // Dummy constructor 109 // Dummy constructor
110 Scope::Scope() 110 Scope::Scope()
111 : inner_scopes_(0), 111 : inner_scopes_(0),
112 locals_(false), 112 locals_(false),
113 temps_(0), 113 temps_(0),
114 params_(0), 114 params_(0),
115 nonlocals_(0), 115 dynamics_(false),
116 dynamics_local_(false),
117 dynamics_global_(false),
116 unresolved_(0), 118 unresolved_(0),
117 decls_(0) { 119 decls_(0) {
118 } 120 }
119 121
120 122
121 Scope::Scope(Scope* outer_scope, Type type) 123 Scope::Scope(Scope* outer_scope, Type type)
122 : outer_scope_(outer_scope), 124 : outer_scope_(outer_scope),
123 inner_scopes_(4), 125 inner_scopes_(4),
124 type_(type), 126 type_(type),
125 scope_name_(Factory::empty_symbol()), 127 scope_name_(Factory::empty_symbol()),
126 locals_(), 128 locals_(),
127 temps_(4), 129 temps_(4),
128 params_(4), 130 params_(4),
129 nonlocals_(4),
130 unresolved_(16), 131 unresolved_(16),
131 decls_(4), 132 decls_(4),
132 receiver_(NULL), 133 receiver_(NULL),
133 function_(NULL), 134 function_(NULL),
134 arguments_(NULL), 135 arguments_(NULL),
135 arguments_shadow_(NULL), 136 arguments_shadow_(NULL),
136 illegal_redecl_(NULL), 137 illegal_redecl_(NULL),
137 scope_inside_with_(false), 138 scope_inside_with_(false),
138 scope_contains_with_(false), 139 scope_contains_with_(false),
139 scope_calls_eval_(false), 140 scope_calls_eval_(false),
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 if (var->is_accessed_from_inner_scope()) PrintF("inner scope access, "); 399 if (var->is_accessed_from_inner_scope()) PrintF("inner scope access, ");
399 PrintF("var "); 400 PrintF("var ");
400 var->var_uses()->Print(); 401 var->var_uses()->Print();
401 PrintF(", obj "); 402 PrintF(", obj ");
402 var->obj_uses()->Print(); 403 var->obj_uses()->Print();
403 PrintF("\n"); 404 PrintF("\n");
404 } 405 }
405 } 406 }
406 407
407 408
409 static void PrintMap(PrettyPrinter* printer, int indent, LocalsMap* map) {
410 for (LocalsMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) {
411 Variable* var = reinterpret_cast<Variable*>(p->value);
412 PrintVar(printer, indent, var);
413 }
414 }
415
416
408 void Scope::Print(int n) { 417 void Scope::Print(int n) {
409 int n0 = (n > 0 ? n : 0); 418 int n0 = (n > 0 ? n : 0);
410 int n1 = n0 + 2; // indentation 419 int n1 = n0 + 2; // indentation
411 420
412 // Print header. 421 // Print header.
413 Indent(n0, Header(type_)); 422 Indent(n0, Header(type_));
414 if (scope_name_->length() > 0) { 423 if (scope_name_->length() > 0) {
415 PrintF(" "); 424 PrintF(" ");
416 PrintName(scope_name_); 425 PrintName(scope_name_);
417 } 426 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 if (function_ != NULL) { 467 if (function_ != NULL) {
459 PrintVar(&printer, n1, function_); 468 PrintVar(&printer, n1, function_);
460 } 469 }
461 470
462 Indent(n1, "// temporary vars\n"); 471 Indent(n1, "// temporary vars\n");
463 for (int i = 0; i < temps_.length(); i++) { 472 for (int i = 0; i < temps_.length(); i++) {
464 PrintVar(&printer, n1, temps_[i]); 473 PrintVar(&printer, n1, temps_[i]);
465 } 474 }
466 475
467 Indent(n1, "// local vars\n"); 476 Indent(n1, "// local vars\n");
468 for (LocalsMap::Entry* p = locals_.Start(); p != NULL; p = locals_.Next(p)) { 477 PrintMap(&printer, n1, &locals_);
469 Variable* var = reinterpret_cast<Variable*>(p->value);
470 PrintVar(&printer, n1, var);
471 }
472 478
473 Indent(n1, "// nonlocal vars\n"); 479 Indent(n1, "// dynamic vars\n");
474 for (int i = 0; i < nonlocals_.length(); i++) 480 PrintMap(&printer, n1, &dynamics_);
475 PrintVar(&printer, n1, nonlocals_[i]); 481 PrintMap(&printer, n1, &dynamics_local_);
482 PrintMap(&printer, n1, &dynamics_global_);
476 483
477 // Print inner scopes (disable by providing negative n). 484 // Print inner scopes (disable by providing negative n).
478 if (n >= 0) { 485 if (n >= 0) {
479 for (int i = 0; i < inner_scopes_.length(); i++) { 486 for (int i = 0; i < inner_scopes_.length(); i++) {
480 PrintF("\n"); 487 PrintF("\n");
481 inner_scopes_[i]->Print(n1); 488 inner_scopes_[i]->Print(n1);
482 } 489 }
483 } 490 }
484 491
485 Indent(n0, "}\n"); 492 Indent(n0, "}\n");
486 } 493 }
487 #endif // DEBUG 494 #endif // DEBUG
488 495
489 496
490 Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) { 497 Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) {
491 // Space optimization: reuse existing non-local with the same name 498 // Space optimization: reuse existing non-local with the same name
492 // and mode. 499 // and mode.
493 for (int i = 0; i < nonlocals_.length(); i++) { 500 LocalsMap* map = NULL;
494 Variable* var = nonlocals_[i]; 501 switch (mode) {
495 if (var->name().is_identical_to(name) && var->mode() == mode) { 502 case Variable::DYNAMIC:
496 return var; 503 map = &dynamics_;
497 } 504 break;
505 case Variable::DYNAMIC_LOCAL:
506 map = &dynamics_local_;
507 break;
508 case Variable::DYNAMIC_GLOBAL:
509 map = &dynamics_global_;
510 break;
511 default:
512 UNREACHABLE();
513 break;
498 } 514 }
499 515 Variable* var = map->Lookup(name);
500 // Otherwise create a new non-local and add it to the list. 516 if (var == NULL) {
501 Variable* var = new Variable(NULL, name, mode, true, false); 517 // Declare a new non-local.
502 nonlocals_.Add(var); 518 var = map->Declare(NULL, name, mode, true, false);
503 519 // Allocate it by giving it a dynamic lookup.
504 // Allocate it by giving it a dynamic lookup. 520 var->rewrite_ = new Slot(var, Slot::LOOKUP, -1);
505 var->rewrite_ = new Slot(var, Slot::LOOKUP, -1); 521 }
506
507 return var; 522 return var;
508 } 523 }
509 524
510 525
511 // Lookup a variable starting with this scope. The result is either 526 // Lookup a variable starting with this scope. The result is either
512 // the statically resolved (local!) variable belonging to an outer scope, 527 // the statically resolved (local!) variable belonging to an outer scope,
513 // or NULL. It may be NULL because a) we couldn't find a variable, or b) 528 // or NULL. It may be NULL because a) we couldn't find a variable, or b)
514 // because the variable is just a guess (and may be shadowed by another 529 // because the variable is just a guess (and may be shadowed by another
515 // variable that is introduced dynamically via an 'eval' call or a 'with' 530 // variable that is introduced dynamically via an 'eval' call or a 'with'
516 // statement). 531 // statement).
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
610 // a local or outer eval() call, or an outer 'with' statement), 625 // a local or outer eval() call, or an outer 'with' statement),
611 // or we don't know about the outer scope (because we are 626 // or we don't know about the outer scope (because we are
612 // in an eval scope). 627 // in an eval scope).
613 if (is_global_scope() || 628 if (is_global_scope() ||
614 !(scope_inside_with_ || outer_scope_is_eval_scope_ || 629 !(scope_inside_with_ || outer_scope_is_eval_scope_ ||
615 scope_calls_eval_ || outer_scope_calls_eval_)) { 630 scope_calls_eval_ || outer_scope_calls_eval_)) {
616 // We must have a global variable. 631 // We must have a global variable.
617 ASSERT(global_scope != NULL); 632 ASSERT(global_scope != NULL);
618 var = new Variable(global_scope, proxy->name(), 633 var = new Variable(global_scope, proxy->name(),
619 Variable::DYNAMIC, true, false); 634 Variable::DYNAMIC, true, false);
620 // Ideally we simply rewrite these variables into property
621 // accesses. Unfortunately, we cannot do this here at the
622 // moment because then we can't differentiate between
623 // global variable ('x') and global property ('this.x') access.
624 // If 'x' doesn't exist, the former leads to an error, while the
625 // latter returns undefined. Sigh...
626 // var->rewrite_ = new Property(new Literal(env_->global()),
627 // new Literal(proxy->name()));
628 635
629 } else if (scope_inside_with_) { 636 } else if (scope_inside_with_) {
630 // If we are inside a with statement we give up and look up 637 // If we are inside a with statement we give up and look up
631 // the variable at runtime. 638 // the variable at runtime.
632 var = NonLocal(proxy->name(), Variable::DYNAMIC); 639 var = NonLocal(proxy->name(), Variable::DYNAMIC);
633 640
634 } else if (invalidated_local != NULL) { 641 } else if (invalidated_local != NULL) {
635 // No with statements are involved and we found a local 642 // No with statements are involved and we found a local
636 // variable that might be shadowed by eval introduced 643 // variable that might be shadowed by eval introduced
637 // variables. 644 // variables.
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
937 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && 944 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS &&
938 !must_have_local_context) { 945 !must_have_local_context) {
939 num_heap_slots_ = 0; 946 num_heap_slots_ = 0;
940 } 947 }
941 948
942 // Allocation done. 949 // Allocation done.
943 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); 950 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
944 } 951 }
945 952
946 } } // namespace v8::internal 953 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/scopes.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698