| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
| 9 #include "vm/flow_graph_builder.h" | 9 #include "vm/flow_graph_builder.h" |
| 10 #include "vm/flow_graph_compiler.h" | 10 #include "vm/flow_graph_compiler.h" |
| 11 #include "vm/locations.h" | 11 #include "vm/locations.h" |
| 12 #include "vm/object.h" | 12 #include "vm/object.h" |
| 13 #include "vm/os.h" | 13 #include "vm/os.h" |
| 14 #include "vm/scopes.h" | 14 #include "vm/scopes.h" |
| 15 #include "vm/stub_code.h" | 15 #include "vm/stub_code.h" |
| 16 #include "vm/symbols.h" | 16 #include "vm/symbols.h" |
| 17 | 17 |
| 18 namespace dart { | 18 namespace dart { |
| 19 | 19 |
| 20 DECLARE_FLAG(bool, enable_type_checks); |
| 21 |
| 22 |
| 20 MethodRecognizer::Kind MethodRecognizer::RecognizeKind( | 23 MethodRecognizer::Kind MethodRecognizer::RecognizeKind( |
| 21 const Function& function) { | 24 const Function& function) { |
| 22 // Only core library methods can be recognized. | 25 // Only core library methods can be recognized. |
| 23 const Library& core_lib = Library::Handle(Library::CoreLibrary()); | 26 const Library& core_lib = Library::Handle(Library::CoreLibrary()); |
| 24 const Library& core_impl_lib = Library::Handle(Library::CoreImplLibrary()); | 27 const Library& core_impl_lib = Library::Handle(Library::CoreImplLibrary()); |
| 25 const Class& function_class = Class::Handle(function.owner()); | 28 const Class& function_class = Class::Handle(function.owner()); |
| 26 if ((function_class.library() != core_lib.raw()) && | 29 if ((function_class.library() != core_lib.raw()) && |
| 27 (function_class.library() != core_impl_lib.raw())) { | 30 (function_class.library() != core_impl_lib.raw())) { |
| 28 return kUnknown; | 31 return kUnknown; |
| 29 } | 32 } |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 320 Value* PhiInstr::InputAt(intptr_t i) const { | 323 Value* PhiInstr::InputAt(intptr_t i) const { |
| 321 return inputs_[i]; | 324 return inputs_[i]; |
| 322 } | 325 } |
| 323 | 326 |
| 324 | 327 |
| 325 void PhiInstr::SetInputAt(intptr_t i, Value* value) { | 328 void PhiInstr::SetInputAt(intptr_t i, Value* value) { |
| 326 inputs_[i] = value; | 329 inputs_[i] = value; |
| 327 } | 330 } |
| 328 | 331 |
| 329 | 332 |
| 333 RawAbstractType* PhiInstr::StaticType() const { |
| 334 // TODO(regis): Return the least upper bound of the input static types. |
| 335 return Type::DynamicType(); |
| 336 } |
| 337 |
| 338 |
| 330 intptr_t ParameterInstr::InputCount() const { | 339 intptr_t ParameterInstr::InputCount() const { |
| 331 return 0; | 340 return 0; |
| 332 } | 341 } |
| 333 | 342 |
| 334 | 343 |
| 335 Value* ParameterInstr::InputAt(intptr_t i) const { | 344 Value* ParameterInstr::InputAt(intptr_t i) const { |
| 336 UNREACHABLE(); | 345 UNREACHABLE(); |
| 337 return NULL; | 346 return NULL; |
| 338 } | 347 } |
| 339 | 348 |
| 340 | 349 |
| 341 void ParameterInstr::SetInputAt(intptr_t i, Value* value) { | 350 void ParameterInstr::SetInputAt(intptr_t i, Value* value) { |
| 342 UNREACHABLE(); | 351 UNREACHABLE(); |
| 343 } | 352 } |
| 344 | 353 |
| 345 | 354 |
| 355 RawAbstractType* ParameterInstr::StaticType() const { |
| 356 // TODO(regis): Can type feedback provide information about the static type |
| 357 // of a passed-in parameter? |
| 358 // Note that in checked mode, we could return the static type of the formal |
| 359 // parameter. However, this would be wrong if ParameterInstr is used to type |
| 360 // check the passed-in parameter, since the type check would then always be |
| 361 // wrongly eliminated. |
| 362 return Type::DynamicType(); |
| 363 } |
| 364 |
| 365 |
| 346 intptr_t GraphEntryInstr::InputCount() const { | 366 intptr_t GraphEntryInstr::InputCount() const { |
| 347 return 0; | 367 return 0; |
| 348 } | 368 } |
| 349 | 369 |
| 350 | 370 |
| 351 Value* GraphEntryInstr::InputAt(intptr_t i) const { | 371 Value* GraphEntryInstr::InputAt(intptr_t i) const { |
| 352 UNREACHABLE(); | 372 UNREACHABLE(); |
| 353 return NULL; | 373 return NULL; |
| 354 } | 374 } |
| 355 | 375 |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 643 } | 663 } |
| 644 } | 664 } |
| 645 | 665 |
| 646 | 666 |
| 647 RawAbstractType* UseVal::StaticType() const { | 667 RawAbstractType* UseVal::StaticType() const { |
| 648 return definition()->StaticType(); | 668 return definition()->StaticType(); |
| 649 } | 669 } |
| 650 | 670 |
| 651 | 671 |
| 652 RawAbstractType* AssertAssignableComp::StaticType() const { | 672 RawAbstractType* AssertAssignableComp::StaticType() const { |
| 673 const AbstractType& value_static_type = |
| 674 AbstractType::Handle(value()->StaticType()); |
| 675 if (value_static_type.IsMoreSpecificThan(dst_type(), NULL)) { |
| 676 return value_static_type.raw(); |
| 677 } |
| 653 return dst_type().raw(); | 678 return dst_type().raw(); |
| 654 } | 679 } |
| 655 | 680 |
| 656 | 681 |
| 657 RawAbstractType* AssertBooleanComp::StaticType() const { | 682 RawAbstractType* AssertBooleanComp::StaticType() const { |
| 658 return Type::BoolInterface(); | 683 return Type::BoolInterface(); |
| 659 } | 684 } |
| 660 | 685 |
| 661 | 686 |
| 662 RawAbstractType* CurrentContextComp::StaticType() const { | 687 RawAbstractType* CurrentContextComp::StaticType() const { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 674 RawAbstractType* ClosureCallComp::StaticType() const { | 699 RawAbstractType* ClosureCallComp::StaticType() const { |
| 675 // Because of function subtyping rules, the static return type of a closure | 700 // Because of function subtyping rules, the static return type of a closure |
| 676 // call cannot be relied upon for static type analysis. For example, a | 701 // call cannot be relied upon for static type analysis. For example, a |
| 677 // function returning Dynamic can be assigned to a closure variable declared | 702 // function returning Dynamic can be assigned to a closure variable declared |
| 678 // to return int and may actually return a double at run-time. | 703 // to return int and may actually return a double at run-time. |
| 679 return Type::DynamicType(); | 704 return Type::DynamicType(); |
| 680 } | 705 } |
| 681 | 706 |
| 682 | 707 |
| 683 RawAbstractType* InstanceCallComp::StaticType() const { | 708 RawAbstractType* InstanceCallComp::StaticType() const { |
| 709 // TODO(regis): Return a more specific type than Dynamic for recognized |
| 710 // combinations of receiver static type and method name. |
| 684 return Type::DynamicType(); | 711 return Type::DynamicType(); |
| 685 } | 712 } |
| 686 | 713 |
| 687 | 714 |
| 688 RawAbstractType* PolymorphicInstanceCallComp::StaticType() const { | 715 RawAbstractType* PolymorphicInstanceCallComp::StaticType() const { |
| 689 return Type::DynamicType(); | 716 return Type::DynamicType(); |
| 690 } | 717 } |
| 691 | 718 |
| 692 | 719 |
| 693 RawAbstractType* StaticCallComp::StaticType() const { | 720 RawAbstractType* StaticCallComp::StaticType() const { |
| 694 return function().result_type(); | 721 return function().result_type(); |
| 695 } | 722 } |
| 696 | 723 |
| 697 | 724 |
| 698 RawAbstractType* LoadLocalComp::StaticType() const { | 725 RawAbstractType* LoadLocalComp::StaticType() const { |
| 699 return local().type().raw(); | 726 // TODO(regis): Verify that the type of the receiver is properly set. |
| 727 if (FLAG_enable_type_checks) { |
| 728 return local().type().raw(); |
| 729 } |
| 730 return Type::DynamicType(); |
| 700 } | 731 } |
| 701 | 732 |
| 702 | 733 |
| 703 RawAbstractType* StoreLocalComp::StaticType() const { | 734 RawAbstractType* StoreLocalComp::StaticType() const { |
| 704 const AbstractType& assigned_value_type = | 735 return value()->StaticType(); |
| 705 AbstractType::Handle(value()->StaticType()); | |
| 706 if (assigned_value_type.IsDynamicType()) { | |
| 707 // Static type of assigned value is unknown, return static type of local. | |
| 708 return local().type().raw(); | |
| 709 } | |
| 710 return assigned_value_type.raw(); | |
| 711 } | 736 } |
| 712 | 737 |
| 713 | 738 |
| 714 RawAbstractType* StrictCompareComp::StaticType() const { | 739 RawAbstractType* StrictCompareComp::StaticType() const { |
| 715 return Type::BoolInterface(); | 740 return Type::BoolInterface(); |
| 716 } | 741 } |
| 717 | 742 |
| 718 | 743 |
| 719 RawAbstractType* EqualityCompareComp::StaticType() const { | 744 RawAbstractType* EqualityCompareComp::StaticType() const { |
| 720 return Type::BoolInterface(); | 745 return Type::BoolInterface(); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 744 return AbstractType::null(); | 769 return AbstractType::null(); |
| 745 } | 770 } |
| 746 | 771 |
| 747 | 772 |
| 748 RawAbstractType* InstanceSetterComp::StaticType() const { | 773 RawAbstractType* InstanceSetterComp::StaticType() const { |
| 749 return value()->StaticType(); | 774 return value()->StaticType(); |
| 750 } | 775 } |
| 751 | 776 |
| 752 | 777 |
| 753 RawAbstractType* StaticSetterComp::StaticType() const { | 778 RawAbstractType* StaticSetterComp::StaticType() const { |
| 754 const AbstractType& assigned_value_type = | 779 return value()->StaticType(); |
| 755 AbstractType::Handle(value()->StaticType()); | |
| 756 if (assigned_value_type.IsDynamicType()) { | |
| 757 // Static type of assigned value is unknown, return static type of setter | |
| 758 // value parameter. | |
| 759 return setter_function().ParameterTypeAt(0); | |
| 760 } | |
| 761 return assigned_value_type.raw(); | |
| 762 } | 780 } |
| 763 | 781 |
| 764 | 782 |
| 765 RawAbstractType* LoadInstanceFieldComp::StaticType() const { | 783 RawAbstractType* LoadInstanceFieldComp::StaticType() const { |
| 766 return field().type(); | 784 if (FLAG_enable_type_checks) { |
| 785 return field().type(); |
| 786 } |
| 787 return Type::DynamicType(); |
| 767 } | 788 } |
| 768 | 789 |
| 769 | 790 |
| 770 RawAbstractType* StoreInstanceFieldComp::StaticType() const { | 791 RawAbstractType* StoreInstanceFieldComp::StaticType() const { |
| 771 const AbstractType& assigned_value_type = | 792 return value()->StaticType(); |
| 772 AbstractType::Handle(value()->StaticType()); | |
| 773 if (assigned_value_type.IsDynamicType()) { | |
| 774 // Static type of assigned value is unknown, return static type of field. | |
| 775 return field().type(); | |
| 776 } | |
| 777 return assigned_value_type.raw(); | |
| 778 } | 793 } |
| 779 | 794 |
| 780 | 795 |
| 781 RawAbstractType* LoadStaticFieldComp::StaticType() const { | 796 RawAbstractType* LoadStaticFieldComp::StaticType() const { |
| 782 return field().type(); | 797 if (FLAG_enable_type_checks) { |
| 798 return field().type(); |
| 799 } |
| 800 return Type::DynamicType(); |
| 783 } | 801 } |
| 784 | 802 |
| 785 | 803 |
| 786 RawAbstractType* StoreStaticFieldComp::StaticType() const { | 804 RawAbstractType* StoreStaticFieldComp::StaticType() const { |
| 787 const AbstractType& assigned_value_type = | 805 return value()->StaticType(); |
| 788 AbstractType::Handle(value()->StaticType()); | |
| 789 if (assigned_value_type.IsDynamicType()) { | |
| 790 // Static type of assigned value is unknown, return static type of field. | |
| 791 return field().type(); | |
| 792 } | |
| 793 return assigned_value_type.raw(); | |
| 794 } | 806 } |
| 795 | 807 |
| 796 | 808 |
| 797 RawAbstractType* BooleanNegateComp::StaticType() const { | 809 RawAbstractType* BooleanNegateComp::StaticType() const { |
| 798 return Type::BoolInterface(); | 810 return Type::BoolInterface(); |
| 799 } | 811 } |
| 800 | 812 |
| 801 | 813 |
| 802 RawAbstractType* InstanceOfComp::StaticType() const { | 814 RawAbstractType* InstanceOfComp::StaticType() const { |
| 803 return Type::BoolInterface(); | 815 return Type::BoolInterface(); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 829 } | 841 } |
| 830 | 842 |
| 831 | 843 |
| 832 RawAbstractType* LoadVMFieldComp::StaticType() const { | 844 RawAbstractType* LoadVMFieldComp::StaticType() const { |
| 833 ASSERT(!type().IsNull()); | 845 ASSERT(!type().IsNull()); |
| 834 return type().raw(); | 846 return type().raw(); |
| 835 } | 847 } |
| 836 | 848 |
| 837 | 849 |
| 838 RawAbstractType* StoreVMFieldComp::StaticType() const { | 850 RawAbstractType* StoreVMFieldComp::StaticType() const { |
| 839 ASSERT(!type().IsNull()); | 851 return value()->StaticType(); |
| 840 const AbstractType& assigned_value_type = | |
| 841 AbstractType::Handle(value()->StaticType()); | |
| 842 if (assigned_value_type.IsDynamicType()) { | |
| 843 // Static type of assigned value is unknown, return static type of field. | |
| 844 return type().raw(); | |
| 845 } | |
| 846 return assigned_value_type.raw(); | |
| 847 } | 852 } |
| 848 | 853 |
| 849 | 854 |
| 850 RawAbstractType* InstantiateTypeArgumentsComp::StaticType() const { | 855 RawAbstractType* InstantiateTypeArgumentsComp::StaticType() const { |
| 851 UNREACHABLE(); | 856 UNREACHABLE(); |
| 852 return AbstractType::null(); | 857 return AbstractType::null(); |
| 853 } | 858 } |
| 854 | 859 |
| 855 | 860 |
| 856 RawAbstractType* ExtractConstructorTypeArgumentsComp::StaticType() const { | 861 RawAbstractType* ExtractConstructorTypeArgumentsComp::StaticType() const { |
| (...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1343 if (compiler->is_ssa()) { | 1348 if (compiler->is_ssa()) { |
| 1344 ASSERT(locs()->in(0).IsRegister()); | 1349 ASSERT(locs()->in(0).IsRegister()); |
| 1345 __ PushRegister(locs()->in(0).reg()); | 1350 __ PushRegister(locs()->in(0).reg()); |
| 1346 } | 1351 } |
| 1347 } | 1352 } |
| 1348 | 1353 |
| 1349 | 1354 |
| 1350 #undef __ | 1355 #undef __ |
| 1351 | 1356 |
| 1352 } // namespace dart | 1357 } // namespace dart |
| OLD | NEW |