| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 | 337 |
| 338 void AstTyper::VisitVariableProxy(VariableProxy* expr) { | 338 void AstTyper::VisitVariableProxy(VariableProxy* expr) { |
| 339 Variable* var = expr->var(); | 339 Variable* var = expr->var(); |
| 340 if (var->IsStackAllocated()) { | 340 if (var->IsStackAllocated()) { |
| 341 NarrowType(expr, store_.LookupBounds(variable_index(var))); | 341 NarrowType(expr, store_.LookupBounds(variable_index(var))); |
| 342 } | 342 } |
| 343 } | 343 } |
| 344 | 344 |
| 345 | 345 |
| 346 void AstTyper::VisitLiteral(Literal* expr) { | 346 void AstTyper::VisitLiteral(Literal* expr) { |
| 347 Type* type = Type::Constant(expr->value(), isolate_); | 347 Handle<Type> type = Type::Constant(expr->value(), isolate_); |
| 348 NarrowType(expr, Bounds(type, isolate_)); | 348 NarrowType(expr, Bounds(type)); |
| 349 } | 349 } |
| 350 | 350 |
| 351 | 351 |
| 352 void AstTyper::VisitRegExpLiteral(RegExpLiteral* expr) { | 352 void AstTyper::VisitRegExpLiteral(RegExpLiteral* expr) { |
| 353 NarrowType(expr, Bounds(Type::RegExp(), isolate_)); | 353 NarrowType(expr, Bounds(Type::RegExp(isolate_))); |
| 354 } | 354 } |
| 355 | 355 |
| 356 | 356 |
| 357 void AstTyper::VisitObjectLiteral(ObjectLiteral* expr) { | 357 void AstTyper::VisitObjectLiteral(ObjectLiteral* expr) { |
| 358 ZoneList<ObjectLiteral::Property*>* properties = expr->properties(); | 358 ZoneList<ObjectLiteral::Property*>* properties = expr->properties(); |
| 359 for (int i = 0; i < properties->length(); ++i) { | 359 for (int i = 0; i < properties->length(); ++i) { |
| 360 ObjectLiteral::Property* prop = properties->at(i); | 360 ObjectLiteral::Property* prop = properties->at(i); |
| 361 | 361 |
| 362 // Collect type feedback. | 362 // Collect type feedback. |
| 363 if ((prop->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL && | 363 if ((prop->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL && |
| 364 !CompileTimeValue::IsCompileTimeValue(prop->value())) || | 364 !CompileTimeValue::IsCompileTimeValue(prop->value())) || |
| 365 prop->kind() == ObjectLiteral::Property::COMPUTED) { | 365 prop->kind() == ObjectLiteral::Property::COMPUTED) { |
| 366 if (prop->key()->value()->IsInternalizedString() && prop->emit_store()) { | 366 if (prop->key()->value()->IsInternalizedString() && prop->emit_store()) { |
| 367 prop->RecordTypeFeedback(oracle()); | 367 prop->RecordTypeFeedback(oracle()); |
| 368 } | 368 } |
| 369 } | 369 } |
| 370 | 370 |
| 371 RECURSE(Visit(prop->value())); | 371 RECURSE(Visit(prop->value())); |
| 372 } | 372 } |
| 373 | 373 |
| 374 NarrowType(expr, Bounds(Type::Object(), isolate_)); | 374 NarrowType(expr, Bounds(Type::Object(isolate_))); |
| 375 } | 375 } |
| 376 | 376 |
| 377 | 377 |
| 378 void AstTyper::VisitArrayLiteral(ArrayLiteral* expr) { | 378 void AstTyper::VisitArrayLiteral(ArrayLiteral* expr) { |
| 379 ZoneList<Expression*>* values = expr->values(); | 379 ZoneList<Expression*>* values = expr->values(); |
| 380 for (int i = 0; i < values->length(); ++i) { | 380 for (int i = 0; i < values->length(); ++i) { |
| 381 Expression* value = values->at(i); | 381 Expression* value = values->at(i); |
| 382 RECURSE(Visit(value)); | 382 RECURSE(Visit(value)); |
| 383 } | 383 } |
| 384 | 384 |
| 385 NarrowType(expr, Bounds(Type::Array(), isolate_)); | 385 NarrowType(expr, Bounds(Type::Array(isolate_))); |
| 386 } | 386 } |
| 387 | 387 |
| 388 | 388 |
| 389 void AstTyper::VisitAssignment(Assignment* expr) { | 389 void AstTyper::VisitAssignment(Assignment* expr) { |
| 390 // Collect type feedback. | 390 // Collect type feedback. |
| 391 Property* prop = expr->target()->AsProperty(); | 391 Property* prop = expr->target()->AsProperty(); |
| 392 if (prop != NULL) { | 392 if (prop != NULL) { |
| 393 TypeFeedbackId id = expr->AssignmentFeedbackId(); | 393 TypeFeedbackId id = expr->AssignmentFeedbackId(); |
| 394 expr->set_is_uninitialized(oracle()->StoreIsUninitialized(id)); | 394 expr->set_is_uninitialized(oracle()->StoreIsUninitialized(id)); |
| 395 if (!expr->IsUninitialized()) { | 395 if (!expr->IsUninitialized()) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 RECURSE(Visit(expr->expression())); | 428 RECURSE(Visit(expr->expression())); |
| 429 | 429 |
| 430 // We don't know anything about the result type. | 430 // We don't know anything about the result type. |
| 431 } | 431 } |
| 432 | 432 |
| 433 | 433 |
| 434 void AstTyper::VisitThrow(Throw* expr) { | 434 void AstTyper::VisitThrow(Throw* expr) { |
| 435 RECURSE(Visit(expr->exception())); | 435 RECURSE(Visit(expr->exception())); |
| 436 // TODO(rossberg): is it worth having a non-termination effect? | 436 // TODO(rossberg): is it worth having a non-termination effect? |
| 437 | 437 |
| 438 NarrowType(expr, Bounds(Type::None(), isolate_)); | 438 NarrowType(expr, Bounds(Type::None(isolate_))); |
| 439 } | 439 } |
| 440 | 440 |
| 441 | 441 |
| 442 void AstTyper::VisitProperty(Property* expr) { | 442 void AstTyper::VisitProperty(Property* expr) { |
| 443 // Collect type feedback. | 443 // Collect type feedback. |
| 444 TypeFeedbackId id = expr->PropertyFeedbackId(); | 444 TypeFeedbackId id = expr->PropertyFeedbackId(); |
| 445 expr->set_is_uninitialized(oracle()->LoadIsUninitialized(id)); | 445 expr->set_is_uninitialized(oracle()->LoadIsUninitialized(id)); |
| 446 if (!expr->IsUninitialized()) { | 446 if (!expr->IsUninitialized()) { |
| 447 expr->set_is_pre_monomorphic(oracle()->LoadIsPreMonomorphic(id)); | 447 expr->set_is_pre_monomorphic(oracle()->LoadIsPreMonomorphic(id)); |
| 448 expr->set_is_monomorphic(oracle()->LoadIsMonomorphicNormal(id)); | 448 expr->set_is_monomorphic(oracle()->LoadIsMonomorphicNormal(id)); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 if (expr->op() == Token::NOT) { | 527 if (expr->op() == Token::NOT) { |
| 528 // TODO(rossberg): only do in test or value context. | 528 // TODO(rossberg): only do in test or value context. |
| 529 expr->expression()->RecordToBooleanTypeFeedback(oracle()); | 529 expr->expression()->RecordToBooleanTypeFeedback(oracle()); |
| 530 } | 530 } |
| 531 | 531 |
| 532 RECURSE(Visit(expr->expression())); | 532 RECURSE(Visit(expr->expression())); |
| 533 | 533 |
| 534 switch (expr->op()) { | 534 switch (expr->op()) { |
| 535 case Token::NOT: | 535 case Token::NOT: |
| 536 case Token::DELETE: | 536 case Token::DELETE: |
| 537 NarrowType(expr, Bounds(Type::Boolean(), isolate_)); | 537 NarrowType(expr, Bounds(Type::Boolean(isolate_))); |
| 538 break; | 538 break; |
| 539 case Token::VOID: | 539 case Token::VOID: |
| 540 NarrowType(expr, Bounds(Type::Undefined(), isolate_)); | 540 NarrowType(expr, Bounds(Type::Undefined(isolate_))); |
| 541 break; | 541 break; |
| 542 case Token::TYPEOF: | 542 case Token::TYPEOF: |
| 543 NarrowType(expr, Bounds(Type::InternalizedString(), isolate_)); | 543 NarrowType(expr, Bounds(Type::InternalizedString(isolate_))); |
| 544 break; | 544 break; |
| 545 default: | 545 default: |
| 546 UNREACHABLE(); | 546 UNREACHABLE(); |
| 547 } | 547 } |
| 548 } | 548 } |
| 549 | 549 |
| 550 | 550 |
| 551 void AstTyper::VisitCountOperation(CountOperation* expr) { | 551 void AstTyper::VisitCountOperation(CountOperation* expr) { |
| 552 // Collect type feedback. | 552 // Collect type feedback. |
| 553 TypeFeedbackId store_id = expr->CountStoreFeedbackId(); | 553 TypeFeedbackId store_id = expr->CountStoreFeedbackId(); |
| 554 expr->set_is_monomorphic(oracle()->StoreIsMonomorphicNormal(store_id)); | 554 expr->set_is_monomorphic(oracle()->StoreIsMonomorphicNormal(store_id)); |
| 555 expr->set_store_mode(oracle()->GetStoreMode(store_id)); | 555 expr->set_store_mode(oracle()->GetStoreMode(store_id)); |
| 556 oracle()->CountReceiverTypes(store_id, expr->GetReceiverTypes()); | 556 oracle()->CountReceiverTypes(store_id, expr->GetReceiverTypes()); |
| 557 expr->set_type(oracle()->CountType(expr->CountBinOpFeedbackId())); | 557 expr->set_type(oracle()->CountType(expr->CountBinOpFeedbackId())); |
| 558 // TODO(rossberg): merge the count type with the generic expression type. | 558 // TODO(rossberg): merge the count type with the generic expression type. |
| 559 | 559 |
| 560 RECURSE(Visit(expr->expression())); | 560 RECURSE(Visit(expr->expression())); |
| 561 | 561 |
| 562 NarrowType(expr, Bounds(Type::Smi(), Type::Number(), isolate_)); | 562 NarrowType(expr, Bounds(Type::Smi(isolate_), Type::Number(isolate_))); |
| 563 | 563 |
| 564 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 564 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 565 if (proxy != NULL && proxy->var()->IsStackAllocated()) { | 565 if (proxy != NULL && proxy->var()->IsStackAllocated()) { |
| 566 store_.Seq(variable_index(proxy->var()), Effect(expr->bounds())); | 566 store_.Seq(variable_index(proxy->var()), Effect(expr->bounds())); |
| 567 } | 567 } |
| 568 } | 568 } |
| 569 | 569 |
| 570 | 570 |
| 571 void AstTyper::VisitBinaryOperation(BinaryOperation* expr) { | 571 void AstTyper::VisitBinaryOperation(BinaryOperation* expr) { |
| 572 // Collect type feedback. | 572 // Collect type feedback. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 600 store_.Seq(left_effects); | 600 store_.Seq(left_effects); |
| 601 | 601 |
| 602 NarrowType(expr, Bounds::Either( | 602 NarrowType(expr, Bounds::Either( |
| 603 expr->left()->bounds(), expr->right()->bounds(), isolate_)); | 603 expr->left()->bounds(), expr->right()->bounds(), isolate_)); |
| 604 break; | 604 break; |
| 605 } | 605 } |
| 606 case Token::BIT_OR: | 606 case Token::BIT_OR: |
| 607 case Token::BIT_AND: { | 607 case Token::BIT_AND: { |
| 608 RECURSE(Visit(expr->left())); | 608 RECURSE(Visit(expr->left())); |
| 609 RECURSE(Visit(expr->right())); | 609 RECURSE(Visit(expr->right())); |
| 610 Handle<Type> upper( | 610 Handle<Type> upper = Type::Union( |
| 611 Type::Union( | 611 expr->left()->bounds().upper, expr->right()->bounds().upper, |
| 612 expr->left()->bounds().upper, expr->right()->bounds().upper), | |
| 613 isolate_); | 612 isolate_); |
| 614 if (!upper->Is(Type::Signed32())) | 613 if (!upper->Is(Type::Signed32())) |
| 615 upper = handle(Type::Signed32(), isolate_); | 614 upper = Type::Signed32(isolate_); |
| 616 Handle<Type> lower(Type::Intersect( | 615 Handle<Type> lower = |
| 617 handle(Type::Smi(), isolate_), upper), isolate_); | 616 Type::Intersect(Type::Smi(isolate_), upper, isolate_); |
| 618 NarrowType(expr, Bounds(lower, upper)); | 617 NarrowType(expr, Bounds(lower, upper)); |
| 619 break; | 618 break; |
| 620 } | 619 } |
| 621 case Token::BIT_XOR: | 620 case Token::BIT_XOR: |
| 622 case Token::SHL: | 621 case Token::SHL: |
| 623 case Token::SAR: | 622 case Token::SAR: |
| 624 RECURSE(Visit(expr->left())); | 623 RECURSE(Visit(expr->left())); |
| 625 RECURSE(Visit(expr->right())); | 624 RECURSE(Visit(expr->right())); |
| 626 NarrowType(expr, Bounds(Type::Smi(), Type::Signed32(), isolate_)); | 625 NarrowType(expr, Bounds(Type::Smi(isolate_), Type::Signed32(isolate_))); |
| 627 break; | 626 break; |
| 628 case Token::SHR: | 627 case Token::SHR: |
| 629 RECURSE(Visit(expr->left())); | 628 RECURSE(Visit(expr->left())); |
| 630 RECURSE(Visit(expr->right())); | 629 RECURSE(Visit(expr->right())); |
| 631 // TODO(rossberg): The upper bound would be Unsigned32, but since there | 630 // TODO(rossberg): The upper bound would be Unsigned32, but since there |
| 632 // is no 'positive Smi' type for the lower bound, we use the smallest | 631 // is no 'positive Smi' type for the lower bound, we use the smallest |
| 633 // union of Smi and Unsigned32 as upper bound instead. | 632 // union of Smi and Unsigned32 as upper bound instead. |
| 634 NarrowType(expr, Bounds(Type::Smi(), Type::Number(), isolate_)); | 633 NarrowType(expr, Bounds(Type::Smi(isolate_), Type::Number(isolate_))); |
| 635 break; | 634 break; |
| 636 case Token::ADD: { | 635 case Token::ADD: { |
| 637 RECURSE(Visit(expr->left())); | 636 RECURSE(Visit(expr->left())); |
| 638 RECURSE(Visit(expr->right())); | 637 RECURSE(Visit(expr->right())); |
| 639 Bounds l = expr->left()->bounds(); | 638 Bounds l = expr->left()->bounds(); |
| 640 Bounds r = expr->right()->bounds(); | 639 Bounds r = expr->right()->bounds(); |
| 641 Type* lower = | 640 Handle<Type> lower = |
| 642 l.lower->Is(Type::None()) || r.lower->Is(Type::None()) ? | 641 l.lower->Is(Type::None()) || r.lower->Is(Type::None()) ? |
| 643 Type::None() : | 642 Type::None(isolate_) : |
| 644 l.lower->Is(Type::String()) || r.lower->Is(Type::String()) ? | 643 l.lower->Is(Type::String()) || r.lower->Is(Type::String()) ? |
| 645 Type::String() : | 644 Type::String(isolate_) : |
| 646 l.lower->Is(Type::Number()) && r.lower->Is(Type::Number()) ? | 645 l.lower->Is(Type::Number()) && r.lower->Is(Type::Number()) ? |
| 647 Type::Smi() : Type::None(); | 646 Type::Smi(isolate_) : Type::None(isolate_); |
| 648 Type* upper = | 647 Handle<Type> upper = |
| 649 l.upper->Is(Type::String()) || r.upper->Is(Type::String()) ? | 648 l.upper->Is(Type::String()) || r.upper->Is(Type::String()) ? |
| 650 Type::String() : | 649 Type::String(isolate_) : |
| 651 l.upper->Is(Type::Number()) && r.upper->Is(Type::Number()) ? | 650 l.upper->Is(Type::Number()) && r.upper->Is(Type::Number()) ? |
| 652 Type::Number() : Type::NumberOrString(); | 651 Type::Number(isolate_) : Type::NumberOrString(isolate_); |
| 653 NarrowType(expr, Bounds(lower, upper, isolate_)); | 652 NarrowType(expr, Bounds(lower, upper)); |
| 654 break; | 653 break; |
| 655 } | 654 } |
| 656 case Token::SUB: | 655 case Token::SUB: |
| 657 case Token::MUL: | 656 case Token::MUL: |
| 658 case Token::DIV: | 657 case Token::DIV: |
| 659 case Token::MOD: | 658 case Token::MOD: |
| 660 RECURSE(Visit(expr->left())); | 659 RECURSE(Visit(expr->left())); |
| 661 RECURSE(Visit(expr->right())); | 660 RECURSE(Visit(expr->right())); |
| 662 NarrowType(expr, Bounds(Type::Smi(), Type::Number(), isolate_)); | 661 NarrowType(expr, Bounds(Type::Smi(isolate_), Type::Number(isolate_))); |
| 663 break; | 662 break; |
| 664 default: | 663 default: |
| 665 UNREACHABLE(); | 664 UNREACHABLE(); |
| 666 } | 665 } |
| 667 } | 666 } |
| 668 | 667 |
| 669 | 668 |
| 670 void AstTyper::VisitCompareOperation(CompareOperation* expr) { | 669 void AstTyper::VisitCompareOperation(CompareOperation* expr) { |
| 671 // Collect type feedback. | 670 // Collect type feedback. |
| 672 Handle<Type> left_type, right_type, combined_type; | 671 Handle<Type> left_type, right_type, combined_type; |
| 673 oracle()->CompareType(expr->CompareOperationFeedbackId(), | 672 oracle()->CompareType(expr->CompareOperationFeedbackId(), |
| 674 &left_type, &right_type, &combined_type); | 673 &left_type, &right_type, &combined_type); |
| 675 NarrowLowerType(expr->left(), left_type); | 674 NarrowLowerType(expr->left(), left_type); |
| 676 NarrowLowerType(expr->right(), right_type); | 675 NarrowLowerType(expr->right(), right_type); |
| 677 expr->set_combined_type(combined_type); | 676 expr->set_combined_type(combined_type); |
| 678 | 677 |
| 679 RECURSE(Visit(expr->left())); | 678 RECURSE(Visit(expr->left())); |
| 680 RECURSE(Visit(expr->right())); | 679 RECURSE(Visit(expr->right())); |
| 681 | 680 |
| 682 NarrowType(expr, Bounds(Type::Boolean(), isolate_)); | 681 NarrowType(expr, Bounds(Type::Boolean(isolate_))); |
| 683 } | 682 } |
| 684 | 683 |
| 685 | 684 |
| 686 void AstTyper::VisitThisFunction(ThisFunction* expr) { | 685 void AstTyper::VisitThisFunction(ThisFunction* expr) { |
| 687 } | 686 } |
| 688 | 687 |
| 689 | 688 |
| 690 void AstTyper::VisitDeclarations(ZoneList<Declaration*>* decls) { | 689 void AstTyper::VisitDeclarations(ZoneList<Declaration*>* decls) { |
| 691 for (int i = 0; i < decls->length(); ++i) { | 690 for (int i = 0; i < decls->length(); ++i) { |
| 692 Declaration* decl = decls->at(i); | 691 Declaration* decl = decls->at(i); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 735 void AstTyper::VisitModuleUrl(ModuleUrl* module) { | 734 void AstTyper::VisitModuleUrl(ModuleUrl* module) { |
| 736 } | 735 } |
| 737 | 736 |
| 738 | 737 |
| 739 void AstTyper::VisitModuleStatement(ModuleStatement* stmt) { | 738 void AstTyper::VisitModuleStatement(ModuleStatement* stmt) { |
| 740 RECURSE(Visit(stmt->body())); | 739 RECURSE(Visit(stmt->body())); |
| 741 } | 740 } |
| 742 | 741 |
| 743 | 742 |
| 744 } } // namespace v8::internal | 743 } } // namespace v8::internal |
| OLD | NEW |