| 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 |