| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 }; | 73 }; |
| 74 | 74 |
| 75 void Initialize(); | 75 void Initialize(); |
| 76 | 76 |
| 77 Handle<JSObject> StubHolder(Handle<JSObject> receiver, | 77 Handle<JSObject> StubHolder(Handle<JSObject> receiver, |
| 78 Handle<JSObject> holder); | 78 Handle<JSObject> holder); |
| 79 | 79 |
| 80 Handle<Code> FindIC(Handle<Name> name, | 80 Handle<Code> FindIC(Handle<Name> name, |
| 81 Handle<JSObject> stub_holder, | 81 Handle<JSObject> stub_holder, |
| 82 Code::Kind kind, | 82 Code::Kind kind, |
| 83 Code::StubType type); | 83 Code::StubType type, |
| 84 Code::ExtraICState extra_state = Code::kNoExtraICState); |
| 84 | 85 |
| 85 Handle<Code> FindStub(Handle<Name> name, | 86 Handle<Code> FindHandler( |
| 86 Handle<JSObject> stub_holder, | 87 Handle<Name> name, |
| 87 Code::Kind kind, | 88 Handle<JSObject> stub_holder, |
| 88 Code::StubType type); | 89 Code::Kind kind, |
| 90 Code::StubType type, |
| 91 Code::ExtraICState extra_state = Code::kNoExtraICState); |
| 89 | 92 |
| 90 Handle<Code> ComputeMonomorphicIC(Handle<JSObject> receiver, | 93 Handle<Code> ComputeMonomorphicIC(Handle<JSObject> receiver, |
| 91 Handle<Code> handler, | 94 Handle<Code> handler, |
| 92 Handle<Name> name); | 95 Handle<Name> name); |
| 93 Handle<Code> ComputeKeyedMonomorphicIC(Handle<JSObject> receiver, | 96 Handle<Code> ComputeKeyedMonomorphicIC(Handle<JSObject> receiver, |
| 94 Handle<Code> handler, | 97 Handle<Code> handler, |
| 95 Handle<Name> name); | 98 Handle<Name> name); |
| 96 | 99 |
| 97 // Computes the right stub matching. Inserts the result in the | 100 // Computes the right stub matching. Inserts the result in the |
| 98 // cache before returning. This might compile a stub if needed. | 101 // cache before returning. This might compile a stub if needed. |
| (...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 Register scratch2, | 509 Register scratch2, |
| 507 Label* miss_label); | 510 Label* miss_label); |
| 508 | 511 |
| 509 void GenerateStoreField(MacroAssembler* masm, | 512 void GenerateStoreField(MacroAssembler* masm, |
| 510 Handle<JSObject> object, | 513 Handle<JSObject> object, |
| 511 int index, | 514 int index, |
| 512 Handle<Map> transition, | 515 Handle<Map> transition, |
| 513 Handle<Name> name, | 516 Handle<Name> name, |
| 514 Register receiver_reg, | 517 Register receiver_reg, |
| 515 Register name_reg, | 518 Register name_reg, |
| 519 Register value_reg, |
| 516 Register scratch1, | 520 Register scratch1, |
| 517 Register scratch2, | 521 Register scratch2, |
| 518 Label* miss_label); | 522 Label* miss_label, |
| 523 Label* miss_restore_name); |
| 519 | 524 |
| 520 static void GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind); | 525 static Builtins::Name MissBuiltin(Code::Kind kind) { |
| 521 static void GenerateStoreMiss(MacroAssembler* masm, Code::Kind kind); | 526 switch (kind) { |
| 522 | 527 case Code::LOAD_IC: return Builtins::kLoadIC_Miss; |
| 523 static void GenerateKeyedLoadMissForceGeneric(MacroAssembler* masm); | 528 case Code::STORE_IC: return Builtins::kStoreIC_Miss; |
| 529 case Code::KEYED_LOAD_IC: return Builtins::kKeyedLoadIC_Miss; |
| 530 case Code::KEYED_STORE_IC: return Builtins::kKeyedStoreIC_Miss; |
| 531 default: UNREACHABLE(); |
| 532 } |
| 533 return Builtins::kLoadIC_Miss; |
| 534 } |
| 535 static void TailCallBuiltin(MacroAssembler* masm, Builtins::Name name); |
| 524 | 536 |
| 525 // Generates code that verifies that the property holder has not changed | 537 // Generates code that verifies that the property holder has not changed |
| 526 // (checking maps of objects in the prototype chain for fast and global | 538 // (checking maps of objects in the prototype chain for fast and global |
| 527 // objects or doing negative lookup for slow objects, ensures that the | 539 // objects or doing negative lookup for slow objects, ensures that the |
| 528 // property cells for global objects are still empty) and checks that the map | 540 // property cells for global objects are still empty) and checks that the map |
| 529 // of the holder has not changed. If necessary the function also generates | 541 // of the holder has not changed. If necessary the function also generates |
| 530 // code for security check in case of global object holders. Helps to make | 542 // code for security check in case of global object holders. Helps to make |
| 531 // sure that the current IC is still valid. | 543 // sure that the current IC is still valid. |
| 532 // | 544 // |
| 533 // The scratch and holder registers are always clobbered, but the object | 545 // The scratch and holder registers are always clobbered, but the object |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 570 void set_failure(Failure* failure) { failure_ = failure; } | 582 void set_failure(Failure* failure) { failure_ = failure; } |
| 571 | 583 |
| 572 static void LookupPostInterceptor(Handle<JSObject> holder, | 584 static void LookupPostInterceptor(Handle<JSObject> holder, |
| 573 Handle<Name> name, | 585 Handle<Name> name, |
| 574 LookupResult* lookup); | 586 LookupResult* lookup); |
| 575 | 587 |
| 576 Isolate* isolate() { return isolate_; } | 588 Isolate* isolate() { return isolate_; } |
| 577 Heap* heap() { return isolate()->heap(); } | 589 Heap* heap() { return isolate()->heap(); } |
| 578 Factory* factory() { return isolate()->factory(); } | 590 Factory* factory() { return isolate()->factory(); } |
| 579 | 591 |
| 580 void GenerateTailCall(Handle<Code> code); | 592 static void GenerateTailCall(MacroAssembler* masm, Handle<Code> code); |
| 581 | 593 |
| 582 private: | 594 private: |
| 583 Isolate* isolate_; | 595 Isolate* isolate_; |
| 584 MacroAssembler masm_; | 596 MacroAssembler masm_; |
| 585 Failure* failure_; | 597 Failure* failure_; |
| 586 }; | 598 }; |
| 587 | 599 |
| 588 | 600 |
| 589 enum FrontendCheckType { PERFORM_INITIAL_CHECKS, SKIP_INITIAL_CHECKS }; | 601 enum FrontendCheckType { PERFORM_INITIAL_CHECKS, SKIP_INITIAL_CHECKS }; |
| 590 | 602 |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 class KeyedLoadStubCompiler: public BaseLoadStubCompiler { | 744 class KeyedLoadStubCompiler: public BaseLoadStubCompiler { |
| 733 public: | 745 public: |
| 734 explicit KeyedLoadStubCompiler(Isolate* isolate) | 746 explicit KeyedLoadStubCompiler(Isolate* isolate) |
| 735 : BaseLoadStubCompiler(isolate, registers()) { } | 747 : BaseLoadStubCompiler(isolate, registers()) { } |
| 736 | 748 |
| 737 Handle<Code> CompileLoadElement(Handle<Map> receiver_map); | 749 Handle<Code> CompileLoadElement(Handle<Map> receiver_map); |
| 738 | 750 |
| 739 void CompileElementHandlers(MapHandleList* receiver_maps, | 751 void CompileElementHandlers(MapHandleList* receiver_maps, |
| 740 CodeHandleList* handlers); | 752 CodeHandleList* handlers); |
| 741 | 753 |
| 742 Handle<Code> CompileLoadElementPolymorphic(MapHandleList* receiver_maps); | |
| 743 | |
| 744 static void GenerateLoadDictionaryElement(MacroAssembler* masm); | 754 static void GenerateLoadDictionaryElement(MacroAssembler* masm); |
| 745 | 755 |
| 746 static Register receiver() { return registers()[0]; } | 756 static Register receiver() { return registers()[0]; } |
| 747 | 757 |
| 748 private: | 758 private: |
| 749 static Register* registers(); | 759 static Register* registers(); |
| 750 virtual Code::Kind kind() { return Code::KEYED_LOAD_IC; } | 760 virtual Code::Kind kind() { return Code::KEYED_LOAD_IC; } |
| 751 virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) { | 761 virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) { |
| 752 if (!code->is_inline_cache_stub()) return Logger::STUB_TAG; | 762 if (!code->is_inline_cache_stub()) return Logger::STUB_TAG; |
| 753 return code->ic_state() == MONOMORPHIC | 763 return code->ic_state() == MONOMORPHIC |
| 754 ? Logger::KEYED_LOAD_IC_TAG : Logger::KEYED_LOAD_POLYMORPHIC_IC_TAG; | 764 ? Logger::KEYED_LOAD_IC_TAG : Logger::KEYED_LOAD_POLYMORPHIC_IC_TAG; |
| 755 } | 765 } |
| 756 virtual void JitEvent(Handle<Name> name, Handle<Code> code); | 766 virtual void JitEvent(Handle<Name> name, Handle<Code> code); |
| 757 virtual void GenerateNameCheck(Handle<Name> name, | 767 virtual void GenerateNameCheck(Handle<Name> name, |
| 758 Register name_reg, | 768 Register name_reg, |
| 759 Label* miss); | 769 Label* miss); |
| 760 }; | 770 }; |
| 761 | 771 |
| 762 | 772 |
| 763 class StoreStubCompiler: public StubCompiler { | 773 class BaseStoreStubCompiler: public StubCompiler { |
| 764 public: | 774 public: |
| 765 StoreStubCompiler(Isolate* isolate, StrictModeFlag strict_mode) | 775 BaseStoreStubCompiler(Isolate* isolate, |
| 766 : StubCompiler(isolate), strict_mode_(strict_mode) { } | 776 StrictModeFlag strict_mode, |
| 777 Register* registers) |
| 778 : StubCompiler(isolate), |
| 779 strict_mode_(strict_mode), |
| 780 registers_(registers) { } |
| 767 | 781 |
| 782 virtual ~BaseStoreStubCompiler() { } |
| 768 | 783 |
| 769 Handle<Code> CompileStoreField(Handle<JSObject> object, | 784 Handle<Code> CompileStoreField(Handle<JSObject> object, |
| 770 int index, | 785 int index, |
| 771 Handle<Map> transition, | 786 Handle<Map> transition, |
| 772 Handle<Name> name); | 787 Handle<Name> name); |
| 773 | 788 |
| 789 protected: |
| 790 Handle<Code> GetICCode(Code::Kind kind, |
| 791 Code::StubType type, |
| 792 Handle<Name> name, |
| 793 InlineCacheState state = MONOMORPHIC); |
| 794 |
| 795 Handle<Code> GetCode(Code::Kind kind, |
| 796 Code::StubType type, |
| 797 Handle<Name> name); |
| 798 |
| 799 void GenerateRestoreName(MacroAssembler* masm, |
| 800 Label* label, |
| 801 Handle<Name> name); |
| 802 |
| 803 Register receiver() { return registers_[0]; } |
| 804 Register name() { return registers_[1]; } |
| 805 Register value() { return registers_[2]; } |
| 806 Register scratch1() { return registers_[3]; } |
| 807 Register scratch2() { return registers_[4]; } |
| 808 Register scratch3() { return registers_[5]; } |
| 809 StrictModeFlag strict_mode() { return strict_mode_; } |
| 810 virtual Code::ExtraICState extra_state() { return strict_mode_; } |
| 811 |
| 812 private: |
| 813 virtual Code::Kind kind() = 0; |
| 814 virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) = 0; |
| 815 virtual void JitEvent(Handle<Name> name, Handle<Code> code) = 0; |
| 816 virtual void GenerateNameCheck(Handle<Name> name, |
| 817 Register name_reg, |
| 818 Label* miss) { } |
| 819 StrictModeFlag strict_mode_; |
| 820 Register* registers_; |
| 821 }; |
| 822 |
| 823 |
| 824 class StoreStubCompiler: public BaseStoreStubCompiler { |
| 825 public: |
| 826 StoreStubCompiler(Isolate* isolate, StrictModeFlag strict_mode) |
| 827 : BaseStoreStubCompiler(isolate, strict_mode, registers()) { } |
| 828 |
| 829 |
| 774 Handle<Code> CompileStoreCallback(Handle<Name> name, | 830 Handle<Code> CompileStoreCallback(Handle<Name> name, |
| 775 Handle<JSObject> object, | 831 Handle<JSObject> object, |
| 776 Handle<JSObject> holder, | 832 Handle<JSObject> holder, |
| 777 Handle<ExecutableAccessorInfo> callback); | 833 Handle<ExecutableAccessorInfo> callback); |
| 778 | 834 |
| 779 static void GenerateStoreViaSetter(MacroAssembler* masm, | 835 static void GenerateStoreViaSetter(MacroAssembler* masm, |
| 780 Handle<JSFunction> setter); | 836 Handle<JSFunction> setter); |
| 781 | 837 |
| 782 Handle<Code> CompileStoreViaSetter(Handle<Name> name, | 838 Handle<Code> CompileStoreViaSetter(Handle<Name> name, |
| 783 Handle<JSObject> object, | 839 Handle<JSObject> object, |
| 784 Handle<JSObject> holder, | 840 Handle<JSObject> holder, |
| 785 Handle<JSFunction> setter); | 841 Handle<JSFunction> setter); |
| 786 | 842 |
| 787 Handle<Code> CompileStoreInterceptor(Handle<JSObject> object, | 843 Handle<Code> CompileStoreInterceptor(Handle<JSObject> object, |
| 788 Handle<Name> name); | 844 Handle<Name> name); |
| 789 | 845 |
| 790 Handle<Code> CompileStoreGlobal(Handle<GlobalObject> object, | 846 Handle<Code> CompileStoreGlobal(Handle<GlobalObject> object, |
| 791 Handle<JSGlobalPropertyCell> holder, | 847 Handle<JSGlobalPropertyCell> holder, |
| 792 Handle<Name> name); | 848 Handle<Name> name); |
| 793 | 849 |
| 794 private: | 850 private: |
| 795 Handle<Code> GetCode(Code::StubType type, Handle<Name> name); | 851 static Register* registers(); |
| 796 | 852 virtual Code::Kind kind() { return Code::STORE_IC; } |
| 797 StrictModeFlag strict_mode_; | 853 virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) { |
| 854 if (!code->is_inline_cache_stub()) return Logger::STUB_TAG; |
| 855 return code->ic_state() == MONOMORPHIC |
| 856 ? Logger::STORE_IC_TAG : Logger::STORE_POLYMORPHIC_IC_TAG; |
| 857 } |
| 858 virtual void JitEvent(Handle<Name> name, Handle<Code> code); |
| 798 }; | 859 }; |
| 799 | 860 |
| 800 | 861 |
| 801 class KeyedStoreStubCompiler: public StubCompiler { | 862 class KeyedStoreStubCompiler: public BaseStoreStubCompiler { |
| 802 public: | 863 public: |
| 803 KeyedStoreStubCompiler(Isolate* isolate, | 864 KeyedStoreStubCompiler(Isolate* isolate, |
| 804 StrictModeFlag strict_mode, | 865 StrictModeFlag strict_mode, |
| 805 KeyedAccessStoreMode store_mode) | 866 KeyedAccessStoreMode store_mode) |
| 806 : StubCompiler(isolate), | 867 : BaseStoreStubCompiler(isolate, strict_mode, registers()), |
| 807 strict_mode_(strict_mode), | 868 store_mode_(store_mode) { } |
| 808 store_mode_(store_mode) { } | |
| 809 | |
| 810 Handle<Code> CompileStoreField(Handle<JSObject> object, | |
| 811 int index, | |
| 812 Handle<Map> transition, | |
| 813 Handle<Name> name); | |
| 814 | 869 |
| 815 Handle<Code> CompileStoreElement(Handle<Map> receiver_map); | 870 Handle<Code> CompileStoreElement(Handle<Map> receiver_map); |
| 816 | 871 |
| 817 Handle<Code> CompileStorePolymorphic(MapHandleList* receiver_maps, | 872 Handle<Code> CompileStorePolymorphic(MapHandleList* receiver_maps, |
| 818 CodeHandleList* handler_stubs, | 873 CodeHandleList* handler_stubs, |
| 819 MapHandleList* transitioned_maps); | 874 MapHandleList* transitioned_maps); |
| 820 | 875 |
| 821 Handle<Code> CompileStoreElementPolymorphic(MapHandleList* receiver_maps); | 876 Handle<Code> CompileStoreElementPolymorphic(MapHandleList* receiver_maps); |
| 822 | 877 |
| 823 static void GenerateStoreFastElement(MacroAssembler* masm, | 878 static void GenerateStoreFastElement(MacroAssembler* masm, |
| 824 bool is_js_array, | 879 bool is_js_array, |
| 825 ElementsKind element_kind, | 880 ElementsKind element_kind, |
| 826 KeyedAccessStoreMode store_mode); | 881 KeyedAccessStoreMode store_mode); |
| 827 | 882 |
| 828 static void GenerateStoreFastDoubleElement(MacroAssembler* masm, | 883 static void GenerateStoreFastDoubleElement(MacroAssembler* masm, |
| 829 bool is_js_array, | 884 bool is_js_array, |
| 830 KeyedAccessStoreMode store_mode); | 885 KeyedAccessStoreMode store_mode); |
| 831 | 886 |
| 832 static void GenerateStoreExternalArray(MacroAssembler* masm, | 887 static void GenerateStoreExternalArray(MacroAssembler* masm, |
| 833 ElementsKind elements_kind); | 888 ElementsKind elements_kind); |
| 834 | 889 |
| 835 static void GenerateStoreDictionaryElement(MacroAssembler* masm); | 890 static void GenerateStoreDictionaryElement(MacroAssembler* masm); |
| 836 | 891 |
| 892 protected: |
| 893 virtual Code::ExtraICState extra_state() { |
| 894 return Code::ComputeExtraICState(store_mode_, strict_mode()); |
| 895 } |
| 896 |
| 837 private: | 897 private: |
| 838 Handle<Code> GetCode(Code::StubType type, | 898 static Register* registers(); |
| 839 Handle<Name> name, | 899 virtual Code::Kind kind() { return Code::KEYED_STORE_IC; } |
| 840 InlineCacheState state = MONOMORPHIC); | 900 virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) { |
| 841 | 901 if (!code->is_inline_cache_stub()) return Logger::STUB_TAG; |
| 842 StrictModeFlag strict_mode_; | 902 return code->ic_state() == MONOMORPHIC |
| 903 ? Logger::KEYED_STORE_IC_TAG : Logger::KEYED_STORE_POLYMORPHIC_IC_TAG; |
| 904 } |
| 905 virtual void JitEvent(Handle<Name> name, Handle<Code> code); |
| 906 virtual void GenerateNameCheck(Handle<Name> name, |
| 907 Register name_reg, |
| 908 Label* miss); |
| 843 KeyedAccessStoreMode store_mode_; | 909 KeyedAccessStoreMode store_mode_; |
| 844 }; | 910 }; |
| 845 | 911 |
| 846 | 912 |
| 847 // Subset of FUNCTIONS_WITH_ID_LIST with custom constant/global call | 913 // Subset of FUNCTIONS_WITH_ID_LIST with custom constant/global call |
| 848 // IC stubs. | 914 // IC stubs. |
| 849 #define CUSTOM_CALL_IC_GENERATORS(V) \ | 915 #define CUSTOM_CALL_IC_GENERATORS(V) \ |
| 850 V(ArrayPush) \ | 916 V(ArrayPush) \ |
| 851 V(ArrayPop) \ | 917 V(ArrayPop) \ |
| 852 V(StringCharCodeAt) \ | 918 V(StringCharCodeAt) \ |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1007 Handle<JSFunction> constant_function_; | 1073 Handle<JSFunction> constant_function_; |
| 1008 bool is_simple_api_call_; | 1074 bool is_simple_api_call_; |
| 1009 Handle<FunctionTemplateInfo> expected_receiver_type_; | 1075 Handle<FunctionTemplateInfo> expected_receiver_type_; |
| 1010 Handle<CallHandlerInfo> api_call_info_; | 1076 Handle<CallHandlerInfo> api_call_info_; |
| 1011 }; | 1077 }; |
| 1012 | 1078 |
| 1013 | 1079 |
| 1014 } } // namespace v8::internal | 1080 } } // namespace v8::internal |
| 1015 | 1081 |
| 1016 #endif // V8_STUB_CACHE_H_ | 1082 #endif // V8_STUB_CACHE_H_ |
| OLD | NEW |