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

Side by Side Diff: src/mips/stub-cache-mips.cc

Issue 145583012: MIPS: stub fast api calls (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Optimize pushes. Created 6 years, 10 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/mips/macro-assembler-mips.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 747 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 Register name, 758 Register name,
759 Handle<JSObject> holder_obj, 759 Handle<JSObject> holder_obj,
760 IC::UtilityId id) { 760 IC::UtilityId id) {
761 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); 761 PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
762 __ CallExternalReference( 762 __ CallExternalReference(
763 ExternalReference(IC_Utility(id), masm->isolate()), 763 ExternalReference(IC_Utility(id), masm->isolate()),
764 StubCache::kInterceptorArgsLength); 764 StubCache::kInterceptorArgsLength);
765 } 765 }
766 766
767 767
768 static const int kFastApiCallArguments = FunctionCallbackArguments::kArgsLength;
769
770
771 static void GenerateFastApiCallBody(MacroAssembler* masm, 768 static void GenerateFastApiCallBody(MacroAssembler* masm,
772 const CallOptimization& optimization, 769 const CallOptimization& optimization,
773 int argc, 770 int argc,
774 Register holder, 771 Register holder_in,
775 Register scratch1,
776 Register scratch2,
777 Register scratch3,
778 bool restore_context) { 772 bool restore_context) {
779 // ----------- S t a t e -------------
780 // -- sp[0] : last JS argument
781 // -- ...
782 // -- sp[(argc - 1) * 4] : first JS argument
783 // -- sp[argc * 4] : receiver
784 // -----------------------------------
785 ASSERT(optimization.is_simple_api_call()); 773 ASSERT(optimization.is_simple_api_call());
786 774
787 typedef FunctionCallbackArguments FCA; 775 // Abi for CallApiFunctionStub.
776 Register callee = a0;
777 Register call_data = t0;
778 Register holder = a2;
779 Register api_function_address = a3;
780 Register thunk_arg = a1;
788 781
789 STATIC_ASSERT(FCA::kHolderIndex == 0); 782 // Put holder in place.
790 STATIC_ASSERT(FCA::kIsolateIndex == 1); 783 __ mov(holder, holder_in);
791 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2);
792 STATIC_ASSERT(FCA::kReturnValueOffset == 3);
793 STATIC_ASSERT(FCA::kDataIndex == 4);
794 STATIC_ASSERT(FCA::kCalleeIndex == 5);
795 STATIC_ASSERT(FCA::kContextSaveIndex == 6);
796 STATIC_ASSERT(FCA::kArgsLength == 7);
797 784
798 ASSERT(!holder.is(cp)); 785 Isolate* isolate = masm->isolate();
786 Handle<JSFunction> function = optimization.constant_function();
787 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
788 Handle<Object> call_data_obj(api_call_info->data(), isolate);
799 789
800 // Save calling context. 790 // Put callee in place.
801 __ push(cp); 791 __ li(callee, function);
802 // Get the function and setup the context.
803 Handle<JSFunction> function = optimization.constant_function();
804 __ li(scratch1, function);
805 __ lw(cp, FieldMemOperand(scratch1, JSFunction::kContextOffset));
806 __ push(scratch1);
807 792
808 // Construct the FunctionCallbackInfo.
809 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
810 Handle<Object> call_data(api_call_info->data(), masm->isolate());
811 bool call_data_undefined = false; 793 bool call_data_undefined = false;
812 if (masm->isolate()->heap()->InNewSpace(*call_data)) { 794 // Put call_data in place.
813 __ li(scratch1, api_call_info); 795 if (isolate->heap()->InNewSpace(*call_data_obj)) {
814 __ lw(scratch1, FieldMemOperand(scratch1, CallHandlerInfo::kDataOffset)); 796 __ li(call_data, api_call_info);
815 } else if (call_data->IsUndefined()) { 797 __ lw(call_data, FieldMemOperand(call_data, CallHandlerInfo::kDataOffset));
798 } else if (call_data_obj->IsUndefined()) {
816 call_data_undefined = true; 799 call_data_undefined = true;
817 __ LoadRoot(scratch3, Heap::kUndefinedValueRootIndex); 800 __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex);
818 } else { 801 } else {
819 __ li(scratch1, call_data); 802 __ li(call_data, call_data_obj);
820 } 803 }
821 // Store call data. 804 // Put api_function_address in place.
822 __ push(scratch1);
823 if (!call_data_undefined) {
824 __ LoadRoot(scratch1, Heap::kUndefinedValueRootIndex);
825 }
826 // Store ReturnValue default and ReturnValue.
827 __ LoadRoot(scratch1, Heap::kUndefinedValueRootIndex);
828 __ Push(scratch1, scratch1);
829 // Store isolate.
830 __ li(scratch1, Operand(ExternalReference::isolate_address(masm->isolate())));
831 __ push(scratch1);
832 // Store holder.
833 __ push(holder);
834
835 // Prepare arguments.
836 __ Move(a2, sp);
837
838 // Allocate the v8::Arguments structure in the arguments' space since
839 // it's not controlled by GC.
840 const int kApiStackSpace = 4;
841
842 FrameScope frame_scope(masm, StackFrame::MANUAL);
843 __ EnterExitFrame(false, kApiStackSpace);
844
845 // a0 = FunctionCallbackInfo&
846 // Arguments is built at sp + 1 (sp is a reserved spot for ra).
847 __ Addu(a0, sp, kPointerSize);
848 // FunctionCallbackInfo::implicit_args_
849 __ sw(a2, MemOperand(a0, 0 * kPointerSize));
850 // FunctionCallbackInfo::values_
851 __ Addu(t0, a2, Operand((kFastApiCallArguments - 1 + argc) * kPointerSize));
852 __ sw(t0, MemOperand(a0, 1 * kPointerSize));
853 // FunctionCallbackInfo::length_ = argc
854 __ li(t0, Operand(argc));
855 __ sw(t0, MemOperand(a0, 2 * kPointerSize));
856 // FunctionCallbackInfo::is_construct_call = 0
857 __ sw(zero_reg, MemOperand(a0, 3 * kPointerSize));
858
859 const int kStackUnwindSpace = argc + kFastApiCallArguments + 1;
860 Address function_address = v8::ToCData<Address>(api_call_info->callback()); 805 Address function_address = v8::ToCData<Address>(api_call_info->callback());
861 ApiFunction fun(function_address); 806 ApiFunction fun(function_address);
862 ExternalReference::Type type = ExternalReference::DIRECT_API_CALL; 807 ExternalReference::Type type = ExternalReference::DIRECT_API_CALL;
863 ExternalReference ref = 808 ExternalReference ref =
864 ExternalReference(&fun, 809 ExternalReference(&fun,
865 type, 810 type,
866 masm->isolate()); 811 masm->isolate());
867 Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback); 812 __ li(api_function_address, Operand(ref));
868 ExternalReference::Type thunk_type = ExternalReference::PROFILING_API_CALL; 813 __ li(thunk_arg, Operand(reinterpret_cast<int32_t>(function_address)));
869 ApiFunction thunk_fun(thunk_address);
870 ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
871 masm->isolate());
872 814
873 AllowExternalCallThatCantCauseGC scope(masm); 815 // Jump to stub.
874 MemOperand context_restore_operand( 816 CallApiFunctionStub stub(restore_context, call_data_undefined, argc);
875 fp, (2 + FCA::kContextSaveIndex) * kPointerSize); 817 __ TailCallStub(&stub);
876 MemOperand return_value_operand(
877 fp, (2 + FCA::kReturnValueOffset) * kPointerSize);
878
879 __ CallApiFunctionAndReturn(ref,
880 function_address,
881 thunk_ref,
882 a1,
883 kStackUnwindSpace,
884 return_value_operand,
885 restore_context ?
886 &context_restore_operand : NULL);
887 } 818 }
888 819
889 820
890 // Generates call to API function. 821 // Generates call to API function.
891 static void GenerateFastApiCall(MacroAssembler* masm, 822 static void GenerateFastApiCall(MacroAssembler* masm,
892 const CallOptimization& optimization, 823 const CallOptimization& optimization,
893 int argc, 824 int argc,
894 Handle<Map> map_to_holder, 825 Handle<Map> map_to_holder,
895 CallOptimization::HolderLookup holder_lookup) { 826 CallOptimization::HolderLookup holder_lookup) {
896 Counters* counters = masm->isolate()->counters(); 827 Counters* counters = masm->isolate()->counters();
897 __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a1); 828 __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a1);
898 829
899 // Move holder to a register. 830 // Move holder to a register.
900 Register holder_reg = a0; 831 Register holder_reg = a2;
901 switch (holder_lookup) { 832 switch (holder_lookup) {
902 case CallOptimization::kHolderIsReceiver: 833 case CallOptimization::kHolderIsReceiver:
903 { 834 {
904 ASSERT(map_to_holder.is_null()); 835 ASSERT(map_to_holder.is_null());
905 __ lw(holder_reg, MemOperand(sp, argc * kPointerSize)); 836 __ lw(holder_reg, MemOperand(sp, argc * kPointerSize));
906 } 837 }
907 break; 838 break;
908 case CallOptimization::kHolderIsPrototypeOfMap: 839 case CallOptimization::kHolderIsPrototypeOfMap:
909 { 840 {
910 Handle<JSObject> holder(JSObject::cast(map_to_holder->prototype())); 841 Handle<JSObject> holder(JSObject::cast(map_to_holder->prototype()));
911 if (!masm->isolate()->heap()->InNewSpace(*holder)) { 842 if (!masm->isolate()->heap()->InNewSpace(*holder)) {
912 __ li(holder_reg, holder); 843 __ li(holder_reg, holder);
913 } else { 844 } else {
914 __ li(holder_reg, map_to_holder); 845 __ li(holder_reg, map_to_holder);
915 __ lw(holder_reg, 846 __ lw(holder_reg,
916 FieldMemOperand(holder_reg, Map::kPrototypeOffset)); 847 FieldMemOperand(holder_reg, Map::kPrototypeOffset));
917 } 848 }
918 } 849 }
919 break; 850 break;
920 case CallOptimization::kHolderNotFound: 851 case CallOptimization::kHolderNotFound:
921 UNREACHABLE(); 852 UNREACHABLE();
922 } 853 }
923 GenerateFastApiCallBody(masm, 854 GenerateFastApiCallBody(masm,
924 optimization, 855 optimization,
925 argc, 856 argc,
926 holder_reg, 857 holder_reg,
927 a1,
928 a2,
929 a3,
930 false); 858 false);
931 } 859 }
932 860
933 861
934 // Generate call to api function. 862 // Generate call to api function.
935 static void GenerateFastApiCall(MacroAssembler* masm, 863 static void GenerateFastApiCall(MacroAssembler* masm,
936 const CallOptimization& optimization, 864 const CallOptimization& optimization,
937 Register receiver, 865 Register receiver,
938 Register scratch, 866 Register scratch,
939 int argc, 867 int argc,
940 Register* values) { 868 Register* values) {
941 ASSERT(!receiver.is(scratch)); 869 ASSERT(!receiver.is(scratch));
942 __ push(receiver); 870 __ push(receiver);
943 // Write the arguments to stack frame. 871 // Write the arguments to stack frame.
944 for (int i = 0; i < argc; i++) { 872 for (int i = 0; i < argc; i++) {
945 Register arg = values[argc-1-i]; 873 Register arg = values[argc-1-i];
946 ASSERT(!receiver.is(arg)); 874 ASSERT(!receiver.is(arg));
947 ASSERT(!scratch.is(arg)); 875 ASSERT(!scratch.is(arg));
948 __ push(arg); 876 __ push(arg);
949 } 877 }
950 878
951 Register scratch1 = a0;
952 Register scratch2 = a1;
953 Register scratch3 = a2;
954 if (!a3.is(receiver)) {
955 __ mov(a3, receiver);
956 receiver = a3;
957 }
958 // Stack now matches JSFunction abi. 879 // Stack now matches JSFunction abi.
959 GenerateFastApiCallBody(masm, 880 GenerateFastApiCallBody(masm,
960 optimization, 881 optimization,
961 argc, 882 argc,
962 receiver, 883 receiver,
963 scratch1,
964 scratch2,
965 scratch3,
966 true); 884 true);
967 } 885 }
968 886
969 887
970 class CallInterceptorCompiler BASE_EMBEDDED { 888 class CallInterceptorCompiler BASE_EMBEDDED {
971 public: 889 public:
972 CallInterceptorCompiler(CallStubCompiler* stub_compiler, 890 CallInterceptorCompiler(CallStubCompiler* stub_compiler,
973 const ParameterCount& arguments, 891 const ParameterCount& arguments,
974 Register name) 892 Register name)
975 : stub_compiler_(stub_compiler), 893 : stub_compiler_(stub_compiler),
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
1405 // scratch2 (internal::Object** args_) as the data. 1323 // scratch2 (internal::Object** args_) as the data.
1406 __ sw(a2, MemOperand(sp, kPointerSize)); 1324 __ sw(a2, MemOperand(sp, kPointerSize));
1407 // (second argument - a1) = AccessorInfo& 1325 // (second argument - a1) = AccessorInfo&
1408 __ Addu(a1, sp, kPointerSize); 1326 __ Addu(a1, sp, kPointerSize);
1409 1327
1410 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1; 1328 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
1411 Address getter_address = v8::ToCData<Address>(callback->getter()); 1329 Address getter_address = v8::ToCData<Address>(callback->getter());
1412 ApiFunction fun(getter_address); 1330 ApiFunction fun(getter_address);
1413 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL; 1331 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
1414 ExternalReference ref = ExternalReference(&fun, type, isolate()); 1332 ExternalReference ref = ExternalReference(&fun, type, isolate());
1333 Register getter_address_reg = a3;
1334 Register thunk_last_arg = a2;
1335 __ li(getter_address_reg, Operand(ref));
1336 __ li(thunk_last_arg, Operand(reinterpret_cast<int32_t>(getter_address)));
1415 1337
1416 Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback); 1338 Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
1417 ExternalReference::Type thunk_type = 1339 ExternalReference::Type thunk_type =
1418 ExternalReference::PROFILING_GETTER_CALL; 1340 ExternalReference::PROFILING_GETTER_CALL;
1419 ApiFunction thunk_fun(thunk_address); 1341 ApiFunction thunk_fun(thunk_address);
1420 ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type, 1342 ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
1421 isolate()); 1343 isolate());
1422 __ CallApiFunctionAndReturn(ref, 1344 __ CallApiFunctionAndReturn(getter_address_reg,
1423 getter_address,
1424 thunk_ref, 1345 thunk_ref,
1425 a2, 1346 thunk_last_arg,
1426 kStackUnwindSpace, 1347 kStackUnwindSpace,
1427 MemOperand(fp, 6 * kPointerSize), 1348 MemOperand(fp, 6 * kPointerSize),
1428 NULL); 1349 NULL);
1429 } 1350 }
1430 1351
1431 1352
1432 void LoadStubCompiler::GenerateLoadInterceptor( 1353 void LoadStubCompiler::GenerateLoadInterceptor(
1433 Register holder_reg, 1354 Register holder_reg,
1434 Handle<Object> object, 1355 Handle<Object> object,
1435 Handle<JSObject> interceptor_holder, 1356 Handle<JSObject> interceptor_holder,
(...skipping 747 matching lines...) Expand 10 before | Expand all | Expand 10 after
2183 // ----------------------------------- 2104 // -----------------------------------
2184 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 2105 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
2185 } 2106 }
2186 2107
2187 2108
2188 #undef __ 2109 #undef __
2189 2110
2190 } } // namespace v8::internal 2111 } } // namespace v8::internal
2191 2112
2192 #endif // V8_TARGET_ARCH_MIPS 2113 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/macro-assembler-mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698