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 void GenerateMiss(MacroAssembler* masm, Code::Kind kind); |
521 static void GenerateStoreMiss(MacroAssembler* masm, Code::Kind kind); | 526 static void GenerateMissForceGeneric(MacroAssembler* masm, Code::Kind kind); |
522 | |
523 static void GenerateKeyedLoadMissForceGeneric(MacroAssembler* masm); | |
524 | 527 |
525 // Generates code that verifies that the property holder has not changed | 528 // Generates code that verifies that the property holder has not changed |
526 // (checking maps of objects in the prototype chain for fast and global | 529 // (checking maps of objects in the prototype chain for fast and global |
527 // objects or doing negative lookup for slow objects, ensures that the | 530 // 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 | 531 // 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 | 532 // 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 | 533 // code for security check in case of global object holders. Helps to make |
531 // sure that the current IC is still valid. | 534 // sure that the current IC is still valid. |
532 // | 535 // |
533 // The scratch and holder registers are always clobbered, but the object | 536 // 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; } | 573 void set_failure(Failure* failure) { failure_ = failure; } |
571 | 574 |
572 static void LookupPostInterceptor(Handle<JSObject> holder, | 575 static void LookupPostInterceptor(Handle<JSObject> holder, |
573 Handle<Name> name, | 576 Handle<Name> name, |
574 LookupResult* lookup); | 577 LookupResult* lookup); |
575 | 578 |
576 Isolate* isolate() { return isolate_; } | 579 Isolate* isolate() { return isolate_; } |
577 Heap* heap() { return isolate()->heap(); } | 580 Heap* heap() { return isolate()->heap(); } |
578 Factory* factory() { return isolate()->factory(); } | 581 Factory* factory() { return isolate()->factory(); } |
579 | 582 |
580 void GenerateTailCall(Handle<Code> code); | 583 static void GenerateTailCall(MacroAssembler* masm, Handle<Code> code); |
581 | 584 |
582 private: | 585 private: |
583 Isolate* isolate_; | 586 Isolate* isolate_; |
584 MacroAssembler masm_; | 587 MacroAssembler masm_; |
585 Failure* failure_; | 588 Failure* failure_; |
586 }; | 589 }; |
587 | 590 |
588 | 591 |
589 enum FrontendCheckType { PERFORM_INITIAL_CHECKS, SKIP_INITIAL_CHECKS }; | 592 enum FrontendCheckType { PERFORM_INITIAL_CHECKS, SKIP_INITIAL_CHECKS }; |
590 | 593 |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
732 class KeyedLoadStubCompiler: public BaseLoadStubCompiler { | 735 class KeyedLoadStubCompiler: public BaseLoadStubCompiler { |
733 public: | 736 public: |
734 explicit KeyedLoadStubCompiler(Isolate* isolate) | 737 explicit KeyedLoadStubCompiler(Isolate* isolate) |
735 : BaseLoadStubCompiler(isolate, registers()) { } | 738 : BaseLoadStubCompiler(isolate, registers()) { } |
736 | 739 |
737 Handle<Code> CompileLoadElement(Handle<Map> receiver_map); | 740 Handle<Code> CompileLoadElement(Handle<Map> receiver_map); |
738 | 741 |
739 void CompileElementHandlers(MapHandleList* receiver_maps, | 742 void CompileElementHandlers(MapHandleList* receiver_maps, |
740 CodeHandleList* handlers); | 743 CodeHandleList* handlers); |
741 | 744 |
742 Handle<Code> CompileLoadElementPolymorphic(MapHandleList* receiver_maps); | |
743 | |
744 static void GenerateLoadDictionaryElement(MacroAssembler* masm); | 745 static void GenerateLoadDictionaryElement(MacroAssembler* masm); |
745 | 746 |
746 static Register receiver() { return registers()[0]; } | 747 static Register receiver() { return registers()[0]; } |
747 | 748 |
748 private: | 749 private: |
749 static Register* registers(); | 750 static Register* registers(); |
750 virtual Code::Kind kind() { return Code::KEYED_LOAD_IC; } | 751 virtual Code::Kind kind() { return Code::KEYED_LOAD_IC; } |
751 virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) { | 752 virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) { |
752 if (!code->is_inline_cache_stub()) return Logger::STUB_TAG; | 753 if (!code->is_inline_cache_stub()) return Logger::STUB_TAG; |
753 return code->ic_state() == MONOMORPHIC | 754 return code->ic_state() == MONOMORPHIC |
754 ? Logger::KEYED_LOAD_IC_TAG : Logger::KEYED_LOAD_POLYMORPHIC_IC_TAG; | 755 ? Logger::KEYED_LOAD_IC_TAG : Logger::KEYED_LOAD_POLYMORPHIC_IC_TAG; |
755 } | 756 } |
756 virtual void JitEvent(Handle<Name> name, Handle<Code> code); | 757 virtual void JitEvent(Handle<Name> name, Handle<Code> code); |
757 virtual void GenerateNameCheck(Handle<Name> name, | 758 virtual void GenerateNameCheck(Handle<Name> name, |
758 Register name_reg, | 759 Register name_reg, |
759 Label* miss); | 760 Label* miss); |
760 }; | 761 }; |
761 | 762 |
762 | 763 |
763 class StoreStubCompiler: public StubCompiler { | 764 class BaseStoreStubCompiler: public StubCompiler { |
764 public: | 765 public: |
765 StoreStubCompiler(Isolate* isolate, StrictModeFlag strict_mode) | 766 BaseStoreStubCompiler(Isolate* isolate, |
766 : StubCompiler(isolate), strict_mode_(strict_mode) { } | 767 StrictModeFlag strict_mode, |
768 Register* registers) | |
769 : StubCompiler(isolate), | |
770 strict_mode_(strict_mode), | |
771 registers_(registers) { } | |
767 | 772 |
773 virtual ~BaseStoreStubCompiler() { } | |
768 | 774 |
769 Handle<Code> CompileStoreField(Handle<JSObject> object, | 775 Handle<Code> CompileStoreField(Handle<JSObject> object, |
770 int index, | 776 int index, |
771 Handle<Map> transition, | 777 Handle<Map> transition, |
772 Handle<Name> name); | 778 Handle<Name> name); |
773 | 779 |
780 protected: | |
781 Handle<Code> GetICCode(Code::Kind kind, | |
782 Code::StubType type, | |
783 Handle<Name> name, | |
784 InlineCacheState state = MONOMORPHIC); | |
785 | |
786 Handle<Code> GetCode(Code::Kind kind, | |
787 Code::StubType type, | |
788 Handle<Name> name); | |
789 | |
790 void GenerateRestoreName(MacroAssembler* masm, | |
791 Label* label, | |
792 Handle<Name> name); | |
793 | |
794 Register receiver() { return registers_[0]; } | |
795 Register name() { return registers_[1]; } | |
796 Register value() { return registers_[2]; } | |
797 Register scratch1() { return registers_[3]; } | |
798 Register scratch2() { return registers_[4]; } | |
799 Register scratch3() { return registers_[5]; } | |
800 StrictModeFlag strict_mode() { return strict_mode_; } | |
801 virtual Code::ExtraICState extra_state() { return strict_mode_; } | |
802 | |
803 private: | |
804 virtual Code::Kind kind() = 0; | |
805 virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) = 0; | |
806 virtual void JitEvent(Handle<Name> name, Handle<Code> code) = 0; | |
807 virtual void GenerateNameCheck(Handle<Name> name, | |
808 Register name_reg, | |
809 Label* miss) { } | |
810 StrictModeFlag strict_mode_; | |
811 Register* registers_; | |
812 }; | |
813 | |
814 | |
815 class StoreStubCompiler: public BaseStoreStubCompiler { | |
816 public: | |
817 StoreStubCompiler(Isolate* isolate, StrictModeFlag strict_mode) | |
818 : BaseStoreStubCompiler(isolate, strict_mode, registers()) { } | |
Jakob Kummerow
2013/03/13 13:27:25
nit: 4-space indent
Toon Verwaest
2013/03/13 14:07:21
Done.
| |
819 | |
820 | |
774 Handle<Code> CompileStoreCallback(Handle<Name> name, | 821 Handle<Code> CompileStoreCallback(Handle<Name> name, |
775 Handle<JSObject> object, | 822 Handle<JSObject> object, |
776 Handle<JSObject> holder, | 823 Handle<JSObject> holder, |
777 Handle<ExecutableAccessorInfo> callback); | 824 Handle<ExecutableAccessorInfo> callback); |
778 | 825 |
779 static void GenerateStoreViaSetter(MacroAssembler* masm, | 826 static void GenerateStoreViaSetter(MacroAssembler* masm, |
780 Handle<JSFunction> setter); | 827 Handle<JSFunction> setter); |
781 | 828 |
782 Handle<Code> CompileStoreViaSetter(Handle<Name> name, | 829 Handle<Code> CompileStoreViaSetter(Handle<Name> name, |
783 Handle<JSObject> object, | 830 Handle<JSObject> object, |
784 Handle<JSObject> holder, | 831 Handle<JSObject> holder, |
785 Handle<JSFunction> setter); | 832 Handle<JSFunction> setter); |
786 | 833 |
787 Handle<Code> CompileStoreInterceptor(Handle<JSObject> object, | 834 Handle<Code> CompileStoreInterceptor(Handle<JSObject> object, |
788 Handle<Name> name); | 835 Handle<Name> name); |
789 | 836 |
790 Handle<Code> CompileStoreGlobal(Handle<GlobalObject> object, | 837 Handle<Code> CompileStoreGlobal(Handle<GlobalObject> object, |
791 Handle<JSGlobalPropertyCell> holder, | 838 Handle<JSGlobalPropertyCell> holder, |
792 Handle<Name> name); | 839 Handle<Name> name); |
793 | 840 |
794 private: | 841 private: |
795 Handle<Code> GetCode(Code::StubType type, Handle<Name> name); | 842 static Register* registers(); |
796 | 843 virtual Code::Kind kind() { return Code::STORE_IC; } |
797 StrictModeFlag strict_mode_; | 844 virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) { |
845 if (!code->is_inline_cache_stub()) return Logger::STUB_TAG; | |
846 return code->ic_state() == MONOMORPHIC | |
847 ? Logger::STORE_IC_TAG : Logger::STORE_POLYMORPHIC_IC_TAG; | |
848 } | |
849 virtual void JitEvent(Handle<Name> name, Handle<Code> code); | |
798 }; | 850 }; |
799 | 851 |
800 | 852 |
801 class KeyedStoreStubCompiler: public StubCompiler { | 853 class KeyedStoreStubCompiler: public BaseStoreStubCompiler { |
802 public: | 854 public: |
803 KeyedStoreStubCompiler(Isolate* isolate, | 855 KeyedStoreStubCompiler(Isolate* isolate, |
804 StrictModeFlag strict_mode, | 856 StrictModeFlag strict_mode, |
805 KeyedAccessStoreMode store_mode) | 857 KeyedAccessStoreMode store_mode) |
806 : StubCompiler(isolate), | 858 : BaseStoreStubCompiler(isolate, strict_mode, registers()), |
Jakob Kummerow
2013/03/13 13:27:25
nit: 4-space indent
Toon Verwaest
2013/03/13 14:07:21
Done.
| |
807 strict_mode_(strict_mode), | |
808 store_mode_(store_mode) { } | 859 store_mode_(store_mode) { } |
809 | 860 |
810 Handle<Code> CompileStoreField(Handle<JSObject> object, | |
811 int index, | |
812 Handle<Map> transition, | |
813 Handle<Name> name); | |
814 | |
815 Handle<Code> CompileStoreElement(Handle<Map> receiver_map); | 861 Handle<Code> CompileStoreElement(Handle<Map> receiver_map); |
816 | 862 |
817 Handle<Code> CompileStorePolymorphic(MapHandleList* receiver_maps, | 863 Handle<Code> CompileStorePolymorphic(MapHandleList* receiver_maps, |
818 CodeHandleList* handler_stubs, | 864 CodeHandleList* handler_stubs, |
819 MapHandleList* transitioned_maps); | 865 MapHandleList* transitioned_maps); |
820 | 866 |
821 Handle<Code> CompileStoreElementPolymorphic(MapHandleList* receiver_maps); | 867 Handle<Code> CompileStoreElementPolymorphic(MapHandleList* receiver_maps); |
822 | 868 |
823 static void GenerateStoreFastElement(MacroAssembler* masm, | 869 static void GenerateStoreFastElement(MacroAssembler* masm, |
824 bool is_js_array, | 870 bool is_js_array, |
825 ElementsKind element_kind, | 871 ElementsKind element_kind, |
826 KeyedAccessStoreMode store_mode); | 872 KeyedAccessStoreMode store_mode); |
827 | 873 |
828 static void GenerateStoreFastDoubleElement(MacroAssembler* masm, | 874 static void GenerateStoreFastDoubleElement(MacroAssembler* masm, |
829 bool is_js_array, | 875 bool is_js_array, |
830 KeyedAccessStoreMode store_mode); | 876 KeyedAccessStoreMode store_mode); |
831 | 877 |
832 static void GenerateStoreExternalArray(MacroAssembler* masm, | 878 static void GenerateStoreExternalArray(MacroAssembler* masm, |
833 ElementsKind elements_kind); | 879 ElementsKind elements_kind); |
834 | 880 |
835 static void GenerateStoreDictionaryElement(MacroAssembler* masm); | 881 static void GenerateStoreDictionaryElement(MacroAssembler* masm); |
836 | 882 |
883 protected: | |
884 virtual Code::ExtraICState extra_state() { | |
885 return Code::ComputeExtraICState(store_mode_, strict_mode()); | |
886 } | |
887 | |
837 private: | 888 private: |
838 Handle<Code> GetCode(Code::StubType type, | 889 static Register* registers(); |
839 Handle<Name> name, | 890 virtual Code::Kind kind() { return Code::KEYED_STORE_IC; } |
840 InlineCacheState state = MONOMORPHIC); | 891 virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) { |
841 | 892 if (!code->is_inline_cache_stub()) return Logger::STUB_TAG; |
842 StrictModeFlag strict_mode_; | 893 return code->ic_state() == MONOMORPHIC |
894 ? Logger::KEYED_STORE_IC_TAG : Logger::KEYED_STORE_POLYMORPHIC_IC_TAG; | |
895 } | |
896 virtual void JitEvent(Handle<Name> name, Handle<Code> code); | |
897 virtual void GenerateNameCheck(Handle<Name> name, | |
898 Register name_reg, | |
899 Label* miss); | |
843 KeyedAccessStoreMode store_mode_; | 900 KeyedAccessStoreMode store_mode_; |
844 }; | 901 }; |
845 | 902 |
846 | 903 |
847 // Subset of FUNCTIONS_WITH_ID_LIST with custom constant/global call | 904 // Subset of FUNCTIONS_WITH_ID_LIST with custom constant/global call |
848 // IC stubs. | 905 // IC stubs. |
849 #define CUSTOM_CALL_IC_GENERATORS(V) \ | 906 #define CUSTOM_CALL_IC_GENERATORS(V) \ |
850 V(ArrayPush) \ | 907 V(ArrayPush) \ |
851 V(ArrayPop) \ | 908 V(ArrayPop) \ |
852 V(StringCharCodeAt) \ | 909 V(StringCharCodeAt) \ |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1007 Handle<JSFunction> constant_function_; | 1064 Handle<JSFunction> constant_function_; |
1008 bool is_simple_api_call_; | 1065 bool is_simple_api_call_; |
1009 Handle<FunctionTemplateInfo> expected_receiver_type_; | 1066 Handle<FunctionTemplateInfo> expected_receiver_type_; |
1010 Handle<CallHandlerInfo> api_call_info_; | 1067 Handle<CallHandlerInfo> api_call_info_; |
1011 }; | 1068 }; |
1012 | 1069 |
1013 | 1070 |
1014 } } // namespace v8::internal | 1071 } } // namespace v8::internal |
1015 | 1072 |
1016 #endif // V8_STUB_CACHE_H_ | 1073 #endif // V8_STUB_CACHE_H_ |
OLD | NEW |