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

Side by Side Diff: src/parser.cc

Issue 8139037: Don't count duplicate assignments to the same property as distinct ones. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 2 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 939 matching lines...) Expand 10 before | Expand all | Expand 10 after
950 950
951 const bool enabled_; 951 const bool enabled_;
952 Assignment* first_in_block_; 952 Assignment* first_in_block_;
953 Assignment* last_in_block_; 953 Assignment* last_in_block_;
954 int block_size_; 954 int block_size_;
955 955
956 DISALLOW_COPY_AND_ASSIGN(InitializationBlockFinder); 956 DISALLOW_COPY_AND_ASSIGN(InitializationBlockFinder);
957 }; 957 };
958 958
959 959
960 // A ThisNamedPropertyAssigmentFinder finds and marks statements of the form 960 // A ThisNamedPropertyAssignmentFinder finds and marks statements of the form
961 // this.x = ...;, where x is a named property. It also determines whether a 961 // this.x = ...;, where x is a named property. It also determines whether a
962 // function contains only assignments of this type. 962 // function contains only assignments of this type.
963 class ThisNamedPropertyAssigmentFinder : public ParserFinder { 963 class ThisNamedPropertyAssignmentFinder : public ParserFinder {
964 public: 964 public:
965 explicit ThisNamedPropertyAssigmentFinder(Isolate* isolate) 965 explicit ThisNamedPropertyAssignmentFinder(Isolate* isolate)
966 : isolate_(isolate), 966 : isolate_(isolate),
967 only_simple_this_property_assignments_(true), 967 only_simple_this_property_assignments_(true),
968 names_(NULL), 968 names_(0),
969 assigned_arguments_(NULL), 969 assigned_arguments_(0),
970 assigned_constants_(NULL) {} 970 assigned_constants_(0) {
971 }
971 972
972 void Update(Scope* scope, Statement* stat) { 973 void Update(Scope* scope, Statement* stat) {
973 // Bail out if function already has property assignment that are 974 // Bail out if function already has property assignment that are
974 // not simple this property assignments. 975 // not simple this property assignments.
975 if (!only_simple_this_property_assignments_) { 976 if (!only_simple_this_property_assignments_) {
976 return; 977 return;
977 } 978 }
978 979
979 // Check whether this statement is of the form this.x = ...; 980 // Check whether this statement is of the form this.x = ...;
980 Assignment* assignment = AsAssignment(stat); 981 Assignment* assignment = AsAssignment(stat);
981 if (IsThisPropertyAssignment(assignment)) { 982 if (IsThisPropertyAssignment(assignment)) {
982 HandleThisPropertyAssignment(scope, assignment); 983 HandleThisPropertyAssignment(scope, assignment);
983 } else { 984 } else {
984 only_simple_this_property_assignments_ = false; 985 only_simple_this_property_assignments_ = false;
985 } 986 }
986 } 987 }
987 988
988 // Returns whether only statements of the form this.x = y; where y is either a 989 // Returns whether only statements of the form this.x = y; where y is either a
989 // constant or a function argument was encountered. 990 // constant or a function argument was encountered.
990 bool only_simple_this_property_assignments() { 991 bool only_simple_this_property_assignments() {
991 return only_simple_this_property_assignments_; 992 return only_simple_this_property_assignments_;
992 } 993 }
993 994
994 // Returns a fixed array containing three elements for each assignment of the 995 // Returns a fixed array containing three elements for each assignment of the
995 // form this.x = y; 996 // form this.x = y;
996 Handle<FixedArray> GetThisPropertyAssignments() { 997 Handle<FixedArray> GetThisPropertyAssignments() {
997 if (names_ == NULL) { 998 if (names_.is_empty()) {
998 return isolate_->factory()->empty_fixed_array(); 999 return isolate_->factory()->empty_fixed_array();
999 } 1000 }
1000 ASSERT(names_ != NULL); 1001 ASSERT_EQ(names_.length(), assigned_arguments_.length());
1001 ASSERT(assigned_arguments_ != NULL); 1002 ASSERT_EQ(names_.length(), assigned_constants_.length());
1002 ASSERT_EQ(names_->length(), assigned_arguments_->length());
1003 ASSERT_EQ(names_->length(), assigned_constants_->length());
1004 Handle<FixedArray> assignments = 1003 Handle<FixedArray> assignments =
1005 isolate_->factory()->NewFixedArray(names_->length() * 3); 1004 isolate_->factory()->NewFixedArray(names_.length() * 3);
1006 for (int i = 0; i < names_->length(); i++) { 1005 for (int i = 0; i < names_.length(); ++i) {
1007 assignments->set(i * 3, *names_->at(i)); 1006 assignments->set(i * 3, *names_[i]);
1008 assignments->set(i * 3 + 1, Smi::FromInt(assigned_arguments_->at(i))); 1007 assignments->set(i * 3 + 1, Smi::FromInt(assigned_arguments_[i]));
1009 assignments->set(i * 3 + 2, *assigned_constants_->at(i)); 1008 assignments->set(i * 3 + 2, *assigned_constants_[i]);
1010 } 1009 }
1011 return assignments; 1010 return assignments;
1012 } 1011 }
1013 1012
1014 private: 1013 private:
1015 bool IsThisPropertyAssignment(Assignment* assignment) { 1014 bool IsThisPropertyAssignment(Assignment* assignment) {
1016 if (assignment != NULL) { 1015 if (assignment != NULL) {
1017 Property* property = assignment->target()->AsProperty(); 1016 Property* property = assignment->target()->AsProperty();
1018 return assignment->op() == Token::ASSIGN 1017 return assignment->op() == Token::ASSIGN
1019 && property != NULL 1018 && property != NULL
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1056 return; 1055 return;
1057 } 1056 }
1058 } 1057 }
1059 } 1058 }
1060 } 1059 }
1061 // It is not a simple "this.x = value;" assignment with a constant 1060 // It is not a simple "this.x = value;" assignment with a constant
1062 // or parameter value. 1061 // or parameter value.
1063 AssignmentFromSomethingElse(); 1062 AssignmentFromSomethingElse();
1064 } 1063 }
1065 1064
1065
1066
1067
1068 // We will potentially reorder the property assignments, so they must be
1069 // simple enough that the ordering does not matter.
1066 void AssignmentFromParameter(Handle<String> name, int index) { 1070 void AssignmentFromParameter(Handle<String> name, int index) {
1067 EnsureAllocation(); 1071 EnsureInitialized();
1068 names_->Add(name); 1072 for (int i = 0; i < names_.length(); ++i) {
1069 assigned_arguments_->Add(index); 1073 if (name->Equals(*names_[i])) {
1070 assigned_constants_->Add(isolate_->factory()->undefined_value()); 1074 assigned_arguments_[i] = index;
1075 assigned_constants_[i] = isolate_->factory()->undefined_value();
1076 return;
1077 }
1078 }
1079 names_.Add(name);
1080 assigned_arguments_.Add(index);
1081 assigned_constants_.Add(isolate_->factory()->undefined_value());
1071 } 1082 }
1072 1083
1073 void AssignmentFromConstant(Handle<String> name, Handle<Object> value) { 1084 void AssignmentFromConstant(Handle<String> name, Handle<Object> value) {
1074 EnsureAllocation(); 1085 EnsureInitialized();
1075 names_->Add(name); 1086 for (int i = 0; i < names_.length(); ++i) {
1076 assigned_arguments_->Add(-1); 1087 if (name->Equals(*names_[i])) {
1077 assigned_constants_->Add(value); 1088 assigned_arguments_[i] = -1;
1089 assigned_constants_[i] = value;
1090 return;
1091 }
1092 }
1093 names_.Add(name);
1094 assigned_arguments_.Add(-1);
1095 assigned_constants_.Add(value);
1078 } 1096 }
1079 1097
1080 void AssignmentFromSomethingElse() { 1098 void AssignmentFromSomethingElse() {
1081 // The this assignment is not a simple one. 1099 // The this assignment is not a simple one.
1082 only_simple_this_property_assignments_ = false; 1100 only_simple_this_property_assignments_ = false;
1083 } 1101 }
1084 1102
1085 void EnsureAllocation() { 1103 void EnsureInitialized() {
1086 if (names_ == NULL) { 1104 if (names_.capacity() == 0) {
1087 ASSERT(assigned_arguments_ == NULL); 1105 ASSERT(assigned_arguments_.capacity() == 0);
1088 ASSERT(assigned_constants_ == NULL); 1106 ASSERT(assigned_constants_.capacity() == 0);
1089 Zone* zone = isolate_->zone(); 1107 names_.Initialize(4);
1090 names_ = new(zone) ZoneStringList(4); 1108 assigned_arguments_.Initialize(4);
1091 assigned_arguments_ = new(zone) ZoneList<int>(4); 1109 assigned_constants_.Initialize(4);
1092 assigned_constants_ = new(zone) ZoneObjectList(4);
1093 } 1110 }
1094 } 1111 }
1095 1112
1096 Isolate* isolate_; 1113 Isolate* isolate_;
1097 bool only_simple_this_property_assignments_; 1114 bool only_simple_this_property_assignments_;
1098 ZoneStringList* names_; 1115 ZoneStringList names_;
1099 ZoneList<int>* assigned_arguments_; 1116 ZoneList<int> assigned_arguments_;
1100 ZoneObjectList* assigned_constants_; 1117 ZoneObjectList assigned_constants_;
1101 }; 1118 };
1102 1119
1103 1120
1104 Statement* Parser::ParseSourceElement(ZoneStringList* labels, 1121 Statement* Parser::ParseSourceElement(ZoneStringList* labels,
1105 bool* ok) { 1122 bool* ok) {
1106 // (Ecma 262 5th Edition, clause 14): 1123 // (Ecma 262 5th Edition, clause 14):
1107 // SourceElement: 1124 // SourceElement:
1108 // Statement 1125 // Statement
1109 // FunctionDeclaration 1126 // FunctionDeclaration
1110 // 1127 //
(...skipping 18 matching lines...) Expand all
1129 // (SourceElement)* <end_token> 1146 // (SourceElement)* <end_token>
1130 1147
1131 // Allocate a target stack to use for this set of source 1148 // Allocate a target stack to use for this set of source
1132 // elements. This way, all scripts and functions get their own 1149 // elements. This way, all scripts and functions get their own
1133 // target stack thus avoiding illegal breaks and continues across 1150 // target stack thus avoiding illegal breaks and continues across
1134 // functions. 1151 // functions.
1135 TargetScope scope(&this->target_stack_); 1152 TargetScope scope(&this->target_stack_);
1136 1153
1137 ASSERT(processor != NULL); 1154 ASSERT(processor != NULL);
1138 InitializationBlockFinder block_finder(top_scope_, target_stack_); 1155 InitializationBlockFinder block_finder(top_scope_, target_stack_);
1139 ThisNamedPropertyAssigmentFinder this_property_assignment_finder(isolate()); 1156 ThisNamedPropertyAssignmentFinder this_property_assignment_finder(isolate());
1140 bool directive_prologue = true; // Parsing directive prologue. 1157 bool directive_prologue = true; // Parsing directive prologue.
1141 1158
1142 while (peek() != end_token) { 1159 while (peek() != end_token) {
1143 if (directive_prologue && peek() != Token::STRING) { 1160 if (directive_prologue && peek() != Token::STRING) {
1144 directive_prologue = false; 1161 directive_prologue = false;
1145 } 1162 }
1146 1163
1147 Scanner::Location token_loc = scanner().peek_location(); 1164 Scanner::Location token_loc = scanner().peek_location();
1148 Statement* stat = ParseSourceElement(NULL, CHECK_OK); 1165 Statement* stat = ParseSourceElement(NULL, CHECK_OK);
1149 if (stat == NULL || stat->IsEmpty()) { 1166 if (stat == NULL || stat->IsEmpty()) {
(...skipping 4068 matching lines...) Expand 10 before | Expand all | Expand 10 after
5218 result = parser.ParseProgram(source, 5235 result = parser.ParseProgram(source,
5219 info->is_global(), 5236 info->is_global(),
5220 info->StrictMode()); 5237 info->StrictMode());
5221 } 5238 }
5222 } 5239 }
5223 info->SetFunction(result); 5240 info->SetFunction(result);
5224 return (result != NULL); 5241 return (result != NULL);
5225 } 5242 }
5226 5243
5227 } } // namespace v8::internal 5244 } } // 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