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

Side by Side Diff: src/ic/arm64/handler-compiler-arm64.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/arm/ic-compiler-arm.cc ('k') | src/ic/arm64/ic-compiler-arm64.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_ARM64 7 #if V8_TARGET_ARCH_ARM64
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 PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( 18 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
19 MacroAssembler* masm, Label* miss_label, Register receiver, 19 MacroAssembler* masm, Label* miss_label, Register receiver,
20 Handle<Name> name, Register scratch0, Register scratch1) { 20 Handle<Name> name, Register scratch0, Register scratch1) {
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 ExternalReference ref = ExternalReference( 199 ExternalReference ref = ExternalReference(
200 &fun, ExternalReference::DIRECT_API_CALL, masm->isolate()); 200 &fun, ExternalReference::DIRECT_API_CALL, masm->isolate());
201 __ Mov(api_function_address, ref); 201 __ Mov(api_function_address, ref);
202 202
203 // Jump to stub. 203 // Jump to stub.
204 CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc); 204 CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
205 __ TailCallStub(&stub); 205 __ TailCallStub(&stub);
206 } 206 }
207 207
208 208
209 void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
210 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
211 Handle<JSFunction> setter) {
212 // ----------- S t a t e -------------
213 // -- lr : return address
214 // -----------------------------------
215 Label miss;
216
217 {
218 FrameScope scope(masm, StackFrame::INTERNAL);
219
220 // Save value register, so we can restore it later.
221 __ Push(value());
222
223 if (!setter.is_null()) {
224 // Call the JavaScript setter with receiver and value on the stack.
225 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
226 // Swap in the global receiver.
227 __ Ldr(receiver,
228 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
229 }
230 __ Push(receiver, value());
231 ParameterCount actual(1);
232 ParameterCount expected(setter);
233 __ InvokeFunction(setter, expected, actual, CALL_FUNCTION,
234 NullCallWrapper());
235 } else {
236 // If we generate a global code snippet for deoptimization only, remember
237 // the place to continue after deoptimization.
238 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
239 }
240
241 // We have to return the passed value, not the return value of the setter.
242 __ Pop(x0);
243
244 // Restore context register.
245 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
246 }
247 __ Ret();
248 }
249
250
251 void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
252 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
253 Handle<JSFunction> getter) {
254 {
255 FrameScope scope(masm, StackFrame::INTERNAL);
256
257 if (!getter.is_null()) {
258 // Call the JavaScript getter with the receiver on the stack.
259 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
260 // Swap in the global receiver.
261 __ Ldr(receiver,
262 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
263 }
264 __ Push(receiver);
265 ParameterCount actual(0);
266 ParameterCount expected(getter);
267 __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
268 NullCallWrapper());
269 } else {
270 // If we generate a global code snippet for deoptimization only, remember
271 // the place to continue after deoptimization.
272 masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
273 }
274
275 // Restore context register.
276 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
277 }
278 __ Ret();
279 }
280
281
282 void ElementHandlerCompiler::GenerateLoadDictionaryElement(
283 MacroAssembler* masm) {
284 // The return address is in lr.
285 Label slow, miss;
286
287 Register result = x0;
288 Register key = LoadIC::NameRegister();
289 Register receiver = LoadIC::ReceiverRegister();
290 DCHECK(receiver.is(x1));
291 DCHECK(key.is(x2));
292
293 __ JumpIfNotSmi(key, &miss);
294 __ Ldr(x4, FieldMemOperand(receiver, JSObject::kElementsOffset));
295 __ LoadFromNumberDictionary(&slow, x4, key, result, x7, x3, x5, x6);
296 __ Ret();
297
298 __ Bind(&slow);
299 __ IncrementCounter(
300 masm->isolate()->counters()->keyed_load_external_array_slow(), 1, x4, x3);
301 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
302
303 // Miss case, call the runtime.
304 __ Bind(&miss);
305 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
306 }
307
308
209 #undef __ 309 #undef __
210 #define __ ACCESS_MASM(masm()) 310 #define __ ACCESS_MASM(masm())
211 311
212 312
313 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
314 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
315 Label miss;
316 FrontendHeader(receiver(), name, &miss);
317
318 // Get the value from the cell.
319 Register result = StoreIC::ValueRegister();
320 __ Mov(result, Operand(cell));
321 __ Ldr(result, FieldMemOperand(result, Cell::kValueOffset));
322
323 // Check for deleted property if property can actually be deleted.
324 if (is_configurable) {
325 __ JumpIfRoot(result, Heap::kTheHoleValueRootIndex, &miss);
326 }
327
328 Counters* counters = isolate()->counters();
329 __ IncrementCounter(counters->named_load_global_stub(), 1, x1, x3);
330 __ Ret();
331
332 FrontendFooter(name, &miss);
333
334 // Return the generated code.
335 return GetCode(kind(), Code::NORMAL, name);
336 }
337
338
339 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
340 Handle<Name> name) {
341 Label miss;
342
343 ASM_LOCATION("NamedStoreHandlerCompiler::CompileStoreInterceptor");
344
345 __ Push(receiver(), this->name(), value());
346
347 // Do tail-call to the runtime system.
348 ExternalReference store_ic_property = ExternalReference(
349 IC_Utility(IC::kStorePropertyWithInterceptor), isolate());
350 __ TailCallExternalReference(store_ic_property, 3, 1);
351
352 // Return the generated code.
353 return GetCode(kind(), Code::FAST, name);
354 }
355
356
357 Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); }
358
359
213 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label, 360 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
214 Handle<Name> name) { 361 Handle<Name> name) {
215 if (!label->is_unused()) { 362 if (!label->is_unused()) {
216 __ Bind(label); 363 __ Bind(label);
217 __ Mov(this->name(), Operand(name)); 364 __ Mov(this->name(), Operand(name));
218 } 365 }
219 } 366 }
220 367
221 368
222 // Generate StoreTransition code, value is passed in x0 register. 369 // Generate StoreTransition code, value is passed in x0 register.
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
684 ExternalReference store_callback_property = 831 ExternalReference store_callback_property =
685 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 832 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
686 __ TailCallExternalReference(store_callback_property, 5, 1); 833 __ TailCallExternalReference(store_callback_property, 5, 1);
687 834
688 // Return the generated code. 835 // Return the generated code.
689 return GetCode(kind(), Code::FAST, name); 836 return GetCode(kind(), Code::FAST, name);
690 } 837 }
691 838
692 839
693 #undef __ 840 #undef __
694 #define __ ACCESS_MASM(masm)
695
696
697 void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
698 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
699 Handle<JSFunction> setter) {
700 // ----------- S t a t e -------------
701 // -- lr : return address
702 // -----------------------------------
703 Label miss;
704
705 {
706 FrameScope scope(masm, StackFrame::INTERNAL);
707
708 // Save value register, so we can restore it later.
709 __ Push(value());
710
711 if (!setter.is_null()) {
712 // Call the JavaScript setter with receiver and value on the stack.
713 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
714 // Swap in the global receiver.
715 __ Ldr(receiver,
716 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
717 }
718 __ Push(receiver, value());
719 ParameterCount actual(1);
720 ParameterCount expected(setter);
721 __ InvokeFunction(setter, expected, actual, CALL_FUNCTION,
722 NullCallWrapper());
723 } else {
724 // If we generate a global code snippet for deoptimization only, remember
725 // the place to continue after deoptimization.
726 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
727 }
728
729 // We have to return the passed value, not the return value of the setter.
730 __ Pop(x0);
731
732 // Restore context register.
733 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
734 }
735 __ Ret();
736 }
737
738
739 #undef __
740 #define __ ACCESS_MASM(masm())
741
742
743 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
744 Handle<Name> name) {
745 Label miss;
746
747 ASM_LOCATION("NamedStoreHandlerCompiler::CompileStoreInterceptor");
748
749 __ Push(receiver(), this->name(), value());
750
751 // Do tail-call to the runtime system.
752 ExternalReference store_ic_property = ExternalReference(
753 IC_Utility(IC::kStorePropertyWithInterceptor), isolate());
754 __ TailCallExternalReference(store_ic_property, 3, 1);
755
756 // Return the generated code.
757 return GetCode(kind(), Code::FAST, name);
758 }
759
760
761 Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); }
762
763
764 #undef __
765 #define __ ACCESS_MASM(masm)
766
767 void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
768 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
769 Handle<JSFunction> getter) {
770 {
771 FrameScope scope(masm, StackFrame::INTERNAL);
772
773 if (!getter.is_null()) {
774 // Call the JavaScript getter with the receiver on the stack.
775 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
776 // Swap in the global receiver.
777 __ Ldr(receiver,
778 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
779 }
780 __ Push(receiver);
781 ParameterCount actual(0);
782 ParameterCount expected(getter);
783 __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
784 NullCallWrapper());
785 } else {
786 // If we generate a global code snippet for deoptimization only, remember
787 // the place to continue after deoptimization.
788 masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
789 }
790
791 // Restore context register.
792 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
793 }
794 __ Ret();
795 }
796
797
798 #undef __
799 #define __ ACCESS_MASM(masm())
800
801
802 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
803 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
804 Label miss;
805 FrontendHeader(receiver(), name, &miss);
806
807 // Get the value from the cell.
808 Register result = StoreIC::ValueRegister();
809 __ Mov(result, Operand(cell));
810 __ Ldr(result, FieldMemOperand(result, Cell::kValueOffset));
811
812 // Check for deleted property if property can actually be deleted.
813 if (is_configurable) {
814 __ JumpIfRoot(result, Heap::kTheHoleValueRootIndex, &miss);
815 }
816
817 Counters* counters = isolate()->counters();
818 __ IncrementCounter(counters->named_load_global_stub(), 1, x1, x3);
819 __ Ret();
820
821 FrontendFooter(name, &miss);
822
823 // Return the generated code.
824 return GetCode(kind(), Code::NORMAL, name);
825 }
826
827
828 Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
829 CodeHandleList* handlers,
830 Handle<Name> name,
831 Code::StubType type,
832 IcCheckType check) {
833 Label miss;
834
835 if (check == PROPERTY &&
836 (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) {
837 // In case we are compiling an IC for dictionary loads and stores, just
838 // check whether the name is unique.
839 if (name.is_identical_to(isolate()->factory()->normal_ic_symbol())) {
840 __ JumpIfNotUniqueName(this->name(), &miss);
841 } else {
842 __ CompareAndBranch(this->name(), Operand(name), ne, &miss);
843 }
844 }
845
846 Label number_case;
847 Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
848 __ JumpIfSmi(receiver(), smi_target);
849
850 // Polymorphic keyed stores may use the map register
851 Register map_reg = scratch1();
852 DCHECK(kind() != Code::KEYED_STORE_IC ||
853 map_reg.is(KeyedStoreIC::MapRegister()));
854 __ Ldr(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset));
855 int receiver_count = types->length();
856 int number_of_handled_maps = 0;
857 for (int current = 0; current < receiver_count; ++current) {
858 Handle<HeapType> type = types->at(current);
859 Handle<Map> map = IC::TypeToMap(*type, isolate());
860 if (!map->is_deprecated()) {
861 number_of_handled_maps++;
862 Label try_next;
863 __ Cmp(map_reg, Operand(map));
864 __ B(ne, &try_next);
865 if (type->Is(HeapType::Number())) {
866 DCHECK(!number_case.is_unused());
867 __ Bind(&number_case);
868 }
869 __ Jump(handlers->at(current), RelocInfo::CODE_TARGET);
870 __ Bind(&try_next);
871 }
872 }
873 DCHECK(number_of_handled_maps != 0);
874
875 __ Bind(&miss);
876 TailCallBuiltin(masm(), MissBuiltin(kind()));
877
878 // Return the generated code.
879 InlineCacheState state =
880 (number_of_handled_maps > 1) ? POLYMORPHIC : MONOMORPHIC;
881 return GetCode(kind(), type, name, state);
882 }
883
884
885 Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
886 MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
887 MapHandleList* transitioned_maps) {
888 Label miss;
889
890 ASM_LOCATION("PropertyICCompiler::CompileStorePolymorphic");
891
892 __ JumpIfSmi(receiver(), &miss);
893
894 int receiver_count = receiver_maps->length();
895 __ Ldr(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset));
896 for (int i = 0; i < receiver_count; i++) {
897 __ Cmp(scratch1(), Operand(receiver_maps->at(i)));
898
899 Label skip;
900 __ B(&skip, ne);
901 if (!transitioned_maps->at(i).is_null()) {
902 // This argument is used by the handler stub. For example, see
903 // ElementsTransitionGenerator::GenerateMapChangeElementsTransition.
904 __ Mov(transition_map(), Operand(transitioned_maps->at(i)));
905 }
906 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET);
907 __ Bind(&skip);
908 }
909
910 __ Bind(&miss);
911 TailCallBuiltin(masm(), MissBuiltin(kind()));
912
913 return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
914 }
915
916
917 #undef __
918 #define __ ACCESS_MASM(masm)
919
920 void ElementHandlerCompiler::GenerateLoadDictionaryElement(
921 MacroAssembler* masm) {
922 // The return address is in lr.
923 Label slow, miss;
924
925 Register result = x0;
926 Register key = LoadIC::NameRegister();
927 Register receiver = LoadIC::ReceiverRegister();
928 DCHECK(receiver.is(x1));
929 DCHECK(key.is(x2));
930
931 __ JumpIfNotSmi(key, &miss);
932 __ Ldr(x4, FieldMemOperand(receiver, JSObject::kElementsOffset));
933 __ LoadFromNumberDictionary(&slow, x4, key, result, x7, x3, x5, x6);
934 __ Ret();
935
936 __ Bind(&slow);
937 __ IncrementCounter(
938 masm->isolate()->counters()->keyed_load_external_array_slow(), 1, x4, x3);
939 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
940
941 // Miss case, call the runtime.
942 __ Bind(&miss);
943 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
944 }
945
946
947 void PropertyICCompiler::GenerateRuntimeSetProperty(MacroAssembler* masm,
948 StrictMode strict_mode) {
949 ASM_LOCATION("PropertyICCompiler::GenerateRuntimeSetProperty");
950
951 __ Push(StoreIC::ReceiverRegister(), StoreIC::NameRegister(),
952 StoreIC::ValueRegister());
953
954 __ Mov(x10, Smi::FromInt(strict_mode));
955 __ Push(x10);
956
957 // Do tail-call to runtime routine.
958 __ TailCallRuntime(Runtime::kSetProperty, 4, 1);
959 }
960
961
962 #undef __
963 } 841 }
964 } // namespace v8::internal 842 } // namespace v8::internal
965 843
966 #endif // V8_TARGET_ARCH_ARM64 844 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ic/arm/ic-compiler-arm.cc ('k') | src/ic/arm64/ic-compiler-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698