| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
| 6 | 6 |
| 7 #include "src/arm64/frames-arm64.h" | 7 #include "src/arm64/frames-arm64.h" |
| 8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
| 9 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
| 10 #include "src/deoptimizer.h" | 10 #include "src/deoptimizer.h" |
| (...skipping 1294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1305 __ Drop(1); | 1305 __ Drop(1); |
| 1306 } | 1306 } |
| 1307 | 1307 |
| 1308 // 4. Call the callable. | 1308 // 4. Call the callable. |
| 1309 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 1309 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 1310 } | 1310 } |
| 1311 | 1311 |
| 1312 | 1312 |
| 1313 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { | 1313 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { |
| 1314 // ----------- S t a t e ------------- | 1314 // ----------- S t a t e ------------- |
| 1315 // -- x0 : argc | 1315 // -- r0 : argc |
| 1316 // -- jssp[0] : argArray (if argc == 2) | 1316 // -- sp[0] : argArray |
| 1317 // -- jssp[8] : thisArg (if argc >= 1) | 1317 // -- sp[8] : thisArg |
| 1318 // -- jssp[16] : receiver | 1318 // -- sp[16] : receiver |
| 1319 // ----------------------------------- | 1319 // ----------------------------------- |
| 1320 ASM_LOCATION("Builtins::Generate_FunctionApply"); | 1320 ASM_LOCATION("Builtins::Generate_FunctionApply"); |
| 1321 | 1321 |
| 1322 Register argc = x0; | |
| 1323 Register arg_array = x0; | |
| 1324 Register receiver = x1; | |
| 1325 Register this_arg = x2; | |
| 1326 Register undefined = x3; | |
| 1327 Register null = x4; | |
| 1328 | |
| 1329 __ LoadRoot(undefined, Heap::kUndefinedValueRootIndex); | |
| 1330 __ LoadRoot(null, Heap::kNullValueRootIndex); | |
| 1331 | |
| 1332 // 1. Load receiver into x1, argArray into x0 (if present), remove all | 1322 // 1. Load receiver into x1, argArray into x0 (if present), remove all |
| 1333 // arguments from the stack (including the receiver), and push thisArg (if | 1323 // arguments from the stack (including the receiver), and push thisArg (if |
| 1334 // present) instead. | 1324 // present) instead. |
| 1335 { | 1325 { |
| 1336 // Claim (2 - argc) dummy arguments from the stack, to put the stack in a | 1326 Label done; |
| 1337 // consistent state for a simple pop operation. | 1327 __ LoadRoot(x2, Heap::kUndefinedValueRootIndex); |
| 1338 Register neg_argc = x10; | 1328 __ Mov(x3, x2); |
| 1339 __ Negs(neg_argc, argc); // Negate; set the Z flag if argc == 0. | 1329 __ Peek(x1, Operand(x0, LSL, kPointerSizeLog2)); // receiver |
| 1340 __ Add(x11, neg_argc, 2); | 1330 __ Subs(x4, x0, 1); |
| 1341 __ Claim(x11); | 1331 __ B(lt, &done); |
| 1342 | 1332 __ Peek(x2, Operand(x4, LSL, kPointerSizeLog2)); // thisArg |
| 1343 // ----------- S t a t e ------------- | 1333 __ Subs(x4, x4, 1); |
| 1344 // -- x0 : argc | 1334 __ B(lt, &done); |
| 1345 // -- jssp[0] : argArray (dummy value if argc <= 1) | 1335 __ Peek(x3, Operand(x4, LSL, kPointerSizeLog2)); // argArray |
| 1346 // -- jssp[8] : thisArg (dummy value if argc == 0) | 1336 __ Bind(&done); |
| 1347 // -- jssp[16] : receiver | 1337 __ Drop(x0); |
| 1348 // ----------------------------------- | 1338 __ Poke(x2, 0); |
| 1349 __ Pop(arg_array, this_arg); | 1339 __ Mov(x0, x3); |
| 1350 __ CmovX(this_arg, undefined, eq); // undefined if argc == 0. | |
| 1351 __ Cmp(neg_argc, -1); | |
| 1352 __ CmovX(arg_array, undefined, ge); // undefined if argc <= 1. | |
| 1353 | |
| 1354 __ Peek(receiver, 0); | |
| 1355 __ Poke(this_arg, 0); | |
| 1356 } | 1340 } |
| 1357 | 1341 |
| 1358 // ----------- S t a t e ------------- | 1342 // ----------- S t a t e ------------- |
| 1359 // -- x0 : argArray | 1343 // -- x0 : argArray |
| 1360 // -- x1 : receiver | 1344 // -- x1 : receiver |
| 1361 // -- x3 : undefined root value | 1345 // -- sp[0] : thisArg |
| 1362 // -- jssp[0] : thisArg | |
| 1363 // ----------------------------------- | 1346 // ----------------------------------- |
| 1364 | 1347 |
| 1365 // 2. Make sure the receiver is actually callable. | 1348 // 2. Make sure the receiver is actually callable. |
| 1366 Label receiver_not_callable; | 1349 Label receiver_not_callable; |
| 1367 __ JumpIfSmi(receiver, &receiver_not_callable); | 1350 __ JumpIfSmi(x1, &receiver_not_callable); |
| 1368 __ Ldr(x10, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 1351 __ Ldr(x4, FieldMemOperand(x1, HeapObject::kMapOffset)); |
| 1369 __ Ldrb(w10, FieldMemOperand(x10, Map::kBitFieldOffset)); | 1352 __ Ldrb(x4, FieldMemOperand(x4, Map::kBitFieldOffset)); |
| 1370 __ TestAndBranchIfAllClear(x10, 1 << Map::kIsCallable, | 1353 __ TestAndBranchIfAllClear(x4, 1 << Map::kIsCallable, &receiver_not_callable); |
| 1371 &receiver_not_callable); | |
| 1372 | 1354 |
| 1373 // 3. Tail call with no arguments if argArray is null or undefined. | 1355 // 3. Tail call with no arguments if argArray is null or undefined. |
| 1374 Label no_arguments; | 1356 Label no_arguments; |
| 1375 __ Cmp(arg_array, null); | 1357 __ JumpIfRoot(x0, Heap::kNullValueRootIndex, &no_arguments); |
| 1376 __ Ccmp(arg_array, undefined, ZFlag, ne); | 1358 __ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex, &no_arguments); |
| 1377 __ B(eq, &no_arguments); | |
| 1378 | 1359 |
| 1379 // 4a. Apply the receiver to the given argArray (passing undefined for | 1360 // 4a. Apply the receiver to the given argArray (passing undefined for |
| 1380 // new.target in x3). | 1361 // new.target). |
| 1381 DCHECK(undefined.Is(x3)); | 1362 __ LoadRoot(x3, Heap::kUndefinedValueRootIndex); |
| 1382 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); | 1363 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); |
| 1383 | 1364 |
| 1384 // 4b. The argArray is either null or undefined, so we tail call without any | 1365 // 4b. The argArray is either null or undefined, so we tail call without any |
| 1385 // arguments to the receiver. | 1366 // arguments to the receiver. |
| 1386 __ Bind(&no_arguments); | 1367 __ Bind(&no_arguments); |
| 1387 { | 1368 { |
| 1388 __ Mov(x0, 0); | 1369 __ Mov(x0, 0); |
| 1389 DCHECK(receiver.Is(x1)); | |
| 1390 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 1370 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 1391 } | 1371 } |
| 1392 | 1372 |
| 1393 // 4c. The receiver is not callable, throw an appropriate TypeError. | 1373 // 4c. The receiver is not callable, throw an appropriate TypeError. |
| 1394 __ Bind(&receiver_not_callable); | 1374 __ Bind(&receiver_not_callable); |
| 1395 { | 1375 { |
| 1396 __ Poke(receiver, 0); | 1376 __ Poke(x1, 0); |
| 1397 __ TailCallRuntime(Runtime::kThrowApplyNonFunction, 1, 1); | 1377 __ TailCallRuntime(Runtime::kThrowApplyNonFunction, 1, 1); |
| 1398 } | 1378 } |
| 1399 } | 1379 } |
| 1400 | 1380 |
| 1401 | 1381 |
| 1402 void Builtins::Generate_ReflectApply(MacroAssembler* masm) { | 1382 void Builtins::Generate_ReflectApply(MacroAssembler* masm) { |
| 1403 // ----------- S t a t e ------------- | 1383 // ----------- S t a t e ------------- |
| 1404 // -- x0 : argc | 1384 // -- x0 : argc |
| 1405 // -- jssp[0] : argumentsList (if argc == 3) | 1385 // -- sp[0] : argumentsList |
| 1406 // -- jssp[8] : thisArgument (if argc >= 2) | 1386 // -- sp[8] : thisArgument |
| 1407 // -- jssp[16] : target (if argc >= 1) | 1387 // -- sp[16] : target |
| 1408 // -- jssp[24] : receiver | 1388 // -- sp[24] : receiver |
| 1409 // ----------------------------------- | 1389 // ----------------------------------- |
| 1410 ASM_LOCATION("Builtins::Generate_ReflectApply"); | 1390 ASM_LOCATION("Builtins::Generate_ReflectApply"); |
| 1411 | 1391 |
| 1412 Register argc = x0; | |
| 1413 Register arguments_list = x0; | |
| 1414 Register target = x1; | |
| 1415 Register this_argument = x2; | |
| 1416 Register undefined = x3; | |
| 1417 | |
| 1418 __ LoadRoot(undefined, Heap::kUndefinedValueRootIndex); | |
| 1419 | |
| 1420 // 1. Load target into x1 (if present), argumentsList into x0 (if present), | 1392 // 1. Load target into x1 (if present), argumentsList into x0 (if present), |
| 1421 // remove all arguments from the stack (including the receiver), and push | 1393 // remove all arguments from the stack (including the receiver), and push |
| 1422 // thisArgument (if present) instead. | 1394 // thisArgument (if present) instead. |
| 1423 { | 1395 { |
| 1424 // Claim (3 - argc) dummy arguments from the stack, to put the stack in a | 1396 Label done; |
| 1425 // consistent state for a simple pop operation. | 1397 __ LoadRoot(x1, Heap::kUndefinedValueRootIndex); |
| 1426 Register neg_argc = x10; | 1398 __ Mov(x2, x1); |
| 1427 __ Negs(neg_argc, argc); // Negate; set the Z flag if argc == 0. | 1399 __ Mov(x3, x1); |
| 1428 __ Add(x11, neg_argc, 3); | 1400 __ Subs(x4, x0, 1); |
| 1429 __ Claim(x11); | 1401 __ B(lt, &done); |
| 1430 | 1402 __ Peek(x1, Operand(x4, LSL, kPointerSizeLog2)); // target |
| 1431 // ----------- S t a t e ------------- | 1403 __ Subs(x4, x4, 1); |
| 1432 // -- x0 : argc | 1404 __ B(lt, &done); |
| 1433 // -- jssp[0] : argumentsList (dummy value if argc <= 2) | 1405 __ Peek(x2, Operand(x4, LSL, kPointerSizeLog2)); // thisArgument |
| 1434 // -- jssp[8] : thisArgument (dummy value if argc <= 1) | 1406 __ Subs(x4, x4, 1); |
| 1435 // -- jssp[16] : target (dummy value if argc == 0) | 1407 __ B(lt, &done); |
| 1436 // -- jssp[24] : receiver | 1408 __ Peek(x3, Operand(x4, LSL, kPointerSizeLog2)); // argumentsList |
| 1437 // ----------------------------------- | 1409 __ Bind(&done); |
| 1438 __ Pop(arguments_list, this_argument, target); | 1410 __ Drop(x0); |
| 1439 __ CmovX(target, undefined, eq); // undefined if argc == 0. | 1411 __ Poke(x2, 0); |
| 1440 __ Cmp(neg_argc, -2); | 1412 __ Mov(x0, x3); |
| 1441 __ CmovX(this_argument, undefined, gt); // undefined if argc <= 1. | |
| 1442 __ CmovX(arguments_list, undefined, ge); // undefined if argc <= 2. | |
| 1443 __ Poke(this_argument, 0); // Overwrite receiver. | |
| 1444 } | 1413 } |
| 1445 | 1414 |
| 1446 // ----------- S t a t e ------------- | 1415 // ----------- S t a t e ------------- |
| 1447 // -- x0 : argumentsList | 1416 // -- x0 : argumentsList |
| 1448 // -- x1 : target | 1417 // -- x1 : target |
| 1449 // -- jssp[0] : thisArgument | 1418 // -- sp[0] : thisArgument |
| 1450 // ----------------------------------- | 1419 // ----------------------------------- |
| 1451 | 1420 |
| 1452 // 2. Make sure the target is actually callable. | 1421 // 2. Make sure the target is actually callable. |
| 1453 Label target_not_callable; | 1422 Label target_not_callable; |
| 1454 __ JumpIfSmi(target, &target_not_callable); | 1423 __ JumpIfSmi(x1, &target_not_callable); |
| 1455 __ Ldr(x10, FieldMemOperand(target, HeapObject::kMapOffset)); | 1424 __ Ldr(x4, FieldMemOperand(x1, HeapObject::kMapOffset)); |
| 1456 __ Ldr(x10, FieldMemOperand(x10, Map::kBitFieldOffset)); | 1425 __ Ldrb(x4, FieldMemOperand(x4, Map::kBitFieldOffset)); |
| 1457 __ TestAndBranchIfAllClear(x10, 1 << Map::kIsCallable, &target_not_callable); | 1426 __ TestAndBranchIfAllClear(x4, 1 << Map::kIsCallable, &target_not_callable); |
| 1458 | 1427 |
| 1459 // 3a. Apply the target to the given argumentsList (passing undefined for | 1428 // 3a. Apply the target to the given argumentsList (passing undefined for |
| 1460 // new.target in x3). | 1429 // new.target). |
| 1461 DCHECK(undefined.Is(x3)); | 1430 __ LoadRoot(x3, Heap::kUndefinedValueRootIndex); |
| 1462 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); | 1431 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); |
| 1463 | 1432 |
| 1464 // 3b. The target is not callable, throw an appropriate TypeError. | 1433 // 3b. The target is not callable, throw an appropriate TypeError. |
| 1465 __ Bind(&target_not_callable); | 1434 __ Bind(&target_not_callable); |
| 1466 { | 1435 { |
| 1467 __ Poke(target, 0); | 1436 __ Poke(x1, 0); |
| 1468 __ TailCallRuntime(Runtime::kThrowApplyNonFunction, 1, 1); | 1437 __ TailCallRuntime(Runtime::kThrowApplyNonFunction, 1, 1); |
| 1469 } | 1438 } |
| 1470 } | 1439 } |
| 1471 | 1440 |
| 1472 | 1441 |
| 1473 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) { | 1442 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) { |
| 1474 // ----------- S t a t e ------------- | 1443 // ----------- S t a t e ------------- |
| 1475 // -- x0 : argc | 1444 // -- x0 : argc |
| 1476 // -- jssp[0] : new.target (optional) | 1445 // -- sp[0] : new.target (optional) |
| 1477 // -- jssp[8] : argumentsList | 1446 // -- sp[8] : argumentsList |
| 1478 // -- jssp[16] : target | 1447 // -- sp[16] : target |
| 1479 // -- jssp[24] : receiver | 1448 // -- sp[24] : receiver |
| 1480 // ----------------------------------- | 1449 // ----------------------------------- |
| 1481 ASM_LOCATION("Builtins::Generate_ReflectConstruct"); | 1450 ASM_LOCATION("Builtins::Generate_ReflectConstruct"); |
| 1482 | 1451 |
| 1483 Register argc = x0; | |
| 1484 Register arguments_list = x0; | |
| 1485 Register target = x1; | |
| 1486 Register new_target = x3; | |
| 1487 Register undefined = x4; | |
| 1488 | |
| 1489 __ LoadRoot(undefined, Heap::kUndefinedValueRootIndex); | |
| 1490 | |
| 1491 // 1. Load target into x1 (if present), argumentsList into x0 (if present), | 1452 // 1. Load target into x1 (if present), argumentsList into x0 (if present), |
| 1492 // new.target into x3 (if present, otherwise use target), remove all | 1453 // new.target into x3 (if present, otherwise use target), remove all |
| 1493 // arguments from the stack (including the receiver), and push thisArgument | 1454 // arguments from the stack (including the receiver), and push thisArgument |
| 1494 // (if present) instead. | 1455 // (if present) instead. |
| 1495 { | 1456 { |
| 1496 // Claim (3 - argc) dummy arguments from the stack, to put the stack in a | 1457 Label done; |
| 1497 // consistent state for a simple pop operation. | 1458 __ LoadRoot(x1, Heap::kUndefinedValueRootIndex); |
| 1498 Register neg_argc = x10; | 1459 __ Mov(x2, x1); |
| 1499 __ Negs(neg_argc, argc); // Negate; set the Z flag if argc == 0. | 1460 __ Poke(x2, Operand(x0, LSL, kPointerSizeLog2)); // receiver |
| 1500 __ Add(x11, neg_argc, 3); | 1461 __ Subs(x4, x0, 1); |
| 1501 __ Claim(x11); | 1462 __ B(lt, &done); |
| 1502 | 1463 __ Peek(x1, Operand(x4, LSL, kPointerSizeLog2)); // target |
| 1503 // ----------- S t a t e ------------- | 1464 __ Mov(x3, x1); // new.target defaults to target |
| 1504 // -- x0 : argc | 1465 __ Subs(x4, x4, 1); |
| 1505 // -- jssp[0] : new.target (dummy value if argc <= 2) | 1466 __ B(lt, &done); |
| 1506 // -- jssp[8] : argumentsList (dummy value if argc <= 1) | 1467 __ Peek(x2, Operand(x4, LSL, kPointerSizeLog2)); // argumentsList |
| 1507 // -- jssp[16] : target (dummy value if argc == 0) | 1468 __ Subs(x4, x4, 1); |
| 1508 // -- jssp[24] : receiver | 1469 __ B(lt, &done); |
| 1509 // ----------------------------------- | 1470 __ Peek(x3, Operand(x4, LSL, kPointerSizeLog2)); // new.target |
| 1510 __ Pop(new_target, arguments_list, target); | 1471 __ Bind(&done); |
| 1511 __ CmovX(target, undefined, eq); // undefined if argc == 0. | 1472 __ Drop(x0); |
| 1512 __ Cmp(neg_argc, -2); | 1473 __ Mov(x0, x2); |
| 1513 __ CmovX(arguments_list, undefined, gt); // undefined if argc <= 1. | |
| 1514 __ CmovX(new_target, target, ge); // target if argc <= 2. | |
| 1515 __ Poke(undefined, 0); // Overwrite receiver. | |
| 1516 } | 1474 } |
| 1517 | 1475 |
| 1518 // ----------- S t a t e ------------- | 1476 // ----------- S t a t e ------------- |
| 1519 // -- x0 : argumentsList | 1477 // -- x0 : argumentsList |
| 1520 // -- x1 : target | 1478 // -- x3 : new.target |
| 1521 // -- x3 : new.target | 1479 // -- x1 : target |
| 1522 // -- jssp[0] : receiver (undefined) | 1480 // -- sp[0] : receiver (undefined) |
| 1523 // ----------------------------------- | 1481 // ----------------------------------- |
| 1524 | 1482 |
| 1525 // 2. Make sure the target is actually a constructor. | 1483 // 2. Make sure the target is actually a constructor. |
| 1526 Label target_not_constructor; | 1484 Label target_not_constructor; |
| 1527 __ JumpIfSmi(target, &target_not_constructor); | 1485 __ JumpIfSmi(x1, &target_not_constructor); |
| 1528 __ Ldr(x10, FieldMemOperand(target, HeapObject::kMapOffset)); | 1486 __ Ldr(x4, FieldMemOperand(x1, HeapObject::kMapOffset)); |
| 1529 __ Ldrb(x10, FieldMemOperand(x10, Map::kBitFieldOffset)); | 1487 __ Ldrb(x4, FieldMemOperand(x4, Map::kBitFieldOffset)); |
| 1530 __ TestAndBranchIfAllClear(x10, 1 << Map::kIsConstructor, | 1488 __ TestAndBranchIfAllClear(x4, 1 << Map::kIsConstructor, |
| 1531 &target_not_constructor); | 1489 &target_not_constructor); |
| 1532 | 1490 |
| 1533 // 3. Make sure the new.target is actually a constructor. | 1491 // 3. Make sure the target is actually a constructor. |
| 1534 Label new_target_not_constructor; | 1492 Label new_target_not_constructor; |
| 1535 __ JumpIfSmi(new_target, &new_target_not_constructor); | 1493 __ JumpIfSmi(x3, &new_target_not_constructor); |
| 1536 __ Ldr(x10, FieldMemOperand(new_target, HeapObject::kMapOffset)); | 1494 __ Ldr(x4, FieldMemOperand(x3, HeapObject::kMapOffset)); |
| 1537 __ Ldrb(x10, FieldMemOperand(x10, Map::kBitFieldOffset)); | 1495 __ Ldrb(x4, FieldMemOperand(x4, Map::kBitFieldOffset)); |
| 1538 __ TestAndBranchIfAllClear(x10, 1 << Map::kIsConstructor, | 1496 __ TestAndBranchIfAllClear(x4, 1 << Map::kIsConstructor, |
| 1539 &new_target_not_constructor); | 1497 &new_target_not_constructor); |
| 1540 | 1498 |
| 1541 // 4a. Construct the target with the given new.target and argumentsList. | 1499 // 4a. Construct the target with the given new.target and argumentsList. |
| 1542 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); | 1500 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); |
| 1543 | 1501 |
| 1544 // 4b. The target is not a constructor, throw an appropriate TypeError. | 1502 // 4b. The target is not a constructor, throw an appropriate TypeError. |
| 1545 __ Bind(&target_not_constructor); | 1503 __ Bind(&target_not_constructor); |
| 1546 { | 1504 { |
| 1547 __ Poke(target, 0); | 1505 __ Poke(x1, 0); |
| 1548 __ TailCallRuntime(Runtime::kThrowCalledNonCallable, 1, 1); | 1506 __ TailCallRuntime(Runtime::kThrowCalledNonCallable, 1, 1); |
| 1549 } | 1507 } |
| 1550 | 1508 |
| 1551 // 4c. The new.target is not a constructor, throw an appropriate TypeError. | 1509 // 4c. The new.target is not a constructor, throw an appropriate TypeError. |
| 1552 __ Bind(&new_target_not_constructor); | 1510 __ Bind(&new_target_not_constructor); |
| 1553 { | 1511 { |
| 1554 __ Poke(new_target, 0); | 1512 __ Poke(x3, 0); |
| 1555 __ TailCallRuntime(Runtime::kThrowCalledNonCallable, 1, 1); | 1513 __ TailCallRuntime(Runtime::kThrowCalledNonCallable, 1, 1); |
| 1556 } | 1514 } |
| 1557 } | 1515 } |
| 1558 | 1516 |
| 1559 | 1517 |
| 1560 static void ArgumentAdaptorStackCheck(MacroAssembler* masm, | 1518 static void ArgumentAdaptorStackCheck(MacroAssembler* masm, |
| 1561 Label* stack_overflow) { | 1519 Label* stack_overflow) { |
| 1562 // ----------- S t a t e ------------- | 1520 // ----------- S t a t e ------------- |
| 1563 // -- x0 : actual number of arguments | 1521 // -- x0 : actual number of arguments |
| 1564 // -- x1 : function (passed through to callee) | 1522 // -- x1 : function (passed through to callee) |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1600 __ Mov(jssp, fp); | 1558 __ Mov(jssp, fp); |
| 1601 __ Pop(fp, lr); | 1559 __ Pop(fp, lr); |
| 1602 __ DropBySMI(x10, kXRegSize); | 1560 __ DropBySMI(x10, kXRegSize); |
| 1603 __ Drop(1); | 1561 __ Drop(1); |
| 1604 } | 1562 } |
| 1605 | 1563 |
| 1606 | 1564 |
| 1607 // static | 1565 // static |
| 1608 void Builtins::Generate_Apply(MacroAssembler* masm) { | 1566 void Builtins::Generate_Apply(MacroAssembler* masm) { |
| 1609 // ----------- S t a t e ------------- | 1567 // ----------- S t a t e ------------- |
| 1610 // -- x0 : argumentsList | 1568 // -- x0 : argumentsList |
| 1611 // -- x1 : target | 1569 // -- x1 : target |
| 1612 // -- x3 : new.target (checked to be constructor or undefined) | 1570 // -- x3 : new.target (checked to be constructor or undefined) |
| 1613 // -- jssp[0] : thisArgument | 1571 // -- sp[0] : thisArgument |
| 1614 // ----------------------------------- | 1572 // ----------------------------------- |
| 1615 | 1573 |
| 1616 Register arguments_list = x0; | |
| 1617 Register target = x1; | |
| 1618 Register new_target = x3; | |
| 1619 | |
| 1620 Register args = x0; | |
| 1621 Register len = x2; | |
| 1622 | |
| 1623 // Create the list of arguments from the array-like argumentsList. | 1574 // Create the list of arguments from the array-like argumentsList. |
| 1624 { | 1575 { |
| 1625 Label create_arguments, create_array, create_runtime, done_create; | 1576 Label create_arguments, create_array, create_runtime, done_create; |
| 1626 __ JumpIfSmi(arguments_list, &create_runtime); | 1577 __ JumpIfSmi(x0, &create_runtime); |
| 1627 | 1578 |
| 1628 // Load native context. | 1579 // Load the map of argumentsList into x2. |
| 1629 Register native_context = x4; | 1580 __ Ldr(x2, FieldMemOperand(x0, HeapObject::kMapOffset)); |
| 1630 __ Ldr(native_context, NativeContextMemOperand()); | |
| 1631 | 1581 |
| 1632 // Load the map of argumentsList. | 1582 // Load native context into x4. |
| 1633 Register arguments_list_map = x2; | 1583 __ Ldr(x4, NativeContextMemOperand()); |
| 1634 __ Ldr(arguments_list_map, | |
| 1635 FieldMemOperand(arguments_list, HeapObject::kMapOffset)); | |
| 1636 | 1584 |
| 1637 // Check if argumentsList is an (unmodified) arguments object. | 1585 // Check if argumentsList is an (unmodified) arguments object. |
| 1638 __ Ldr(x10, ContextMemOperand(native_context, | 1586 __ Ldr(x5, ContextMemOperand(x4, Context::SLOPPY_ARGUMENTS_MAP_INDEX)); |
| 1639 Context::SLOPPY_ARGUMENTS_MAP_INDEX)); | 1587 __ Cmp(x5, x2); |
| 1640 __ Ldr(x11, ContextMemOperand(native_context, | 1588 __ B(eq, &create_arguments); |
| 1641 Context::STRICT_ARGUMENTS_MAP_INDEX)); | 1589 __ Ldr(x5, ContextMemOperand(x4, Context::STRICT_ARGUMENTS_MAP_INDEX)); |
| 1642 __ Cmp(arguments_list_map, x10); | 1590 __ Cmp(x5, x2); |
| 1643 __ Ccmp(arguments_list_map, x11, ZFlag, ne); | |
| 1644 __ B(eq, &create_arguments); | 1591 __ B(eq, &create_arguments); |
| 1645 | 1592 |
| 1646 // Check if argumentsList is a fast JSArray. | 1593 // Check if argumentsList is a fast JSArray. |
| 1647 __ CompareInstanceType(arguments_list_map, native_context, JS_ARRAY_TYPE); | 1594 __ CompareInstanceType(x2, x4, JS_ARRAY_TYPE); |
| 1648 __ B(eq, &create_array); | 1595 __ B(eq, &create_array); |
| 1649 | 1596 |
| 1650 // Ask the runtime to create the list (actually a FixedArray). | 1597 // Ask the runtime to create the list (actually a FixedArray). |
| 1651 __ Bind(&create_runtime); | 1598 __ Bind(&create_runtime); |
| 1652 { | 1599 { |
| 1653 FrameScope scope(masm, StackFrame::INTERNAL); | 1600 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1654 __ Push(target, new_target, arguments_list); | 1601 __ Push(x1, x3, x0); |
| 1655 __ CallRuntime(Runtime::kCreateListFromArrayLike, 1); | 1602 __ CallRuntime(Runtime::kCreateListFromArrayLike, 1); |
| 1656 __ Pop(new_target, target); | 1603 __ Pop(x3, x1); |
| 1657 __ Ldrsw(len, UntagSmiFieldMemOperand(arguments_list, | 1604 __ Ldrsw(x2, UntagSmiFieldMemOperand(x0, FixedArray::kLengthOffset)); |
| 1658 FixedArray::kLengthOffset)); | |
| 1659 } | 1605 } |
| 1660 __ B(&done_create); | 1606 __ B(&done_create); |
| 1661 | 1607 |
| 1662 // Try to create the list from an arguments object. | 1608 // Try to create the list from an arguments object. |
| 1663 __ Bind(&create_arguments); | 1609 __ Bind(&create_arguments); |
| 1664 __ Ldrsw(len, UntagSmiFieldMemOperand( | 1610 __ Ldr(x2, |
| 1665 arguments_list, | 1611 FieldMemOperand(x0, JSObject::kHeaderSize + |
| 1666 JSObject::kHeaderSize + | 1612 Heap::kArgumentsLengthIndex * kPointerSize)); |
| 1667 Heap::kArgumentsLengthIndex * kPointerSize)); | 1613 __ Ldr(x4, FieldMemOperand(x0, JSObject::kElementsOffset)); |
| 1668 __ Ldr(x10, FieldMemOperand(arguments_list, JSObject::kElementsOffset)); | 1614 __ Ldr(x5, FieldMemOperand(x4, FixedArray::kLengthOffset)); |
| 1669 __ Ldrsw(x11, UntagSmiFieldMemOperand(x10, FixedArray::kLengthOffset)); | 1615 __ Cmp(x2, x4); |
| 1670 __ CompareAndBranch(len, x11, ne, &create_runtime); | 1616 __ B(ne, &create_runtime); |
| 1671 __ Mov(args, x10); | 1617 __ SmiUntag(x2); |
| 1618 __ Mov(x0, x4); |
| 1672 __ B(&done_create); | 1619 __ B(&done_create); |
| 1673 | 1620 |
| 1674 // Try to create the list from a JSArray object. | 1621 // Try to create the list from a JSArray object. |
| 1675 __ Bind(&create_array); | 1622 __ Bind(&create_array); |
| 1676 __ Ldr(x10, FieldMemOperand(arguments_list_map, Map::kBitField2Offset)); | 1623 __ Ldr(x2, FieldMemOperand(x2, Map::kBitField2Offset)); |
| 1677 __ DecodeField<Map::ElementsKindBits>(x10); | 1624 __ DecodeField<Map::ElementsKindBits>(x2); |
| 1678 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | 1625 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); |
| 1626 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); |
| 1679 STATIC_ASSERT(FAST_ELEMENTS == 2); | 1627 STATIC_ASSERT(FAST_ELEMENTS == 2); |
| 1680 // Branch for anything that's not FAST_{SMI_}ELEMENTS. | 1628 __ Cmp(x2, FAST_ELEMENTS); |
| 1681 __ TestAndBranchIfAnySet(x10, ~FAST_ELEMENTS, &create_runtime); | 1629 __ B(hi, &create_runtime); |
| 1682 __ Ldrsw(len, | 1630 __ Cmp(x2, FAST_HOLEY_SMI_ELEMENTS); |
| 1683 UntagSmiFieldMemOperand(arguments_list, JSArray::kLengthOffset)); | 1631 __ B(eq, &create_runtime); |
| 1684 __ Ldr(args, FieldMemOperand(arguments_list, JSArray::kElementsOffset)); | 1632 __ Ldrsw(x2, UntagSmiFieldMemOperand(x0, JSArray::kLengthOffset)); |
| 1633 __ Ldr(x0, FieldMemOperand(x0, JSArray::kElementsOffset)); |
| 1685 | 1634 |
| 1686 __ Bind(&done_create); | 1635 __ Bind(&done_create); |
| 1687 } | 1636 } |
| 1688 | 1637 |
| 1689 // Check for stack overflow. | 1638 // Check for stack overflow. |
| 1690 { | 1639 { |
| 1691 // Check the stack for overflow. We are not trying to catch interruptions | 1640 // Check the stack for overflow. We are not trying to catch interruptions |
| 1692 // (i.e. debug break and preemption) here, so check the "real stack limit". | 1641 // (i.e. debug break and preemption) here, so check the "real stack limit". |
| 1693 Label done; | 1642 Label done; |
| 1694 __ LoadRoot(x10, Heap::kRealStackLimitRootIndex); | 1643 __ LoadRoot(x10, Heap::kRealStackLimitRootIndex); |
| 1695 // Make x10 the space we have left. The stack might already be overflowed | 1644 // Make x10 the space we have left. The stack might already be overflowed |
| 1696 // here which will cause x10 to become negative. | 1645 // here which will cause x10 to become negative. |
| 1697 __ Sub(x10, masm->StackPointer(), x10); | 1646 __ Sub(x10, jssp, x10); |
| 1698 // Check if the arguments will overflow the stack. | 1647 // Check if the arguments will overflow the stack. |
| 1699 __ Cmp(x10, Operand(len, LSL, kPointerSizeLog2)); | 1648 __ Cmp(x10, Operand(x2, LSL, kPointerSizeLog2)); |
| 1700 __ B(gt, &done); // Signed comparison. | 1649 __ B(gt, &done); // Signed comparison. |
| 1701 __ TailCallRuntime(Runtime::kThrowStackOverflow, 1, 1); | 1650 __ TailCallRuntime(Runtime::kThrowStackOverflow, 1, 1); |
| 1702 __ Bind(&done); | 1651 __ Bind(&done); |
| 1703 } | 1652 } |
| 1704 | 1653 |
| 1705 // ----------- S t a t e ------------- | 1654 // ----------- S t a t e ------------- |
| 1706 // -- x0 : args (a FixedArray built from argumentsList) | 1655 // -- x1 : target |
| 1707 // -- x1 : target | 1656 // -- x0 : args (a FixedArray built from argumentsList) |
| 1708 // -- x2 : len (number of elements to push from args) | 1657 // -- x2 : len (number of elements to push from args) |
| 1709 // -- x3 : new.target (checked to be constructor or undefined) | 1658 // -- x3 : new.target (checked to be constructor or undefined) |
| 1710 // -- jssp[0] : thisArgument | 1659 // -- sp[0] : thisArgument |
| 1711 // ----------------------------------- | 1660 // ----------------------------------- |
| 1712 | 1661 |
| 1713 // Push arguments onto the stack (thisArgument is already on the stack). | 1662 // Push arguments onto the stack (thisArgument is already on the stack). |
| 1714 { | 1663 { |
| 1664 __ Mov(x4, 0); |
| 1715 Label done, loop; | 1665 Label done, loop; |
| 1716 Register src = x4; | |
| 1717 | |
| 1718 __ Add(src, args, FixedArray::kHeaderSize - kHeapObjectTag); | |
| 1719 __ Mov(x0, len); // The 'len' argument for Call() or Construct(). | |
| 1720 __ Cbz(len, &done); | |
| 1721 __ Claim(len); | |
| 1722 __ Bind(&loop); | 1666 __ Bind(&loop); |
| 1723 __ Subs(len, len, 1); | 1667 __ Cmp(x4, x2); |
| 1724 __ Ldr(x10, MemOperand(src, kPointerSize, PostIndex)); | 1668 __ B(eq, &done); |
| 1725 __ Poke(x10, Operand(len, LSL, kPointerSizeLog2)); | 1669 __ Add(x10, x0, Operand(x4, LSL, kPointerSizeLog2)); |
| 1726 __ B(ne, &loop); | 1670 __ Ldr(x10, FieldMemOperand(x10, FixedArray::kHeaderSize)); |
| 1671 __ Push(x10); |
| 1672 __ Add(x4, x4, 1); |
| 1673 __ B(&loop); |
| 1727 __ Bind(&done); | 1674 __ Bind(&done); |
| 1675 __ Mov(x0, x4); |
| 1728 } | 1676 } |
| 1729 | 1677 |
| 1730 // ----------- S t a t e ------------- | |
| 1731 // -- x0 : argument count (len) | |
| 1732 // -- x1 : target | |
| 1733 // -- x3 : new.target (checked to be constructor or undefined) | |
| 1734 // -- jssp[0] : args[len-1] | |
| 1735 // -- jssp[8] : args[len-2] | |
| 1736 // ... : ... | |
| 1737 // -- jssp[8*(len-2)] : args[1] | |
| 1738 // -- jssp[8*(len-1)] : args[0] | |
| 1739 // ----------------------------------- | |
| 1740 | |
| 1741 // Dispatch to Call or Construct depending on whether new.target is undefined. | 1678 // Dispatch to Call or Construct depending on whether new.target is undefined. |
| 1742 { | 1679 { |
| 1743 __ CompareRoot(new_target, Heap::kUndefinedValueRootIndex); | 1680 __ CompareRoot(x3, Heap::kUndefinedValueRootIndex); |
| 1744 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET, eq); | 1681 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET, eq); |
| 1745 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 1682 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
| 1746 } | 1683 } |
| 1747 } | 1684 } |
| 1748 | 1685 |
| 1749 | 1686 |
| 1750 // static | 1687 // static |
| 1751 void Builtins::Generate_CallFunction(MacroAssembler* masm, | 1688 void Builtins::Generate_CallFunction(MacroAssembler* masm, |
| 1752 ConvertReceiverMode mode) { | 1689 ConvertReceiverMode mode) { |
| 1753 // ----------- S t a t e ------------- | 1690 // ----------- S t a t e ------------- |
| (...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2228 } | 2165 } |
| 2229 } | 2166 } |
| 2230 | 2167 |
| 2231 | 2168 |
| 2232 #undef __ | 2169 #undef __ |
| 2233 | 2170 |
| 2234 } // namespace internal | 2171 } // namespace internal |
| 2235 } // namespace v8 | 2172 } // namespace v8 |
| 2236 | 2173 |
| 2237 #endif // V8_TARGET_ARCH_ARM | 2174 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |