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

Side by Side Diff: src/arm64/builtins-arm64.cc

Issue 1533803002: Revert of [es6] Correct Function.prototype.apply, Reflect.construct and Reflect.apply. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years 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/arm/builtins-arm.cc ('k') | src/bootstrapper.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 // 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 1292 matching lines...) Expand 10 before | Expand all | Expand 10 after
1303 // (which is a copy of the last argument). 1303 // (which is a copy of the last argument).
1304 __ Sub(argc, argc, 1); 1304 __ Sub(argc, argc, 1);
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 static void Generate_PushAppliedArguments(MacroAssembler* masm,
1314 const int vectorOffset,
1315 const int argumentsOffset,
1316 const int indexOffset,
1317 const int limitOffset) {
1318 Label entry, loop;
1319 Register receiver = LoadDescriptor::ReceiverRegister();
1320 Register key = LoadDescriptor::NameRegister();
1321 Register slot = LoadDescriptor::SlotRegister();
1322 Register vector = LoadWithVectorDescriptor::VectorRegister();
1323
1324 __ Ldr(key, MemOperand(fp, indexOffset));
1325 __ B(&entry);
1326
1327 // Load the current argument from the arguments array.
1328 __ Bind(&loop);
1329 __ Ldr(receiver, MemOperand(fp, argumentsOffset));
1330
1331 // Use inline caching to speed up access to arguments.
1332 int slot_index = TypeFeedbackVector::PushAppliedArgumentsIndex();
1333 __ Mov(slot, Operand(Smi::FromInt(slot_index)));
1334 __ Ldr(vector, MemOperand(fp, vectorOffset));
1335 Handle<Code> ic =
1336 KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode();
1337 __ Call(ic, RelocInfo::CODE_TARGET);
1338
1339 // Push the nth argument.
1340 __ Push(x0);
1341
1342 __ Ldr(key, MemOperand(fp, indexOffset));
1343 __ Add(key, key, Smi::FromInt(1));
1344 __ Str(key, MemOperand(fp, indexOffset));
1345
1346 // Test if the copy loop has finished copying all the elements from the
1347 // arguments object.
1348 __ Bind(&entry);
1349 __ Ldr(x1, MemOperand(fp, limitOffset));
1350 __ Cmp(key, x1);
1351 __ B(ne, &loop);
1352
1353 // On exit, the pushed arguments count is in x0, untagged
1354 __ Mov(x0, key);
1355 __ SmiUntag(x0);
1356 }
1357
1358
1359 static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
1360 const int kFormalParameters = targetIsArgument ? 3 : 2;
1361 const int kStackSize = kFormalParameters + 1;
1362
1363 {
1364 FrameScope frame_scope(masm, StackFrame::INTERNAL);
1365
1366 const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize;
1367 const int kReceiverOffset = kArgumentsOffset + kPointerSize;
1368 const int kFunctionOffset = kReceiverOffset + kPointerSize;
1369 const int kVectorOffset =
1370 InternalFrameConstants::kCodeOffset - 1 * kPointerSize;
1371 const int kIndexOffset = kVectorOffset - (2 * kPointerSize);
1372 const int kLimitOffset = kVectorOffset - (1 * kPointerSize);
1373
1374 Register args = x12;
1375 Register receiver = x14;
1376 Register function = x15;
1377 Register apply_function = x1;
1378
1379 // Push the vector.
1380 __ Ldr(
1381 apply_function,
1382 FieldMemOperand(apply_function, JSFunction::kSharedFunctionInfoOffset));
1383 __ Ldr(apply_function,
1384 FieldMemOperand(apply_function,
1385 SharedFunctionInfo::kFeedbackVectorOffset));
1386 __ Push(apply_function);
1387
1388 // Get the length of the arguments via a builtin call.
1389 __ Ldr(function, MemOperand(fp, kFunctionOffset));
1390 __ Ldr(args, MemOperand(fp, kArgumentsOffset));
1391 __ Push(function, args);
1392 if (targetIsArgument) {
1393 __ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX,
1394 CALL_FUNCTION);
1395 } else {
1396 __ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION);
1397 }
1398 Register argc = x0;
1399
1400 Generate_CheckStackOverflow(masm, argc, kArgcIsSmiTagged);
1401
1402 // Push current limit, index and receiver.
1403 __ Mov(x1, 0); // Initial index.
1404 __ Ldr(receiver, MemOperand(fp, kReceiverOffset));
1405 __ Push(argc, x1, receiver);
1406
1407 // Copy all arguments from the array to the stack.
1408 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset,
1409 kIndexOffset, kLimitOffset);
1410
1411 // At the end of the loop, the number of arguments is stored in x0, untagged
1412
1413 // Call the callable.
1414 // TODO(bmeurer): This should be a tail call according to ES6.
1415 __ Ldr(x1, MemOperand(fp, kFunctionOffset));
1416 __ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1417 }
1418 __ Drop(kStackSize);
1419 __ Ret();
1420 }
1421
1422
1423 static void Generate_ConstructHelper(MacroAssembler* masm) {
1424 const int kFormalParameters = 3;
1425 const int kStackSize = kFormalParameters + 1;
1426
1427 {
1428 FrameScope frame_scope(masm, StackFrame::INTERNAL);
1429
1430 const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize;
1431 const int kArgumentsOffset = kNewTargetOffset + kPointerSize;
1432 const int kFunctionOffset = kArgumentsOffset + kPointerSize;
1433 const int kVectorOffset =
1434 InternalFrameConstants::kCodeOffset - 1 * kPointerSize;
1435 const int kIndexOffset = kVectorOffset - (2 * kPointerSize);
1436 const int kLimitOffset = kVectorOffset - (1 * kPointerSize);
1437
1438 // Is x11 safe to use?
1439 Register newTarget = x11;
1440 Register args = x12;
1441 Register function = x15;
1442 Register construct_function = x1;
1443
1444 // Push the vector.
1445 __ Ldr(construct_function,
1446 FieldMemOperand(construct_function,
1447 JSFunction::kSharedFunctionInfoOffset));
1448 __ Ldr(construct_function,
1449 FieldMemOperand(construct_function,
1450 SharedFunctionInfo::kFeedbackVectorOffset));
1451 __ Push(construct_function);
1452
1453 // If newTarget is not supplied, set it to constructor
1454 Label validate_arguments;
1455 __ Ldr(x0, MemOperand(fp, kNewTargetOffset));
1456 __ CompareRoot(x0, Heap::kUndefinedValueRootIndex);
1457 __ B(ne, &validate_arguments);
1458 __ Ldr(x0, MemOperand(fp, kFunctionOffset));
1459 __ Str(x0, MemOperand(fp, kNewTargetOffset));
1460
1461 // Validate arguments
1462 __ Bind(&validate_arguments);
1463 __ Ldr(function, MemOperand(fp, kFunctionOffset));
1464 __ Ldr(args, MemOperand(fp, kArgumentsOffset));
1465 __ Ldr(newTarget, MemOperand(fp, kNewTargetOffset));
1466 __ Push(function, args, newTarget);
1467 __ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX,
1468 CALL_FUNCTION);
1469 Register argc = x0;
1470
1471 Generate_CheckStackOverflow(masm, argc, kArgcIsSmiTagged);
1472
1473 // Push current limit and index & constructor function as callee.
1474 __ Mov(x1, 0); // Initial index.
1475 __ Push(argc, x1, function);
1476
1477 // Copy all arguments from the array to the stack.
1478 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset,
1479 kIndexOffset, kLimitOffset);
1480
1481 // Use undefined feedback vector
1482 __ LoadRoot(x2, Heap::kUndefinedValueRootIndex);
1483 __ Ldr(x1, MemOperand(fp, kFunctionOffset));
1484 __ Ldr(x3, MemOperand(fp, kNewTargetOffset));
1485
1486 // Call the function.
1487 __ Call(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
1488
1489 // Leave internal frame.
1490 }
1491 __ Drop(kStackSize);
1492 __ Ret();
1493 }
1494
1495
1313 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { 1496 void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
1314 // ----------- S t a t e -------------
1315 // -- r0 : argc
1316 // -- sp[0] : argArray
1317 // -- sp[8] : thisArg
1318 // -- sp[16] : receiver
1319 // -----------------------------------
1320 ASM_LOCATION("Builtins::Generate_FunctionApply"); 1497 ASM_LOCATION("Builtins::Generate_FunctionApply");
1321 1498 Generate_ApplyHelper(masm, false);
1322 // 1. Load receiver into x1, argArray into x0 (if present), remove all
1323 // arguments from the stack (including the receiver), and push thisArg (if
1324 // present) instead.
1325 {
1326 Label done;
1327 __ LoadRoot(x2, Heap::kUndefinedValueRootIndex);
1328 __ Mov(x3, x2);
1329 __ Peek(x1, Operand(x0, LSL, kPointerSizeLog2)); // receiver
1330 __ Subs(x4, x0, 1);
1331 __ B(lt, &done);
1332 __ Peek(x2, Operand(x4, LSL, kPointerSizeLog2)); // thisArg
1333 __ Subs(x4, x4, 1);
1334 __ B(lt, &done);
1335 __ Peek(x3, Operand(x4, LSL, kPointerSizeLog2)); // argArray
1336 __ Bind(&done);
1337 __ Drop(x0);
1338 __ Poke(x2, 0);
1339 __ Mov(x0, x3);
1340 }
1341
1342 // ----------- S t a t e -------------
1343 // -- x0 : argArray
1344 // -- x1 : receiver
1345 // -- sp[0] : thisArg
1346 // -----------------------------------
1347
1348 // 2. Make sure the receiver is actually callable.
1349 Label receiver_not_callable;
1350 __ JumpIfSmi(x1, &receiver_not_callable);
1351 __ Ldr(x4, FieldMemOperand(x1, HeapObject::kMapOffset));
1352 __ Ldrb(x4, FieldMemOperand(x4, Map::kBitFieldOffset));
1353 __ TestAndBranchIfAllClear(x4, 1 << Map::kIsCallable, &receiver_not_callable);
1354
1355 // 3. Tail call with no arguments if argArray is null or undefined.
1356 Label no_arguments;
1357 __ JumpIfRoot(x0, Heap::kNullValueRootIndex, &no_arguments);
1358 __ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex, &no_arguments);
1359
1360 // 4a. Apply the receiver to the given argArray (passing undefined for
1361 // new.target).
1362 __ LoadRoot(x3, Heap::kUndefinedValueRootIndex);
1363 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1364
1365 // 4b. The argArray is either null or undefined, so we tail call without any
1366 // arguments to the receiver.
1367 __ Bind(&no_arguments);
1368 {
1369 __ Mov(x0, 0);
1370 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1371 }
1372
1373 // 4c. The receiver is not callable, throw an appropriate TypeError.
1374 __ Bind(&receiver_not_callable);
1375 {
1376 __ Poke(x1, 0);
1377 __ TailCallRuntime(Runtime::kThrowApplyNonFunction, 1, 1);
1378 }
1379 } 1499 }
1380 1500
1381 1501
1382 void Builtins::Generate_ReflectApply(MacroAssembler* masm) { 1502 void Builtins::Generate_ReflectApply(MacroAssembler* masm) {
1383 // ----------- S t a t e -------------
1384 // -- x0 : argc
1385 // -- sp[0] : argumentsList
1386 // -- sp[8] : thisArgument
1387 // -- sp[16] : target
1388 // -- sp[24] : receiver
1389 // -----------------------------------
1390 ASM_LOCATION("Builtins::Generate_ReflectApply"); 1503 ASM_LOCATION("Builtins::Generate_ReflectApply");
1391 1504 Generate_ApplyHelper(masm, true);
1392 // 1. Load target into x1 (if present), argumentsList into x0 (if present),
1393 // remove all arguments from the stack (including the receiver), and push
1394 // thisArgument (if present) instead.
1395 {
1396 Label done;
1397 __ LoadRoot(x1, Heap::kUndefinedValueRootIndex);
1398 __ Mov(x2, x1);
1399 __ Mov(x3, x1);
1400 __ Subs(x4, x0, 1);
1401 __ B(lt, &done);
1402 __ Peek(x1, Operand(x4, LSL, kPointerSizeLog2)); // target
1403 __ Subs(x4, x4, 1);
1404 __ B(lt, &done);
1405 __ Peek(x2, Operand(x4, LSL, kPointerSizeLog2)); // thisArgument
1406 __ Subs(x4, x4, 1);
1407 __ B(lt, &done);
1408 __ Peek(x3, Operand(x4, LSL, kPointerSizeLog2)); // argumentsList
1409 __ Bind(&done);
1410 __ Drop(x0);
1411 __ Poke(x2, 0);
1412 __ Mov(x0, x3);
1413 }
1414
1415 // ----------- S t a t e -------------
1416 // -- x0 : argumentsList
1417 // -- x1 : target
1418 // -- sp[0] : thisArgument
1419 // -----------------------------------
1420
1421 // 2. Make sure the target is actually callable.
1422 Label target_not_callable;
1423 __ JumpIfSmi(x1, &target_not_callable);
1424 __ Ldr(x4, FieldMemOperand(x1, HeapObject::kMapOffset));
1425 __ Ldrb(x4, FieldMemOperand(x4, Map::kBitFieldOffset));
1426 __ TestAndBranchIfAllClear(x4, 1 << Map::kIsCallable, &target_not_callable);
1427
1428 // 3a. Apply the target to the given argumentsList (passing undefined for
1429 // new.target).
1430 __ LoadRoot(x3, Heap::kUndefinedValueRootIndex);
1431 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1432
1433 // 3b. The target is not callable, throw an appropriate TypeError.
1434 __ Bind(&target_not_callable);
1435 {
1436 __ Poke(x1, 0);
1437 __ TailCallRuntime(Runtime::kThrowApplyNonFunction, 1, 1);
1438 }
1439 } 1505 }
1440 1506
1441 1507
1442 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) { 1508 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
1443 // ----------- S t a t e -------------
1444 // -- x0 : argc
1445 // -- sp[0] : new.target (optional)
1446 // -- sp[8] : argumentsList
1447 // -- sp[16] : target
1448 // -- sp[24] : receiver
1449 // -----------------------------------
1450 ASM_LOCATION("Builtins::Generate_ReflectConstruct"); 1509 ASM_LOCATION("Builtins::Generate_ReflectConstruct");
1451 1510 Generate_ConstructHelper(masm);
1452 // 1. Load target into x1 (if present), argumentsList into x0 (if present), 1511 }
1453 // new.target into x3 (if present, otherwise use target), remove all 1512
1454 // arguments from the stack (including the receiver), and push thisArgument 1513
1455 // (if present) instead.
1456 {
1457 Label done;
1458 __ LoadRoot(x1, Heap::kUndefinedValueRootIndex);
1459 __ Mov(x2, x1);
1460 __ Poke(x2, Operand(x0, LSL, kPointerSizeLog2)); // receiver
1461 __ Subs(x4, x0, 1);
1462 __ B(lt, &done);
1463 __ Peek(x1, Operand(x4, LSL, kPointerSizeLog2)); // target
1464 __ Mov(x3, x1); // new.target defaults to target
1465 __ Subs(x4, x4, 1);
1466 __ B(lt, &done);
1467 __ Peek(x2, Operand(x4, LSL, kPointerSizeLog2)); // argumentsList
1468 __ Subs(x4, x4, 1);
1469 __ B(lt, &done);
1470 __ Peek(x3, Operand(x4, LSL, kPointerSizeLog2)); // new.target
1471 __ Bind(&done);
1472 __ Drop(x0);
1473 __ Mov(x0, x2);
1474 }
1475
1476 // ----------- S t a t e -------------
1477 // -- x0 : argumentsList
1478 // -- x3 : new.target
1479 // -- x1 : target
1480 // -- sp[0] : receiver (undefined)
1481 // -----------------------------------
1482
1483 // 2. Make sure the target is actually a constructor.
1484 Label target_not_constructor;
1485 __ JumpIfSmi(x1, &target_not_constructor);
1486 __ Ldr(x4, FieldMemOperand(x1, HeapObject::kMapOffset));
1487 __ Ldrb(x4, FieldMemOperand(x4, Map::kBitFieldOffset));
1488 __ TestAndBranchIfAllClear(x4, 1 << Map::kIsConstructor,
1489 &target_not_constructor);
1490
1491 // 3. Make sure the target is actually a constructor.
1492 Label new_target_not_constructor;
1493 __ JumpIfSmi(x3, &new_target_not_constructor);
1494 __ Ldr(x4, FieldMemOperand(x3, HeapObject::kMapOffset));
1495 __ Ldrb(x4, FieldMemOperand(x4, Map::kBitFieldOffset));
1496 __ TestAndBranchIfAllClear(x4, 1 << Map::kIsConstructor,
1497 &new_target_not_constructor);
1498
1499 // 4a. Construct the target with the given new.target and argumentsList.
1500 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1501
1502 // 4b. The target is not a constructor, throw an appropriate TypeError.
1503 __ Bind(&target_not_constructor);
1504 {
1505 __ Poke(x1, 0);
1506 __ TailCallRuntime(Runtime::kThrowCalledNonCallable, 1, 1);
1507 }
1508
1509 // 4c. The new.target is not a constructor, throw an appropriate TypeError.
1510 __ Bind(&new_target_not_constructor);
1511 {
1512 __ Poke(x3, 0);
1513 __ TailCallRuntime(Runtime::kThrowCalledNonCallable, 1, 1);
1514 }
1515 }
1516
1517
1518 static void ArgumentAdaptorStackCheck(MacroAssembler* masm, 1514 static void ArgumentAdaptorStackCheck(MacroAssembler* masm,
1519 Label* stack_overflow) { 1515 Label* stack_overflow) {
1520 // ----------- S t a t e ------------- 1516 // ----------- S t a t e -------------
1521 // -- x0 : actual number of arguments 1517 // -- x0 : actual number of arguments
1522 // -- x1 : function (passed through to callee) 1518 // -- x1 : function (passed through to callee)
1523 // -- x2 : expected number of arguments 1519 // -- x2 : expected number of arguments
1524 // -- x3 : new target (passed through to callee) 1520 // -- x3 : new target (passed through to callee)
1525 // ----------------------------------- 1521 // -----------------------------------
1526 // Check the stack for overflow. 1522 // Check the stack for overflow.
1527 // We are not trying to catch interruptions (e.g. debug break and 1523 // We are not trying to catch interruptions (e.g. debug break and
(...skipping 27 matching lines...) Expand all
1555 // then drop the parameters and the receiver. 1551 // then drop the parameters and the receiver.
1556 __ Ldr(x10, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + 1552 __ Ldr(x10, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp +
1557 kPointerSize))); 1553 kPointerSize)));
1558 __ Mov(jssp, fp); 1554 __ Mov(jssp, fp);
1559 __ Pop(fp, lr); 1555 __ Pop(fp, lr);
1560 __ DropBySMI(x10, kXRegSize); 1556 __ DropBySMI(x10, kXRegSize);
1561 __ Drop(1); 1557 __ Drop(1);
1562 } 1558 }
1563 1559
1564 1560
1565 // static
1566 void Builtins::Generate_Apply(MacroAssembler* masm) {
1567 // ----------- S t a t e -------------
1568 // -- x0 : argumentsList
1569 // -- x1 : target
1570 // -- x3 : new.target (checked to be constructor or undefined)
1571 // -- sp[0] : thisArgument
1572 // -----------------------------------
1573
1574 // Create the list of arguments from the array-like argumentsList.
1575 {
1576 Label create_arguments, create_array, create_runtime, done_create;
1577 __ JumpIfSmi(x0, &create_runtime);
1578
1579 // Load the map of argumentsList into x2.
1580 __ Ldr(x2, FieldMemOperand(x0, HeapObject::kMapOffset));
1581
1582 // Load native context into x4.
1583 __ Ldr(x4, NativeContextMemOperand());
1584
1585 // Check if argumentsList is an (unmodified) arguments object.
1586 __ Ldr(x5, ContextMemOperand(x4, Context::SLOPPY_ARGUMENTS_MAP_INDEX));
1587 __ Cmp(x5, x2);
1588 __ B(eq, &create_arguments);
1589 __ Ldr(x5, ContextMemOperand(x4, Context::STRICT_ARGUMENTS_MAP_INDEX));
1590 __ Cmp(x5, x2);
1591 __ B(eq, &create_arguments);
1592
1593 // Check if argumentsList is a fast JSArray.
1594 __ CompareInstanceType(x2, x4, JS_ARRAY_TYPE);
1595 __ B(eq, &create_array);
1596
1597 // Ask the runtime to create the list (actually a FixedArray).
1598 __ Bind(&create_runtime);
1599 {
1600 FrameScope scope(masm, StackFrame::INTERNAL);
1601 __ Push(x1, x3, x0);
1602 __ CallRuntime(Runtime::kCreateListFromArrayLike, 1);
1603 __ Pop(x3, x1);
1604 __ Ldrsw(x2, UntagSmiFieldMemOperand(x0, FixedArray::kLengthOffset));
1605 }
1606 __ B(&done_create);
1607
1608 // Try to create the list from an arguments object.
1609 __ Bind(&create_arguments);
1610 __ Ldr(x2,
1611 FieldMemOperand(x0, JSObject::kHeaderSize +
1612 Heap::kArgumentsLengthIndex * kPointerSize));
1613 __ Ldr(x4, FieldMemOperand(x0, JSObject::kElementsOffset));
1614 __ Ldr(x5, FieldMemOperand(x4, FixedArray::kLengthOffset));
1615 __ Cmp(x2, x4);
1616 __ B(ne, &create_runtime);
1617 __ SmiUntag(x2);
1618 __ Mov(x0, x4);
1619 __ B(&done_create);
1620
1621 // Try to create the list from a JSArray object.
1622 __ Bind(&create_array);
1623 __ Ldr(x2, FieldMemOperand(x2, Map::kBitField2Offset));
1624 __ DecodeField<Map::ElementsKindBits>(x2);
1625 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
1626 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
1627 STATIC_ASSERT(FAST_ELEMENTS == 2);
1628 __ Cmp(x2, FAST_ELEMENTS);
1629 __ B(hi, &create_runtime);
1630 __ Cmp(x2, FAST_HOLEY_SMI_ELEMENTS);
1631 __ B(eq, &create_runtime);
1632 __ Ldrsw(x2, UntagSmiFieldMemOperand(x0, JSArray::kLengthOffset));
1633 __ Ldr(x0, FieldMemOperand(x0, JSArray::kElementsOffset));
1634
1635 __ Bind(&done_create);
1636 }
1637
1638 // Check for stack overflow.
1639 {
1640 // Check the stack for overflow. We are not trying to catch interruptions
1641 // (i.e. debug break and preemption) here, so check the "real stack limit".
1642 Label done;
1643 __ LoadRoot(x10, Heap::kRealStackLimitRootIndex);
1644 // Make x10 the space we have left. The stack might already be overflowed
1645 // here which will cause x10 to become negative.
1646 __ Sub(x10, jssp, x10);
1647 // Check if the arguments will overflow the stack.
1648 __ Cmp(x10, Operand(x2, LSL, kPointerSizeLog2));
1649 __ B(gt, &done); // Signed comparison.
1650 __ TailCallRuntime(Runtime::kThrowStackOverflow, 1, 1);
1651 __ Bind(&done);
1652 }
1653
1654 // ----------- S t a t e -------------
1655 // -- x1 : target
1656 // -- x0 : args (a FixedArray built from argumentsList)
1657 // -- x2 : len (number of elements to push from args)
1658 // -- x3 : new.target (checked to be constructor or undefined)
1659 // -- sp[0] : thisArgument
1660 // -----------------------------------
1661
1662 // Push arguments onto the stack (thisArgument is already on the stack).
1663 {
1664 __ Mov(x4, 0);
1665 Label done, loop;
1666 __ Bind(&loop);
1667 __ Cmp(x4, x2);
1668 __ B(eq, &done);
1669 __ Add(x10, x0, Operand(x4, LSL, kPointerSizeLog2));
1670 __ Ldr(x10, FieldMemOperand(x10, FixedArray::kHeaderSize));
1671 __ Push(x10);
1672 __ Add(x4, x4, 1);
1673 __ B(&loop);
1674 __ Bind(&done);
1675 __ Mov(x0, x4);
1676 }
1677
1678 // Dispatch to Call or Construct depending on whether new.target is undefined.
1679 {
1680 __ CompareRoot(x3, Heap::kUndefinedValueRootIndex);
1681 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET, eq);
1682 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
1683 }
1684 }
1685
1686
1687 // static 1561 // static
1688 void Builtins::Generate_CallFunction(MacroAssembler* masm, 1562 void Builtins::Generate_CallFunction(MacroAssembler* masm,
1689 ConvertReceiverMode mode) { 1563 ConvertReceiverMode mode) {
1690 // ----------- S t a t e ------------- 1564 // ----------- S t a t e -------------
1691 // -- x0 : the number of arguments (not including the receiver) 1565 // -- x0 : the number of arguments (not including the receiver)
1692 // -- x1 : the function to call (checked to be a JSFunction) 1566 // -- x1 : the function to call (checked to be a JSFunction)
1693 // ----------------------------------- 1567 // -----------------------------------
1694 __ AssertFunction(x1); 1568 __ AssertFunction(x1);
1695 1569
1696 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) 1570 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList)
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after
2165 } 2039 }
2166 } 2040 }
2167 2041
2168 2042
2169 #undef __ 2043 #undef __
2170 2044
2171 } // namespace internal 2045 } // namespace internal
2172 } // namespace v8 2046 } // namespace v8
2173 2047
2174 #endif // V8_TARGET_ARCH_ARM 2048 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/builtins-arm.cc ('k') | src/bootstrapper.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698