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

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

Issue 196133017: Experimental parser: merge r19949 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 years, 9 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/x64/code-stubs-x64.h ('k') | src/x64/deoptimizer-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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 void KeyedLoadFieldStub::InitializeInterfaceDescriptor( 159 void KeyedLoadFieldStub::InitializeInterfaceDescriptor(
160 Isolate* isolate, 160 Isolate* isolate,
161 CodeStubInterfaceDescriptor* descriptor) { 161 CodeStubInterfaceDescriptor* descriptor) {
162 static Register registers[] = { rdx }; 162 static Register registers[] = { rdx };
163 descriptor->register_param_count_ = 1; 163 descriptor->register_param_count_ = 1;
164 descriptor->register_params_ = registers; 164 descriptor->register_params_ = registers;
165 descriptor->deoptimization_handler_ = NULL; 165 descriptor->deoptimization_handler_ = NULL;
166 } 166 }
167 167
168 168
169 void StringLengthStub::InitializeInterfaceDescriptor(
170 Isolate* isolate,
171 CodeStubInterfaceDescriptor* descriptor) {
172 static Register registers[] = { rax, rcx };
173 descriptor->register_param_count_ = 2;
174 descriptor->register_params_ = registers;
175 descriptor->deoptimization_handler_ = NULL;
176 }
177
178
179 void KeyedStringLengthStub::InitializeInterfaceDescriptor(
180 Isolate* isolate,
181 CodeStubInterfaceDescriptor* descriptor) {
182 static Register registers[] = { rdx, rax };
183 descriptor->register_param_count_ = 2;
184 descriptor->register_params_ = registers;
185 descriptor->deoptimization_handler_ = NULL;
186 }
187
188
169 void KeyedStoreFastElementStub::InitializeInterfaceDescriptor( 189 void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
170 Isolate* isolate, 190 Isolate* isolate,
171 CodeStubInterfaceDescriptor* descriptor) { 191 CodeStubInterfaceDescriptor* descriptor) {
172 static Register registers[] = { rdx, rcx, rax }; 192 static Register registers[] = { rdx, rcx, rax };
173 descriptor->register_param_count_ = 3; 193 descriptor->register_param_count_ = 3;
174 descriptor->register_params_ = registers; 194 descriptor->register_params_ = registers;
175 descriptor->deoptimization_handler_ = 195 descriptor->deoptimization_handler_ =
176 FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure); 196 FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure);
177 } 197 }
178 198
(...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 receiver = rax; 926 receiver = rax;
907 } 927 }
908 928
909 StubCompiler::GenerateLoadFunctionPrototype(masm, receiver, r8, r9, &miss); 929 StubCompiler::GenerateLoadFunctionPrototype(masm, receiver, r8, r9, &miss);
910 __ bind(&miss); 930 __ bind(&miss);
911 StubCompiler::TailCallBuiltin( 931 StubCompiler::TailCallBuiltin(
912 masm, BaseLoadStoreStubCompiler::MissBuiltin(kind())); 932 masm, BaseLoadStoreStubCompiler::MissBuiltin(kind()));
913 } 933 }
914 934
915 935
916 void StringLengthStub::Generate(MacroAssembler* masm) {
917 Label miss;
918 Register receiver;
919 if (kind() == Code::KEYED_LOAD_IC) {
920 // ----------- S t a t e -------------
921 // -- rax : key
922 // -- rdx : receiver
923 // -- rsp[0] : return address
924 // -----------------------------------
925 __ Cmp(rax, masm->isolate()->factory()->length_string());
926 __ j(not_equal, &miss);
927 receiver = rdx;
928 } else {
929 ASSERT(kind() == Code::LOAD_IC);
930 // ----------- S t a t e -------------
931 // -- rax : receiver
932 // -- rcx : name
933 // -- rsp[0] : return address
934 // -----------------------------------
935 receiver = rax;
936 }
937
938 StubCompiler::GenerateLoadStringLength(masm, receiver, r8, r9, &miss);
939 __ bind(&miss);
940 StubCompiler::TailCallBuiltin(
941 masm, BaseLoadStoreStubCompiler::MissBuiltin(kind()));
942 }
943
944
945 void StoreArrayLengthStub::Generate(MacroAssembler* masm) { 936 void StoreArrayLengthStub::Generate(MacroAssembler* masm) {
946 // ----------- S t a t e ------------- 937 // ----------- S t a t e -------------
947 // -- rax : value 938 // -- rax : value
948 // -- rcx : key 939 // -- rcx : key
949 // -- rdx : receiver 940 // -- rdx : receiver
950 // -- rsp[0] : return address 941 // -- rsp[0] : return address
951 // ----------------------------------- 942 // -----------------------------------
952 // 943 //
953 // This accepts as a receiver anything JSArray::SetElementsLength accepts 944 // This accepts as a receiver anything JSArray::SetElementsLength accepts
954 // (currently anything except for external arrays which means anything with 945 // (currently anything except for external arrays which means anything with
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1055 // Slow-case: Handle non-smi or out-of-bounds access to arguments 1046 // Slow-case: Handle non-smi or out-of-bounds access to arguments
1056 // by calling the runtime system. 1047 // by calling the runtime system.
1057 __ bind(&slow); 1048 __ bind(&slow);
1058 __ PopReturnAddressTo(rbx); 1049 __ PopReturnAddressTo(rbx);
1059 __ push(rdx); 1050 __ push(rdx);
1060 __ PushReturnAddressFrom(rbx); 1051 __ PushReturnAddressFrom(rbx);
1061 __ TailCallRuntime(Runtime::kGetArgumentsProperty, 1, 1); 1052 __ TailCallRuntime(Runtime::kGetArgumentsProperty, 1, 1);
1062 } 1053 }
1063 1054
1064 1055
1065 void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) { 1056 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
1066 // Stack layout: 1057 // Stack layout:
1067 // rsp[0] : return address 1058 // rsp[0] : return address
1068 // rsp[8] : number of parameters (tagged) 1059 // rsp[8] : number of parameters (tagged)
1069 // rsp[16] : receiver displacement 1060 // rsp[16] : receiver displacement
1070 // rsp[24] : function 1061 // rsp[24] : function
1071 // Registers used over the whole function: 1062 // Registers used over the whole function:
1072 // rbx: the mapped parameter count (untagged) 1063 // rbx: the mapped parameter count (untagged)
1073 // rax: the allocated object (tagged). 1064 // rax: the allocated object (tagged).
1074 1065
1075 Factory* factory = masm->isolate()->factory(); 1066 Factory* factory = masm->isolate()->factory();
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1116 __ xor_(r8, r8); 1107 __ xor_(r8, r8);
1117 __ testq(rbx, rbx); 1108 __ testq(rbx, rbx);
1118 __ j(zero, &no_parameter_map, Label::kNear); 1109 __ j(zero, &no_parameter_map, Label::kNear);
1119 __ lea(r8, Operand(rbx, times_pointer_size, kParameterMapHeaderSize)); 1110 __ lea(r8, Operand(rbx, times_pointer_size, kParameterMapHeaderSize));
1120 __ bind(&no_parameter_map); 1111 __ bind(&no_parameter_map);
1121 1112
1122 // 2. Backing store. 1113 // 2. Backing store.
1123 __ lea(r8, Operand(r8, rcx, times_pointer_size, FixedArray::kHeaderSize)); 1114 __ lea(r8, Operand(r8, rcx, times_pointer_size, FixedArray::kHeaderSize));
1124 1115
1125 // 3. Arguments object. 1116 // 3. Arguments object.
1126 __ addq(r8, Immediate(Heap::kArgumentsObjectSize)); 1117 __ addq(r8, Immediate(Heap::kSloppyArgumentsObjectSize));
1127 1118
1128 // Do the allocation of all three objects in one go. 1119 // Do the allocation of all three objects in one go.
1129 __ Allocate(r8, rax, rdx, rdi, &runtime, TAG_OBJECT); 1120 __ Allocate(r8, rax, rdx, rdi, &runtime, TAG_OBJECT);
1130 1121
1131 // rax = address of new object(s) (tagged) 1122 // rax = address of new object(s) (tagged)
1132 // rcx = argument count (untagged) 1123 // rcx = argument count (untagged)
1133 // Get the arguments boilerplate from the current native context into rdi. 1124 // Get the arguments boilerplate from the current native context into rdi.
1134 Label has_mapped_parameters, copy; 1125 Label has_mapped_parameters, copy;
1135 __ movp(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 1126 __ movp(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
1136 __ movp(rdi, FieldOperand(rdi, GlobalObject::kNativeContextOffset)); 1127 __ movp(rdi, FieldOperand(rdi, GlobalObject::kNativeContextOffset));
1137 __ testq(rbx, rbx); 1128 __ testq(rbx, rbx);
1138 __ j(not_zero, &has_mapped_parameters, Label::kNear); 1129 __ j(not_zero, &has_mapped_parameters, Label::kNear);
1139 1130
1140 const int kIndex = Context::ARGUMENTS_BOILERPLATE_INDEX; 1131 const int kIndex = Context::SLOPPY_ARGUMENTS_BOILERPLATE_INDEX;
1141 __ movp(rdi, Operand(rdi, Context::SlotOffset(kIndex))); 1132 __ movp(rdi, Operand(rdi, Context::SlotOffset(kIndex)));
1142 __ jmp(&copy, Label::kNear); 1133 __ jmp(&copy, Label::kNear);
1143 1134
1144 const int kAliasedIndex = Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX; 1135 const int kAliasedIndex = Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX;
1145 __ bind(&has_mapped_parameters); 1136 __ bind(&has_mapped_parameters);
1146 __ movp(rdi, Operand(rdi, Context::SlotOffset(kAliasedIndex))); 1137 __ movp(rdi, Operand(rdi, Context::SlotOffset(kAliasedIndex)));
1147 __ bind(&copy); 1138 __ bind(&copy);
1148 1139
1149 // rax = address of new object (tagged) 1140 // rax = address of new object (tagged)
1150 // rbx = mapped parameter count (untagged) 1141 // rbx = mapped parameter count (untagged)
(...skipping 16 matching lines...) Expand all
1167 // Note: rcx is tagged from here on. 1158 // Note: rcx is tagged from here on.
1168 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); 1159 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
1169 __ Integer32ToSmi(rcx, rcx); 1160 __ Integer32ToSmi(rcx, rcx);
1170 __ movp(FieldOperand(rax, JSObject::kHeaderSize + 1161 __ movp(FieldOperand(rax, JSObject::kHeaderSize +
1171 Heap::kArgumentsLengthIndex * kPointerSize), 1162 Heap::kArgumentsLengthIndex * kPointerSize),
1172 rcx); 1163 rcx);
1173 1164
1174 // Set up the elements pointer in the allocated arguments object. 1165 // Set up the elements pointer in the allocated arguments object.
1175 // If we allocated a parameter map, edi will point there, otherwise to the 1166 // If we allocated a parameter map, edi will point there, otherwise to the
1176 // backing store. 1167 // backing store.
1177 __ lea(rdi, Operand(rax, Heap::kArgumentsObjectSize)); 1168 __ lea(rdi, Operand(rax, Heap::kSloppyArgumentsObjectSize));
1178 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rdi); 1169 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rdi);
1179 1170
1180 // rax = address of new object (tagged) 1171 // rax = address of new object (tagged)
1181 // rbx = mapped parameter count (untagged) 1172 // rbx = mapped parameter count (untagged)
1182 // rcx = argument count (tagged) 1173 // rcx = argument count (tagged)
1183 // rdi = address of parameter map or backing store (tagged) 1174 // rdi = address of parameter map or backing store (tagged)
1184 1175
1185 // Initialize parameter map. If there are no mapped arguments, we're done. 1176 // Initialize parameter map. If there are no mapped arguments, we're done.
1186 Label skip_parameter_map; 1177 Label skip_parameter_map;
1187 __ testq(rbx, rbx); 1178 __ testq(rbx, rbx);
1188 __ j(zero, &skip_parameter_map); 1179 __ j(zero, &skip_parameter_map);
1189 1180
1190 __ LoadRoot(kScratchRegister, Heap::kNonStrictArgumentsElementsMapRootIndex); 1181 __ LoadRoot(kScratchRegister, Heap::kSloppyArgumentsElementsMapRootIndex);
1191 // rbx contains the untagged argument count. Add 2 and tag to write. 1182 // rbx contains the untagged argument count. Add 2 and tag to write.
1192 __ movp(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister); 1183 __ movp(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister);
1193 __ Integer64PlusConstantToSmi(r9, rbx, 2); 1184 __ Integer64PlusConstantToSmi(r9, rbx, 2);
1194 __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), r9); 1185 __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), r9);
1195 __ movp(FieldOperand(rdi, FixedArray::kHeaderSize + 0 * kPointerSize), rsi); 1186 __ movp(FieldOperand(rdi, FixedArray::kHeaderSize + 0 * kPointerSize), rsi);
1196 __ lea(r9, Operand(rdi, rbx, times_pointer_size, kParameterMapHeaderSize)); 1187 __ lea(r9, Operand(rdi, rbx, times_pointer_size, kParameterMapHeaderSize));
1197 __ movp(FieldOperand(rdi, FixedArray::kHeaderSize + 1 * kPointerSize), r9); 1188 __ movp(FieldOperand(rdi, FixedArray::kHeaderSize + 1 * kPointerSize), r9);
1198 1189
1199 // Copy the parameter slots and the holes in the arguments. 1190 // Copy the parameter slots and the holes in the arguments.
1200 // We need to fill in mapped_parameter_count slots. They index the context, 1191 // We need to fill in mapped_parameter_count slots. They index the context,
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1273 1264
1274 // Do the runtime call to allocate the arguments object. 1265 // Do the runtime call to allocate the arguments object.
1275 // rcx = argument count (untagged) 1266 // rcx = argument count (untagged)
1276 __ bind(&runtime); 1267 __ bind(&runtime);
1277 __ Integer32ToSmi(rcx, rcx); 1268 __ Integer32ToSmi(rcx, rcx);
1278 __ movp(args.GetArgumentOperand(2), rcx); // Patch argument count. 1269 __ movp(args.GetArgumentOperand(2), rcx); // Patch argument count.
1279 __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1); 1270 __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
1280 } 1271 }
1281 1272
1282 1273
1283 void ArgumentsAccessStub::GenerateNewNonStrictSlow(MacroAssembler* masm) { 1274 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) {
1284 // rsp[0] : return address 1275 // rsp[0] : return address
1285 // rsp[8] : number of parameters 1276 // rsp[8] : number of parameters
1286 // rsp[16] : receiver displacement 1277 // rsp[16] : receiver displacement
1287 // rsp[24] : function 1278 // rsp[24] : function
1288 1279
1289 // Check if the calling frame is an arguments adaptor frame. 1280 // Check if the calling frame is an arguments adaptor frame.
1290 Label runtime; 1281 Label runtime;
1291 __ movp(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 1282 __ movp(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
1292 __ movp(rcx, Operand(rdx, StandardFrameConstants::kContextOffset)); 1283 __ movp(rcx, Operand(rdx, StandardFrameConstants::kContextOffset));
1293 __ Cmp(rcx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 1284 __ Cmp(rcx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1336 __ movp(args.GetArgumentOperand(1), rdx); 1327 __ movp(args.GetArgumentOperand(1), rdx);
1337 1328
1338 // Try the new space allocation. Start out with computing the size of 1329 // Try the new space allocation. Start out with computing the size of
1339 // the arguments object and the elements array. 1330 // the arguments object and the elements array.
1340 Label add_arguments_object; 1331 Label add_arguments_object;
1341 __ bind(&try_allocate); 1332 __ bind(&try_allocate);
1342 __ testq(rcx, rcx); 1333 __ testq(rcx, rcx);
1343 __ j(zero, &add_arguments_object, Label::kNear); 1334 __ j(zero, &add_arguments_object, Label::kNear);
1344 __ lea(rcx, Operand(rcx, times_pointer_size, FixedArray::kHeaderSize)); 1335 __ lea(rcx, Operand(rcx, times_pointer_size, FixedArray::kHeaderSize));
1345 __ bind(&add_arguments_object); 1336 __ bind(&add_arguments_object);
1346 __ addq(rcx, Immediate(Heap::kArgumentsObjectSizeStrict)); 1337 __ addq(rcx, Immediate(Heap::kStrictArgumentsObjectSize));
1347 1338
1348 // Do the allocation of both objects in one go. 1339 // Do the allocation of both objects in one go.
1349 __ Allocate(rcx, rax, rdx, rbx, &runtime, TAG_OBJECT); 1340 __ Allocate(rcx, rax, rdx, rbx, &runtime, TAG_OBJECT);
1350 1341
1351 // Get the arguments boilerplate from the current native context. 1342 // Get the arguments boilerplate from the current native context.
1352 __ movp(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 1343 __ movp(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
1353 __ movp(rdi, FieldOperand(rdi, GlobalObject::kNativeContextOffset)); 1344 __ movp(rdi, FieldOperand(rdi, GlobalObject::kNativeContextOffset));
1354 const int offset = 1345 const int offset =
1355 Context::SlotOffset(Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX); 1346 Context::SlotOffset(Context::STRICT_ARGUMENTS_BOILERPLATE_INDEX);
1356 __ movp(rdi, Operand(rdi, offset)); 1347 __ movp(rdi, Operand(rdi, offset));
1357 1348
1358 // Copy the JS object part. 1349 // Copy the JS object part.
1359 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) { 1350 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
1360 __ movp(rbx, FieldOperand(rdi, i)); 1351 __ movp(rbx, FieldOperand(rdi, i));
1361 __ movp(FieldOperand(rax, i), rbx); 1352 __ movp(FieldOperand(rax, i), rbx);
1362 } 1353 }
1363 1354
1364 // Get the length (smi tagged) and set that as an in-object property too. 1355 // Get the length (smi tagged) and set that as an in-object property too.
1365 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); 1356 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
1366 __ movp(rcx, args.GetArgumentOperand(2)); 1357 __ movp(rcx, args.GetArgumentOperand(2));
1367 __ movp(FieldOperand(rax, JSObject::kHeaderSize + 1358 __ movp(FieldOperand(rax, JSObject::kHeaderSize +
1368 Heap::kArgumentsLengthIndex * kPointerSize), 1359 Heap::kArgumentsLengthIndex * kPointerSize),
1369 rcx); 1360 rcx);
1370 1361
1371 // If there are no actual arguments, we're done. 1362 // If there are no actual arguments, we're done.
1372 Label done; 1363 Label done;
1373 __ testq(rcx, rcx); 1364 __ testq(rcx, rcx);
1374 __ j(zero, &done); 1365 __ j(zero, &done);
1375 1366
1376 // Get the parameters pointer from the stack. 1367 // Get the parameters pointer from the stack.
1377 __ movp(rdx, args.GetArgumentOperand(1)); 1368 __ movp(rdx, args.GetArgumentOperand(1));
1378 1369
1379 // Set up the elements pointer in the allocated arguments object and 1370 // Set up the elements pointer in the allocated arguments object and
1380 // initialize the header in the elements fixed array. 1371 // initialize the header in the elements fixed array.
1381 __ lea(rdi, Operand(rax, Heap::kArgumentsObjectSizeStrict)); 1372 __ lea(rdi, Operand(rax, Heap::kStrictArgumentsObjectSize));
1382 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rdi); 1373 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rdi);
1383 __ LoadRoot(kScratchRegister, Heap::kFixedArrayMapRootIndex); 1374 __ LoadRoot(kScratchRegister, Heap::kFixedArrayMapRootIndex);
1384 __ movp(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister); 1375 __ movp(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister);
1385 1376
1386 1377
1387 __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), rcx); 1378 __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), rcx);
1388 // Untag the length for the loop below. 1379 // Untag the length for the loop below.
1389 __ SmiToInteger64(rcx, rcx); 1380 __ SmiToInteger64(rcx, rcx);
1390 1381
1391 // Copy the fixed array slots. 1382 // Copy the fixed array slots.
(...skipping 868 matching lines...) Expand 10 before | Expand all | Expand 10 after
2260 2251
2261 __ bind(&done); 2252 __ bind(&done);
2262 __ Integer32ToSmi(rdx, rdx); 2253 __ Integer32ToSmi(rdx, rdx);
2263 2254
2264 __ bind(&done_no_smi_convert); 2255 __ bind(&done_no_smi_convert);
2265 } 2256 }
2266 2257
2267 2258
2268 void CallFunctionStub::Generate(MacroAssembler* masm) { 2259 void CallFunctionStub::Generate(MacroAssembler* masm) {
2269 // rbx : feedback vector 2260 // rbx : feedback vector
2270 // rdx : (only if rbx is not undefined) slot in feedback vector (Smi) 2261 // rdx : (only if rbx is not the megamorphic symbol) slot in feedback
2262 // vector (Smi)
2271 // rdi : the function to call 2263 // rdi : the function to call
2272 Isolate* isolate = masm->isolate(); 2264 Isolate* isolate = masm->isolate();
2273 Label slow, non_function, wrap, cont; 2265 Label slow, non_function, wrap, cont;
2274 StackArgumentsAccessor args(rsp, argc_); 2266 StackArgumentsAccessor args(rsp, argc_);
2275 2267
2276 if (NeedsChecks()) { 2268 if (NeedsChecks()) {
2277 // Check that the function really is a JavaScript function. 2269 // Check that the function really is a JavaScript function.
2278 __ JumpIfSmi(rdi, &non_function); 2270 __ JumpIfSmi(rdi, &non_function);
2279 2271
2280 // Goto slow case if we do not have a function. 2272 // Goto slow case if we do not have a function.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2320 __ bind(&cont); 2312 __ bind(&cont);
2321 } 2313 }
2322 __ InvokeFunction(rdi, actual, JUMP_FUNCTION, NullCallWrapper()); 2314 __ InvokeFunction(rdi, actual, JUMP_FUNCTION, NullCallWrapper());
2323 2315
2324 if (NeedsChecks()) { 2316 if (NeedsChecks()) {
2325 // Slow-case: Non-function called. 2317 // Slow-case: Non-function called.
2326 __ bind(&slow); 2318 __ bind(&slow);
2327 if (RecordCallTarget()) { 2319 if (RecordCallTarget()) {
2328 // If there is a call target cache, mark it megamorphic in the 2320 // If there is a call target cache, mark it megamorphic in the
2329 // non-function case. MegamorphicSentinel is an immortal immovable 2321 // non-function case. MegamorphicSentinel is an immortal immovable
2330 // object (undefined) so no write barrier is needed. 2322 // object (megamorphic symbol) so no write barrier is needed.
2331 __ SmiToInteger32(rdx, rdx); 2323 __ SmiToInteger32(rdx, rdx);
2332 __ Move(FieldOperand(rbx, rdx, times_pointer_size, 2324 __ Move(FieldOperand(rbx, rdx, times_pointer_size,
2333 FixedArray::kHeaderSize), 2325 FixedArray::kHeaderSize),
2334 TypeFeedbackInfo::MegamorphicSentinel(isolate)); 2326 TypeFeedbackInfo::MegamorphicSentinel(isolate));
2335 __ Integer32ToSmi(rdx, rdx); 2327 __ Integer32ToSmi(rdx, rdx);
2336 } 2328 }
2337 // Check for function proxy. 2329 // Check for function proxy.
2338 __ CmpInstanceType(rcx, JS_FUNCTION_PROXY_TYPE); 2330 __ CmpInstanceType(rcx, JS_FUNCTION_PROXY_TYPE);
2339 __ j(not_equal, &non_function); 2331 __ j(not_equal, &non_function);
2340 __ PopReturnAddressTo(rcx); 2332 __ PopReturnAddressTo(rcx);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2372 } 2364 }
2373 __ movp(args.GetReceiverOperand(), rax); 2365 __ movp(args.GetReceiverOperand(), rax);
2374 __ jmp(&cont); 2366 __ jmp(&cont);
2375 } 2367 }
2376 } 2368 }
2377 2369
2378 2370
2379 void CallConstructStub::Generate(MacroAssembler* masm) { 2371 void CallConstructStub::Generate(MacroAssembler* masm) {
2380 // rax : number of arguments 2372 // rax : number of arguments
2381 // rbx : feedback vector 2373 // rbx : feedback vector
2382 // rdx : (only if rbx is not undefined) slot in feedback vector (Smi) 2374 // rdx : (only if rbx is not the megamorphic symbol) slot in feedback
2375 // vector (Smi)
2383 // rdi : constructor function 2376 // rdi : constructor function
2384 Label slow, non_function_call; 2377 Label slow, non_function_call;
2385 2378
2386 // Check that function is not a smi. 2379 // Check that function is not a smi.
2387 __ JumpIfSmi(rdi, &non_function_call); 2380 __ JumpIfSmi(rdi, &non_function_call);
2388 // Check that function is a JSFunction. 2381 // Check that function is a JSFunction.
2389 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); 2382 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
2390 __ j(not_equal, &slow); 2383 __ j(not_equal, &slow);
2391 2384
2392 if (RecordCallTarget()) { 2385 if (RecordCallTarget()) {
(...skipping 2137 matching lines...) Expand 10 before | Expand all | Expand 10 after
4530 __ CheckPageFlag(regs_.object(), 4523 __ CheckPageFlag(regs_.object(),
4531 regs_.scratch0(), 4524 regs_.scratch0(),
4532 1 << MemoryChunk::SCAN_ON_SCAVENGE, 4525 1 << MemoryChunk::SCAN_ON_SCAVENGE,
4533 not_zero, 4526 not_zero,
4534 &dont_need_remembered_set); 4527 &dont_need_remembered_set);
4535 4528
4536 // First notify the incremental marker if necessary, then update the 4529 // First notify the incremental marker if necessary, then update the
4537 // remembered set. 4530 // remembered set.
4538 CheckNeedsToInformIncrementalMarker( 4531 CheckNeedsToInformIncrementalMarker(
4539 masm, kUpdateRememberedSetOnNoNeedToInformIncrementalMarker, mode); 4532 masm, kUpdateRememberedSetOnNoNeedToInformIncrementalMarker, mode);
4540 InformIncrementalMarker(masm, mode); 4533 InformIncrementalMarker(masm);
4541 regs_.Restore(masm); 4534 regs_.Restore(masm);
4542 __ RememberedSetHelper(object_, 4535 __ RememberedSetHelper(object_,
4543 address_, 4536 address_,
4544 value_, 4537 value_,
4545 save_fp_regs_mode_, 4538 save_fp_regs_mode_,
4546 MacroAssembler::kReturnAtEnd); 4539 MacroAssembler::kReturnAtEnd);
4547 4540
4548 __ bind(&dont_need_remembered_set); 4541 __ bind(&dont_need_remembered_set);
4549 } 4542 }
4550 4543
4551 CheckNeedsToInformIncrementalMarker( 4544 CheckNeedsToInformIncrementalMarker(
4552 masm, kReturnOnNoNeedToInformIncrementalMarker, mode); 4545 masm, kReturnOnNoNeedToInformIncrementalMarker, mode);
4553 InformIncrementalMarker(masm, mode); 4546 InformIncrementalMarker(masm);
4554 regs_.Restore(masm); 4547 regs_.Restore(masm);
4555 __ ret(0); 4548 __ ret(0);
4556 } 4549 }
4557 4550
4558 4551
4559 void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm, Mode mode) { 4552 void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) {
4560 regs_.SaveCallerSaveRegisters(masm, save_fp_regs_mode_); 4553 regs_.SaveCallerSaveRegisters(masm, save_fp_regs_mode_);
4561 Register address = 4554 Register address =
4562 arg_reg_1.is(regs_.address()) ? kScratchRegister : regs_.address(); 4555 arg_reg_1.is(regs_.address()) ? kScratchRegister : regs_.address();
4563 ASSERT(!address.is(regs_.object())); 4556 ASSERT(!address.is(regs_.object()));
4564 ASSERT(!address.is(arg_reg_1)); 4557 ASSERT(!address.is(arg_reg_1));
4565 __ Move(address, regs_.address()); 4558 __ Move(address, regs_.address());
4566 __ Move(arg_reg_1, regs_.object()); 4559 __ Move(arg_reg_1, regs_.object());
4567 // TODO(gc) Can we just set address arg2 in the beginning? 4560 // TODO(gc) Can we just set address arg2 in the beginning?
4568 __ Move(arg_reg_2, address); 4561 __ Move(arg_reg_2, address);
4569 __ LoadAddress(arg_reg_3, 4562 __ LoadAddress(arg_reg_3,
4570 ExternalReference::isolate_address(masm->isolate())); 4563 ExternalReference::isolate_address(masm->isolate()));
4571 int argument_count = 3; 4564 int argument_count = 3;
4572 4565
4573 AllowExternalCallThatCantCauseGC scope(masm); 4566 AllowExternalCallThatCantCauseGC scope(masm);
4574 __ PrepareCallCFunction(argument_count); 4567 __ PrepareCallCFunction(argument_count);
4575 if (mode == INCREMENTAL_COMPACTION) { 4568 __ CallCFunction(
4576 __ CallCFunction( 4569 ExternalReference::incremental_marking_record_write_function(
4577 ExternalReference::incremental_evacuation_record_write_function( 4570 masm->isolate()),
4578 masm->isolate()), 4571 argument_count);
4579 argument_count);
4580 } else {
4581 ASSERT(mode == INCREMENTAL);
4582 __ CallCFunction(
4583 ExternalReference::incremental_marking_record_write_function(
4584 masm->isolate()),
4585 argument_count);
4586 }
4587 regs_.RestoreCallerSaveRegisters(masm, save_fp_regs_mode_); 4572 regs_.RestoreCallerSaveRegisters(masm, save_fp_regs_mode_);
4588 } 4573 }
4589 4574
4590 4575
4591 void RecordWriteStub::CheckNeedsToInformIncrementalMarker( 4576 void RecordWriteStub::CheckNeedsToInformIncrementalMarker(
4592 MacroAssembler* masm, 4577 MacroAssembler* masm,
4593 OnNoNeedToInformIncrementalMarker on_no_need, 4578 OnNoNeedToInformIncrementalMarker on_no_need,
4594 Mode mode) { 4579 Mode mode) {
4595 Label on_black; 4580 Label on_black;
4596 Label need_incremental; 4581 Label need_incremental;
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
4996 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode); 4981 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
4997 } else { 4982 } else {
4998 UNREACHABLE(); 4983 UNREACHABLE();
4999 } 4984 }
5000 } 4985 }
5001 4986
5002 4987
5003 void ArrayConstructorStub::Generate(MacroAssembler* masm) { 4988 void ArrayConstructorStub::Generate(MacroAssembler* masm) {
5004 // ----------- S t a t e ------------- 4989 // ----------- S t a t e -------------
5005 // -- rax : argc 4990 // -- rax : argc
5006 // -- rbx : feedback vector (fixed array or undefined) 4991 // -- rbx : feedback vector (fixed array or megamorphic symbol)
5007 // -- rdx : slot index (if ebx is fixed array) 4992 // -- rdx : slot index (if ebx is fixed array)
5008 // -- rdi : constructor 4993 // -- rdi : constructor
5009 // -- rsp[0] : return address 4994 // -- rsp[0] : return address
5010 // -- rsp[8] : last argument 4995 // -- rsp[8] : last argument
5011 // ----------------------------------- 4996 // -----------------------------------
5012 Handle<Object> undefined_sentinel( 4997 Handle<Object> megamorphic_sentinel =
5013 masm->isolate()->heap()->undefined_value(), 4998 TypeFeedbackInfo::MegamorphicSentinel(masm->isolate());
5014 masm->isolate());
5015 4999
5016 if (FLAG_debug_code) { 5000 if (FLAG_debug_code) {
5017 // The array construct code is only set for the global and natives 5001 // The array construct code is only set for the global and natives
5018 // builtin Array functions which always have maps. 5002 // builtin Array functions which always have maps.
5019 5003
5020 // Initial map for the builtin Array function should be a map. 5004 // Initial map for the builtin Array function should be a map.
5021 __ movp(rcx, FieldOperand(rdi, JSFunction::kPrototypeOrInitialMapOffset)); 5005 __ movp(rcx, FieldOperand(rdi, JSFunction::kPrototypeOrInitialMapOffset));
5022 // Will both indicate a NULL and a Smi. 5006 // Will both indicate a NULL and a Smi.
5023 STATIC_ASSERT(kSmiTag == 0); 5007 STATIC_ASSERT(kSmiTag == 0);
5024 Condition not_smi = NegateCondition(masm->CheckSmi(rcx)); 5008 Condition not_smi = NegateCondition(masm->CheckSmi(rcx));
5025 __ Check(not_smi, kUnexpectedInitialMapForArrayFunction); 5009 __ Check(not_smi, kUnexpectedInitialMapForArrayFunction);
5026 __ CmpObjectType(rcx, MAP_TYPE, rcx); 5010 __ CmpObjectType(rcx, MAP_TYPE, rcx);
5027 __ Check(equal, kUnexpectedInitialMapForArrayFunction); 5011 __ Check(equal, kUnexpectedInitialMapForArrayFunction);
5028 5012
5029 // We should either have undefined in rbx or a valid fixed array. 5013 // We should either have the megamorphic symbol in rbx or a valid
5014 // fixed array.
5030 Label okay_here; 5015 Label okay_here;
5031 Handle<Map> fixed_array_map = masm->isolate()->factory()->fixed_array_map(); 5016 Handle<Map> fixed_array_map = masm->isolate()->factory()->fixed_array_map();
5032 __ Cmp(rbx, undefined_sentinel); 5017 __ Cmp(rbx, megamorphic_sentinel);
5033 __ j(equal, &okay_here); 5018 __ j(equal, &okay_here);
5034 __ Cmp(FieldOperand(rbx, 0), fixed_array_map); 5019 __ Cmp(FieldOperand(rbx, 0), fixed_array_map);
5035 __ Assert(equal, kExpectedFixedArrayInRegisterRbx); 5020 __ Assert(equal, kExpectedFixedArrayInRegisterRbx);
5036 5021
5037 // rdx should be a smi if we don't have undefined in rbx. 5022 // rdx should be a smi if we don't have the megamorphic symbol in rbx.
5038 __ AssertSmi(rdx); 5023 __ AssertSmi(rdx);
5039 5024
5040 __ bind(&okay_here); 5025 __ bind(&okay_here);
5041 } 5026 }
5042 5027
5043 Label no_info; 5028 Label no_info;
5044 // If the feedback slot is undefined, or contains anything other than an 5029 // If the feedback slot is the megamorphic sentinel, or contains anything
5045 // AllocationSite, call an array constructor that doesn't use AllocationSites. 5030 // other than an AllocationSite, call an array constructor that doesn't use
5046 __ Cmp(rbx, undefined_sentinel); 5031 // AllocationSites.
5032 __ Cmp(rbx, megamorphic_sentinel);
5047 __ j(equal, &no_info); 5033 __ j(equal, &no_info);
5048 __ SmiToInteger32(rdx, rdx); 5034 __ SmiToInteger32(rdx, rdx);
5049 __ movp(rbx, FieldOperand(rbx, rdx, times_pointer_size, 5035 __ movp(rbx, FieldOperand(rbx, rdx, times_pointer_size,
5050 FixedArray::kHeaderSize)); 5036 FixedArray::kHeaderSize));
5051 __ Integer32ToSmi(rdx, rdx); 5037 __ Integer32ToSmi(rdx, rdx);
5052 __ Cmp(FieldOperand(rbx, 0), 5038 __ Cmp(FieldOperand(rbx, 0),
5053 masm->isolate()->factory()->allocation_site_map()); 5039 masm->isolate()->factory()->allocation_site_map());
5054 __ j(not_equal, &no_info); 5040 __ j(not_equal, &no_info);
5055 5041
5056 // Only look at the lower 16 bits of the transition info. 5042 // Only look at the lower 16 bits of the transition info.
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
5329 return_value_operand, 5315 return_value_operand,
5330 NULL); 5316 NULL);
5331 } 5317 }
5332 5318
5333 5319
5334 #undef __ 5320 #undef __
5335 5321
5336 } } // namespace v8::internal 5322 } } // namespace v8::internal
5337 5323
5338 #endif // V8_TARGET_ARCH_X64 5324 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/code-stubs-x64.h ('k') | src/x64/deoptimizer-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698