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

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

Issue 497083002: Move handler compilers to handler-compiler (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix include 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/ia32/code-stubs-ia32.cc ('k') | src/ic/arm/ic-compiler-arm.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_ARM 7 #if V8_TARGET_ARCH_ARM
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 // -- r0 : receiver
23 // -- r2 : name
24 // -- lr : return address
25 // -----------------------------------
26 {
27 FrameAndConstantPoolScope 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 __ ldr(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 __ ldr(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 // -- lr : return address
59 // -----------------------------------
60 {
61 FrameAndConstantPoolScope 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 __ ldr(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(r0);
86
87 // Restore context register.
88 __ ldr(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 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 ExternalReference::Type type = ExternalReference::DIRECT_API_CALL; 279 ExternalReference::Type type = ExternalReference::DIRECT_API_CALL;
204 ExternalReference ref = ExternalReference(&fun, type, masm->isolate()); 280 ExternalReference ref = ExternalReference(&fun, type, masm->isolate());
205 __ mov(api_function_address, Operand(ref)); 281 __ mov(api_function_address, Operand(ref));
206 282
207 // Jump to stub. 283 // Jump to stub.
208 CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc); 284 CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
209 __ TailCallStub(&stub); 285 __ TailCallStub(&stub);
210 } 286 }
211 287
212 288
289 void ElementHandlerCompiler::GenerateLoadDictionaryElement(
290 MacroAssembler* masm) {
291 // The return address is in lr.
292 Label slow, miss;
293
294 Register key = LoadIC::NameRegister();
295 Register receiver = LoadIC::ReceiverRegister();
296 DCHECK(receiver.is(r1));
297 DCHECK(key.is(r2));
298
299 __ UntagAndJumpIfNotSmi(r6, key, &miss);
300 __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset));
301 __ LoadFromNumberDictionary(&slow, r4, key, r0, r6, r3, r5);
302 __ Ret();
303
304 __ bind(&slow);
305 __ IncrementCounter(
306 masm->isolate()->counters()->keyed_load_external_array_slow(), 1, r2, r3);
307
308 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
309
310 // Miss case, call the runtime.
311 __ bind(&miss);
312
313 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
314 }
315
316
213 #undef __ 317 #undef __
214 #define __ ACCESS_MASM(masm()) 318 #define __ ACCESS_MASM(masm())
215 319
216 320
217 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label, 321 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
218 Handle<Name> name) { 322 Handle<Name> name) {
219 if (!label->is_unused()) { 323 if (!label->is_unused()) {
220 __ bind(label); 324 __ bind(label);
221 __ mov(this->name(), Operand(name)); 325 __ mov(this->name(), Operand(name));
222 } 326 }
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 // Do tail-call to the runtime system. 781 // Do tail-call to the runtime system.
678 ExternalReference store_callback_property = 782 ExternalReference store_callback_property =
679 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 783 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
680 __ TailCallExternalReference(store_callback_property, 5, 1); 784 __ TailCallExternalReference(store_callback_property, 5, 1);
681 785
682 // Return the generated code. 786 // Return the generated code.
683 return GetCode(kind(), Code::FAST, name); 787 return GetCode(kind(), Code::FAST, name);
684 } 788 }
685 789
686 790
687 #undef __
688 #define __ ACCESS_MASM(masm)
689
690
691 void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
692 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
693 Handle<JSFunction> setter) {
694 // ----------- S t a t e -------------
695 // -- lr : return address
696 // -----------------------------------
697 {
698 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
699
700 // Save value register, so we can restore it later.
701 __ push(value());
702
703 if (!setter.is_null()) {
704 // Call the JavaScript setter with receiver and value on the stack.
705 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
706 // Swap in the global receiver.
707 __ ldr(receiver,
708 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
709 }
710 __ Push(receiver, value());
711 ParameterCount actual(1);
712 ParameterCount expected(setter);
713 __ InvokeFunction(setter, expected, actual, CALL_FUNCTION,
714 NullCallWrapper());
715 } else {
716 // If we generate a global code snippet for deoptimization only, remember
717 // the place to continue after deoptimization.
718 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
719 }
720
721 // We have to return the passed value, not the return value of the setter.
722 __ pop(r0);
723
724 // Restore context register.
725 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
726 }
727 __ Ret();
728 }
729
730
731 #undef __
732 #define __ ACCESS_MASM(masm())
733
734
735 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor( 791 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
736 Handle<Name> name) { 792 Handle<Name> name) {
737 __ Push(receiver(), this->name(), value()); 793 __ Push(receiver(), this->name(), value());
738 794
739 // Do tail-call to the runtime system. 795 // Do tail-call to the runtime system.
740 ExternalReference store_ic_property = ExternalReference( 796 ExternalReference store_ic_property = ExternalReference(
741 IC_Utility(IC::kStorePropertyWithInterceptor), isolate()); 797 IC_Utility(IC::kStorePropertyWithInterceptor), isolate());
742 __ TailCallExternalReference(store_ic_property, 3, 1); 798 __ TailCallExternalReference(store_ic_property, 3, 1);
743 799
744 // Return the generated code. 800 // Return the generated code.
745 return GetCode(kind(), Code::FAST, name); 801 return GetCode(kind(), Code::FAST, name);
746 } 802 }
747 803
748 804
749 Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); } 805 Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); }
750 806
751 807
752 #undef __
753 #define __ ACCESS_MASM(masm)
754
755
756 void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
757 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
758 Handle<JSFunction> getter) {
759 // ----------- S t a t e -------------
760 // -- r0 : receiver
761 // -- r2 : name
762 // -- lr : return address
763 // -----------------------------------
764 {
765 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
766
767 if (!getter.is_null()) {
768 // Call the JavaScript getter with the receiver on the stack.
769 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
770 // Swap in the global receiver.
771 __ ldr(receiver,
772 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
773 }
774 __ push(receiver);
775 ParameterCount actual(0);
776 ParameterCount expected(getter);
777 __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
778 NullCallWrapper());
779 } else {
780 // If we generate a global code snippet for deoptimization only, remember
781 // the place to continue after deoptimization.
782 masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
783 }
784
785 // Restore context register.
786 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
787 }
788 __ Ret();
789 }
790
791
792 #undef __
793 #define __ ACCESS_MASM(masm())
794
795
796 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( 808 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
797 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { 809 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
798 Label miss; 810 Label miss;
799 FrontendHeader(receiver(), name, &miss); 811 FrontendHeader(receiver(), name, &miss);
800 812
801 // Get the value from the cell. 813 // Get the value from the cell.
802 Register result = StoreIC::ValueRegister(); 814 Register result = StoreIC::ValueRegister();
803 __ mov(result, Operand(cell)); 815 __ mov(result, Operand(cell));
804 __ ldr(result, FieldMemOperand(result, Cell::kValueOffset)); 816 __ ldr(result, FieldMemOperand(result, Cell::kValueOffset));
805 817
806 // Check for deleted property if property can actually be deleted. 818 // Check for deleted property if property can actually be deleted.
807 if (is_configurable) { 819 if (is_configurable) {
808 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 820 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
809 __ cmp(result, ip); 821 __ cmp(result, ip);
810 __ b(eq, &miss); 822 __ b(eq, &miss);
811 } 823 }
812 824
813 Counters* counters = isolate()->counters(); 825 Counters* counters = isolate()->counters();
814 __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3); 826 __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3);
815 __ Ret(); 827 __ Ret();
816 828
817 FrontendFooter(name, &miss); 829 FrontendFooter(name, &miss);
818 830
819 // Return the generated code. 831 // Return the generated code.
820 return GetCode(kind(), Code::NORMAL, name); 832 return GetCode(kind(), Code::NORMAL, name);
821 } 833 }
822 834
823 835
824 Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
825 CodeHandleList* handlers,
826 Handle<Name> name,
827 Code::StubType type,
828 IcCheckType check) {
829 Label miss;
830
831 if (check == PROPERTY &&
832 (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) {
833 // In case we are compiling an IC for dictionary loads and stores, just
834 // check whether the name is unique.
835 if (name.is_identical_to(isolate()->factory()->normal_ic_symbol())) {
836 __ JumpIfNotUniqueName(this->name(), &miss);
837 } else {
838 __ cmp(this->name(), Operand(name));
839 __ b(ne, &miss);
840 }
841 }
842
843 Label number_case;
844 Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
845 __ JumpIfSmi(receiver(), smi_target);
846
847 // Polymorphic keyed stores may use the map register
848 Register map_reg = scratch1();
849 DCHECK(kind() != Code::KEYED_STORE_IC ||
850 map_reg.is(KeyedStoreIC::MapRegister()));
851
852 int receiver_count = types->length();
853 int number_of_handled_maps = 0;
854 __ ldr(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset));
855 for (int current = 0; current < receiver_count; ++current) {
856 Handle<HeapType> type = types->at(current);
857 Handle<Map> map = IC::TypeToMap(*type, isolate());
858 if (!map->is_deprecated()) {
859 number_of_handled_maps++;
860 __ mov(ip, Operand(map));
861 __ cmp(map_reg, ip);
862 if (type->Is(HeapType::Number())) {
863 DCHECK(!number_case.is_unused());
864 __ bind(&number_case);
865 }
866 __ Jump(handlers->at(current), RelocInfo::CODE_TARGET, eq);
867 }
868 }
869 DCHECK(number_of_handled_maps != 0);
870
871 __ bind(&miss);
872 TailCallBuiltin(masm(), MissBuiltin(kind()));
873
874 // Return the generated code.
875 InlineCacheState state =
876 number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC;
877 return GetCode(kind(), type, name, state);
878 }
879
880
881 Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
882 MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
883 MapHandleList* transitioned_maps) {
884 Label miss;
885 __ JumpIfSmi(receiver(), &miss);
886
887 int receiver_count = receiver_maps->length();
888 __ ldr(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset));
889 for (int i = 0; i < receiver_count; ++i) {
890 __ mov(ip, Operand(receiver_maps->at(i)));
891 __ cmp(scratch1(), ip);
892 if (transitioned_maps->at(i).is_null()) {
893 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq);
894 } else {
895 Label next_map;
896 __ b(ne, &next_map);
897 __ mov(transition_map(), Operand(transitioned_maps->at(i)));
898 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, al);
899 __ bind(&next_map);
900 }
901 }
902
903 __ bind(&miss);
904 TailCallBuiltin(masm(), MissBuiltin(kind()));
905
906 // Return the generated code.
907 return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
908 }
909
910
911 #undef __
912 #define __ ACCESS_MASM(masm)
913
914
915 void ElementHandlerCompiler::GenerateLoadDictionaryElement(
916 MacroAssembler* masm) {
917 // The return address is in lr.
918 Label slow, miss;
919
920 Register key = LoadIC::NameRegister();
921 Register receiver = LoadIC::ReceiverRegister();
922 DCHECK(receiver.is(r1));
923 DCHECK(key.is(r2));
924
925 __ UntagAndJumpIfNotSmi(r6, key, &miss);
926 __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset));
927 __ LoadFromNumberDictionary(&slow, r4, key, r0, r6, r3, r5);
928 __ Ret();
929
930 __ bind(&slow);
931 __ IncrementCounter(
932 masm->isolate()->counters()->keyed_load_external_array_slow(), 1, r2, r3);
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 __ mov(r0, Operand(Smi::FromInt(strict_mode)));
949 __ Push(r0);
950
951 // Do tail-call to runtime routine.
952 __ TailCallRuntime(Runtime::kSetProperty, 4, 1);
953 }
954
955
956 #undef __ 836 #undef __
957 } 837 }
958 } // namespace v8::internal 838 } // namespace v8::internal
959 839
960 #endif // V8_TARGET_ARCH_ARM 840 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/ic/arm/ic-compiler-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698