OLD | NEW |
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 1142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1153 // rsp[8]: last argument | 1153 // rsp[8]: last argument |
1154 // This function is used for both construct and normal calls of Array. The only | 1154 // This function is used for both construct and normal calls of Array. The only |
1155 // difference between handling a construct call and a normal call is that for a | 1155 // difference between handling a construct call and a normal call is that for a |
1156 // construct call the constructor function in rdi needs to be preserved for | 1156 // construct call the constructor function in rdi needs to be preserved for |
1157 // entering the generic code. In both cases argc in rax needs to be preserved. | 1157 // entering the generic code. In both cases argc in rax needs to be preserved. |
1158 // Both registers are preserved by this code so no need to differentiate between | 1158 // Both registers are preserved by this code so no need to differentiate between |
1159 // a construct call and a normal call. | 1159 // a construct call and a normal call. |
1160 static void ArrayNativeCode(MacroAssembler* masm, | 1160 static void ArrayNativeCode(MacroAssembler* masm, |
1161 Label* call_generic_code) { | 1161 Label* call_generic_code) { |
1162 Label argc_one_or_more, argc_two_or_more, empty_array, not_empty_array, | 1162 Label argc_one_or_more, argc_two_or_more, empty_array, not_empty_array, |
1163 has_non_smi_element; | 1163 has_non_smi_element, finish, cant_transition_map, not_double; |
1164 | 1164 |
1165 // Check for array construction with zero arguments. | 1165 // Check for array construction with zero arguments. |
1166 __ testq(rax, rax); | 1166 __ testq(rax, rax); |
1167 __ j(not_zero, &argc_one_or_more); | 1167 __ j(not_zero, &argc_one_or_more); |
1168 | 1168 |
1169 __ bind(&empty_array); | 1169 __ bind(&empty_array); |
1170 // Handle construction of an empty array. | 1170 // Handle construction of an empty array. |
1171 AllocateEmptyJSArray(masm, | 1171 AllocateEmptyJSArray(masm, |
1172 rdi, | 1172 rdi, |
1173 rbx, | 1173 rbx, |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1258 // rax: argc | 1258 // rax: argc |
1259 // rbx: JSArray | 1259 // rbx: JSArray |
1260 // rdx: location of the first array element | 1260 // rdx: location of the first array element |
1261 // r9: location of the last argument | 1261 // r9: location of the last argument |
1262 // esp[0]: return address | 1262 // esp[0]: return address |
1263 // esp[8]: last argument | 1263 // esp[8]: last argument |
1264 Label loop, entry; | 1264 Label loop, entry; |
1265 __ movq(rcx, rax); | 1265 __ movq(rcx, rax); |
1266 __ jmp(&entry); | 1266 __ jmp(&entry); |
1267 __ bind(&loop); | 1267 __ bind(&loop); |
1268 __ movq(kScratchRegister, Operand(r9, rcx, times_pointer_size, 0)); | 1268 __ movq(r8, Operand(r9, rcx, times_pointer_size, 0)); |
1269 if (FLAG_smi_only_arrays) { | 1269 if (FLAG_smi_only_arrays) { |
1270 __ JumpIfNotSmi(kScratchRegister, &has_non_smi_element); | 1270 __ JumpIfNotSmi(r8, &has_non_smi_element); |
1271 } | 1271 } |
1272 __ movq(Operand(rdx, 0), kScratchRegister); | 1272 __ movq(Operand(rdx, 0), r8); |
1273 __ addq(rdx, Immediate(kPointerSize)); | 1273 __ addq(rdx, Immediate(kPointerSize)); |
1274 __ bind(&entry); | 1274 __ bind(&entry); |
1275 __ decq(rcx); | 1275 __ decq(rcx); |
1276 __ j(greater_equal, &loop); | 1276 __ j(greater_equal, &loop); |
1277 | 1277 |
1278 // Remove caller arguments from the stack and return. | 1278 // Remove caller arguments from the stack and return. |
1279 // rax: argc | 1279 // rax: argc |
1280 // rbx: JSArray | 1280 // rbx: JSArray |
1281 // esp[0]: return address | 1281 // esp[0]: return address |
1282 // esp[8]: last argument | 1282 // esp[8]: last argument |
| 1283 __ bind(&finish); |
1283 __ pop(rcx); | 1284 __ pop(rcx); |
1284 __ lea(rsp, Operand(rsp, rax, times_pointer_size, 1 * kPointerSize)); | 1285 __ lea(rsp, Operand(rsp, rax, times_pointer_size, 1 * kPointerSize)); |
1285 __ push(rcx); | 1286 __ push(rcx); |
1286 __ movq(rax, rbx); | 1287 __ movq(rax, rbx); |
1287 __ ret(0); | 1288 __ ret(0); |
1288 | 1289 |
1289 __ bind(&has_non_smi_element); | 1290 __ bind(&has_non_smi_element); |
| 1291 // Double values are handled by the runtime. |
| 1292 __ CheckMap(r8, |
| 1293 masm->isolate()->factory()->heap_number_map(), |
| 1294 ¬_double, |
| 1295 DONT_DO_SMI_CHECK); |
| 1296 __ bind(&cant_transition_map); |
1290 __ UndoAllocationInNewSpace(rbx); | 1297 __ UndoAllocationInNewSpace(rbx); |
1291 __ jmp(call_generic_code); | 1298 __ jmp(call_generic_code); |
| 1299 |
| 1300 __ bind(¬_double); |
| 1301 // Transition FAST_SMI_ONLY_ELEMENTS to FAST_ELEMENTS. |
| 1302 // rbx: JSArray |
| 1303 __ movq(r11, FieldOperand(rbx, HeapObject::kMapOffset)); |
| 1304 __ LoadTransitionedArrayMapConditional(FAST_SMI_ONLY_ELEMENTS, |
| 1305 FAST_ELEMENTS, |
| 1306 r11, |
| 1307 kScratchRegister, |
| 1308 &cant_transition_map); |
| 1309 |
| 1310 __ movq(FieldOperand(rbx, HeapObject::kMapOffset), r11); |
| 1311 __ RecordWriteField(rbx, HeapObject::kMapOffset, r11, r8, |
| 1312 kDontSaveFPRegs, OMIT_REMEMBERED_SET, OMIT_SMI_CHECK); |
| 1313 |
| 1314 // Finish the array initialization loop. |
| 1315 Label loop2; |
| 1316 __ bind(&loop2); |
| 1317 __ movq(r8, Operand(r9, rcx, times_pointer_size, 0)); |
| 1318 __ movq(Operand(rdx, 0), r8); |
| 1319 __ addq(rdx, Immediate(kPointerSize)); |
| 1320 __ decq(rcx); |
| 1321 __ j(greater_equal, &loop2); |
| 1322 __ jmp(&finish); |
1292 } | 1323 } |
1293 | 1324 |
1294 | 1325 |
1295 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) { | 1326 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) { |
1296 // ----------- S t a t e ------------- | 1327 // ----------- S t a t e ------------- |
1297 // -- rax : argc | 1328 // -- rax : argc |
1298 // -- rsp[0] : return address | 1329 // -- rsp[0] : return address |
1299 // -- rsp[8] : last argument | 1330 // -- rsp[8] : last argument |
1300 // ----------------------------------- | 1331 // ----------------------------------- |
1301 Label generic_array_code; | 1332 Label generic_array_code; |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1577 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); | 1608 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); |
1578 generator.Generate(); | 1609 generator.Generate(); |
1579 } | 1610 } |
1580 | 1611 |
1581 | 1612 |
1582 #undef __ | 1613 #undef __ |
1583 | 1614 |
1584 } } // namespace v8::internal | 1615 } } // namespace v8::internal |
1585 | 1616 |
1586 #endif // V8_TARGET_ARCH_X64 | 1617 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |