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/ast.h" | 5 #include "src/ast/ast.h" |
6 | 6 |
7 #include <cmath> // For isfinite. | 7 #include <cmath> // For isfinite. |
8 | 8 |
9 #include "src/ast/compile-time-value.h" | 9 #include "src/ast/compile-time-value.h" |
10 #include "src/ast/prettyprinter.h" | 10 #include "src/ast/prettyprinter.h" |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 | 215 |
216 void VariableProxy::BindTo(Variable* var) { | 216 void VariableProxy::BindTo(Variable* var) { |
217 DCHECK((is_this() && var->is_this()) || raw_name() == var->raw_name()); | 217 DCHECK((is_this() && var->is_this()) || raw_name() == var->raw_name()); |
218 set_var(var); | 218 set_var(var); |
219 set_is_resolved(); | 219 set_is_resolved(); |
220 var->set_is_used(); | 220 var->set_is_used(); |
221 if (is_assigned()) var->set_maybe_assigned(); | 221 if (is_assigned()) var->set_maybe_assigned(); |
222 } | 222 } |
223 | 223 |
224 void VariableProxy::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec, | 224 void VariableProxy::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec, |
| 225 LanguageMode language_mode, |
225 FeedbackVectorSlotCache* cache) { | 226 FeedbackVectorSlotCache* cache) { |
226 if (UsesVariableFeedbackSlot()) { | 227 if (UsesVariableFeedbackSlot()) { |
227 // VariableProxies that point to the same Variable within a function can | 228 // VariableProxies that point to the same Variable within a function can |
228 // make their loads from the same IC slot. | 229 // make their loads from the same IC slot. |
229 if (var()->IsUnallocated() || var()->mode() == DYNAMIC_GLOBAL) { | 230 if (var()->IsUnallocated() || var()->mode() == DYNAMIC_GLOBAL) { |
230 ZoneHashMap::Entry* entry = cache->Get(var()); | 231 ZoneHashMap::Entry* entry = cache->Get(var()); |
231 if (entry != NULL) { | 232 if (entry != NULL) { |
232 variable_feedback_slot_ = FeedbackVectorSlot( | 233 variable_feedback_slot_ = FeedbackVectorSlot( |
233 static_cast<int>(reinterpret_cast<intptr_t>(entry->value))); | 234 static_cast<int>(reinterpret_cast<intptr_t>(entry->value))); |
234 return; | 235 return; |
235 } | 236 } |
236 variable_feedback_slot_ = spec->AddLoadGlobalICSlot(); | 237 variable_feedback_slot_ = spec->AddLoadGlobalICSlot(); |
237 cache->Put(var(), variable_feedback_slot_); | 238 cache->Put(var(), variable_feedback_slot_); |
238 } else { | 239 } else { |
239 variable_feedback_slot_ = spec->AddLoadICSlot(); | 240 variable_feedback_slot_ = spec->AddLoadICSlot(); |
240 } | 241 } |
241 } | 242 } |
242 } | 243 } |
243 | 244 |
244 | |
245 static void AssignVectorSlots(Expression* expr, FeedbackVectorSpec* spec, | 245 static void AssignVectorSlots(Expression* expr, FeedbackVectorSpec* spec, |
| 246 LanguageMode language_mode, |
246 FeedbackVectorSlot* out_slot) { | 247 FeedbackVectorSlot* out_slot) { |
247 Property* property = expr->AsProperty(); | 248 Property* property = expr->AsProperty(); |
248 LhsKind assign_type = Property::GetAssignType(property); | 249 LhsKind assign_type = Property::GetAssignType(property); |
249 if ((assign_type == VARIABLE && | 250 if ((assign_type == VARIABLE && |
250 expr->AsVariableProxy()->var()->IsUnallocated()) || | 251 expr->AsVariableProxy()->var()->IsUnallocated()) || |
251 assign_type == NAMED_PROPERTY || assign_type == KEYED_PROPERTY) { | 252 assign_type == NAMED_PROPERTY || assign_type == KEYED_PROPERTY) { |
252 // TODO(ishell): consider using ICSlotCache for variables here. | 253 // TODO(ishell): consider using ICSlotCache for variables here. |
253 FeedbackVectorSlotKind kind = assign_type == KEYED_PROPERTY | 254 if (assign_type == KEYED_PROPERTY) { |
254 ? FeedbackVectorSlotKind::KEYED_STORE_IC | 255 *out_slot = spec->AddKeyedStoreICSlot(language_mode); |
255 : FeedbackVectorSlotKind::STORE_IC; | 256 |
256 *out_slot = spec->AddSlot(kind); | 257 } else { |
| 258 *out_slot = spec->AddStoreICSlot(language_mode); |
| 259 } |
257 } | 260 } |
258 } | 261 } |
259 | 262 |
260 void ForInStatement::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec, | 263 void ForInStatement::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec, |
| 264 LanguageMode language_mode, |
261 FeedbackVectorSlotCache* cache) { | 265 FeedbackVectorSlotCache* cache) { |
262 AssignVectorSlots(each(), spec, &each_slot_); | 266 AssignVectorSlots(each(), spec, language_mode, &each_slot_); |
263 for_in_feedback_slot_ = spec->AddGeneralSlot(); | 267 for_in_feedback_slot_ = spec->AddGeneralSlot(); |
264 } | 268 } |
265 | 269 |
266 Assignment::Assignment(Token::Value op, Expression* target, Expression* value, | 270 Assignment::Assignment(Token::Value op, Expression* target, Expression* value, |
267 int pos) | 271 int pos) |
268 : Expression(pos, kAssignment), | 272 : Expression(pos, kAssignment), |
269 target_(target), | 273 target_(target), |
270 value_(value), | 274 value_(value), |
271 binary_operation_(NULL) { | 275 binary_operation_(NULL) { |
272 bit_field_ |= IsUninitializedField::encode(false) | | 276 bit_field_ |= IsUninitializedField::encode(false) | |
273 KeyTypeField::encode(ELEMENT) | | 277 KeyTypeField::encode(ELEMENT) | |
274 StoreModeField::encode(STANDARD_STORE) | TokenField::encode(op); | 278 StoreModeField::encode(STANDARD_STORE) | TokenField::encode(op); |
275 } | 279 } |
276 | 280 |
277 void Assignment::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec, | 281 void Assignment::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec, |
| 282 LanguageMode language_mode, |
278 FeedbackVectorSlotCache* cache) { | 283 FeedbackVectorSlotCache* cache) { |
279 AssignVectorSlots(target(), spec, &slot_); | 284 AssignVectorSlots(target(), spec, language_mode, &slot_); |
280 } | 285 } |
281 | 286 |
282 void CountOperation::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec, | 287 void CountOperation::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec, |
| 288 LanguageMode language_mode, |
283 FeedbackVectorSlotCache* cache) { | 289 FeedbackVectorSlotCache* cache) { |
284 AssignVectorSlots(expression(), spec, &slot_); | 290 AssignVectorSlots(expression(), spec, language_mode, &slot_); |
285 // Assign a slot to collect feedback about binary operations. Used only in | 291 // Assign a slot to collect feedback about binary operations. Used only in |
286 // ignition. Fullcodegen uses AstId to record type feedback. | 292 // ignition. Fullcodegen uses AstId to record type feedback. |
287 binary_operation_slot_ = spec->AddInterpreterBinaryOpICSlot(); | 293 binary_operation_slot_ = spec->AddInterpreterBinaryOpICSlot(); |
288 } | 294 } |
289 | 295 |
290 | 296 |
291 Token::Value Assignment::binary_op() const { | 297 Token::Value Assignment::binary_op() const { |
292 switch (op()) { | 298 switch (op()) { |
293 case Token::ASSIGN_BIT_OR: return Token::BIT_OR; | 299 case Token::ASSIGN_BIT_OR: return Token::BIT_OR; |
294 case Token::ASSIGN_BIT_XOR: return Token::BIT_XOR; | 300 case Token::ASSIGN_BIT_XOR: return Token::BIT_XOR; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 } | 388 } |
383 | 389 |
384 ClassLiteralProperty::ClassLiteralProperty(Expression* key, Expression* value, | 390 ClassLiteralProperty::ClassLiteralProperty(Expression* key, Expression* value, |
385 Kind kind, bool is_static, | 391 Kind kind, bool is_static, |
386 bool is_computed_name) | 392 bool is_computed_name) |
387 : LiteralProperty(key, value, is_computed_name), | 393 : LiteralProperty(key, value, is_computed_name), |
388 kind_(kind), | 394 kind_(kind), |
389 is_static_(is_static) {} | 395 is_static_(is_static) {} |
390 | 396 |
391 void ClassLiteral::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec, | 397 void ClassLiteral::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec, |
| 398 LanguageMode language_mode, |
392 FeedbackVectorSlotCache* cache) { | 399 FeedbackVectorSlotCache* cache) { |
393 // This logic that computes the number of slots needed for vector store | 400 // This logic that computes the number of slots needed for vector store |
394 // ICs must mirror BytecodeGenerator::VisitClassLiteral. | 401 // ICs must mirror BytecodeGenerator::VisitClassLiteral. |
395 if (FunctionLiteral::NeedsHomeObject(constructor())) { | 402 if (FunctionLiteral::NeedsHomeObject(constructor())) { |
396 home_object_slot_ = spec->AddStoreICSlot(); | 403 home_object_slot_ = spec->AddStoreICSlot(language_mode); |
397 } | 404 } |
398 | 405 |
399 if (NeedsProxySlot()) { | 406 if (NeedsProxySlot()) { |
400 proxy_slot_ = spec->AddStoreICSlot(); | 407 proxy_slot_ = spec->AddStoreICSlot(language_mode); |
401 } | 408 } |
402 | 409 |
403 for (int i = 0; i < properties()->length(); i++) { | 410 for (int i = 0; i < properties()->length(); i++) { |
404 ClassLiteral::Property* property = properties()->at(i); | 411 ClassLiteral::Property* property = properties()->at(i); |
405 Expression* value = property->value(); | 412 Expression* value = property->value(); |
406 if (FunctionLiteral::NeedsHomeObject(value)) { | 413 if (FunctionLiteral::NeedsHomeObject(value)) { |
407 property->SetSlot(spec->AddStoreICSlot()); | 414 property->SetSlot(spec->AddStoreICSlot(language_mode)); |
408 } | 415 } |
409 property->SetStoreDataPropertySlot( | 416 property->SetStoreDataPropertySlot( |
410 spec->AddStoreDataPropertyInLiteralICSlot()); | 417 spec->AddStoreDataPropertyInLiteralICSlot()); |
411 } | 418 } |
412 } | 419 } |
413 | 420 |
414 bool ObjectLiteral::Property::IsCompileTimeValue() const { | 421 bool ObjectLiteral::Property::IsCompileTimeValue() const { |
415 return kind_ == CONSTANT || | 422 return kind_ == CONSTANT || |
416 (kind_ == MATERIALIZED_LITERAL && | 423 (kind_ == MATERIALIZED_LITERAL && |
417 CompileTimeValue::IsCompileTimeValue(value_)); | 424 CompileTimeValue::IsCompileTimeValue(value_)); |
418 } | 425 } |
419 | 426 |
420 | 427 |
421 void ObjectLiteral::Property::set_emit_store(bool emit_store) { | 428 void ObjectLiteral::Property::set_emit_store(bool emit_store) { |
422 emit_store_ = emit_store; | 429 emit_store_ = emit_store; |
423 } | 430 } |
424 | 431 |
425 bool ObjectLiteral::Property::emit_store() const { return emit_store_; } | 432 bool ObjectLiteral::Property::emit_store() const { return emit_store_; } |
426 | 433 |
427 void ObjectLiteral::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec, | 434 void ObjectLiteral::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec, |
| 435 LanguageMode language_mode, |
428 FeedbackVectorSlotCache* cache) { | 436 FeedbackVectorSlotCache* cache) { |
429 MaterializedLiteral::AssignFeedbackVectorSlots(spec, cache); | 437 MaterializedLiteral::AssignFeedbackVectorSlots(spec, language_mode, cache); |
430 | 438 |
431 // This logic that computes the number of slots needed for vector store | 439 // This logic that computes the number of slots needed for vector store |
432 // ics must mirror FullCodeGenerator::VisitObjectLiteral. | 440 // ics must mirror FullCodeGenerator::VisitObjectLiteral. |
433 int property_index = 0; | 441 int property_index = 0; |
434 for (; property_index < properties()->length(); property_index++) { | 442 for (; property_index < properties()->length(); property_index++) { |
435 ObjectLiteral::Property* property = properties()->at(property_index); | 443 ObjectLiteral::Property* property = properties()->at(property_index); |
436 if (property->is_computed_name()) break; | 444 if (property->is_computed_name()) break; |
437 if (property->IsCompileTimeValue()) continue; | 445 if (property->IsCompileTimeValue()) continue; |
438 | 446 |
439 Literal* key = property->key()->AsLiteral(); | 447 Literal* key = property->key()->AsLiteral(); |
440 Expression* value = property->value(); | 448 Expression* value = property->value(); |
441 switch (property->kind()) { | 449 switch (property->kind()) { |
442 case ObjectLiteral::Property::SPREAD: | 450 case ObjectLiteral::Property::SPREAD: |
443 case ObjectLiteral::Property::CONSTANT: | 451 case ObjectLiteral::Property::CONSTANT: |
444 UNREACHABLE(); | 452 UNREACHABLE(); |
445 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 453 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
446 // Fall through. | 454 // Fall through. |
447 case ObjectLiteral::Property::COMPUTED: | 455 case ObjectLiteral::Property::COMPUTED: |
448 // It is safe to use [[Put]] here because the boilerplate already | 456 // It is safe to use [[Put]] here because the boilerplate already |
449 // contains computed properties with an uninitialized value. | 457 // contains computed properties with an uninitialized value. |
450 if (key->IsStringLiteral()) { | 458 if (key->IsStringLiteral()) { |
451 if (property->emit_store()) { | 459 if (property->emit_store()) { |
452 property->SetSlot(spec->AddStoreICSlot()); | 460 property->SetSlot(spec->AddStoreICSlot(language_mode)); |
453 if (FunctionLiteral::NeedsHomeObject(value)) { | 461 if (FunctionLiteral::NeedsHomeObject(value)) { |
454 property->SetSlot(spec->AddStoreICSlot(), 1); | 462 property->SetSlot(spec->AddStoreICSlot(language_mode), 1); |
455 } | 463 } |
456 } | 464 } |
457 break; | 465 break; |
458 } | 466 } |
459 if (property->emit_store() && FunctionLiteral::NeedsHomeObject(value)) { | 467 if (property->emit_store() && FunctionLiteral::NeedsHomeObject(value)) { |
460 property->SetSlot(spec->AddStoreICSlot()); | 468 property->SetSlot(spec->AddStoreICSlot(language_mode)); |
461 } | 469 } |
462 break; | 470 break; |
463 case ObjectLiteral::Property::PROTOTYPE: | 471 case ObjectLiteral::Property::PROTOTYPE: |
464 break; | 472 break; |
465 case ObjectLiteral::Property::GETTER: | 473 case ObjectLiteral::Property::GETTER: |
466 if (property->emit_store() && FunctionLiteral::NeedsHomeObject(value)) { | 474 if (property->emit_store() && FunctionLiteral::NeedsHomeObject(value)) { |
467 property->SetSlot(spec->AddStoreICSlot()); | 475 property->SetSlot(spec->AddStoreICSlot(language_mode)); |
468 } | 476 } |
469 break; | 477 break; |
470 case ObjectLiteral::Property::SETTER: | 478 case ObjectLiteral::Property::SETTER: |
471 if (property->emit_store() && FunctionLiteral::NeedsHomeObject(value)) { | 479 if (property->emit_store() && FunctionLiteral::NeedsHomeObject(value)) { |
472 property->SetSlot(spec->AddStoreICSlot()); | 480 property->SetSlot(spec->AddStoreICSlot(language_mode)); |
473 } | 481 } |
474 break; | 482 break; |
475 } | 483 } |
476 } | 484 } |
477 | 485 |
478 for (; property_index < properties()->length(); property_index++) { | 486 for (; property_index < properties()->length(); property_index++) { |
479 ObjectLiteral::Property* property = properties()->at(property_index); | 487 ObjectLiteral::Property* property = properties()->at(property_index); |
480 | 488 |
481 Expression* value = property->value(); | 489 Expression* value = property->value(); |
482 if (property->kind() != ObjectLiteral::Property::PROTOTYPE) { | 490 if (property->kind() != ObjectLiteral::Property::PROTOTYPE) { |
483 if (FunctionLiteral::NeedsHomeObject(value)) { | 491 if (FunctionLiteral::NeedsHomeObject(value)) { |
484 property->SetSlot(spec->AddStoreICSlot()); | 492 property->SetSlot(spec->AddStoreICSlot(language_mode)); |
485 } | 493 } |
486 } | 494 } |
487 property->SetStoreDataPropertySlot( | 495 property->SetStoreDataPropertySlot( |
488 spec->AddStoreDataPropertyInLiteralICSlot()); | 496 spec->AddStoreDataPropertyInLiteralICSlot()); |
489 } | 497 } |
490 } | 498 } |
491 | 499 |
492 | 500 |
493 void ObjectLiteral::CalculateEmitStore(Zone* zone) { | 501 void ObjectLiteral::CalculateEmitStore(Zone* zone) { |
494 const auto GETTER = ObjectLiteral::Property::GETTER; | 502 const auto GETTER = ObjectLiteral::Property::GETTER; |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
773 constant_elements_ = literals; | 781 constant_elements_ = literals; |
774 } | 782 } |
775 | 783 |
776 bool ArrayLiteral::IsFastCloningSupported() const { | 784 bool ArrayLiteral::IsFastCloningSupported() const { |
777 return depth() <= 1 && | 785 return depth() <= 1 && |
778 values()->length() <= | 786 values()->length() <= |
779 ConstructorBuiltinsAssembler::kMaximumClonedShallowArrayElements; | 787 ConstructorBuiltinsAssembler::kMaximumClonedShallowArrayElements; |
780 } | 788 } |
781 | 789 |
782 void ArrayLiteral::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec, | 790 void ArrayLiteral::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec, |
| 791 LanguageMode language_mode, |
783 FeedbackVectorSlotCache* cache) { | 792 FeedbackVectorSlotCache* cache) { |
784 MaterializedLiteral::AssignFeedbackVectorSlots(spec, cache); | 793 MaterializedLiteral::AssignFeedbackVectorSlots(spec, language_mode, cache); |
785 | 794 |
786 // This logic that computes the number of slots needed for vector store | 795 // This logic that computes the number of slots needed for vector store |
787 // ics must mirror FullCodeGenerator::VisitArrayLiteral. | 796 // ics must mirror FullCodeGenerator::VisitArrayLiteral. |
788 for (int array_index = 0; array_index < values()->length(); array_index++) { | 797 for (int array_index = 0; array_index < values()->length(); array_index++) { |
789 Expression* subexpr = values()->at(array_index); | 798 Expression* subexpr = values()->at(array_index); |
790 DCHECK(!subexpr->IsSpread()); | 799 DCHECK(!subexpr->IsSpread()); |
791 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; | 800 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
792 | 801 |
793 // We'll reuse the same literal slot for all of the non-constant | 802 // We'll reuse the same literal slot for all of the non-constant |
794 // subexpressions that use a keyed store IC. | 803 // subexpressions that use a keyed store IC. |
795 literal_slot_ = spec->AddKeyedStoreICSlot(); | 804 literal_slot_ = spec->AddKeyedStoreICSlot(language_mode); |
796 return; | 805 return; |
797 } | 806 } |
798 } | 807 } |
799 | 808 |
800 | 809 |
801 Handle<Object> MaterializedLiteral::GetBoilerplateValue(Expression* expression, | 810 Handle<Object> MaterializedLiteral::GetBoilerplateValue(Expression* expression, |
802 Isolate* isolate) { | 811 Isolate* isolate) { |
803 if (expression->IsLiteral()) { | 812 if (expression->IsLiteral()) { |
804 return expression->AsLiteral()->value(); | 813 return expression->AsLiteral()->value(); |
805 } | 814 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
844 void BinaryOperation::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) { | 853 void BinaryOperation::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) { |
845 // TODO(olivf) If this Operation is used in a test context, then the right | 854 // TODO(olivf) If this Operation is used in a test context, then the right |
846 // hand side has a ToBoolean stub and we want to collect the type information. | 855 // hand side has a ToBoolean stub and we want to collect the type information. |
847 // However the GraphBuilder expects it to be on the instruction corresponding | 856 // However the GraphBuilder expects it to be on the instruction corresponding |
848 // to the TestContext, therefore we have to store it here and not on the | 857 // to the TestContext, therefore we have to store it here and not on the |
849 // right hand operand. | 858 // right hand operand. |
850 set_to_boolean_types(oracle->ToBooleanTypes(right()->test_id())); | 859 set_to_boolean_types(oracle->ToBooleanTypes(right()->test_id())); |
851 } | 860 } |
852 | 861 |
853 void BinaryOperation::AssignFeedbackVectorSlots( | 862 void BinaryOperation::AssignFeedbackVectorSlots( |
854 FeedbackVectorSpec* spec, FeedbackVectorSlotCache* cache) { | 863 FeedbackVectorSpec* spec, LanguageMode language_mode, |
| 864 FeedbackVectorSlotCache* cache) { |
855 // Feedback vector slot is only used by interpreter for binary operations. | 865 // Feedback vector slot is only used by interpreter for binary operations. |
856 // Full-codegen uses AstId to record type feedback. | 866 // Full-codegen uses AstId to record type feedback. |
857 switch (op()) { | 867 switch (op()) { |
858 // Comma, logical_or and logical_and do not collect type feedback. | 868 // Comma, logical_or and logical_and do not collect type feedback. |
859 case Token::COMMA: | 869 case Token::COMMA: |
860 case Token::AND: | 870 case Token::AND: |
861 case Token::OR: | 871 case Token::OR: |
862 return; | 872 return; |
863 default: | 873 default: |
864 type_feedback_slot_ = spec->AddInterpreterBinaryOpICSlot(); | 874 type_feedback_slot_ = spec->AddInterpreterBinaryOpICSlot(); |
865 return; | 875 return; |
866 } | 876 } |
867 } | 877 } |
868 | 878 |
869 static bool IsTypeof(Expression* expr) { | 879 static bool IsTypeof(Expression* expr) { |
870 UnaryOperation* maybe_unary = expr->AsUnaryOperation(); | 880 UnaryOperation* maybe_unary = expr->AsUnaryOperation(); |
871 return maybe_unary != NULL && maybe_unary->op() == Token::TYPEOF; | 881 return maybe_unary != NULL && maybe_unary->op() == Token::TYPEOF; |
872 } | 882 } |
873 | 883 |
874 void CompareOperation::AssignFeedbackVectorSlots( | 884 void CompareOperation::AssignFeedbackVectorSlots( |
875 FeedbackVectorSpec* spec, FeedbackVectorSlotCache* cache_) { | 885 FeedbackVectorSpec* spec, LanguageMode language_mode, |
| 886 FeedbackVectorSlotCache* cache_) { |
876 // Feedback vector slot is only used by interpreter for binary operations. | 887 // Feedback vector slot is only used by interpreter for binary operations. |
877 // Full-codegen uses AstId to record type feedback. | 888 // Full-codegen uses AstId to record type feedback. |
878 switch (op()) { | 889 switch (op()) { |
879 // instanceof and in do not collect type feedback. | 890 // instanceof and in do not collect type feedback. |
880 case Token::INSTANCEOF: | 891 case Token::INSTANCEOF: |
881 case Token::IN: | 892 case Token::IN: |
882 return; | 893 return; |
883 default: | 894 default: |
884 type_feedback_slot_ = spec->AddInterpreterCompareICSlot(); | 895 type_feedback_slot_ = spec->AddInterpreterCompareICSlot(); |
885 } | 896 } |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1024 PROPERTY_NODE_LIST(GENERATE_CASE) | 1035 PROPERTY_NODE_LIST(GENERATE_CASE) |
1025 CALL_NODE_LIST(GENERATE_CASE) | 1036 CALL_NODE_LIST(GENERATE_CASE) |
1026 #undef GENERATE_CASE | 1037 #undef GENERATE_CASE |
1027 default: | 1038 default: |
1028 UNREACHABLE(); | 1039 UNREACHABLE(); |
1029 return false; | 1040 return false; |
1030 } | 1041 } |
1031 } | 1042 } |
1032 | 1043 |
1033 void Call::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec, | 1044 void Call::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec, |
| 1045 LanguageMode language_mode, |
1034 FeedbackVectorSlotCache* cache) { | 1046 FeedbackVectorSlotCache* cache) { |
1035 ic_slot_ = spec->AddCallICSlot(); | 1047 ic_slot_ = spec->AddCallICSlot(); |
1036 } | 1048 } |
1037 | 1049 |
1038 Call::CallType Call::GetCallType() const { | 1050 Call::CallType Call::GetCallType() const { |
1039 VariableProxy* proxy = expression()->AsVariableProxy(); | 1051 VariableProxy* proxy = expression()->AsVariableProxy(); |
1040 if (proxy != NULL) { | 1052 if (proxy != NULL) { |
1041 if (proxy->var()->IsUnallocated()) { | 1053 if (proxy->var()->IsUnallocated()) { |
1042 return GLOBAL_CALL; | 1054 return GLOBAL_CALL; |
1043 } else if (proxy->var()->IsLookupSlot()) { | 1055 } else if (proxy->var()->IsLookupSlot()) { |
(...skipping 19 matching lines...) Expand all Loading... |
1063 } | 1075 } |
1064 | 1076 |
1065 CaseClause::CaseClause(Expression* label, ZoneList<Statement*>* statements, | 1077 CaseClause::CaseClause(Expression* label, ZoneList<Statement*>* statements, |
1066 int pos) | 1078 int pos) |
1067 : Expression(pos, kCaseClause), | 1079 : Expression(pos, kCaseClause), |
1068 label_(label), | 1080 label_(label), |
1069 statements_(statements), | 1081 statements_(statements), |
1070 compare_type_(AstType::None()) {} | 1082 compare_type_(AstType::None()) {} |
1071 | 1083 |
1072 void CaseClause::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec, | 1084 void CaseClause::AssignFeedbackVectorSlots(FeedbackVectorSpec* spec, |
| 1085 LanguageMode language_mode, |
1073 FeedbackVectorSlotCache* cache) { | 1086 FeedbackVectorSlotCache* cache) { |
1074 type_feedback_slot_ = spec->AddInterpreterCompareICSlot(); | 1087 type_feedback_slot_ = spec->AddInterpreterCompareICSlot(); |
1075 } | 1088 } |
1076 | 1089 |
1077 uint32_t Literal::Hash() { | 1090 uint32_t Literal::Hash() { |
1078 return raw_value()->IsString() | 1091 return raw_value()->IsString() |
1079 ? raw_value()->AsString()->hash() | 1092 ? raw_value()->AsString()->hash() |
1080 : ComputeLongHash(double_to_uint64(raw_value()->AsNumber())); | 1093 : ComputeLongHash(double_to_uint64(raw_value()->AsNumber())); |
1081 } | 1094 } |
1082 | 1095 |
1083 | 1096 |
1084 // static | 1097 // static |
1085 bool Literal::Match(void* literal1, void* literal2) { | 1098 bool Literal::Match(void* literal1, void* literal2) { |
1086 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); | 1099 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); |
1087 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); | 1100 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); |
1088 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) || | 1101 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) || |
1089 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); | 1102 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); |
1090 } | 1103 } |
1091 | 1104 |
1092 const char* CallRuntime::debug_name() { | 1105 const char* CallRuntime::debug_name() { |
1093 #ifdef DEBUG | 1106 #ifdef DEBUG |
1094 return NameForNativeContextIntrinsicIndex(context_index_); | 1107 return NameForNativeContextIntrinsicIndex(context_index_); |
1095 #else | 1108 #else |
1096 return is_jsruntime() ? "(context function)" : function_->name; | 1109 return is_jsruntime() ? "(context function)" : function_->name; |
1097 #endif // DEBUG | 1110 #endif // DEBUG |
1098 } | 1111 } |
1099 | 1112 |
1100 } // namespace internal | 1113 } // namespace internal |
1101 } // namespace v8 | 1114 } // namespace v8 |
OLD | NEW |