OLD | NEW |
---|---|
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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
114 return FeedbackVectorRequirements(0, 0); | 114 return FeedbackVectorRequirements(0, 0); |
115 } | 115 } |
116 } | 116 } |
117 } | 117 } |
118 return FeedbackVectorRequirements(0, 1); | 118 return FeedbackVectorRequirements(0, 1); |
119 } | 119 } |
120 return FeedbackVectorRequirements(0, 0); | 120 return FeedbackVectorRequirements(0, 0); |
121 } | 121 } |
122 | 122 |
123 | 123 |
124 static int GetStoreICSlots(Expression* expr) { | |
125 int ic_slots = 0; | |
126 if (FLAG_vector_stores) { | |
127 Property* property = expr->AsProperty(); | |
128 LhsKind assign_type = Property::GetAssignType(property); | |
129 if ((assign_type == VARIABLE && | |
130 expr->AsVariableProxy()->var()->IsUnallocated()) || | |
131 assign_type == NAMED_PROPERTY || assign_type == KEYED_PROPERTY) { | |
132 ic_slots++; | |
133 } | |
134 } | |
135 return ic_slots; | |
136 } | |
137 | |
138 | |
139 static Code::Kind GetStoreICKind(Expression* expr) { | |
140 LhsKind assign_type = Property::GetAssignType(expr->AsProperty()); | |
141 return assign_type == KEYED_PROPERTY ? Code::KEYED_STORE_IC : Code::STORE_IC; | |
142 } | |
143 | |
144 | |
145 FeedbackVectorRequirements ForEachStatement::ComputeFeedbackRequirements( | |
146 Isolate* isolate, const ICSlotCache* cache) { | |
147 int ic_slots = GetStoreICSlots(each()); | |
148 return FeedbackVectorRequirements(0, ic_slots); | |
149 } | |
150 | |
151 | |
152 Code::Kind ForEachStatement::FeedbackICSlotKind(int index) { | |
153 return GetStoreICKind(each()); | |
154 } | |
155 | |
156 | |
124 Assignment::Assignment(Zone* zone, Token::Value op, Expression* target, | 157 Assignment::Assignment(Zone* zone, Token::Value op, Expression* target, |
125 Expression* value, int pos) | 158 Expression* value, int pos) |
126 : Expression(zone, pos), | 159 : Expression(zone, pos), |
127 bit_field_(IsUninitializedField::encode(false) | | 160 bit_field_( |
128 KeyTypeField::encode(ELEMENT) | | 161 IsUninitializedField::encode(false) | KeyTypeField::encode(ELEMENT) | |
129 StoreModeField::encode(STANDARD_STORE) | | 162 StoreModeField::encode(STANDARD_STORE) | TokenField::encode(op)), |
130 TokenField::encode(op)), | |
131 target_(target), | 163 target_(target), |
132 value_(value), | 164 value_(value), |
133 binary_operation_(NULL) {} | 165 binary_operation_(NULL), |
166 slot_(FeedbackVectorICSlot::Invalid()) {} | |
167 | |
168 | |
169 FeedbackVectorRequirements Assignment::ComputeFeedbackRequirements( | |
170 Isolate* isolate, const ICSlotCache* cache) { | |
171 int ic_slots = GetStoreICSlots(target()); | |
172 return FeedbackVectorRequirements(0, ic_slots); | |
173 } | |
174 | |
175 | |
176 Code::Kind Assignment::FeedbackICSlotKind(int index) { | |
177 return GetStoreICKind(target()); | |
178 } | |
179 | |
180 | |
181 FeedbackVectorRequirements CountOperation::ComputeFeedbackRequirements( | |
182 Isolate* isolate, const ICSlotCache* cache) { | |
183 int ic_slots = GetStoreICSlots(expression()); | |
184 return FeedbackVectorRequirements(0, ic_slots); | |
185 } | |
186 | |
187 | |
188 Code::Kind CountOperation::FeedbackICSlotKind(int index) { | |
189 return GetStoreICKind(expression()); | |
190 } | |
134 | 191 |
135 | 192 |
136 Token::Value Assignment::binary_op() const { | 193 Token::Value Assignment::binary_op() const { |
137 switch (op()) { | 194 switch (op()) { |
138 case Token::ASSIGN_BIT_OR: return Token::BIT_OR; | 195 case Token::ASSIGN_BIT_OR: return Token::BIT_OR; |
139 case Token::ASSIGN_BIT_XOR: return Token::BIT_XOR; | 196 case Token::ASSIGN_BIT_XOR: return Token::BIT_XOR; |
140 case Token::ASSIGN_BIT_AND: return Token::BIT_AND; | 197 case Token::ASSIGN_BIT_AND: return Token::BIT_AND; |
141 case Token::ASSIGN_SHL: return Token::SHL; | 198 case Token::ASSIGN_SHL: return Token::SHL; |
142 case Token::ASSIGN_SAR: return Token::SAR; | 199 case Token::ASSIGN_SAR: return Token::SAR; |
143 case Token::ASSIGN_SHR: return Token::SHR; | 200 case Token::ASSIGN_SHR: return Token::SHR; |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
246 void ObjectLiteral::Property::set_emit_store(bool emit_store) { | 303 void ObjectLiteral::Property::set_emit_store(bool emit_store) { |
247 emit_store_ = emit_store; | 304 emit_store_ = emit_store; |
248 } | 305 } |
249 | 306 |
250 | 307 |
251 bool ObjectLiteral::Property::emit_store() { | 308 bool ObjectLiteral::Property::emit_store() { |
252 return emit_store_; | 309 return emit_store_; |
253 } | 310 } |
254 | 311 |
255 | 312 |
313 FeedbackVectorRequirements ObjectLiteral::ComputeFeedbackRequirements( | |
314 Isolate* isolate, const ICSlotCache* cache) { | |
315 if (!FLAG_vector_stores) return FeedbackVectorRequirements(0, 0); | |
316 | |
Jakob Kummerow
2015/05/27 13:24:35
As discussed, this is kind of brittle, but hard to
mvstanton
2015/05/27 14:00:18
Good idea, done.
| |
317 int ic_slots = 0; | |
318 for (int i = 0; i < properties()->length(); i++) { | |
319 ObjectLiteral::Property* property = properties()->at(i); | |
320 if (property->IsCompileTimeValue()) continue; | |
321 | |
322 Expression* value = property->value(); | |
323 if (property->is_computed_name() && | |
324 property->kind() != ObjectLiteral::Property::PROTOTYPE) { | |
325 if (FunctionLiteral::NeedsHomeObject(value)) ic_slots++; | |
326 } else if (property->emit_store()) { | |
327 if (property->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL || | |
328 property->kind() == ObjectLiteral::Property::COMPUTED) { | |
329 Literal* key = property->key()->AsLiteral(); | |
330 if (key->value()->IsInternalizedString()) ic_slots++; | |
331 if (FunctionLiteral::NeedsHomeObject(value)) ic_slots++; | |
332 } else if (property->kind() == ObjectLiteral::Property::GETTER || | |
333 property->kind() == ObjectLiteral::Property::SETTER) { | |
334 // We might need a slot for the home object. | |
335 if (FunctionLiteral::NeedsHomeObject(value)) ic_slots++; | |
336 } | |
337 } | |
338 } | |
339 | |
340 return FeedbackVectorRequirements(0, ic_slots); | |
341 } | |
342 | |
343 | |
344 FeedbackVectorICSlot ObjectLiteral::SlotForHomeObject(Expression* value, | |
345 int* slot_index) const { | |
346 if (FLAG_vector_stores && FunctionLiteral::NeedsHomeObject(value)) { | |
347 return GetNthSlot(*slot_index++); | |
Jakob Kummerow
2015/05/27 13:24:35
I'm pretty sure this moves the pointer instead of
mvstanton
2015/05/27 14:00:18
Heh-heh. :p Fixed, thanks!
| |
348 } | |
349 return FeedbackVectorICSlot::Invalid(); | |
350 } | |
351 | |
352 | |
256 void ObjectLiteral::CalculateEmitStore(Zone* zone) { | 353 void ObjectLiteral::CalculateEmitStore(Zone* zone) { |
257 const auto GETTER = ObjectLiteral::Property::GETTER; | 354 const auto GETTER = ObjectLiteral::Property::GETTER; |
258 const auto SETTER = ObjectLiteral::Property::SETTER; | 355 const auto SETTER = ObjectLiteral::Property::SETTER; |
259 | 356 |
260 ZoneAllocationPolicy allocator(zone); | 357 ZoneAllocationPolicy allocator(zone); |
261 | 358 |
262 ZoneHashMap table(Literal::Match, ZoneHashMap::kDefaultHashMapCapacity, | 359 ZoneHashMap table(Literal::Match, ZoneHashMap::kDefaultHashMapCapacity, |
263 allocator); | 360 allocator); |
264 for (int i = properties()->length() - 1; i >= 0; i--) { | 361 for (int i = properties()->length() - 1; i >= 0; i--) { |
265 ObjectLiteral::Property* property = properties()->at(i); | 362 ObjectLiteral::Property* property = properties()->at(i); |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
583 // TODO(rossberg): all RecordTypeFeedback functions should disappear | 680 // TODO(rossberg): all RecordTypeFeedback functions should disappear |
584 // once we use the common type field in the AST consistently. | 681 // once we use the common type field in the AST consistently. |
585 | 682 |
586 void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) { | 683 void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) { |
587 set_to_boolean_types(oracle->ToBooleanTypes(test_id())); | 684 set_to_boolean_types(oracle->ToBooleanTypes(test_id())); |
588 } | 685 } |
589 | 686 |
590 | 687 |
591 bool Call::IsUsingCallFeedbackICSlot(Isolate* isolate) const { | 688 bool Call::IsUsingCallFeedbackICSlot(Isolate* isolate) const { |
592 CallType call_type = GetCallType(isolate); | 689 CallType call_type = GetCallType(isolate); |
593 if (IsUsingCallFeedbackSlot(isolate) || call_type == POSSIBLY_EVAL_CALL) { | 690 if (call_type == POSSIBLY_EVAL_CALL) { |
691 return false; | |
692 } | |
693 if (call_type == SUPER_CALL && !FLAG_vector_stores) { | |
594 return false; | 694 return false; |
595 } | 695 } |
596 return true; | 696 return true; |
597 } | 697 } |
598 | 698 |
599 | 699 |
600 bool Call::IsUsingCallFeedbackSlot(Isolate* isolate) const { | 700 bool Call::IsUsingCallFeedbackSlot(Isolate* isolate) const { |
601 // SuperConstructorCall uses a CallConstructStub, which wants | 701 // SuperConstructorCall uses a CallConstructStub, which wants |
602 // a Slot, not an IC slot. | 702 // a Slot, in addition to any IC slots requested elsewhere. |
603 return GetCallType(isolate) == SUPER_CALL; | 703 return GetCallType(isolate) == SUPER_CALL; |
604 } | 704 } |
605 | 705 |
606 | 706 |
607 FeedbackVectorRequirements Call::ComputeFeedbackRequirements( | 707 FeedbackVectorRequirements Call::ComputeFeedbackRequirements( |
608 Isolate* isolate, const ICSlotCache* cache) { | 708 Isolate* isolate, const ICSlotCache* cache) { |
609 int ic_slots = IsUsingCallFeedbackICSlot(isolate) ? 1 : 0; | 709 int ic_slots = IsUsingCallFeedbackICSlot(isolate) ? 1 : 0; |
610 int slots = IsUsingCallFeedbackSlot(isolate) ? 1 : 0; | 710 int slots = IsUsingCallFeedbackSlot(isolate) ? 1 : 0; |
611 // A Call uses either a slot or an IC slot. | |
612 DCHECK((ic_slots & slots) == 0); | |
613 return FeedbackVectorRequirements(slots, ic_slots); | 711 return FeedbackVectorRequirements(slots, ic_slots); |
614 } | 712 } |
615 | 713 |
616 | 714 |
617 Call::CallType Call::GetCallType(Isolate* isolate) const { | 715 Call::CallType Call::GetCallType(Isolate* isolate) const { |
618 VariableProxy* proxy = expression()->AsVariableProxy(); | 716 VariableProxy* proxy = expression()->AsVariableProxy(); |
619 if (proxy != NULL) { | 717 if (proxy != NULL) { |
620 if (proxy->var()->is_possibly_eval(isolate)) { | 718 if (proxy->var()->is_possibly_eval(isolate)) { |
621 return POSSIBLY_EVAL_CALL; | 719 return POSSIBLY_EVAL_CALL; |
622 } else if (proxy->var()->IsUnallocated()) { | 720 } else if (proxy->var()->IsUnallocated()) { |
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1011 // static | 1109 // static |
1012 bool Literal::Match(void* literal1, void* literal2) { | 1110 bool Literal::Match(void* literal1, void* literal2) { |
1013 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); | 1111 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); |
1014 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); | 1112 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); |
1015 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) || | 1113 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) || |
1016 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); | 1114 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); |
1017 } | 1115 } |
1018 | 1116 |
1019 | 1117 |
1020 } } // namespace v8::internal | 1118 } } // namespace v8::internal |
OLD | NEW |