OLD | NEW |
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 1349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1360 | 1360 |
1361 | 1361 |
1362 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { | 1362 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { |
1363 ASM_LOCATION("Builtins::Generate_ArgumentsAdaptorTrampoline"); | 1363 ASM_LOCATION("Builtins::Generate_ArgumentsAdaptorTrampoline"); |
1364 // ----------- S t a t e ------------- | 1364 // ----------- S t a t e ------------- |
1365 // -- x0 : actual number of arguments | 1365 // -- x0 : actual number of arguments |
1366 // -- x1 : function (passed through to callee) | 1366 // -- x1 : function (passed through to callee) |
1367 // -- x2 : expected number of arguments | 1367 // -- x2 : expected number of arguments |
1368 // ----------------------------------- | 1368 // ----------------------------------- |
1369 | 1369 |
| 1370 Register argc_actual = x0; // Excluding the receiver. |
| 1371 Register argc_expected = x2; // Excluding the receiver. |
| 1372 Register function = x1; |
| 1373 Register code_entry = x3; |
| 1374 |
1370 Label invoke, dont_adapt_arguments; | 1375 Label invoke, dont_adapt_arguments; |
1371 | 1376 |
1372 Label enough, too_few; | 1377 Label enough, too_few; |
1373 __ Ldr(x3, FieldMemOperand(x1, JSFunction::kCodeEntryOffset)); | 1378 __ Ldr(code_entry, FieldMemOperand(function, JSFunction::kCodeEntryOffset)); |
1374 __ Cmp(x0, x2); | 1379 __ Cmp(argc_actual, argc_expected); |
1375 __ B(lt, &too_few); | 1380 __ B(lt, &too_few); |
1376 __ Cmp(x2, SharedFunctionInfo::kDontAdaptArgumentsSentinel); | 1381 __ Cmp(argc_expected, SharedFunctionInfo::kDontAdaptArgumentsSentinel); |
1377 __ B(eq, &dont_adapt_arguments); | 1382 __ B(eq, &dont_adapt_arguments); |
1378 | 1383 |
1379 { // Enough parameters: actual >= expected | 1384 { // Enough parameters: actual >= expected |
1380 EnterArgumentsAdaptorFrame(masm); | 1385 EnterArgumentsAdaptorFrame(masm); |
1381 | 1386 |
1382 // Calculate copy start address into x10 and end address into x11. | 1387 Register copy_start = x10; |
1383 // x0: actual number of arguments | 1388 Register copy_end = x11; |
1384 // x1: function | 1389 Register copy_to = x12; |
1385 // x2: expected number of arguments | 1390 Register scratch1 = x13, scratch2 = x14; |
1386 // x3: code entry to call | 1391 |
1387 __ Add(x10, fp, Operand(x0, LSL, kPointerSizeLog2)); | 1392 __ Lsl(argc_expected, argc_expected, kPointerSizeLog2); |
1388 // Adjust for return address and receiver | 1393 |
1389 __ Add(x10, x10, 2 * kPointerSize); | 1394 // Adjust for fp, lr, and the receiver. |
1390 __ Sub(x11, x10, Operand(x2, LSL, kPointerSizeLog2)); | 1395 __ Add(copy_start, fp, 3 * kPointerSize); |
| 1396 __ Add(copy_start, copy_start, Operand(argc_actual, LSL, kPointerSizeLog2)); |
| 1397 __ Sub(copy_end, copy_start, argc_expected); |
| 1398 __ Sub(copy_end, copy_end, kPointerSize); |
| 1399 __ Mov(copy_to, jssp); |
| 1400 |
| 1401 // Claim space for the arguments, the receiver, and one extra slot. |
| 1402 // The extra slot ensures we do not write under jssp. It will be popped |
| 1403 // later. |
| 1404 __ Add(scratch1, argc_expected, 2 * kPointerSize); |
| 1405 __ Claim(scratch1, 1); |
1391 | 1406 |
1392 // Copy the arguments (including the receiver) to the new stack frame. | 1407 // Copy the arguments (including the receiver) to the new stack frame. |
1393 // x0: actual number of arguments | 1408 Label copy_2_by_2; |
1394 // x1: function | 1409 __ Bind(©_2_by_2); |
1395 // x2: expected number of arguments | 1410 __ Ldp(scratch1, scratch2, |
1396 // x3: code entry to call | 1411 MemOperand(copy_start, - 2 * kPointerSize, PreIndex)); |
1397 // x10: copy start address | 1412 __ Stp(scratch1, scratch2, |
1398 // x11: copy end address | 1413 MemOperand(copy_to, - 2 * kPointerSize, PreIndex)); |
| 1414 __ Cmp(copy_start, copy_end); |
| 1415 __ B(hi, ©_2_by_2); |
1399 | 1416 |
1400 // TODO(all): Should we push values 2 by 2? | 1417 // Correct the space allocated for the extra slot. |
1401 Label copy; | 1418 __ Drop(1); |
1402 __ Bind(©); | |
1403 __ Cmp(x10, x11); | |
1404 __ Ldr(x12, MemOperand(x10, -kPointerSize, PostIndex)); | |
1405 __ Push(x12); | |
1406 __ B(gt, ©); | |
1407 | 1419 |
1408 __ B(&invoke); | 1420 __ B(&invoke); |
1409 } | 1421 } |
1410 | 1422 |
1411 { // Too few parameters: Actual < expected | 1423 { // Too few parameters: Actual < expected |
1412 __ Bind(&too_few); | 1424 __ Bind(&too_few); |
1413 EnterArgumentsAdaptorFrame(masm); | 1425 EnterArgumentsAdaptorFrame(masm); |
1414 | 1426 |
1415 // Calculate copy start address into x10 and copy end address into x11. | 1427 Register copy_from = x10; |
1416 // x0: actual number of arguments | 1428 Register copy_end = x11; |
1417 // x1: function | 1429 Register copy_to = x12; |
1418 // x2: expected number of arguments | 1430 Register scratch1 = x13, scratch2 = x14; |
1419 // x3: code entry to call | 1431 |
1420 // Adjust for return address. | 1432 __ Lsl(argc_expected, argc_expected, kPointerSizeLog2); |
1421 __ Add(x11, fp, 1 * kPointerSize); | 1433 __ Lsl(argc_actual, argc_actual, kPointerSizeLog2); |
1422 __ Add(x10, x11, Operand(x0, LSL, kPointerSizeLog2)); | 1434 |
1423 __ Add(x10, x10, 1 * kPointerSize); | 1435 // Adjust for fp, lr, and the receiver. |
| 1436 __ Add(copy_from, fp, 3 * kPointerSize); |
| 1437 __ Add(copy_from, copy_from, argc_actual); |
| 1438 __ Mov(copy_to, jssp); |
| 1439 __ Sub(copy_end, copy_to, 1 * kPointerSize); // Adjust for the receiver. |
| 1440 __ Sub(copy_end, copy_end, argc_actual); |
| 1441 |
| 1442 // Claim space for the arguments, the receiver, and one extra slot. |
| 1443 // The extra slot ensures we do not write under jssp. It will be popped |
| 1444 // later. |
| 1445 __ Add(scratch1, argc_expected, 2 * kPointerSize); |
| 1446 __ Claim(scratch1, 1); |
1424 | 1447 |
1425 // Copy the arguments (including the receiver) to the new stack frame. | 1448 // Copy the arguments (including the receiver) to the new stack frame. |
1426 // x0: actual number of arguments | 1449 Label copy_2_by_2; |
1427 // x1: function | 1450 __ Bind(©_2_by_2); |
1428 // x2: expected number of arguments | 1451 __ Ldp(scratch1, scratch2, |
1429 // x3: code entry to call | 1452 MemOperand(copy_from, - 2 * kPointerSize, PreIndex)); |
1430 // x10: copy start address | 1453 __ Stp(scratch1, scratch2, |
1431 // x11: copy end address | 1454 MemOperand(copy_to, - 2 * kPointerSize, PreIndex)); |
1432 Label copy; | 1455 __ Cmp(copy_to, copy_end); |
1433 __ Bind(©); | 1456 __ B(hi, ©_2_by_2); |
1434 __ Ldr(x12, MemOperand(x10, -kPointerSize, PostIndex)); | 1457 |
1435 __ Push(x12); | 1458 __ Mov(copy_to, copy_end); |
1436 __ Cmp(x10, x11); // Compare before moving to next argument. | |
1437 __ B(ne, ©); | |
1438 | 1459 |
1439 // Fill the remaining expected arguments with undefined. | 1460 // Fill the remaining expected arguments with undefined. |
1440 // x0: actual number of arguments | 1461 __ LoadRoot(scratch1, Heap::kUndefinedValueRootIndex); |
1441 // x1: function | 1462 __ Add(copy_end, jssp, kPointerSize); |
1442 // x2: expected number of arguments | |
1443 // x3: code entry to call | |
1444 __ LoadRoot(x10, Heap::kUndefinedValueRootIndex); | |
1445 __ Sub(x11, fp, Operand(x2, LSL, kPointerSizeLog2)); | |
1446 // Adjust for the arguments adaptor frame and already pushed receiver. | |
1447 __ Sub(x11, x11, | |
1448 StandardFrameConstants::kFixedFrameSizeFromFp + (2 * kPointerSize)); | |
1449 | 1463 |
1450 // TODO(all): Optimize this to use ldp? | |
1451 Label fill; | 1464 Label fill; |
1452 __ Bind(&fill); | 1465 __ Bind(&fill); |
1453 __ Push(x10); | 1466 __ Stp(scratch1, scratch1, |
1454 __ Cmp(jssp, x11); | 1467 MemOperand(copy_to, - 2 * kPointerSize, PreIndex)); |
1455 __ B(ne, &fill); | 1468 __ Cmp(copy_to, copy_end); |
| 1469 __ B(hi, &fill); |
| 1470 |
| 1471 // Correct the space allocated for the extra slot. |
| 1472 __ Drop(1); |
1456 } | 1473 } |
1457 | 1474 |
1458 // Arguments have been adapted. Now call the entry point. | 1475 // Arguments have been adapted. Now call the entry point. |
1459 __ Bind(&invoke); | 1476 __ Bind(&invoke); |
1460 __ Call(x3); | 1477 __ Call(code_entry); |
1461 | 1478 |
1462 // Store offset of return address for deoptimizer. | 1479 // Store offset of return address for deoptimizer. |
1463 masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset()); | 1480 masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset()); |
1464 | 1481 |
1465 // Exit frame and return. | 1482 // Exit frame and return. |
1466 LeaveArgumentsAdaptorFrame(masm); | 1483 LeaveArgumentsAdaptorFrame(masm); |
1467 __ Ret(); | 1484 __ Ret(); |
1468 | 1485 |
1469 // Call the entry point without adapting the arguments. | 1486 // Call the entry point without adapting the arguments. |
1470 __ Bind(&dont_adapt_arguments); | 1487 __ Bind(&dont_adapt_arguments); |
1471 __ Jump(x3); | 1488 __ Jump(code_entry); |
1472 } | 1489 } |
1473 | 1490 |
1474 | 1491 |
1475 #undef __ | 1492 #undef __ |
1476 | 1493 |
1477 } } // namespace v8::internal | 1494 } } // namespace v8::internal |
1478 | 1495 |
1479 #endif // V8_TARGET_ARCH_ARM | 1496 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |