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

Side by Side Diff: src/ia32/code-stubs-ia32.cc

Issue 1693513002: [runtime] Introduce FastNewStrictArgumentsStub to optimize strict arguments. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix mips and mips64. Created 4 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
« no previous file with comments | « src/ia32/builtins-ia32.cc ('k') | src/ia32/interface-descriptors-ia32.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 #if V8_TARGET_ARCH_IA32 5 #if V8_TARGET_ARCH_IA32
6 6
7 #include "src/base/bits.h" 7 #include "src/base/bits.h"
8 #include "src/bootstrapper.h" 8 #include "src/bootstrapper.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after
870 Label no_parameter_map; 870 Label no_parameter_map;
871 __ test(ebx, ebx); 871 __ test(ebx, ebx);
872 __ j(zero, &no_parameter_map, Label::kNear); 872 __ j(zero, &no_parameter_map, Label::kNear);
873 __ lea(ebx, Operand(ebx, times_2, kParameterMapHeaderSize)); 873 __ lea(ebx, Operand(ebx, times_2, kParameterMapHeaderSize));
874 __ bind(&no_parameter_map); 874 __ bind(&no_parameter_map);
875 875
876 // 2. Backing store. 876 // 2. Backing store.
877 __ lea(ebx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize)); 877 __ lea(ebx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize));
878 878
879 // 3. Arguments object. 879 // 3. Arguments object.
880 __ add(ebx, Immediate(Heap::kSloppyArgumentsObjectSize)); 880 __ add(ebx, Immediate(JSSloppyArgumentsObject::kSize));
881 881
882 // Do the allocation of all three objects in one go. 882 // Do the allocation of all three objects in one go.
883 __ Allocate(ebx, eax, edi, no_reg, &runtime, TAG_OBJECT); 883 __ Allocate(ebx, eax, edi, no_reg, &runtime, TAG_OBJECT);
884 884
885 // eax = address of new object(s) (tagged) 885 // eax = address of new object(s) (tagged)
886 // ecx = argument count (smi-tagged) 886 // ecx = argument count (smi-tagged)
887 // esp[0] = mapped parameter count (tagged) 887 // esp[0] = mapped parameter count (tagged)
888 // esp[4] = function 888 // esp[4] = function
889 // esp[8] = parameter count (tagged) 889 // esp[8] = parameter count (tagged)
890 // Get the arguments map from the current native context into edi. 890 // Get the arguments map from the current native context into edi.
(...skipping 20 matching lines...) Expand all
911 // esp[4] = function 911 // esp[4] = function
912 // esp[8] = parameter count (tagged) 912 // esp[8] = parameter count (tagged)
913 // Copy the JS object part. 913 // Copy the JS object part.
914 __ mov(FieldOperand(eax, JSObject::kMapOffset), edi); 914 __ mov(FieldOperand(eax, JSObject::kMapOffset), edi);
915 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), 915 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset),
916 masm->isolate()->factory()->empty_fixed_array()); 916 masm->isolate()->factory()->empty_fixed_array());
917 __ mov(FieldOperand(eax, JSObject::kElementsOffset), 917 __ mov(FieldOperand(eax, JSObject::kElementsOffset),
918 masm->isolate()->factory()->empty_fixed_array()); 918 masm->isolate()->factory()->empty_fixed_array());
919 919
920 // Set up the callee in-object property. 920 // Set up the callee in-object property.
921 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); 921 STATIC_ASSERT(JSSloppyArgumentsObject::kCalleeIndex == 1);
922 __ mov(edi, Operand(esp, 1 * kPointerSize)); 922 __ mov(edi, Operand(esp, 1 * kPointerSize));
923 __ AssertNotSmi(edi); 923 __ AssertNotSmi(edi);
924 __ mov(FieldOperand(eax, JSObject::kHeaderSize + 924 __ mov(FieldOperand(eax, JSSloppyArgumentsObject::kCalleeOffset), edi);
925 Heap::kArgumentsCalleeIndex * kPointerSize),
926 edi);
927 925
928 // Use the length (smi tagged) and set that as an in-object property too. 926 // Use the length (smi tagged) and set that as an in-object property too.
929 __ AssertSmi(ecx); 927 __ AssertSmi(ecx);
930 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); 928 __ mov(FieldOperand(eax, JSSloppyArgumentsObject::kLengthOffset), ecx);
931 __ mov(FieldOperand(eax, JSObject::kHeaderSize +
932 Heap::kArgumentsLengthIndex * kPointerSize),
933 ecx);
934 929
935 // Set up the elements pointer in the allocated arguments object. 930 // Set up the elements pointer in the allocated arguments object.
936 // If we allocated a parameter map, edi will point there, otherwise to the 931 // If we allocated a parameter map, edi will point there, otherwise to the
937 // backing store. 932 // backing store.
938 __ lea(edi, Operand(eax, Heap::kSloppyArgumentsObjectSize)); 933 __ lea(edi, Operand(eax, JSSloppyArgumentsObject::kSize));
939 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi); 934 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
940 935
941 // eax = address of new object (tagged) 936 // eax = address of new object (tagged)
942 // ebx = mapped parameter count (tagged) 937 // ebx = mapped parameter count (tagged)
943 // ecx = argument count (tagged) 938 // ecx = argument count (tagged)
944 // edx = address of receiver argument 939 // edx = address of receiver argument
945 // edi = address of parameter map or backing store (tagged) 940 // edi = address of parameter map or backing store (tagged)
946 // esp[0] = mapped parameter count (tagged) 941 // esp[0] = mapped parameter count (tagged)
947 // esp[4] = function 942 // esp[4] = function
948 // esp[8] = parameter count (tagged) 943 // esp[8] = parameter count (tagged)
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1048 __ pop(eax); // Remove saved parameter count. 1043 __ pop(eax); // Remove saved parameter count.
1049 __ pop(eax); // Pop return address. 1044 __ pop(eax); // Pop return address.
1050 __ push(edi); // Push function. 1045 __ push(edi); // Push function.
1051 __ push(edx); // Push parameters pointer. 1046 __ push(edx); // Push parameters pointer.
1052 __ push(ecx); // Push parameter count. 1047 __ push(ecx); // Push parameter count.
1053 __ push(eax); // Push return address. 1048 __ push(eax); // Push return address.
1054 __ TailCallRuntime(Runtime::kNewSloppyArguments); 1049 __ TailCallRuntime(Runtime::kNewSloppyArguments);
1055 } 1050 }
1056 1051
1057 1052
1058 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
1059 // ecx : number of parameters (tagged)
1060 // edx : parameters pointer
1061 // edi : function
1062 // esp[0] : return address
1063
1064 DCHECK(edi.is(ArgumentsAccessNewDescriptor::function()));
1065 DCHECK(ecx.is(ArgumentsAccessNewDescriptor::parameter_count()));
1066 DCHECK(edx.is(ArgumentsAccessNewDescriptor::parameter_pointer()));
1067
1068 // Check if the calling frame is an arguments adaptor frame.
1069 Label try_allocate, runtime;
1070 __ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
1071 __ mov(eax, Operand(ebx, StandardFrameConstants::kContextOffset));
1072 __ cmp(eax, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
1073 __ j(not_equal, &try_allocate, Label::kNear);
1074
1075 // Patch the arguments.length and the parameters pointer.
1076 __ mov(ecx, Operand(ebx, ArgumentsAdaptorFrameConstants::kLengthOffset));
1077 __ lea(edx,
1078 Operand(ebx, ecx, times_2, StandardFrameConstants::kCallerSPOffset));
1079
1080 // Try the new space allocation. Start out with computing the size of
1081 // the arguments object and the elements array.
1082 Label add_arguments_object;
1083 __ bind(&try_allocate);
1084 __ mov(eax, ecx);
1085 __ test(eax, eax);
1086 __ j(zero, &add_arguments_object, Label::kNear);
1087 __ lea(eax, Operand(eax, times_2, FixedArray::kHeaderSize));
1088 __ bind(&add_arguments_object);
1089 __ add(eax, Immediate(Heap::kStrictArgumentsObjectSize));
1090
1091 // Do the allocation of both objects in one go.
1092 __ Allocate(eax, eax, ebx, no_reg, &runtime, TAG_OBJECT);
1093
1094 // Get the arguments map from the current native context.
1095 __ mov(edi, NativeContextOperand());
1096 __ mov(edi, ContextOperand(edi, Context::STRICT_ARGUMENTS_MAP_INDEX));
1097
1098 __ mov(FieldOperand(eax, JSObject::kMapOffset), edi);
1099 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset),
1100 masm->isolate()->factory()->empty_fixed_array());
1101 __ mov(FieldOperand(eax, JSObject::kElementsOffset),
1102 masm->isolate()->factory()->empty_fixed_array());
1103
1104 // Get the length (smi tagged) and set that as an in-object property too.
1105 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
1106 __ AssertSmi(ecx);
1107 __ mov(FieldOperand(eax, JSObject::kHeaderSize +
1108 Heap::kArgumentsLengthIndex * kPointerSize),
1109 ecx);
1110
1111 // If there are no actual arguments, we're done.
1112 Label done;
1113 __ test(ecx, ecx);
1114 __ j(zero, &done, Label::kNear);
1115
1116 // Set up the elements pointer in the allocated arguments object and
1117 // initialize the header in the elements fixed array.
1118 __ lea(edi, Operand(eax, Heap::kStrictArgumentsObjectSize));
1119 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
1120 __ mov(FieldOperand(edi, FixedArray::kMapOffset),
1121 Immediate(isolate()->factory()->fixed_array_map()));
1122 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
1123
1124 // Untag the length for the loop below.
1125 __ SmiUntag(ecx);
1126
1127 // Copy the fixed array slots.
1128 Label loop;
1129 __ bind(&loop);
1130 __ mov(ebx, Operand(edx, -1 * kPointerSize)); // Skip receiver.
1131 __ mov(FieldOperand(edi, FixedArray::kHeaderSize), ebx);
1132 __ add(edi, Immediate(kPointerSize));
1133 __ sub(edx, Immediate(kPointerSize));
1134 __ dec(ecx);
1135 __ j(not_zero, &loop);
1136
1137 // Return.
1138 __ bind(&done);
1139 __ ret(0);
1140
1141 // Do the runtime call to allocate the arguments object.
1142 __ bind(&runtime);
1143 __ pop(eax); // Pop return address.
1144 __ push(edi); // Push function.
1145 __ push(edx); // Push parameters pointer.
1146 __ push(ecx); // Push parameter count.
1147 __ push(eax); // Push return address.
1148 __ TailCallRuntime(Runtime::kNewStrictArguments);
1149 }
1150
1151
1152 void RegExpExecStub::Generate(MacroAssembler* masm) { 1053 void RegExpExecStub::Generate(MacroAssembler* masm) {
1153 // Just jump directly to runtime if native RegExp is not selected at compile 1054 // Just jump directly to runtime if native RegExp is not selected at compile
1154 // time or if regexp entry in generated code is turned off runtime switch or 1055 // time or if regexp entry in generated code is turned off runtime switch or
1155 // at compilation. 1056 // at compilation.
1156 #ifdef V8_INTERPRETED_REGEXP 1057 #ifdef V8_INTERPRETED_REGEXP
1157 __ TailCallRuntime(Runtime::kRegExpExec); 1058 __ TailCallRuntime(Runtime::kRegExpExec);
1158 #else // V8_INTERPRETED_REGEXP 1059 #else // V8_INTERPRETED_REGEXP
1159 1060
1160 // Stack frame on entry. 1061 // Stack frame on entry.
1161 // esp[0]: return address 1062 // esp[0]: return address
(...skipping 4148 matching lines...) Expand 10 before | Expand all | Expand 10 after
5310 __ CallRuntime(Runtime::kAllocateInNewSpace); 5211 __ CallRuntime(Runtime::kAllocateInNewSpace);
5311 __ mov(edx, eax); 5212 __ mov(edx, eax);
5312 __ Pop(ebx); 5213 __ Pop(ebx);
5313 __ Pop(eax); 5214 __ Pop(eax);
5314 } 5215 }
5315 __ jmp(&done_allocate); 5216 __ jmp(&done_allocate);
5316 } 5217 }
5317 } 5218 }
5318 5219
5319 5220
5221 void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) {
5222 // ----------- S t a t e -------------
5223 // -- edi : function
5224 // -- esi : context
5225 // -- ebp : frame pointer
5226 // -- esp[0] : return address
5227 // -----------------------------------
5228 __ AssertFunction(edi);
5229
5230 // For Ignition we need to skip all possible handler/stub frames until
5231 // we reach the JavaScript frame for the function (similar to what the
5232 // runtime fallback implementation does). So make edx point to that
5233 // JavaScript frame.
5234 {
5235 Label loop, loop_entry;
5236 __ mov(edx, ebp);
5237 __ jmp(&loop_entry, Label::kNear);
5238 __ bind(&loop);
5239 __ mov(edx, Operand(edx, StandardFrameConstants::kCallerFPOffset));
5240 __ bind(&loop_entry);
5241 __ cmp(edi, Operand(edx, StandardFrameConstants::kMarkerOffset));
5242 __ j(not_equal, &loop);
5243 }
5244
5245 // Check if we have an arguments adaptor frame below the function frame.
5246 Label arguments_adaptor, arguments_done;
5247 __ mov(ebx, Operand(edx, StandardFrameConstants::kCallerFPOffset));
5248 __ cmp(Operand(ebx, StandardFrameConstants::kContextOffset),
5249 Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
5250 __ j(equal, &arguments_adaptor, Label::kNear);
5251 {
5252 __ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
5253 __ mov(eax,
5254 FieldOperand(eax, SharedFunctionInfo::kFormalParameterCountOffset));
5255 __ lea(ebx,
5256 Operand(edx, eax, times_half_pointer_size,
5257 StandardFrameConstants::kCallerSPOffset - 1 * kPointerSize));
5258 }
5259 __ jmp(&arguments_done, Label::kNear);
5260 __ bind(&arguments_adaptor);
5261 {
5262 __ mov(eax, Operand(ebx, ArgumentsAdaptorFrameConstants::kLengthOffset));
5263 __ lea(ebx,
5264 Operand(ebx, eax, times_half_pointer_size,
5265 StandardFrameConstants::kCallerSPOffset - 1 * kPointerSize));
5266 }
5267 __ bind(&arguments_done);
5268
5269 // ----------- S t a t e -------------
5270 // -- eax : number of arguments (tagged)
5271 // -- ebx : pointer to the first argument
5272 // -- esi : context
5273 // -- esp[0] : return address
5274 // -----------------------------------
5275
5276 // Allocate space for the strict arguments object plus the backing store.
5277 Label allocate, done_allocate;
5278 __ lea(ecx,
5279 Operand(eax, times_half_pointer_size,
5280 JSStrictArgumentsObject::kSize + FixedArray::kHeaderSize));
5281 __ Allocate(ecx, edx, edi, no_reg, &allocate, TAG_OBJECT);
5282 __ bind(&done_allocate);
5283
5284 // Setup the elements array in edx.
5285 __ mov(FieldOperand(edx, FixedArray::kMapOffset),
5286 isolate()->factory()->fixed_array_map());
5287 __ mov(FieldOperand(edx, FixedArray::kLengthOffset), eax);
5288 {
5289 Label loop, done_loop;
5290 __ Move(ecx, Smi::FromInt(0));
5291 __ bind(&loop);
5292 __ cmp(ecx, eax);
5293 __ j(equal, &done_loop, Label::kNear);
5294 __ mov(edi, Operand(ebx, 0 * kPointerSize));
5295 __ mov(FieldOperand(edx, ecx, times_half_pointer_size,
5296 FixedArray::kHeaderSize),
5297 edi);
5298 __ sub(ebx, Immediate(1 * kPointerSize));
5299 __ add(ecx, Immediate(Smi::FromInt(1)));
5300 __ jmp(&loop);
5301 __ bind(&done_loop);
5302 }
5303
5304 // Setup the rest parameter array in edi.
5305 __ lea(edi,
5306 Operand(edx, eax, times_half_pointer_size, FixedArray::kHeaderSize));
5307 __ LoadGlobalFunction(Context::STRICT_ARGUMENTS_MAP_INDEX, ecx);
5308 __ mov(FieldOperand(edi, JSStrictArgumentsObject::kMapOffset), ecx);
5309 __ mov(FieldOperand(edi, JSStrictArgumentsObject::kPropertiesOffset),
5310 isolate()->factory()->empty_fixed_array());
5311 __ mov(FieldOperand(edi, JSStrictArgumentsObject::kElementsOffset), edx);
5312 __ mov(FieldOperand(edi, JSStrictArgumentsObject::kLengthOffset), eax);
5313 STATIC_ASSERT(JSStrictArgumentsObject::kSize == 4 * kPointerSize);
5314 __ mov(eax, edi);
5315 __ Ret();
5316
5317 // Fall back to %AllocateInNewSpace.
5318 __ bind(&allocate);
5319 {
5320 FrameScope scope(masm, StackFrame::INTERNAL);
5321 __ SmiTag(ecx);
5322 __ Push(eax);
5323 __ Push(ebx);
5324 __ Push(ecx);
5325 __ CallRuntime(Runtime::kAllocateInNewSpace);
5326 __ mov(edx, eax);
5327 __ Pop(ebx);
5328 __ Pop(eax);
5329 }
5330 __ jmp(&done_allocate);
5331 }
5332
5333
5320 void LoadGlobalViaContextStub::Generate(MacroAssembler* masm) { 5334 void LoadGlobalViaContextStub::Generate(MacroAssembler* masm) {
5321 Register context_reg = esi; 5335 Register context_reg = esi;
5322 Register slot_reg = ebx; 5336 Register slot_reg = ebx;
5323 Register result_reg = eax; 5337 Register result_reg = eax;
5324 Label slow_case; 5338 Label slow_case;
5325 5339
5326 // Go up context chain to the script context. 5340 // Go up context chain to the script context.
5327 for (int i = 0; i < depth(); ++i) { 5341 for (int i = 0; i < depth(); ++i) {
5328 __ mov(result_reg, ContextOperand(context_reg, Context::PREVIOUS_INDEX)); 5342 __ mov(result_reg, ContextOperand(context_reg, Context::PREVIOUS_INDEX));
5329 context_reg = result_reg; 5343 context_reg = result_reg;
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after
5868 return_value_operand, NULL); 5882 return_value_operand, NULL);
5869 } 5883 }
5870 5884
5871 5885
5872 #undef __ 5886 #undef __
5873 5887
5874 } // namespace internal 5888 } // namespace internal
5875 } // namespace v8 5889 } // namespace v8
5876 5890
5877 #endif // V8_TARGET_ARCH_IA32 5891 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/builtins-ia32.cc ('k') | src/ia32/interface-descriptors-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698