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

Side by Side Diff: src/parser.cc

Issue 7314002: Group property assignments in top-level blocks. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: More review fixes Created 9 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 | « no previous file | 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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 805 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 if (exp_stat == NULL) return NULL; 816 if (exp_stat == NULL) return NULL;
817 return exp_stat->expression()->AsAssignment(); 817 return exp_stat->expression()->AsAssignment();
818 } 818 }
819 }; 819 };
820 820
821 821
822 // An InitializationBlockFinder finds and marks sequences of statements of the 822 // An InitializationBlockFinder finds and marks sequences of statements of the
823 // form expr.a = ...; expr.b = ...; etc. 823 // form expr.a = ...; expr.b = ...; etc.
824 class InitializationBlockFinder : public ParserFinder { 824 class InitializationBlockFinder : public ParserFinder {
825 public: 825 public:
826 InitializationBlockFinder() 826 // We find and mark the initialization blocks on top level code only.
827 : first_in_block_(NULL), last_in_block_(NULL), block_size_(0) {} 827 // This is because the optimization prevents reuse of the map transitions,
828 // so it should be used only for code that will only be run once.
Vyacheslav Egorov (Chromium) 2011/07/06 14:19:05 Comment should mention that we do not apply this o
829 InitializationBlockFinder(Scope* top_scope, Target* target)
830 : enabled_(top_scope->DeclarationScope()->is_global_scope() &&
831 !IsLoopTarget(target)),
832 first_in_block_(NULL),
833 last_in_block_(NULL),
834 block_size_(0) {}
828 835
829 ~InitializationBlockFinder() { 836 ~InitializationBlockFinder() {
837 if (!enabled_) return;
830 if (InBlock()) EndBlock(); 838 if (InBlock()) EndBlock();
831 } 839 }
832 840
833 void Update(Statement* stat) { 841 void Update(Statement* stat) {
842 if (!enabled_) return;
834 Assignment* assignment = AsAssignment(stat); 843 Assignment* assignment = AsAssignment(stat);
835 if (InBlock()) { 844 if (InBlock()) {
836 if (BlockContinues(assignment)) { 845 if (BlockContinues(assignment)) {
837 UpdateBlock(assignment); 846 UpdateBlock(assignment);
838 } else { 847 } else {
839 EndBlock(); 848 EndBlock();
840 } 849 }
841 } 850 }
842 if (!InBlock() && (assignment != NULL) && 851 if (!InBlock() && (assignment != NULL) &&
843 (assignment->op() == Token::ASSIGN)) { 852 (assignment->op() == Token::ASSIGN)) {
844 StartBlock(assignment); 853 StartBlock(assignment);
845 } 854 }
846 } 855 }
847 856
848 private: 857 private:
849 // The minimum number of contiguous assignment that will 858 // The minimum number of contiguous assignment that will
850 // be treated as an initialization block. Benchmarks show that 859 // be treated as an initialization block. Benchmarks show that
851 // the overhead exceeds the savings below this limit. 860 // the overhead exceeds the savings below this limit.
852 static const int kMinInitializationBlock = 3; 861 static const int kMinInitializationBlock = 3;
853 862
863 static bool IsLoopTarget(Target* target) {
864 while (target != NULL) {
865 if (target->node()->AsIterationStatement() != NULL) return true;
866 target = target->previous();
867 }
868 return false;
869 }
870
854 // Returns true if the expressions appear to denote the same object. 871 // Returns true if the expressions appear to denote the same object.
855 // In the context of initialization blocks, we only consider expressions 872 // In the context of initialization blocks, we only consider expressions
856 // of the form 'expr.x' or expr["x"]. 873 // of the form 'expr.x' or expr["x"].
857 static bool SameObject(Expression* e1, Expression* e2) { 874 static bool SameObject(Expression* e1, Expression* e2) {
858 VariableProxy* v1 = e1->AsVariableProxy(); 875 VariableProxy* v1 = e1->AsVariableProxy();
859 VariableProxy* v2 = e2->AsVariableProxy(); 876 VariableProxy* v2 = e2->AsVariableProxy();
860 if (v1 != NULL && v2 != NULL) { 877 if (v1 != NULL && v2 != NULL) {
861 return v1->name()->Equals(*v2->name()); 878 return v1->name()->Equals(*v2->name());
862 } 879 }
863 Property* p1 = e1->AsProperty(); 880 Property* p1 = e1->AsProperty();
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 if (block_size_ >= kMinInitializationBlock) { 923 if (block_size_ >= kMinInitializationBlock) {
907 first_in_block_->mark_block_start(); 924 first_in_block_->mark_block_start();
908 last_in_block_->mark_block_end(); 925 last_in_block_->mark_block_end();
909 } 926 }
910 last_in_block_ = first_in_block_ = NULL; 927 last_in_block_ = first_in_block_ = NULL;
911 block_size_ = 0; 928 block_size_ = 0;
912 } 929 }
913 930
914 bool InBlock() { return first_in_block_ != NULL; } 931 bool InBlock() { return first_in_block_ != NULL; }
915 932
933 const bool enabled_;
916 Assignment* first_in_block_; 934 Assignment* first_in_block_;
917 Assignment* last_in_block_; 935 Assignment* last_in_block_;
918 int block_size_; 936 int block_size_;
919 937
920 DISALLOW_COPY_AND_ASSIGN(InitializationBlockFinder); 938 DISALLOW_COPY_AND_ASSIGN(InitializationBlockFinder);
921 }; 939 };
922 940
923 941
924 // A ThisNamedPropertyAssigmentFinder finds and marks statements of the form 942 // A ThisNamedPropertyAssigmentFinder finds and marks statements of the form
925 // this.x = ...;, where x is a named property. It also determines whether a 943 // this.x = ...;, where x is a named property. It also determines whether a
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
1071 // SourceElements :: 1089 // SourceElements ::
1072 // (Statement)* <end_token> 1090 // (Statement)* <end_token>
1073 1091
1074 // Allocate a target stack to use for this set of source 1092 // Allocate a target stack to use for this set of source
1075 // elements. This way, all scripts and functions get their own 1093 // elements. This way, all scripts and functions get their own
1076 // target stack thus avoiding illegal breaks and continues across 1094 // target stack thus avoiding illegal breaks and continues across
1077 // functions. 1095 // functions.
1078 TargetScope scope(&this->target_stack_); 1096 TargetScope scope(&this->target_stack_);
1079 1097
1080 ASSERT(processor != NULL); 1098 ASSERT(processor != NULL);
1081 InitializationBlockFinder block_finder; 1099 InitializationBlockFinder block_finder(top_scope_, target_stack_);
1082 ThisNamedPropertyAssigmentFinder this_property_assignment_finder(isolate()); 1100 ThisNamedPropertyAssigmentFinder this_property_assignment_finder(isolate());
1083 bool directive_prologue = true; // Parsing directive prologue. 1101 bool directive_prologue = true; // Parsing directive prologue.
1084 1102
1085 while (peek() != end_token) { 1103 while (peek() != end_token) {
1086 if (directive_prologue && peek() != Token::STRING) { 1104 if (directive_prologue && peek() != Token::STRING) {
1087 directive_prologue = false; 1105 directive_prologue = false;
1088 } 1106 }
1089 1107
1090 Scanner::Location token_loc = scanner().peek_location(); 1108 Scanner::Location token_loc = scanner().peek_location();
1091 1109
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1126 top_scope_->EnableStrictMode(); 1144 top_scope_->EnableStrictMode();
1127 // "use strict" is the only directive for now. 1145 // "use strict" is the only directive for now.
1128 directive_prologue = false; 1146 directive_prologue = false;
1129 } 1147 }
1130 } else { 1148 } else {
1131 // End of the directive prologue. 1149 // End of the directive prologue.
1132 directive_prologue = false; 1150 directive_prologue = false;
1133 } 1151 }
1134 } 1152 }
1135 1153
1136 // We find and mark the initialization blocks on top level code only. 1154 block_finder.Update(stat);
1137 // This is because the optimization prevents reuse of the map transitions,
1138 // so it should be used only for code that will only be run once.
1139 if (top_scope_->is_global_scope()) {
1140 block_finder.Update(stat);
1141 }
1142 // Find and mark all assignments to named properties in this (this.x =) 1155 // Find and mark all assignments to named properties in this (this.x =)
1143 if (top_scope_->is_function_scope()) { 1156 if (top_scope_->is_function_scope()) {
1144 this_property_assignment_finder.Update(top_scope_, stat); 1157 this_property_assignment_finder.Update(top_scope_, stat);
1145 } 1158 }
1146 processor->Add(stat); 1159 processor->Add(stat);
1147 } 1160 }
1148 1161
1149 // Propagate the collected information on this property assignments. 1162 // Propagate the collected information on this property assignments.
1150 if (top_scope_->is_function_scope()) { 1163 if (top_scope_->is_function_scope()) {
1151 bool only_simple_this_property_assignments = 1164 bool only_simple_this_property_assignments =
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
1471 // Block :: 1484 // Block ::
1472 // '{' Statement* '}' 1485 // '{' Statement* '}'
1473 1486
1474 // Note that a Block does not introduce a new execution scope! 1487 // Note that a Block does not introduce a new execution scope!
1475 // (ECMA-262, 3rd, 12.2) 1488 // (ECMA-262, 3rd, 12.2)
1476 // 1489 //
1477 // Construct block expecting 16 statements. 1490 // Construct block expecting 16 statements.
1478 Block* result = new(zone()) Block(labels, 16, false); 1491 Block* result = new(zone()) Block(labels, 16, false);
1479 Target target(&this->target_stack_, result); 1492 Target target(&this->target_stack_, result);
1480 Expect(Token::LBRACE, CHECK_OK); 1493 Expect(Token::LBRACE, CHECK_OK);
1494 InitializationBlockFinder block_finder(top_scope_, target_stack_);
1481 while (peek() != Token::RBRACE) { 1495 while (peek() != Token::RBRACE) {
1482 Statement* stat = ParseStatement(NULL, CHECK_OK); 1496 Statement* stat = ParseStatement(NULL, CHECK_OK);
1483 if (stat && !stat->IsEmpty()) result->AddStatement(stat); 1497 if (stat && !stat->IsEmpty()) {
1498 result->AddStatement(stat);
1499 block_finder.Update(stat);
1500 }
1484 } 1501 }
1485 Expect(Token::RBRACE, CHECK_OK); 1502 Expect(Token::RBRACE, CHECK_OK);
1486 return result; 1503 return result;
1487 } 1504 }
1488 1505
1489 1506
1490 Block* Parser::ParseVariableStatement(bool* ok) { 1507 Block* Parser::ParseVariableStatement(bool* ok) {
1491 // VariableStatement :: 1508 // VariableStatement ::
1492 // VariableDeclarations ';' 1509 // VariableDeclarations ';'
1493 1510
(...skipping 3573 matching lines...) Expand 10 before | Expand all | Expand 10 after
5067 info->is_global(), 5084 info->is_global(),
5068 info->StrictMode()); 5085 info->StrictMode());
5069 } 5086 }
5070 } 5087 }
5071 5088
5072 info->SetFunction(result); 5089 info->SetFunction(result);
5073 return (result != NULL); 5090 return (result != NULL);
5074 } 5091 }
5075 5092
5076 } } // namespace v8::internal 5093 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698