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 |