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

Side by Side Diff: src/arm/builtins-arm.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 | « no previous file | src/arm64/builtins-arm64.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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_ARM 5 #if V8_TARGET_ARCH_ARM
6 6
7 #include "src/codegen.h" 7 #include "src/codegen.h"
8 #include "src/debug/debug.h" 8 #include "src/debug/debug.h"
9 #include "src/deoptimizer.h" 9 #include "src/deoptimizer.h"
10 #include "src/full-codegen/full-codegen.h" 10 #include "src/full-codegen/full-codegen.h"
(...skipping 1320 matching lines...) Expand 10 before | Expand all | Expand 10 after
1331 // (which is a copy of the last argument). 1331 // (which is a copy of the last argument).
1332 __ sub(r0, r0, Operand(1)); 1332 __ sub(r0, r0, Operand(1));
1333 __ pop(); 1333 __ pop();
1334 } 1334 }
1335 1335
1336 // 4. Call the callable. 1336 // 4. Call the callable.
1337 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 1337 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1338 } 1338 }
1339 1339
1340 1340
1341 static void Generate_PushAppliedArguments(MacroAssembler* masm,
1342 const int vectorOffset,
1343 const int argumentsOffset,
1344 const int indexOffset,
1345 const int limitOffset) {
1346 Label entry, loop;
1347 Register receiver = LoadDescriptor::ReceiverRegister();
1348 Register key = LoadDescriptor::NameRegister();
1349 Register slot = LoadDescriptor::SlotRegister();
1350 Register vector = LoadWithVectorDescriptor::VectorRegister();
1351
1352 __ ldr(key, MemOperand(fp, indexOffset));
1353 __ b(&entry);
1354
1355 // Load the current argument from the arguments array.
1356 __ bind(&loop);
1357 __ ldr(receiver, MemOperand(fp, argumentsOffset));
1358
1359 // Use inline caching to speed up access to arguments.
1360 int slot_index = TypeFeedbackVector::PushAppliedArgumentsIndex();
1361 __ mov(slot, Operand(Smi::FromInt(slot_index)));
1362 __ ldr(vector, MemOperand(fp, vectorOffset));
1363 Handle<Code> ic =
1364 KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode();
1365 __ Call(ic, RelocInfo::CODE_TARGET);
1366
1367 // Push the nth argument.
1368 __ push(r0);
1369
1370 __ ldr(key, MemOperand(fp, indexOffset));
1371 __ add(key, key, Operand(1 << kSmiTagSize));
1372 __ str(key, MemOperand(fp, indexOffset));
1373
1374 // Test if the copy loop has finished copying all the elements from the
1375 // arguments object.
1376 __ bind(&entry);
1377 __ ldr(r1, MemOperand(fp, limitOffset));
1378 __ cmp(key, r1);
1379 __ b(ne, &loop);
1380
1381 // On exit, the pushed arguments count is in r0, untagged
1382 __ mov(r0, key);
1383 __ SmiUntag(r0);
1384 }
1385
1386
1387 // Used by FunctionApply and ReflectApply
1388 static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
1389 const int kFormalParameters = targetIsArgument ? 3 : 2;
1390 const int kStackSize = kFormalParameters + 1;
1391
1392 {
1393 FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL);
1394 const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize;
1395 const int kReceiverOffset = kArgumentsOffset + kPointerSize;
1396 const int kFunctionOffset = kReceiverOffset + kPointerSize;
1397 const int kVectorOffset =
1398 InternalFrameConstants::kCodeOffset - 1 * kPointerSize;
1399
1400 // Push the vector.
1401 __ ldr(r1, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1402 __ ldr(r1, FieldMemOperand(r1, SharedFunctionInfo::kFeedbackVectorOffset));
1403 __ Push(r1);
1404
1405 __ ldr(r0, MemOperand(fp, kFunctionOffset)); // get the function
1406 __ ldr(r1, MemOperand(fp, kArgumentsOffset)); // get the args array
1407 __ Push(r0, r1);
1408 if (targetIsArgument) {
1409 __ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX,
1410 CALL_FUNCTION);
1411 } else {
1412 __ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION);
1413 }
1414
1415 Generate_CheckStackOverflow(masm, r0, kArgcIsSmiTagged);
1416
1417 // Push current limit and index.
1418 const int kIndexOffset = kVectorOffset - (2 * kPointerSize);
1419 const int kLimitOffset = kVectorOffset - (1 * kPointerSize);
1420 __ mov(r1, Operand::Zero());
1421 __ ldr(r2, MemOperand(fp, kReceiverOffset));
1422 __ Push(r0, r1, r2); // limit, initial index and receiver.
1423
1424 // Copy all arguments from the array to the stack.
1425 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset,
1426 kIndexOffset, kLimitOffset);
1427
1428 // Call the callable.
1429 // TODO(bmeurer): This should be a tail call according to ES6.
1430 __ ldr(r1, MemOperand(fp, kFunctionOffset));
1431 __ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1432
1433 // Tear down the internal frame and remove function, receiver and args.
1434 }
1435 __ add(sp, sp, Operand(kStackSize * kPointerSize));
1436 __ Jump(lr);
1437 }
1438
1439
1440 static void Generate_ConstructHelper(MacroAssembler* masm) {
1441 const int kFormalParameters = 3;
1442 const int kStackSize = kFormalParameters + 1;
1443
1444 {
1445 FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL);
1446 const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize;
1447 const int kArgumentsOffset = kNewTargetOffset + kPointerSize;
1448 const int kFunctionOffset = kArgumentsOffset + kPointerSize;
1449 static const int kVectorOffset =
1450 InternalFrameConstants::kCodeOffset - 1 * kPointerSize;
1451
1452 // Push the vector.
1453 __ ldr(r1, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1454 __ ldr(r1, FieldMemOperand(r1, SharedFunctionInfo::kFeedbackVectorOffset));
1455 __ Push(r1);
1456
1457 // If newTarget is not supplied, set it to constructor
1458 Label validate_arguments;
1459 __ ldr(r0, MemOperand(fp, kNewTargetOffset));
1460 __ CompareRoot(r0, Heap::kUndefinedValueRootIndex);
1461 __ b(ne, &validate_arguments);
1462 __ ldr(r0, MemOperand(fp, kFunctionOffset));
1463 __ str(r0, MemOperand(fp, kNewTargetOffset));
1464
1465 // Validate arguments
1466 __ bind(&validate_arguments);
1467 __ ldr(r0, MemOperand(fp, kFunctionOffset)); // get the function
1468 __ push(r0);
1469 __ ldr(r0, MemOperand(fp, kArgumentsOffset)); // get the args array
1470 __ push(r0);
1471 __ ldr(r0, MemOperand(fp, kNewTargetOffset)); // get the new.target
1472 __ push(r0);
1473 __ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX,
1474 CALL_FUNCTION);
1475
1476 Generate_CheckStackOverflow(masm, r0, kArgcIsSmiTagged);
1477
1478 // Push current limit and index.
1479 const int kIndexOffset = kVectorOffset - (2 * kPointerSize);
1480 const int kLimitOffset = kVectorOffset - (1 * kPointerSize);
1481 __ push(r0); // limit
1482 __ mov(r1, Operand::Zero()); // initial index
1483 __ push(r1);
1484 // Push the constructor function as callee.
1485 __ ldr(r0, MemOperand(fp, kFunctionOffset));
1486 __ push(r0);
1487
1488 // Copy all arguments from the array to the stack.
1489 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset,
1490 kIndexOffset, kLimitOffset);
1491
1492 // Use undefined feedback vector
1493 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
1494 __ ldr(r1, MemOperand(fp, kFunctionOffset));
1495 __ ldr(r3, MemOperand(fp, kNewTargetOffset));
1496
1497 // Call the function.
1498 __ Call(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
1499
1500 // Leave internal frame.
1501 }
1502 __ add(sp, sp, Operand(kStackSize * kPointerSize));
1503 __ Jump(lr);
1504 }
1505
1506
1341 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { 1507 void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
1342 // ----------- S t a t e ------------- 1508 Generate_ApplyHelper(masm, false);
1343 // -- r0 : argc
1344 // -- sp[0] : argArray
1345 // -- sp[4] : thisArg
1346 // -- sp[8] : receiver
1347 // -----------------------------------
1348
1349 // 1. Load receiver into r1, argArray into r0 (if present), remove all
1350 // arguments from the stack (including the receiver), and push thisArg (if
1351 // present) instead.
1352 {
1353 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
1354 __ mov(r3, r2);
1355 __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); // receiver
1356 __ sub(r4, r0, Operand(1), SetCC);
1357 __ ldr(r2, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge); // thisArg
1358 __ sub(r4, r4, Operand(1), SetCC, ge);
1359 __ ldr(r3, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge); // argArray
1360 __ add(sp, sp, Operand(r0, LSL, kPointerSizeLog2));
1361 __ str(r2, MemOperand(sp, 0));
1362 __ mov(r0, r3);
1363 }
1364
1365 // ----------- S t a t e -------------
1366 // -- r0 : argArray
1367 // -- r1 : receiver
1368 // -- sp[0] : thisArg
1369 // -----------------------------------
1370
1371 // 2. Make sure the receiver is actually callable.
1372 Label receiver_not_callable;
1373 __ JumpIfSmi(r1, &receiver_not_callable);
1374 __ ldr(r4, FieldMemOperand(r1, HeapObject::kMapOffset));
1375 __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset));
1376 __ tst(r4, Operand(1 << Map::kIsCallable));
1377 __ b(eq, &receiver_not_callable);
1378
1379 // 3. Tail call with no arguments if argArray is null or undefined.
1380 Label no_arguments;
1381 __ JumpIfRoot(r0, Heap::kNullValueRootIndex, &no_arguments);
1382 __ JumpIfRoot(r0, Heap::kUndefinedValueRootIndex, &no_arguments);
1383
1384 // 4a. Apply the receiver to the given argArray (passing undefined for
1385 // new.target).
1386 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex);
1387 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1388
1389 // 4b. The argArray is either null or undefined, so we tail call without any
1390 // arguments to the receiver.
1391 __ bind(&no_arguments);
1392 {
1393 __ mov(r0, Operand(0));
1394 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1395 }
1396
1397 // 4c. The receiver is not callable, throw an appropriate TypeError.
1398 __ bind(&receiver_not_callable);
1399 {
1400 __ str(r1, MemOperand(sp, 0));
1401 __ TailCallRuntime(Runtime::kThrowApplyNonFunction, 1, 1);
1402 }
1403 } 1509 }
1404 1510
1405 1511
1406 void Builtins::Generate_ReflectApply(MacroAssembler* masm) { 1512 void Builtins::Generate_ReflectApply(MacroAssembler* masm) {
1407 // ----------- S t a t e ------------- 1513 Generate_ApplyHelper(masm, true);
1408 // -- r0 : argc
1409 // -- sp[0] : argumentsList
1410 // -- sp[4] : thisArgument
1411 // -- sp[8] : target
1412 // -- sp[12] : receiver
1413 // -----------------------------------
1414
1415 // 1. Load target into r1 (if present), argumentsList into r0 (if present),
1416 // remove all arguments from the stack (including the receiver), and push
1417 // thisArgument (if present) instead.
1418 {
1419 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
1420 __ mov(r2, r1);
1421 __ mov(r3, r1);
1422 __ sub(r4, r0, Operand(1), SetCC);
1423 __ ldr(r1, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge); // target
1424 __ sub(r4, r4, Operand(1), SetCC, ge);
1425 __ ldr(r2, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge); // thisArgument
1426 __ sub(r4, r4, Operand(1), SetCC, ge);
1427 __ ldr(r3, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge); // argumentsList
1428 __ add(sp, sp, Operand(r0, LSL, kPointerSizeLog2));
1429 __ str(r2, MemOperand(sp, 0));
1430 __ mov(r0, r3);
1431 }
1432
1433 // ----------- S t a t e -------------
1434 // -- r0 : argumentsList
1435 // -- r1 : target
1436 // -- sp[0] : thisArgument
1437 // -----------------------------------
1438
1439 // 2. Make sure the target is actually callable.
1440 Label target_not_callable;
1441 __ JumpIfSmi(r1, &target_not_callable);
1442 __ ldr(r4, FieldMemOperand(r1, HeapObject::kMapOffset));
1443 __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset));
1444 __ tst(r4, Operand(1 << Map::kIsCallable));
1445 __ b(eq, &target_not_callable);
1446
1447 // 3a. Apply the target to the given argumentsList (passing undefined for
1448 // new.target).
1449 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex);
1450 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1451
1452 // 3b. The target is not callable, throw an appropriate TypeError.
1453 __ bind(&target_not_callable);
1454 {
1455 __ str(r1, MemOperand(sp, 0));
1456 __ TailCallRuntime(Runtime::kThrowApplyNonFunction, 1, 1);
1457 }
1458 } 1514 }
1459 1515
1460 1516
1461 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) { 1517 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
1462 // ----------- S t a t e ------------- 1518 Generate_ConstructHelper(masm);
1463 // -- r0 : argc
1464 // -- sp[0] : new.target (optional)
1465 // -- sp[4] : argumentsList
1466 // -- sp[8] : target
1467 // -- sp[12] : receiver
1468 // -----------------------------------
1469
1470 // 1. Load target into r1 (if present), argumentsList into r0 (if present),
1471 // new.target into r3 (if present, otherwise use target), remove all
1472 // arguments from the stack (including the receiver), and push thisArgument
1473 // (if present) instead.
1474 {
1475 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
1476 __ mov(r2, r1);
1477 __ str(r2, MemOperand(sp, r0, LSL, kPointerSizeLog2)); // receiver
1478 __ sub(r4, r0, Operand(1), SetCC);
1479 __ ldr(r1, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge); // target
1480 __ mov(r3, r1); // new.target defaults to target
1481 __ sub(r4, r4, Operand(1), SetCC, ge);
1482 __ ldr(r2, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge); // argumentsList
1483 __ sub(r4, r4, Operand(1), SetCC, ge);
1484 __ ldr(r3, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge); // new.target
1485 __ add(sp, sp, Operand(r0, LSL, kPointerSizeLog2));
1486 __ mov(r0, r2);
1487 }
1488
1489 // ----------- S t a t e -------------
1490 // -- r0 : argumentsList
1491 // -- r3 : new.target
1492 // -- r1 : target
1493 // -- sp[0] : receiver (undefined)
1494 // -----------------------------------
1495
1496 // 2. Make sure the target is actually a constructor.
1497 Label target_not_constructor;
1498 __ JumpIfSmi(r1, &target_not_constructor);
1499 __ ldr(r4, FieldMemOperand(r1, HeapObject::kMapOffset));
1500 __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset));
1501 __ tst(r4, Operand(1 << Map::kIsConstructor));
1502 __ b(eq, &target_not_constructor);
1503
1504 // 3. Make sure the target is actually a constructor.
1505 Label new_target_not_constructor;
1506 __ JumpIfSmi(r3, &new_target_not_constructor);
1507 __ ldr(r4, FieldMemOperand(r3, HeapObject::kMapOffset));
1508 __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset));
1509 __ tst(r4, Operand(1 << Map::kIsConstructor));
1510 __ b(eq, &new_target_not_constructor);
1511
1512 // 4a. Construct the target with the given new.target and argumentsList.
1513 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1514
1515 // 4b. The target is not a constructor, throw an appropriate TypeError.
1516 __ bind(&target_not_constructor);
1517 {
1518 __ str(r1, MemOperand(sp, 0));
1519 __ TailCallRuntime(Runtime::kThrowCalledNonCallable, 1, 1);
1520 }
1521
1522 // 4c. The new.target is not a constructor, throw an appropriate TypeError.
1523 __ bind(&new_target_not_constructor);
1524 {
1525 __ str(r3, MemOperand(sp, 0));
1526 __ TailCallRuntime(Runtime::kThrowCalledNonCallable, 1, 1);
1527 }
1528 } 1519 }
1529 1520
1530 1521
1531 static void ArgumentAdaptorStackCheck(MacroAssembler* masm, 1522 static void ArgumentAdaptorStackCheck(MacroAssembler* masm,
1532 Label* stack_overflow) { 1523 Label* stack_overflow) {
1533 // ----------- S t a t e ------------- 1524 // ----------- S t a t e -------------
1534 // -- r0 : actual number of arguments 1525 // -- r0 : actual number of arguments
1535 // -- r1 : function (passed through to callee) 1526 // -- r1 : function (passed through to callee)
1536 // -- r2 : expected number of arguments 1527 // -- r2 : expected number of arguments
1537 // -- r3 : new target (passed through to callee) 1528 // -- r3 : new target (passed through to callee)
(...skipping 30 matching lines...) Expand all
1568 // then tear down the parameters. 1559 // then tear down the parameters.
1569 __ ldr(r1, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + 1560 __ ldr(r1, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp +
1570 kPointerSize))); 1561 kPointerSize)));
1571 1562
1572 __ LeaveFrame(StackFrame::ARGUMENTS_ADAPTOR); 1563 __ LeaveFrame(StackFrame::ARGUMENTS_ADAPTOR);
1573 __ add(sp, sp, Operand::PointerOffsetFromSmiKey(r1)); 1564 __ add(sp, sp, Operand::PointerOffsetFromSmiKey(r1));
1574 __ add(sp, sp, Operand(kPointerSize)); // adjust for receiver 1565 __ add(sp, sp, Operand(kPointerSize)); // adjust for receiver
1575 } 1566 }
1576 1567
1577 1568
1578 // static
1579 void Builtins::Generate_Apply(MacroAssembler* masm) {
1580 // ----------- S t a t e -------------
1581 // -- r0 : argumentsList
1582 // -- r1 : target
1583 // -- r3 : new.target (checked to be constructor or undefined)
1584 // -- sp[0] : thisArgument
1585 // -----------------------------------
1586
1587 // Create the list of arguments from the array-like argumentsList.
1588 {
1589 Label create_arguments, create_array, create_runtime, done_create;
1590 __ JumpIfSmi(r0, &create_runtime);
1591
1592 // Load the map of argumentsList into r2.
1593 __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
1594
1595 // Load native context into r4.
1596 __ ldr(r4, NativeContextMemOperand());
1597
1598 // Check if argumentsList is an (unmodified) arguments object.
1599 __ ldr(ip, ContextMemOperand(r4, Context::SLOPPY_ARGUMENTS_MAP_INDEX));
1600 __ cmp(ip, r2);
1601 __ b(eq, &create_arguments);
1602 __ ldr(ip, ContextMemOperand(r4, Context::STRICT_ARGUMENTS_MAP_INDEX));
1603 __ cmp(ip, r2);
1604 __ b(eq, &create_arguments);
1605
1606 // Check if argumentsList is a fast JSArray.
1607 __ CompareInstanceType(r2, ip, JS_ARRAY_TYPE);
1608 __ b(eq, &create_array);
1609
1610 // Ask the runtime to create the list (actually a FixedArray).
1611 __ bind(&create_runtime);
1612 {
1613 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
1614 __ Push(r1, r3, r0);
1615 __ CallRuntime(Runtime::kCreateListFromArrayLike, 1);
1616 __ Pop(r1, r3);
1617 __ ldr(r2, FieldMemOperand(r0, FixedArray::kLengthOffset));
1618 __ SmiUntag(r2);
1619 }
1620 __ jmp(&done_create);
1621
1622 // Try to create the list from an arguments object.
1623 __ bind(&create_arguments);
1624 __ ldr(r2,
1625 FieldMemOperand(r0, JSObject::kHeaderSize +
1626 Heap::kArgumentsLengthIndex * kPointerSize));
1627 __ ldr(r4, FieldMemOperand(r0, JSObject::kElementsOffset));
1628 __ ldr(ip, FieldMemOperand(r4, FixedArray::kLengthOffset));
1629 __ cmp(r2, ip);
1630 __ b(ne, &create_runtime);
1631 __ SmiUntag(r2);
1632 __ mov(r0, r4);
1633 __ b(&done_create);
1634
1635 // Try to create the list from a JSArray object.
1636 __ bind(&create_array);
1637 __ ldr(r2, FieldMemOperand(r2, Map::kBitField2Offset));
1638 __ DecodeField<Map::ElementsKindBits>(r2);
1639 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
1640 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
1641 STATIC_ASSERT(FAST_ELEMENTS == 2);
1642 __ cmp(r2, Operand(FAST_ELEMENTS));
1643 __ b(hi, &create_runtime);
1644 __ cmp(r2, Operand(FAST_HOLEY_SMI_ELEMENTS));
1645 __ b(eq, &create_runtime);
1646 __ ldr(r2, FieldMemOperand(r0, JSArray::kLengthOffset));
1647 __ ldr(r0, FieldMemOperand(r0, JSArray::kElementsOffset));
1648 __ SmiUntag(r2);
1649
1650 __ bind(&done_create);
1651 }
1652
1653 // Check for stack overflow.
1654 {
1655 // Check the stack for overflow. We are not trying to catch interruptions
1656 // (i.e. debug break and preemption) here, so check the "real stack limit".
1657 Label done;
1658 __ LoadRoot(ip, Heap::kRealStackLimitRootIndex);
1659 // Make ip the space we have left. The stack might already be overflowed
1660 // here which will cause ip to become negative.
1661 __ sub(ip, sp, ip);
1662 // Check if the arguments will overflow the stack.
1663 __ cmp(ip, Operand(r2, LSL, kPointerSizeLog2));
1664 __ b(gt, &done); // Signed comparison.
1665 __ TailCallRuntime(Runtime::kThrowStackOverflow, 1, 1);
1666 __ bind(&done);
1667 }
1668
1669 // ----------- S t a t e -------------
1670 // -- r1 : target
1671 // -- r0 : args (a FixedArray built from argumentsList)
1672 // -- r2 : len (number of elements to push from args)
1673 // -- r3 : new.target (checked to be constructor or undefined)
1674 // -- sp[0] : thisArgument
1675 // -----------------------------------
1676
1677 // Push arguments onto the stack (thisArgument is already on the stack).
1678 {
1679 __ mov(r4, Operand(0));
1680 Label done, loop;
1681 __ bind(&loop);
1682 __ cmp(r4, r2);
1683 __ b(eq, &done);
1684 __ add(ip, r0, Operand(r4, LSL, kPointerSizeLog2));
1685 __ ldr(ip, FieldMemOperand(ip, FixedArray::kHeaderSize));
1686 __ Push(ip);
1687 __ add(r4, r4, Operand(1));
1688 __ b(&loop);
1689 __ bind(&done);
1690 __ Move(r0, r4);
1691 }
1692
1693 // Dispatch to Call or Construct depending on whether new.target is undefined.
1694 {
1695 __ CompareRoot(r3, Heap::kUndefinedValueRootIndex);
1696 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET, eq);
1697 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
1698 }
1699 }
1700
1701
1702 // static 1569 // static
1703 void Builtins::Generate_CallFunction(MacroAssembler* masm, 1570 void Builtins::Generate_CallFunction(MacroAssembler* masm,
1704 ConvertReceiverMode mode) { 1571 ConvertReceiverMode mode) {
1705 // ----------- S t a t e ------------- 1572 // ----------- S t a t e -------------
1706 // -- r0 : the number of arguments (not including the receiver) 1573 // -- r0 : the number of arguments (not including the receiver)
1707 // -- r1 : the function to call (checked to be a JSFunction) 1574 // -- r1 : the function to call (checked to be a JSFunction)
1708 // ----------------------------------- 1575 // -----------------------------------
1709 __ AssertFunction(r1); 1576 __ AssertFunction(r1);
1710 1577
1711 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) 1578 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList)
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
2087 } 1954 }
2088 } 1955 }
2089 1956
2090 1957
2091 #undef __ 1958 #undef __
2092 1959
2093 } // namespace internal 1960 } // namespace internal
2094 } // namespace v8 1961 } // namespace v8
2095 1962
2096 #endif // V8_TARGET_ARCH_ARM 1963 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/arm64/builtins-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698