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

Side by Side Diff: src/ic/x64/handler-compiler-x64.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/ic/ic-compiler.cc ('k') | src/ic/x64/ic-compiler-x64.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_X64 7 #if V8_TARGET_ARCH_X64
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
18 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( 17 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
19 MacroAssembler* masm, Label* miss_label, Register receiver, 18 MacroAssembler* masm, Label* miss_label, Register receiver,
20 Handle<Name> name, Register scratch0, Register scratch1) { 19 Handle<Name> name, Register scratch0, Register scratch1) {
21 DCHECK(name->IsUniqueName()); 20 DCHECK(name->IsUniqueName());
22 DCHECK(!receiver.is(scratch0)); 21 DCHECK(!receiver.is(scratch0));
23 Counters* counters = masm->isolate()->counters(); 22 Counters* counters = masm->isolate()->counters();
24 __ IncrementCounter(counters->negative_lookups(), 1); 23 __ IncrementCounter(counters->negative_lookups(), 1);
25 __ IncrementCounter(counters->negative_lookups_miss(), 1); 24 __ IncrementCounter(counters->negative_lookups_miss(), 1);
26 25
27 __ movp(scratch0, FieldOperand(receiver, HeapObject::kMapOffset)); 26 __ movp(scratch0, FieldOperand(receiver, HeapObject::kMapOffset));
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 Register scratch, Label* miss) { 191 Register scratch, Label* miss) {
193 Handle<PropertyCell> cell = JSGlobalObject::EnsurePropertyCell(global, name); 192 Handle<PropertyCell> cell = JSGlobalObject::EnsurePropertyCell(global, name);
194 DCHECK(cell->value()->IsTheHole()); 193 DCHECK(cell->value()->IsTheHole());
195 __ Move(scratch, cell); 194 __ Move(scratch, cell);
196 __ Cmp(FieldOperand(scratch, Cell::kValueOffset), 195 __ Cmp(FieldOperand(scratch, Cell::kValueOffset),
197 masm->isolate()->factory()->the_hole_value()); 196 masm->isolate()->factory()->the_hole_value());
198 __ j(not_equal, miss); 197 __ j(not_equal, miss);
199 } 198 }
200 199
201 200
201 void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
202 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
203 Handle<JSFunction> setter) {
204 // ----------- S t a t e -------------
205 // -- rsp[0] : return address
206 // -----------------------------------
207 {
208 FrameScope scope(masm, StackFrame::INTERNAL);
209
210 // Save value register, so we can restore it later.
211 __ Push(value());
212
213 if (!setter.is_null()) {
214 // Call the JavaScript setter with receiver and value on the stack.
215 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
216 // Swap in the global receiver.
217 __ movp(receiver,
218 FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
219 }
220 __ Push(receiver);
221 __ Push(value());
222 ParameterCount actual(1);
223 ParameterCount expected(setter);
224 __ InvokeFunction(setter, expected, actual, CALL_FUNCTION,
225 NullCallWrapper());
226 } else {
227 // If we generate a global code snippet for deoptimization only, remember
228 // the place to continue after deoptimization.
229 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
230 }
231
232 // We have to return the passed value, not the return value of the setter.
233 __ Pop(rax);
234
235 // Restore context register.
236 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
237 }
238 __ ret(0);
239 }
240
241
242 void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
243 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
244 Handle<JSFunction> getter) {
245 // ----------- S t a t e -------------
246 // -- rax : receiver
247 // -- rcx : name
248 // -- rsp[0] : return address
249 // -----------------------------------
250 {
251 FrameScope scope(masm, StackFrame::INTERNAL);
252
253 if (!getter.is_null()) {
254 // Call the JavaScript getter with the receiver on the stack.
255 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
256 // Swap in the global receiver.
257 __ movp(receiver,
258 FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
259 }
260 __ Push(receiver);
261 ParameterCount actual(0);
262 ParameterCount expected(getter);
263 __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
264 NullCallWrapper());
265 } else {
266 // If we generate a global code snippet for deoptimization only, remember
267 // the place to continue after deoptimization.
268 masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
269 }
270
271 // Restore context register.
272 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
273 }
274 __ ret(0);
275 }
276
277
278 void ElementHandlerCompiler::GenerateLoadDictionaryElement(
279 MacroAssembler* masm) {
280 // ----------- S t a t e -------------
281 // -- rcx : key
282 // -- rdx : receiver
283 // -- rsp[0] : return address
284 // -----------------------------------
285 DCHECK(rdx.is(LoadIC::ReceiverRegister()));
286 DCHECK(rcx.is(LoadIC::NameRegister()));
287 Label slow, miss;
288
289 // This stub is meant to be tail-jumped to, the receiver must already
290 // have been verified by the caller to not be a smi.
291
292 __ JumpIfNotSmi(rcx, &miss);
293 __ SmiToInteger32(rbx, rcx);
294 __ movp(rax, FieldOperand(rdx, JSObject::kElementsOffset));
295
296 // Check whether the elements is a number dictionary.
297 // rdx: receiver
298 // rcx: key
299 // rbx: key as untagged int32
300 // rax: elements
301 __ LoadFromNumberDictionary(&slow, rax, rcx, rbx, r9, rdi, rax);
302 __ ret(0);
303
304 __ bind(&slow);
305 // ----------- S t a t e -------------
306 // -- rcx : key
307 // -- rdx : receiver
308 // -- rsp[0] : return address
309 // -----------------------------------
310 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
311
312 __ bind(&miss);
313 // ----------- S t a t e -------------
314 // -- rcx : key
315 // -- rdx : receiver
316 // -- rsp[0] : return address
317 // -----------------------------------
318 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
319 }
320
321
202 #undef __ 322 #undef __
203 #define __ ACCESS_MASM((masm())) 323 #define __ ACCESS_MASM((masm()))
204 324
205 325
206 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label, 326 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
207 Handle<Name> name) { 327 Handle<Name> name) {
208 if (!label->is_unused()) { 328 if (!label->is_unused()) {
209 __ bind(label); 329 __ bind(label);
210 __ Move(this->name(), name); 330 __ Move(this->name(), name);
211 } 331 }
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 // Do tail-call to the runtime system. 777 // Do tail-call to the runtime system.
658 ExternalReference store_callback_property = 778 ExternalReference store_callback_property =
659 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 779 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
660 __ TailCallExternalReference(store_callback_property, 5, 1); 780 __ TailCallExternalReference(store_callback_property, 5, 1);
661 781
662 // Return the generated code. 782 // Return the generated code.
663 return GetCode(kind(), Code::FAST, name); 783 return GetCode(kind(), Code::FAST, name);
664 } 784 }
665 785
666 786
667 #undef __
668 #define __ ACCESS_MASM(masm)
669
670
671 void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
672 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
673 Handle<JSFunction> setter) {
674 // ----------- S t a t e -------------
675 // -- rsp[0] : return address
676 // -----------------------------------
677 {
678 FrameScope scope(masm, StackFrame::INTERNAL);
679
680 // Save value register, so we can restore it later.
681 __ Push(value());
682
683 if (!setter.is_null()) {
684 // Call the JavaScript setter with receiver and value on the stack.
685 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
686 // Swap in the global receiver.
687 __ movp(receiver,
688 FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
689 }
690 __ Push(receiver);
691 __ Push(value());
692 ParameterCount actual(1);
693 ParameterCount expected(setter);
694 __ InvokeFunction(setter, expected, actual, CALL_FUNCTION,
695 NullCallWrapper());
696 } else {
697 // If we generate a global code snippet for deoptimization only, remember
698 // the place to continue after deoptimization.
699 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
700 }
701
702 // We have to return the passed value, not the return value of the setter.
703 __ Pop(rax);
704
705 // Restore context register.
706 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
707 }
708 __ ret(0);
709 }
710
711
712 #undef __
713 #define __ ACCESS_MASM(masm())
714
715
716 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor( 787 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
717 Handle<Name> name) { 788 Handle<Name> name) {
718 __ PopReturnAddressTo(scratch1()); 789 __ PopReturnAddressTo(scratch1());
719 __ Push(receiver()); 790 __ Push(receiver());
720 __ Push(this->name()); 791 __ Push(this->name());
721 __ Push(value()); 792 __ Push(value());
722 __ PushReturnAddressFrom(scratch1()); 793 __ PushReturnAddressFrom(scratch1());
723 794
724 // Do tail-call to the runtime system. 795 // Do tail-call to the runtime system.
725 ExternalReference store_ic_property = ExternalReference( 796 ExternalReference store_ic_property = ExternalReference(
726 IC_Utility(IC::kStorePropertyWithInterceptor), isolate()); 797 IC_Utility(IC::kStorePropertyWithInterceptor), isolate());
727 __ TailCallExternalReference(store_ic_property, 3, 1); 798 __ TailCallExternalReference(store_ic_property, 3, 1);
728 799
729 // Return the generated code. 800 // Return the generated code.
730 return GetCode(kind(), Code::FAST, name); 801 return GetCode(kind(), Code::FAST, name);
731 } 802 }
732 803
733 804
734 Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
735 MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
736 MapHandleList* transitioned_maps) {
737 Label miss;
738 __ JumpIfSmi(receiver(), &miss, Label::kNear);
739
740 __ movp(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset));
741 int receiver_count = receiver_maps->length();
742 for (int i = 0; i < receiver_count; ++i) {
743 // Check map and tail call if there's a match
744 __ Cmp(scratch1(), receiver_maps->at(i));
745 if (transitioned_maps->at(i).is_null()) {
746 __ j(equal, handler_stubs->at(i), RelocInfo::CODE_TARGET);
747 } else {
748 Label next_map;
749 __ j(not_equal, &next_map, Label::kNear);
750 __ Move(transition_map(), transitioned_maps->at(i),
751 RelocInfo::EMBEDDED_OBJECT);
752 __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET);
753 __ bind(&next_map);
754 }
755 }
756
757 __ bind(&miss);
758
759 TailCallBuiltin(masm(), MissBuiltin(kind()));
760
761 // Return the generated code.
762 return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
763 }
764
765
766 Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); } 805 Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); }
767 806
768 807
769 #undef __
770 #define __ ACCESS_MASM(masm)
771
772
773 void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
774 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
775 Handle<JSFunction> getter) {
776 // ----------- S t a t e -------------
777 // -- rax : receiver
778 // -- rcx : name
779 // -- rsp[0] : return address
780 // -----------------------------------
781 {
782 FrameScope scope(masm, StackFrame::INTERNAL);
783
784 if (!getter.is_null()) {
785 // Call the JavaScript getter with the receiver on the stack.
786 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
787 // Swap in the global receiver.
788 __ movp(receiver,
789 FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
790 }
791 __ Push(receiver);
792 ParameterCount actual(0);
793 ParameterCount expected(getter);
794 __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
795 NullCallWrapper());
796 } else {
797 // If we generate a global code snippet for deoptimization only, remember
798 // the place to continue after deoptimization.
799 masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
800 }
801
802 // Restore context register.
803 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
804 }
805 __ ret(0);
806 }
807
808
809 #undef __
810 #define __ ACCESS_MASM(masm())
811
812
813 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( 808 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
814 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { 809 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
815 Label miss; 810 Label miss;
816 FrontendHeader(receiver(), name, &miss); 811 FrontendHeader(receiver(), name, &miss);
817 812
818 // Get the value from the cell. 813 // Get the value from the cell.
819 Register result = StoreIC::ValueRegister(); 814 Register result = StoreIC::ValueRegister();
820 __ Move(result, cell); 815 __ Move(result, cell);
821 __ movp(result, FieldOperand(result, PropertyCell::kValueOffset)); 816 __ movp(result, FieldOperand(result, PropertyCell::kValueOffset));
822 817
(...skipping 10 matching lines...) Expand all
833 __ IncrementCounter(counters->named_load_global_stub(), 1); 828 __ IncrementCounter(counters->named_load_global_stub(), 1);
834 __ ret(0); 829 __ ret(0);
835 830
836 FrontendFooter(name, &miss); 831 FrontendFooter(name, &miss);
837 832
838 // Return the generated code. 833 // Return the generated code.
839 return GetCode(kind(), Code::NORMAL, name); 834 return GetCode(kind(), Code::NORMAL, name);
840 } 835 }
841 836
842 837
843 Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
844 CodeHandleList* handlers,
845 Handle<Name> name,
846 Code::StubType type,
847 IcCheckType check) {
848 Label miss;
849
850 if (check == PROPERTY &&
851 (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) {
852 // In case we are compiling an IC for dictionary loads and stores, just
853 // check whether the name is unique.
854 if (name.is_identical_to(isolate()->factory()->normal_ic_symbol())) {
855 __ JumpIfNotUniqueName(this->name(), &miss);
856 } else {
857 __ Cmp(this->name(), name);
858 __ j(not_equal, &miss);
859 }
860 }
861
862 Label number_case;
863 Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
864 __ JumpIfSmi(receiver(), smi_target);
865
866 // Polymorphic keyed stores may use the map register
867 Register map_reg = scratch1();
868 DCHECK(kind() != Code::KEYED_STORE_IC ||
869 map_reg.is(KeyedStoreIC::MapRegister()));
870 __ movp(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset));
871 int receiver_count = types->length();
872 int number_of_handled_maps = 0;
873 for (int current = 0; current < receiver_count; ++current) {
874 Handle<HeapType> type = types->at(current);
875 Handle<Map> map = IC::TypeToMap(*type, isolate());
876 if (!map->is_deprecated()) {
877 number_of_handled_maps++;
878 // Check map and tail call if there's a match
879 __ Cmp(map_reg, map);
880 if (type->Is(HeapType::Number())) {
881 DCHECK(!number_case.is_unused());
882 __ bind(&number_case);
883 }
884 __ j(equal, handlers->at(current), RelocInfo::CODE_TARGET);
885 }
886 }
887 DCHECK(number_of_handled_maps > 0);
888
889 __ bind(&miss);
890 TailCallBuiltin(masm(), MissBuiltin(kind()));
891
892 // Return the generated code.
893 InlineCacheState state =
894 number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC;
895 return GetCode(kind(), type, name, state);
896 }
897
898
899 #undef __
900 #define __ ACCESS_MASM(masm)
901
902
903 void ElementHandlerCompiler::GenerateLoadDictionaryElement(
904 MacroAssembler* masm) {
905 // ----------- S t a t e -------------
906 // -- rcx : key
907 // -- rdx : receiver
908 // -- rsp[0] : return address
909 // -----------------------------------
910 DCHECK(rdx.is(LoadIC::ReceiverRegister()));
911 DCHECK(rcx.is(LoadIC::NameRegister()));
912 Label slow, miss;
913
914 // This stub is meant to be tail-jumped to, the receiver must already
915 // have been verified by the caller to not be a smi.
916
917 __ JumpIfNotSmi(rcx, &miss);
918 __ SmiToInteger32(rbx, rcx);
919 __ movp(rax, FieldOperand(rdx, JSObject::kElementsOffset));
920
921 // Check whether the elements is a number dictionary.
922 // rdx: receiver
923 // rcx: key
924 // rbx: key as untagged int32
925 // rax: elements
926 __ LoadFromNumberDictionary(&slow, rax, rcx, rbx, r9, rdi, rax);
927 __ ret(0);
928
929 __ bind(&slow);
930 // ----------- S t a t e -------------
931 // -- rcx : key
932 // -- rdx : receiver
933 // -- rsp[0] : return address
934 // -----------------------------------
935 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
936
937 __ bind(&miss);
938 // ----------- S t a t e -------------
939 // -- rcx : key
940 // -- rdx : receiver
941 // -- rsp[0] : return address
942 // -----------------------------------
943 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
944 }
945
946
947 void PropertyICCompiler::GenerateRuntimeSetProperty(MacroAssembler* masm,
948 StrictMode strict_mode) {
949 // Return address is on the stack.
950 DCHECK(!rbx.is(StoreIC::ReceiverRegister()) &&
951 !rbx.is(StoreIC::NameRegister()) && !rbx.is(StoreIC::ValueRegister()));
952
953 __ PopReturnAddressTo(rbx);
954 __ Push(StoreIC::ReceiverRegister());
955 __ Push(StoreIC::NameRegister());
956 __ Push(StoreIC::ValueRegister());
957 __ Push(Smi::FromInt(strict_mode));
958 __ PushReturnAddressFrom(rbx);
959
960 // Do tail-call to runtime routine.
961 __ TailCallRuntime(Runtime::kSetProperty, 4, 1);
962 }
963
964
965 #undef __ 838 #undef __
966 } 839 }
967 } // namespace v8::internal 840 } // namespace v8::internal
968 841
969 #endif // V8_TARGET_ARCH_X64 842 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/ic/ic-compiler.cc ('k') | src/ic/x64/ic-compiler-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698