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

Side by Side Diff: src/ast.cc

Issue 1376443002: Refactored interface of FeedbackVectorSpec and friends. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix Created 5 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
« no previous file with comments | « src/ast.h ('k') | src/ast-numbering.cc » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/ast.h" 5 #include "src/ast.h"
6 6
7 #include <cmath> // For isfinite. 7 #include <cmath> // For isfinite.
8 #include "src/builtins.h" 8 #include "src/builtins.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/contexts.h" 10 #include "src/contexts.h"
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 91
92 92
93 void VariableProxy::BindTo(Variable* var) { 93 void VariableProxy::BindTo(Variable* var) {
94 DCHECK((is_this() && var->is_this()) || raw_name() == var->raw_name()); 94 DCHECK((is_this() && var->is_this()) || raw_name() == var->raw_name());
95 set_var(var); 95 set_var(var);
96 set_is_resolved(); 96 set_is_resolved();
97 var->set_is_used(); 97 var->set_is_used();
98 } 98 }
99 99
100 100
101 void VariableProxy::SetFirstFeedbackICSlot(FeedbackVectorICSlot slot, 101 void VariableProxy::AssignFeedbackVectorSlots(Isolate* isolate,
102 ICSlotCache* cache) { 102 FeedbackVectorSpec* spec,
103 variable_feedback_slot_ = slot; 103 ICSlotCache* cache) {
104 if (var()->IsUnallocated()) {
105 cache->Put(var(), slot);
106 }
107 }
108
109
110 FeedbackVectorRequirements VariableProxy::ComputeFeedbackRequirements(
111 Isolate* isolate, const ICSlotCache* cache) {
112 if (UsesVariableFeedbackSlot()) { 104 if (UsesVariableFeedbackSlot()) {
113 // VariableProxies that point to the same Variable within a function can 105 // VariableProxies that point to the same Variable within a function can
114 // make their loads from the same IC slot. 106 // make their loads from the same IC slot.
115 if (var()->IsUnallocated()) { 107 if (var()->IsUnallocated()) {
116 ZoneHashMap::Entry* entry = cache->Get(var()); 108 ZoneHashMap::Entry* entry = cache->Get(var());
117 if (entry != NULL) { 109 if (entry != NULL) {
118 variable_feedback_slot_ = FeedbackVectorICSlot( 110 variable_feedback_slot_ = FeedbackVectorICSlot(
119 static_cast<int>(reinterpret_cast<intptr_t>(entry->value))); 111 static_cast<int>(reinterpret_cast<intptr_t>(entry->value)));
120 return FeedbackVectorRequirements(0, 0); 112 return;
121 } 113 }
122 } 114 }
123 return FeedbackVectorRequirements(0, 1); 115 variable_feedback_slot_ = spec->AddLoadICSlot();
116 if (var()->IsUnallocated()) {
117 cache->Put(var(), variable_feedback_slot_);
118 }
124 } 119 }
125 return FeedbackVectorRequirements(0, 0);
126 } 120 }
127 121
128 122
129 static int GetStoreICSlots(Expression* expr) { 123 static void AssignVectorSlots(Expression* expr, FeedbackVectorSpec* spec,
130 int ic_slots = 0; 124 FeedbackVectorICSlot* out_slot) {
131 if (FLAG_vector_stores) { 125 if (FLAG_vector_stores) {
132 Property* property = expr->AsProperty(); 126 Property* property = expr->AsProperty();
133 LhsKind assign_type = Property::GetAssignType(property); 127 LhsKind assign_type = Property::GetAssignType(property);
134 if ((assign_type == VARIABLE && 128 if ((assign_type == VARIABLE &&
135 expr->AsVariableProxy()->var()->IsUnallocated()) || 129 expr->AsVariableProxy()->var()->IsUnallocated()) ||
136 assign_type == NAMED_PROPERTY || assign_type == KEYED_PROPERTY) { 130 assign_type == NAMED_PROPERTY || assign_type == KEYED_PROPERTY) {
137 ic_slots++; 131 // TODO(ishell): consider using ICSlotCache for variables here.
132 FeedbackVectorSlotKind kind = assign_type == KEYED_PROPERTY
133 ? FeedbackVectorSlotKind::KEYED_STORE_IC
134 : FeedbackVectorSlotKind::STORE_IC;
135 *out_slot = spec->AddSlot(kind);
138 } 136 }
139 } 137 }
140 return ic_slots;
141 } 138 }
142 139
143 140
144 static FeedbackVectorSlotKind GetStoreICKind(Expression* expr) { 141 void ForEachStatement::AssignFeedbackVectorSlots(Isolate* isolate,
145 LhsKind assign_type = Property::GetAssignType(expr->AsProperty()); 142 FeedbackVectorSpec* spec,
146 return assign_type == KEYED_PROPERTY ? FeedbackVectorSlotKind::KEYED_STORE_IC 143 ICSlotCache* cache) {
147 : FeedbackVectorSlotKind::STORE_IC; 144 AssignVectorSlots(each(), spec, &each_slot_);
148 } 145 }
149 146
150 147
151 FeedbackVectorRequirements ForEachStatement::ComputeFeedbackRequirements(
152 Isolate* isolate, const ICSlotCache* cache) {
153 int ic_slots = GetStoreICSlots(each());
154 return FeedbackVectorRequirements(0, ic_slots);
155 }
156
157
158 FeedbackVectorSlotKind ForEachStatement::FeedbackICSlotKind(int index) {
159 return GetStoreICKind(each());
160 }
161
162
163 Assignment::Assignment(Zone* zone, Token::Value op, Expression* target, 148 Assignment::Assignment(Zone* zone, Token::Value op, Expression* target,
164 Expression* value, int pos) 149 Expression* value, int pos)
165 : Expression(zone, pos), 150 : Expression(zone, pos),
166 bit_field_( 151 bit_field_(
167 IsUninitializedField::encode(false) | KeyTypeField::encode(ELEMENT) | 152 IsUninitializedField::encode(false) | KeyTypeField::encode(ELEMENT) |
168 StoreModeField::encode(STANDARD_STORE) | TokenField::encode(op)), 153 StoreModeField::encode(STANDARD_STORE) | TokenField::encode(op)),
169 target_(target), 154 target_(target),
170 value_(value), 155 value_(value),
171 binary_operation_(NULL), 156 binary_operation_(NULL),
172 slot_(FeedbackVectorICSlot::Invalid()) {} 157 slot_(FeedbackVectorICSlot::Invalid()) {}
173 158
174 159
175 FeedbackVectorRequirements Assignment::ComputeFeedbackRequirements( 160 void Assignment::AssignFeedbackVectorSlots(Isolate* isolate,
176 Isolate* isolate, const ICSlotCache* cache) { 161 FeedbackVectorSpec* spec,
177 int ic_slots = GetStoreICSlots(target()); 162 ICSlotCache* cache) {
178 return FeedbackVectorRequirements(0, ic_slots); 163 AssignVectorSlots(target(), spec, &slot_);
179 } 164 }
180 165
181 166
182 FeedbackVectorSlotKind Assignment::FeedbackICSlotKind(int index) { 167 void CountOperation::AssignFeedbackVectorSlots(Isolate* isolate,
183 return GetStoreICKind(target()); 168 FeedbackVectorSpec* spec,
169 ICSlotCache* cache) {
170 AssignVectorSlots(expression(), spec, &slot_);
184 } 171 }
185 172
186 173
187 FeedbackVectorRequirements CountOperation::ComputeFeedbackRequirements(
188 Isolate* isolate, const ICSlotCache* cache) {
189 int ic_slots = GetStoreICSlots(expression());
190 return FeedbackVectorRequirements(0, ic_slots);
191 }
192
193
194 FeedbackVectorSlotKind CountOperation::FeedbackICSlotKind(int index) {
195 return GetStoreICKind(expression());
196 }
197
198
199 Token::Value Assignment::binary_op() const { 174 Token::Value Assignment::binary_op() const {
200 switch (op()) { 175 switch (op()) {
201 case Token::ASSIGN_BIT_OR: return Token::BIT_OR; 176 case Token::ASSIGN_BIT_OR: return Token::BIT_OR;
202 case Token::ASSIGN_BIT_XOR: return Token::BIT_XOR; 177 case Token::ASSIGN_BIT_XOR: return Token::BIT_XOR;
203 case Token::ASSIGN_BIT_AND: return Token::BIT_AND; 178 case Token::ASSIGN_BIT_AND: return Token::BIT_AND;
204 case Token::ASSIGN_SHL: return Token::SHL; 179 case Token::ASSIGN_SHL: return Token::SHL;
205 case Token::ASSIGN_SAR: return Token::SAR; 180 case Token::ASSIGN_SAR: return Token::SAR;
206 case Token::ASSIGN_SHR: return Token::SHR; 181 case Token::ASSIGN_SHR: return Token::SHR;
207 case Token::ASSIGN_ADD: return Token::ADD; 182 case Token::ASSIGN_ADD: return Token::ADD;
208 case Token::ASSIGN_SUB: return Token::SUB; 183 case Token::ASSIGN_SUB: return Token::SUB;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 } else if (value_->AsMaterializedLiteral() != NULL) { 251 } else if (value_->AsMaterializedLiteral() != NULL) {
277 kind_ = MATERIALIZED_LITERAL; 252 kind_ = MATERIALIZED_LITERAL;
278 } else if (value_->IsLiteral()) { 253 } else if (value_->IsLiteral()) {
279 kind_ = CONSTANT; 254 kind_ = CONSTANT;
280 } else { 255 } else {
281 kind_ = COMPUTED; 256 kind_ = COMPUTED;
282 } 257 }
283 } 258 }
284 259
285 260
286 FeedbackVectorRequirements ClassLiteral::ComputeFeedbackRequirements( 261 void ClassLiteral::AssignFeedbackVectorSlots(Isolate* isolate,
287 Isolate* isolate, const ICSlotCache* cache) { 262 FeedbackVectorSpec* spec,
288 if (!FLAG_vector_stores) return FeedbackVectorRequirements(0, 0); 263 ICSlotCache* cache) {
264 if (!FLAG_vector_stores) return;
289 265
290 // This logic that computes the number of slots needed for vector store 266 // This logic that computes the number of slots needed for vector store
291 // ICs must mirror FullCodeGenerator::VisitClassLiteral. 267 // ICs must mirror FullCodeGenerator::VisitClassLiteral.
292 int ic_slots = 0; 268 int ic_slots = 0;
293 if (NeedsProxySlot()) { 269 if (NeedsProxySlot()) {
294 ic_slots++; 270 ic_slots++;
295 } 271 }
296 272
297 for (int i = 0; i < properties()->length(); i++) { 273 for (int i = 0; i < properties()->length(); i++) {
298 ObjectLiteral::Property* property = properties()->at(i); 274 ObjectLiteral::Property* property = properties()->at(i);
299 // In case we don't end up using any slots. 275 // In case we don't end up using any slots.
300 property->set_ic_slot_count(0); 276 property->set_ic_slot_count(0);
301 277
302 Expression* value = property->value(); 278 Expression* value = property->value();
303 if (FunctionLiteral::NeedsHomeObject(value)) { 279 if (FunctionLiteral::NeedsHomeObject(value)) {
304 property->set_ic_slot_count(1); 280 property->set_ic_slot_count(1);
305 ic_slots++; 281 ic_slots++;
306 } 282 }
307 } 283 }
308 284
309 return FeedbackVectorRequirements(0, ic_slots); 285 if (ic_slots > 0) {
286 slot_ = spec->AddStoreICSlots(ic_slots);
287 }
310 } 288 }
311 289
312 290
313 void ClassLiteral::LayoutFeedbackSlots() { 291 void ClassLiteral::LayoutFeedbackSlots() {
314 int base_slot = slot_.ToInt(); 292 int base_slot = slot_.ToInt();
315 if (NeedsProxySlot()) base_slot++; 293 if (NeedsProxySlot()) base_slot++;
316 294
317 for (int i = 0; i < properties()->length(); i++) { 295 for (int i = 0; i < properties()->length(); i++) {
318 ObjectLiteral::Property* property = properties()->at(i); 296 ObjectLiteral::Property* property = properties()->at(i);
319 base_slot += property->set_base_slot(base_slot); 297 base_slot += property->set_base_slot(base_slot);
(...skipping 20 matching lines...) Expand all
340 318
341 void ObjectLiteral::LayoutFeedbackSlots() { 319 void ObjectLiteral::LayoutFeedbackSlots() {
342 int base_slot = slot_.ToInt(); 320 int base_slot = slot_.ToInt();
343 for (int i = 0; i < properties()->length(); i++) { 321 for (int i = 0; i < properties()->length(); i++) {
344 ObjectLiteral::Property* property = properties()->at(i); 322 ObjectLiteral::Property* property = properties()->at(i);
345 base_slot += property->set_base_slot(base_slot); 323 base_slot += property->set_base_slot(base_slot);
346 } 324 }
347 } 325 }
348 326
349 327
350 FeedbackVectorRequirements ObjectLiteral::ComputeFeedbackRequirements( 328 void ObjectLiteral::AssignFeedbackVectorSlots(Isolate* isolate,
351 Isolate* isolate, const ICSlotCache* cache) { 329 FeedbackVectorSpec* spec,
352 if (!FLAG_vector_stores) return FeedbackVectorRequirements(0, 0); 330 ICSlotCache* cache) {
331 if (!FLAG_vector_stores) return;
353 332
354 // This logic that computes the number of slots needed for vector store 333 // This logic that computes the number of slots needed for vector store
355 // ics must mirror FullCodeGenerator::VisitObjectLiteral. 334 // ics must mirror FullCodeGenerator::VisitObjectLiteral.
356 int property_index = 0; 335 int property_index = 0;
357 for (; property_index < properties()->length(); property_index++) { 336 for (; property_index < properties()->length(); property_index++) {
358 ObjectLiteral::Property* property = properties()->at(property_index); 337 ObjectLiteral::Property* property = properties()->at(property_index);
359 // In case we don't end up using any slots. 338 // In case we don't end up using any slots.
360 property->set_ic_slot_count(0); 339 property->set_ic_slot_count(0);
361 340
362 if (property->is_computed_name()) break; 341 if (property->is_computed_name()) break;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 } 391 }
413 } 392 }
414 393
415 // How many slots did we allocate? 394 // How many slots did we allocate?
416 int ic_slots = 0; 395 int ic_slots = 0;
417 for (int i = 0; i < properties()->length(); i++) { 396 for (int i = 0; i < properties()->length(); i++) {
418 ObjectLiteral::Property* property = properties()->at(i); 397 ObjectLiteral::Property* property = properties()->at(i);
419 ic_slots += property->ic_slot_count(); 398 ic_slots += property->ic_slot_count();
420 } 399 }
421 400
422 return FeedbackVectorRequirements(0, ic_slots); 401 if (ic_slots > 0) {
402 slot_ = spec->AddStoreICSlots(ic_slots);
403 }
423 } 404 }
424 405
425 406
426 void ObjectLiteral::CalculateEmitStore(Zone* zone) { 407 void ObjectLiteral::CalculateEmitStore(Zone* zone) {
427 const auto GETTER = ObjectLiteral::Property::GETTER; 408 const auto GETTER = ObjectLiteral::Property::GETTER;
428 const auto SETTER = ObjectLiteral::Property::SETTER; 409 const auto SETTER = ObjectLiteral::Property::SETTER;
429 410
430 ZoneAllocationPolicy allocator(zone); 411 ZoneAllocationPolicy allocator(zone);
431 412
432 ZoneHashMap table(Literal::Match, ZoneHashMap::kDefaultHashMapCapacity, 413 ZoneHashMap table(Literal::Match, ZoneHashMap::kDefaultHashMapCapacity,
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
775 } 756 }
776 757
777 758
778 bool Call::IsUsingCallFeedbackSlot(Isolate* isolate) const { 759 bool Call::IsUsingCallFeedbackSlot(Isolate* isolate) const {
779 // SuperConstructorCall uses a CallConstructStub, which wants 760 // SuperConstructorCall uses a CallConstructStub, which wants
780 // a Slot, in addition to any IC slots requested elsewhere. 761 // a Slot, in addition to any IC slots requested elsewhere.
781 return GetCallType(isolate) == SUPER_CALL; 762 return GetCallType(isolate) == SUPER_CALL;
782 } 763 }
783 764
784 765
785 FeedbackVectorRequirements Call::ComputeFeedbackRequirements( 766 void Call::AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
786 Isolate* isolate, const ICSlotCache* cache) { 767 ICSlotCache* cache) {
787 int ic_slots = IsUsingCallFeedbackICSlot(isolate) ? 1 : 0; 768 if (IsUsingCallFeedbackICSlot(isolate)) {
788 int slots = IsUsingCallFeedbackSlot(isolate) ? 1 : 0; 769 ic_slot_ = spec->AddCallICSlot();
789 return FeedbackVectorRequirements(slots, ic_slots); 770 }
771 if (IsUsingCallFeedbackSlot(isolate)) {
772 slot_ = spec->AddStubSlot();
773 }
790 } 774 }
791 775
792 776
793 Call::CallType Call::GetCallType(Isolate* isolate) const { 777 Call::CallType Call::GetCallType(Isolate* isolate) const {
794 VariableProxy* proxy = expression()->AsVariableProxy(); 778 VariableProxy* proxy = expression()->AsVariableProxy();
795 if (proxy != NULL) { 779 if (proxy != NULL) {
796 if (proxy->var()->is_possibly_eval(isolate)) { 780 if (proxy->var()->is_possibly_eval(isolate)) {
797 return POSSIBLY_EVAL_CALL; 781 return POSSIBLY_EVAL_CALL;
798 } else if (proxy->var()->IsUnallocatedOrGlobalSlot()) { 782 } else if (proxy->var()->IsUnallocatedOrGlobalSlot()) {
799 return GLOBAL_CALL; 783 return GLOBAL_CALL;
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after
1188 bool Literal::Match(void* literal1, void* literal2) { 1172 bool Literal::Match(void* literal1, void* literal2) {
1189 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); 1173 const AstValue* x = static_cast<Literal*>(literal1)->raw_value();
1190 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); 1174 const AstValue* y = static_cast<Literal*>(literal2)->raw_value();
1191 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) || 1175 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) ||
1192 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); 1176 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber());
1193 } 1177 }
1194 1178
1195 1179
1196 } // namespace internal 1180 } // namespace internal
1197 } // namespace v8 1181 } // namespace v8
OLDNEW
« no previous file with comments | « src/ast.h ('k') | src/ast-numbering.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698