Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: src/ic/mips64/handler-compiler-mips64.cc

Issue 501023002: MIPS: Move handler compilers to handler-compiler. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ic/mips/ic-compiler-mips.cc ('k') | src/ic/mips64/ic-compiler-mips64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_MIPS64 7 #if V8_TARGET_ARCH_MIPS64
8 8
9 #include "src/ic/call-optimization.h" 9 #include "src/ic/call-optimization.h"
10 #include "src/ic/ic-compiler.h" 10 #include "src/ic/handler-compiler.h"
11 11
12 namespace v8 { 12 namespace v8 {
13 namespace internal { 13 namespace internal {
14 14
15 #define __ ACCESS_MASM(masm) 15 #define __ ACCESS_MASM(masm)
16 16
17 17
18 void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
19 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
20 Handle<JSFunction> getter) {
21 // ----------- S t a t e -------------
22 // -- a0 : receiver
23 // -- a2 : name
24 // -- ra : return address
25 // -----------------------------------
26 {
27 FrameScope scope(masm, StackFrame::INTERNAL);
28
29 if (!getter.is_null()) {
30 // Call the JavaScript getter with the receiver on the stack.
31 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
32 // Swap in the global receiver.
33 __ ld(receiver,
34 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
35 }
36 __ push(receiver);
37 ParameterCount actual(0);
38 ParameterCount expected(getter);
39 __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
40 NullCallWrapper());
41 } else {
42 // If we generate a global code snippet for deoptimization only, remember
43 // the place to continue after deoptimization.
44 masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
45 }
46
47 // Restore context register.
48 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
49 }
50 __ Ret();
51 }
52
53
54 void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
55 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
56 Handle<JSFunction> setter) {
57 // ----------- S t a t e -------------
58 // -- ra : return address
59 // -----------------------------------
60 {
61 FrameScope scope(masm, StackFrame::INTERNAL);
62
63 // Save value register, so we can restore it later.
64 __ push(value());
65
66 if (!setter.is_null()) {
67 // Call the JavaScript setter with receiver and value on the stack.
68 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
69 // Swap in the global receiver.
70 __ ld(receiver,
71 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
72 }
73 __ Push(receiver, value());
74 ParameterCount actual(1);
75 ParameterCount expected(setter);
76 __ InvokeFunction(setter, expected, actual, CALL_FUNCTION,
77 NullCallWrapper());
78 } else {
79 // If we generate a global code snippet for deoptimization only, remember
80 // the place to continue after deoptimization.
81 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
82 }
83
84 // We have to return the passed value, not the return value of the setter.
85 __ pop(v0);
86
87 // Restore context register.
88 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
89 }
90 __ Ret();
91 }
92
93
18 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( 94 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
19 MacroAssembler* masm, Label* miss_label, Register receiver, 95 MacroAssembler* masm, Label* miss_label, Register receiver,
20 Handle<Name> name, Register scratch0, Register scratch1) { 96 Handle<Name> name, Register scratch0, Register scratch1) {
21 DCHECK(name->IsUniqueName()); 97 DCHECK(name->IsUniqueName());
22 DCHECK(!receiver.is(scratch0)); 98 DCHECK(!receiver.is(scratch0));
23 Counters* counters = masm->isolate()->counters(); 99 Counters* counters = masm->isolate()->counters();
24 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); 100 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
25 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 101 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
26 102
27 Label done; 103 Label done;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 161
86 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype( 162 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
87 MacroAssembler* masm, Register receiver, Register scratch1, 163 MacroAssembler* masm, Register receiver, Register scratch1,
88 Register scratch2, Label* miss_label) { 164 Register scratch2, Label* miss_label) {
89 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); 165 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
90 __ Ret(USE_DELAY_SLOT); 166 __ Ret(USE_DELAY_SLOT);
91 __ mov(v0, scratch1); 167 __ mov(v0, scratch1);
92 } 168 }
93 169
94 170
171 // Generate code to check that a global property cell is empty. Create
172 // the property cell at compilation time if no cell exists for the
173 // property.
95 void PropertyHandlerCompiler::GenerateCheckPropertyCell( 174 void PropertyHandlerCompiler::GenerateCheckPropertyCell(
96 MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name, 175 MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name,
97 Register scratch, Label* miss) { 176 Register scratch, Label* miss) {
98 Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name); 177 Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name);
99 DCHECK(cell->value()->IsTheHole()); 178 DCHECK(cell->value()->IsTheHole());
100 __ li(scratch, Operand(cell)); 179 __ li(scratch, Operand(cell));
101 __ ld(scratch, FieldMemOperand(scratch, Cell::kValueOffset)); 180 __ ld(scratch, FieldMemOperand(scratch, Cell::kValueOffset));
102 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 181 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
103 __ Branch(miss, ne, scratch, Operand(at)); 182 __ Branch(miss, ne, scratch, Operand(at));
104 } 183 }
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 ExternalReference::Type type = ExternalReference::DIRECT_API_CALL; 274 ExternalReference::Type type = ExternalReference::DIRECT_API_CALL;
196 ExternalReference ref = ExternalReference(&fun, type, masm->isolate()); 275 ExternalReference ref = ExternalReference(&fun, type, masm->isolate());
197 __ li(api_function_address, Operand(ref)); 276 __ li(api_function_address, Operand(ref));
198 277
199 // Jump to stub. 278 // Jump to stub.
200 CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc); 279 CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
201 __ TailCallStub(&stub); 280 __ TailCallStub(&stub);
202 } 281 }
203 282
204 283
284 void ElementHandlerCompiler::GenerateLoadDictionaryElement(
285 MacroAssembler* masm) {
286 // The return address is in ra
287 Label slow, miss;
288
289 Register key = LoadIC::NameRegister();
290 Register receiver = LoadIC::ReceiverRegister();
291 DCHECK(receiver.is(a1));
292 DCHECK(key.is(a2));
293
294 __ UntagAndJumpIfNotSmi(a6, key, &miss);
295 __ ld(a4, FieldMemOperand(receiver, JSObject::kElementsOffset));
296 DCHECK(kSmiTagSize + kSmiShiftSize == 32);
297 __ LoadFromNumberDictionary(&slow, a4, key, v0, a6, a3, a5);
298 __ Ret();
299
300 // Slow case, key and receiver still unmodified.
301 __ bind(&slow);
302 __ IncrementCounter(
303 masm->isolate()->counters()->keyed_load_external_array_slow(), 1, a2, a3);
304
305 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
306
307 // Miss case, call the runtime.
308 __ bind(&miss);
309
310 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
311 }
312
313
205 #undef __ 314 #undef __
206 #define __ ACCESS_MASM(masm()) 315 #define __ ACCESS_MASM(masm())
207 316
208 317
209 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label, 318 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
210 Handle<Name> name) { 319 Handle<Name> name) {
211 if (!label->is_unused()) { 320 if (!label->is_unused()) {
212 __ bind(label); 321 __ bind(label);
213 __ li(this->name(), Operand(name)); 322 __ li(this->name(), Operand(name));
214 } 323 }
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 // Do tail-call to the runtime system. 782 // Do tail-call to the runtime system.
674 ExternalReference store_callback_property = 783 ExternalReference store_callback_property =
675 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 784 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
676 __ TailCallExternalReference(store_callback_property, 5, 1); 785 __ TailCallExternalReference(store_callback_property, 5, 1);
677 786
678 // Return the generated code. 787 // Return the generated code.
679 return GetCode(kind(), Code::FAST, name); 788 return GetCode(kind(), Code::FAST, name);
680 } 789 }
681 790
682 791
683 #undef __
684 #define __ ACCESS_MASM(masm)
685
686
687 void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
688 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
689 Handle<JSFunction> setter) {
690 // ----------- S t a t e -------------
691 // -- ra : return address
692 // -----------------------------------
693 {
694 FrameScope scope(masm, StackFrame::INTERNAL);
695
696 // Save value register, so we can restore it later.
697 __ push(value());
698
699 if (!setter.is_null()) {
700 // Call the JavaScript setter with receiver and value on the stack.
701 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
702 // Swap in the global receiver.
703 __ ld(receiver,
704 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
705 }
706 __ Push(receiver, value());
707 ParameterCount actual(1);
708 ParameterCount expected(setter);
709 __ InvokeFunction(setter, expected, actual, CALL_FUNCTION,
710 NullCallWrapper());
711 } else {
712 // If we generate a global code snippet for deoptimization only, remember
713 // the place to continue after deoptimization.
714 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
715 }
716
717 // We have to return the passed value, not the return value of the setter.
718 __ pop(v0);
719
720 // Restore context register.
721 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
722 }
723 __ Ret();
724 }
725
726
727 #undef __
728 #define __ ACCESS_MASM(masm())
729
730
731 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor( 792 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
732 Handle<Name> name) { 793 Handle<Name> name) {
733 __ Push(receiver(), this->name(), value()); 794 __ Push(receiver(), this->name(), value());
734 795
735 // Do tail-call to the runtime system. 796 // Do tail-call to the runtime system.
736 ExternalReference store_ic_property = ExternalReference( 797 ExternalReference store_ic_property = ExternalReference(
737 IC_Utility(IC::kStorePropertyWithInterceptor), isolate()); 798 IC_Utility(IC::kStorePropertyWithInterceptor), isolate());
738 __ TailCallExternalReference(store_ic_property, 3, 1); 799 __ TailCallExternalReference(store_ic_property, 3, 1);
739 800
740 // Return the generated code. 801 // Return the generated code.
741 return GetCode(kind(), Code::FAST, name); 802 return GetCode(kind(), Code::FAST, name);
742 } 803 }
743 804
744 805
745 Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); } 806 Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); }
746 807
747 808
748 #undef __
749 #define __ ACCESS_MASM(masm)
750
751
752 void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
753 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
754 Handle<JSFunction> getter) {
755 // ----------- S t a t e -------------
756 // -- a0 : receiver
757 // -- a2 : name
758 // -- ra : return address
759 // -----------------------------------
760 {
761 FrameScope scope(masm, StackFrame::INTERNAL);
762
763 if (!getter.is_null()) {
764 // Call the JavaScript getter with the receiver on the stack.
765 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
766 // Swap in the global receiver.
767 __ ld(receiver,
768 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
769 }
770 __ push(receiver);
771 ParameterCount actual(0);
772 ParameterCount expected(getter);
773 __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
774 NullCallWrapper());
775 } else {
776 // If we generate a global code snippet for deoptimization only, remember
777 // the place to continue after deoptimization.
778 masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
779 }
780
781 // Restore context register.
782 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
783 }
784 __ Ret();
785 }
786
787
788 #undef __
789 #define __ ACCESS_MASM(masm())
790
791
792 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( 809 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
793 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { 810 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
794 Label miss; 811 Label miss;
795 812
796 FrontendHeader(receiver(), name, &miss); 813 FrontendHeader(receiver(), name, &miss);
797 814
798 // Get the value from the cell. 815 // Get the value from the cell.
799 Register result = StoreIC::ValueRegister(); 816 Register result = StoreIC::ValueRegister();
800 __ li(result, Operand(cell)); 817 __ li(result, Operand(cell));
801 __ ld(result, FieldMemOperand(result, Cell::kValueOffset)); 818 __ ld(result, FieldMemOperand(result, Cell::kValueOffset));
802 819
803 // Check for deleted property if property can actually be deleted. 820 // Check for deleted property if property can actually be deleted.
804 if (is_configurable) { 821 if (is_configurable) {
805 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 822 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
806 __ Branch(&miss, eq, result, Operand(at)); 823 __ Branch(&miss, eq, result, Operand(at));
807 } 824 }
808 825
809 Counters* counters = isolate()->counters(); 826 Counters* counters = isolate()->counters();
810 __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3); 827 __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3);
811 __ Ret(USE_DELAY_SLOT); 828 __ Ret(USE_DELAY_SLOT);
812 __ mov(v0, result); 829 __ mov(v0, result);
813 830
814 FrontendFooter(name, &miss); 831 FrontendFooter(name, &miss);
815 832
816 // Return the generated code. 833 // Return the generated code.
817 return GetCode(kind(), Code::NORMAL, name); 834 return GetCode(kind(), Code::NORMAL, name);
818 } 835 }
819 836
820 837
821 Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
822 CodeHandleList* handlers,
823 Handle<Name> name,
824 Code::StubType type,
825 IcCheckType check) {
826 Label miss;
827
828 if (check == PROPERTY &&
829 (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) {
830 // In case we are compiling an IC for dictionary loads and stores, just
831 // check whether the name is unique.
832 if (name.is_identical_to(isolate()->factory()->normal_ic_symbol())) {
833 __ JumpIfNotUniqueName(this->name(), &miss);
834 } else {
835 __ Branch(&miss, ne, this->name(), Operand(name));
836 }
837 }
838
839 Label number_case;
840 Register match = scratch2();
841 Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
842 __ JumpIfSmi(receiver(), smi_target, match); // Reg match is 0 if Smi.
843
844 // Polymorphic keyed stores may use the map register
845 Register map_reg = scratch1();
846 DCHECK(kind() != Code::KEYED_STORE_IC ||
847 map_reg.is(KeyedStoreIC::MapRegister()));
848
849 int receiver_count = types->length();
850 int number_of_handled_maps = 0;
851 __ ld(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset));
852 for (int current = 0; current < receiver_count; ++current) {
853 Handle<HeapType> type = types->at(current);
854 Handle<Map> map = IC::TypeToMap(*type, isolate());
855 if (!map->is_deprecated()) {
856 number_of_handled_maps++;
857 // Check map and tail call if there's a match.
858 // Separate compare from branch, to provide path for above JumpIfSmi().
859 __ Dsubu(match, map_reg, Operand(map));
860 if (type->Is(HeapType::Number())) {
861 DCHECK(!number_case.is_unused());
862 __ bind(&number_case);
863 }
864 __ Jump(handlers->at(current), RelocInfo::CODE_TARGET, eq, match,
865 Operand(zero_reg));
866 }
867 }
868 DCHECK(number_of_handled_maps != 0);
869
870 __ bind(&miss);
871 TailCallBuiltin(masm(), MissBuiltin(kind()));
872
873 // Return the generated code.
874 InlineCacheState state =
875 number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC;
876 return GetCode(kind(), type, name, state);
877 }
878
879
880 Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
881 MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
882 MapHandleList* transitioned_maps) {
883 Label miss;
884 __ JumpIfSmi(receiver(), &miss);
885
886 int receiver_count = receiver_maps->length();
887 __ ld(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset));
888 for (int i = 0; i < receiver_count; ++i) {
889 if (transitioned_maps->at(i).is_null()) {
890 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq, scratch1(),
891 Operand(receiver_maps->at(i)));
892 } else {
893 Label next_map;
894 __ Branch(&next_map, ne, scratch1(), Operand(receiver_maps->at(i)));
895 __ li(transition_map(), Operand(transitioned_maps->at(i)));
896 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET);
897 __ bind(&next_map);
898 }
899 }
900
901 __ bind(&miss);
902 TailCallBuiltin(masm(), MissBuiltin(kind()));
903
904 // Return the generated code.
905 return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
906 }
907
908
909 #undef __
910 #define __ ACCESS_MASM(masm)
911
912
913 void ElementHandlerCompiler::GenerateLoadDictionaryElement(
914 MacroAssembler* masm) {
915 // The return address is in ra
916 Label slow, miss;
917
918 Register key = LoadIC::NameRegister();
919 Register receiver = LoadIC::ReceiverRegister();
920 DCHECK(receiver.is(a1));
921 DCHECK(key.is(a2));
922
923 __ UntagAndJumpIfNotSmi(a6, key, &miss);
924 __ ld(a4, FieldMemOperand(receiver, JSObject::kElementsOffset));
925 DCHECK(kSmiTagSize + kSmiShiftSize == 32);
926 __ LoadFromNumberDictionary(&slow, a4, key, v0, a6, a3, a5);
927 __ Ret();
928
929 // Slow case, key and receiver still unmodified.
930 __ bind(&slow);
931 __ IncrementCounter(
932 masm->isolate()->counters()->keyed_load_external_array_slow(), 1, a2, a3);
933
934 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
935
936 // Miss case, call the runtime.
937 __ bind(&miss);
938
939 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
940 }
941
942
943 void PropertyICCompiler::GenerateRuntimeSetProperty(MacroAssembler* masm,
944 StrictMode strict_mode) {
945 __ Push(StoreIC::ReceiverRegister(), StoreIC::NameRegister(),
946 StoreIC::ValueRegister());
947
948 __ li(a0, Operand(Smi::FromInt(strict_mode)));
949 __ Push(a0);
950
951 // Do tail-call to runtime routine.
952 __ TailCallRuntime(Runtime::kSetProperty, 4, 1);
953 }
954
955
956 #undef __ 838 #undef __
957 } 839 }
958 } // namespace v8::internal 840 } // namespace v8::internal
959 841
960 #endif // V8_TARGET_ARCH_MIPS64 842 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« no previous file with comments | « src/ic/mips/ic-compiler-mips.cc ('k') | src/ic/mips64/ic-compiler-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698