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

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

Issue 2930623002: [builtins] Start refactoring the Apply builtin. (Closed)
Patch Set: Address feedback. Created 3 years, 6 months 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/builtins/mips64/builtins-mips64.cc ('k') | src/code-factory.h » ('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_X64 5 #if V8_TARGET_ARCH_X64
6 6
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/codegen.h" 8 #include "src/codegen.h"
9 #include "src/counters.h" 9 #include "src/counters.h"
10 #include "src/deoptimizer.h" 10 #include "src/deoptimizer.h"
(...skipping 1469 matching lines...) Expand 10 before | Expand all | Expand 10 after
1480 // static 1480 // static
1481 void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) { 1481 void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) {
1482 // ----------- S t a t e ------------- 1482 // ----------- S t a t e -------------
1483 // -- rax : argc 1483 // -- rax : argc
1484 // -- rsp[0] : return address 1484 // -- rsp[0] : return address
1485 // -- rsp[8] : argArray 1485 // -- rsp[8] : argArray
1486 // -- rsp[16] : thisArg 1486 // -- rsp[16] : thisArg
1487 // -- rsp[24] : receiver 1487 // -- rsp[24] : receiver
1488 // ----------------------------------- 1488 // -----------------------------------
1489 1489
1490 // 1. Load receiver into rdi, argArray into rax (if present), remove all 1490 // 1. Load receiver into rdi, argArray into rbx (if present), remove all
1491 // arguments from the stack (including the receiver), and push thisArg (if 1491 // arguments from the stack (including the receiver), and push thisArg (if
1492 // present) instead. 1492 // present) instead.
1493 { 1493 {
1494 Label no_arg_array, no_this_arg; 1494 Label no_arg_array, no_this_arg;
1495 StackArgumentsAccessor args(rsp, rax); 1495 StackArgumentsAccessor args(rsp, rax);
1496 __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex); 1496 __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex);
1497 __ movp(rbx, rdx); 1497 __ movp(rbx, rdx);
1498 __ movp(rdi, args.GetReceiverOperand()); 1498 __ movp(rdi, args.GetReceiverOperand());
1499 __ testp(rax, rax); 1499 __ testp(rax, rax);
1500 __ j(zero, &no_this_arg, Label::kNear); 1500 __ j(zero, &no_this_arg, Label::kNear);
1501 { 1501 {
1502 __ movp(rdx, args.GetArgumentOperand(1)); 1502 __ movp(rdx, args.GetArgumentOperand(1));
1503 __ cmpp(rax, Immediate(1)); 1503 __ cmpp(rax, Immediate(1));
1504 __ j(equal, &no_arg_array, Label::kNear); 1504 __ j(equal, &no_arg_array, Label::kNear);
1505 __ movp(rbx, args.GetArgumentOperand(2)); 1505 __ movp(rbx, args.GetArgumentOperand(2));
1506 __ bind(&no_arg_array); 1506 __ bind(&no_arg_array);
1507 } 1507 }
1508 __ bind(&no_this_arg); 1508 __ bind(&no_this_arg);
1509 __ PopReturnAddressTo(rcx); 1509 __ PopReturnAddressTo(rcx);
1510 __ leap(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize)); 1510 __ leap(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize));
1511 __ Push(rdx); 1511 __ Push(rdx);
1512 __ PushReturnAddressFrom(rcx); 1512 __ PushReturnAddressFrom(rcx);
1513 __ movp(rax, rbx);
1514 } 1513 }
1515 1514
1516 // ----------- S t a t e ------------- 1515 // ----------- S t a t e -------------
1517 // -- rax : argArray 1516 // -- rbx : argArray
1518 // -- rdi : receiver 1517 // -- rdi : receiver
1519 // -- rsp[0] : return address 1518 // -- rsp[0] : return address
1520 // -- rsp[8] : thisArg 1519 // -- rsp[8] : thisArg
1521 // ----------------------------------- 1520 // -----------------------------------
1522 1521
1523 // 2. Make sure the receiver is actually callable. 1522 // 2. Make sure the receiver is actually callable.
1524 Label receiver_not_callable; 1523 Label receiver_not_callable;
1525 __ JumpIfSmi(rdi, &receiver_not_callable, Label::kNear); 1524 __ JumpIfSmi(rdi, &receiver_not_callable, Label::kNear);
1526 __ movp(rcx, FieldOperand(rdi, HeapObject::kMapOffset)); 1525 __ movp(rcx, FieldOperand(rdi, HeapObject::kMapOffset));
1527 __ testb(FieldOperand(rcx, Map::kBitFieldOffset), 1526 __ testb(FieldOperand(rcx, Map::kBitFieldOffset),
1528 Immediate(1 << Map::kIsCallable)); 1527 Immediate(1 << Map::kIsCallable));
1529 __ j(zero, &receiver_not_callable, Label::kNear); 1528 __ j(zero, &receiver_not_callable, Label::kNear);
1530 1529
1531 // 3. Tail call with no arguments if argArray is null or undefined. 1530 // 3. Tail call with no arguments if argArray is null or undefined.
1532 Label no_arguments; 1531 Label no_arguments;
1533 __ JumpIfRoot(rax, Heap::kNullValueRootIndex, &no_arguments, Label::kNear); 1532 __ JumpIfRoot(rbx, Heap::kNullValueRootIndex, &no_arguments, Label::kNear);
1534 __ JumpIfRoot(rax, Heap::kUndefinedValueRootIndex, &no_arguments, 1533 __ JumpIfRoot(rbx, Heap::kUndefinedValueRootIndex, &no_arguments,
1535 Label::kNear); 1534 Label::kNear);
1536 1535
1537 // 4a. Apply the receiver to the given argArray (passing undefined for 1536 // 4a. Apply the receiver to the given argArray.
1538 // new.target). 1537 __ Jump(masm->isolate()->builtins()->CallWithArrayLike(),
1539 __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex); 1538 RelocInfo::CODE_TARGET);
1540 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1541 1539
1542 // 4b. The argArray is either null or undefined, so we tail call without any 1540 // 4b. The argArray is either null or undefined, so we tail call without any
1543 // arguments to the receiver. Since we did not create a frame for 1541 // arguments to the receiver. Since we did not create a frame for
1544 // Function.prototype.apply() yet, we use a normal Call builtin here. 1542 // Function.prototype.apply() yet, we use a normal Call builtin here.
1545 __ bind(&no_arguments); 1543 __ bind(&no_arguments);
1546 { 1544 {
1547 __ Set(rax, 0); 1545 __ Set(rax, 0);
1548 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 1546 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1549 } 1547 }
1550 1548
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1612 void Builtins::Generate_ReflectApply(MacroAssembler* masm) { 1610 void Builtins::Generate_ReflectApply(MacroAssembler* masm) {
1613 // ----------- S t a t e ------------- 1611 // ----------- S t a t e -------------
1614 // -- rax : argc 1612 // -- rax : argc
1615 // -- rsp[0] : return address 1613 // -- rsp[0] : return address
1616 // -- rsp[8] : argumentsList 1614 // -- rsp[8] : argumentsList
1617 // -- rsp[16] : thisArgument 1615 // -- rsp[16] : thisArgument
1618 // -- rsp[24] : target 1616 // -- rsp[24] : target
1619 // -- rsp[32] : receiver 1617 // -- rsp[32] : receiver
1620 // ----------------------------------- 1618 // -----------------------------------
1621 1619
1622 // 1. Load target into rdi (if present), argumentsList into rax (if present), 1620 // 1. Load target into rdi (if present), argumentsList into rbx (if present),
1623 // remove all arguments from the stack (including the receiver), and push 1621 // remove all arguments from the stack (including the receiver), and push
1624 // thisArgument (if present) instead. 1622 // thisArgument (if present) instead.
1625 { 1623 {
1626 Label done; 1624 Label done;
1627 StackArgumentsAccessor args(rsp, rax); 1625 StackArgumentsAccessor args(rsp, rax);
1628 __ LoadRoot(rdi, Heap::kUndefinedValueRootIndex); 1626 __ LoadRoot(rdi, Heap::kUndefinedValueRootIndex);
1629 __ movp(rdx, rdi); 1627 __ movp(rdx, rdi);
1630 __ movp(rbx, rdi); 1628 __ movp(rbx, rdi);
1631 __ cmpp(rax, Immediate(1)); 1629 __ cmpp(rax, Immediate(1));
1632 __ j(below, &done, Label::kNear); 1630 __ j(below, &done, Label::kNear);
1633 __ movp(rdi, args.GetArgumentOperand(1)); // target 1631 __ movp(rdi, args.GetArgumentOperand(1)); // target
1634 __ j(equal, &done, Label::kNear); 1632 __ j(equal, &done, Label::kNear);
1635 __ movp(rdx, args.GetArgumentOperand(2)); // thisArgument 1633 __ movp(rdx, args.GetArgumentOperand(2)); // thisArgument
1636 __ cmpp(rax, Immediate(3)); 1634 __ cmpp(rax, Immediate(3));
1637 __ j(below, &done, Label::kNear); 1635 __ j(below, &done, Label::kNear);
1638 __ movp(rbx, args.GetArgumentOperand(3)); // argumentsList 1636 __ movp(rbx, args.GetArgumentOperand(3)); // argumentsList
1639 __ bind(&done); 1637 __ bind(&done);
1640 __ PopReturnAddressTo(rcx); 1638 __ PopReturnAddressTo(rcx);
1641 __ leap(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize)); 1639 __ leap(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize));
1642 __ Push(rdx); 1640 __ Push(rdx);
1643 __ PushReturnAddressFrom(rcx); 1641 __ PushReturnAddressFrom(rcx);
1644 __ movp(rax, rbx);
1645 } 1642 }
1646 1643
1647 // ----------- S t a t e ------------- 1644 // ----------- S t a t e -------------
1648 // -- rax : argumentsList 1645 // -- rbx : argumentsList
1649 // -- rdi : target 1646 // -- rdi : target
1650 // -- rsp[0] : return address 1647 // -- rsp[0] : return address
1651 // -- rsp[8] : thisArgument 1648 // -- rsp[8] : thisArgument
1652 // ----------------------------------- 1649 // -----------------------------------
1653 1650
1654 // 2. Make sure the target is actually callable. 1651 // 2. Make sure the target is actually callable.
1655 Label target_not_callable; 1652 Label target_not_callable;
1656 __ JumpIfSmi(rdi, &target_not_callable, Label::kNear); 1653 __ JumpIfSmi(rdi, &target_not_callable, Label::kNear);
1657 __ movp(rcx, FieldOperand(rdi, HeapObject::kMapOffset)); 1654 __ movp(rcx, FieldOperand(rdi, HeapObject::kMapOffset));
1658 __ testb(FieldOperand(rcx, Map::kBitFieldOffset), 1655 __ testb(FieldOperand(rcx, Map::kBitFieldOffset),
1659 Immediate(1 << Map::kIsCallable)); 1656 Immediate(1 << Map::kIsCallable));
1660 __ j(zero, &target_not_callable, Label::kNear); 1657 __ j(zero, &target_not_callable, Label::kNear);
1661 1658
1662 // 3a. Apply the target to the given argumentsList (passing undefined for 1659 // 3a. Apply the target to the given argumentsList.
1663 // new.target). 1660 __ Jump(masm->isolate()->builtins()->CallWithArrayLike(),
1664 __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex); 1661 RelocInfo::CODE_TARGET);
1665 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1666 1662
1667 // 3b. The target is not callable, throw an appropriate TypeError. 1663 // 3b. The target is not callable, throw an appropriate TypeError.
1668 __ bind(&target_not_callable); 1664 __ bind(&target_not_callable);
1669 { 1665 {
1670 StackArgumentsAccessor args(rsp, 0); 1666 StackArgumentsAccessor args(rsp, 0);
1671 __ movp(args.GetReceiverOperand(), rdi); 1667 __ movp(args.GetReceiverOperand(), rdi);
1672 __ TailCallRuntime(Runtime::kThrowApplyNonFunction); 1668 __ TailCallRuntime(Runtime::kThrowApplyNonFunction);
1673 } 1669 }
1674 } 1670 }
1675 1671
1676 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) { 1672 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
1677 // ----------- S t a t e ------------- 1673 // ----------- S t a t e -------------
1678 // -- rax : argc 1674 // -- rax : argc
1679 // -- rsp[0] : return address 1675 // -- rsp[0] : return address
1680 // -- rsp[8] : new.target (optional) 1676 // -- rsp[8] : new.target (optional)
1681 // -- rsp[16] : argumentsList 1677 // -- rsp[16] : argumentsList
1682 // -- rsp[24] : target 1678 // -- rsp[24] : target
1683 // -- rsp[32] : receiver 1679 // -- rsp[32] : receiver
1684 // ----------------------------------- 1680 // -----------------------------------
1685 1681
1686 // 1. Load target into rdi (if present), argumentsList into rax (if present), 1682 // 1. Load target into rdi (if present), argumentsList into rbx (if present),
1687 // new.target into rdx (if present, otherwise use target), remove all 1683 // new.target into rdx (if present, otherwise use target), remove all
1688 // arguments from the stack (including the receiver), and push thisArgument 1684 // arguments from the stack (including the receiver), and push thisArgument
1689 // (if present) instead. 1685 // (if present) instead.
1690 { 1686 {
1691 Label done; 1687 Label done;
1692 StackArgumentsAccessor args(rsp, rax); 1688 StackArgumentsAccessor args(rsp, rax);
1693 __ LoadRoot(rdi, Heap::kUndefinedValueRootIndex); 1689 __ LoadRoot(rdi, Heap::kUndefinedValueRootIndex);
1694 __ movp(rdx, rdi); 1690 __ movp(rdx, rdi);
1695 __ movp(rbx, rdi); 1691 __ movp(rbx, rdi);
1696 __ cmpp(rax, Immediate(1)); 1692 __ cmpp(rax, Immediate(1));
1697 __ j(below, &done, Label::kNear); 1693 __ j(below, &done, Label::kNear);
1698 __ movp(rdi, args.GetArgumentOperand(1)); // target 1694 __ movp(rdi, args.GetArgumentOperand(1)); // target
1699 __ movp(rdx, rdi); // new.target defaults to target 1695 __ movp(rdx, rdi); // new.target defaults to target
1700 __ j(equal, &done, Label::kNear); 1696 __ j(equal, &done, Label::kNear);
1701 __ movp(rbx, args.GetArgumentOperand(2)); // argumentsList 1697 __ movp(rbx, args.GetArgumentOperand(2)); // argumentsList
1702 __ cmpp(rax, Immediate(3)); 1698 __ cmpp(rax, Immediate(3));
1703 __ j(below, &done, Label::kNear); 1699 __ j(below, &done, Label::kNear);
1704 __ movp(rdx, args.GetArgumentOperand(3)); // new.target 1700 __ movp(rdx, args.GetArgumentOperand(3)); // new.target
1705 __ bind(&done); 1701 __ bind(&done);
1706 __ PopReturnAddressTo(rcx); 1702 __ PopReturnAddressTo(rcx);
1707 __ leap(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize)); 1703 __ leap(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize));
1708 __ PushRoot(Heap::kUndefinedValueRootIndex); 1704 __ PushRoot(Heap::kUndefinedValueRootIndex);
1709 __ PushReturnAddressFrom(rcx); 1705 __ PushReturnAddressFrom(rcx);
1710 __ movp(rax, rbx);
1711 } 1706 }
1712 1707
1713 // ----------- S t a t e ------------- 1708 // ----------- S t a t e -------------
1714 // -- rax : argumentsList 1709 // -- rbx : argumentsList
1715 // -- rdx : new.target 1710 // -- rdx : new.target
1716 // -- rdi : target 1711 // -- rdi : target
1717 // -- rsp[0] : return address 1712 // -- rsp[0] : return address
1718 // -- rsp[8] : receiver (undefined) 1713 // -- rsp[8] : receiver (undefined)
1719 // ----------------------------------- 1714 // -----------------------------------
1720 1715
1721 // 2. Make sure the target is actually a constructor. 1716 // 2. Make sure the target is actually a constructor.
1722 Label target_not_constructor; 1717 Label target_not_constructor;
1723 __ JumpIfSmi(rdi, &target_not_constructor, Label::kNear); 1718 __ JumpIfSmi(rdi, &target_not_constructor, Label::kNear);
1724 __ movp(rcx, FieldOperand(rdi, HeapObject::kMapOffset)); 1719 __ movp(rcx, FieldOperand(rdi, HeapObject::kMapOffset));
1725 __ testb(FieldOperand(rcx, Map::kBitFieldOffset), 1720 __ testb(FieldOperand(rcx, Map::kBitFieldOffset),
1726 Immediate(1 << Map::kIsConstructor)); 1721 Immediate(1 << Map::kIsConstructor));
1727 __ j(zero, &target_not_constructor, Label::kNear); 1722 __ j(zero, &target_not_constructor, Label::kNear);
1728 1723
1729 // 3. Make sure the target is actually a constructor. 1724 // 3. Make sure the target is actually a constructor.
1730 Label new_target_not_constructor; 1725 Label new_target_not_constructor;
1731 __ JumpIfSmi(rdx, &new_target_not_constructor, Label::kNear); 1726 __ JumpIfSmi(rdx, &new_target_not_constructor, Label::kNear);
1732 __ movp(rcx, FieldOperand(rdx, HeapObject::kMapOffset)); 1727 __ movp(rcx, FieldOperand(rdx, HeapObject::kMapOffset));
1733 __ testb(FieldOperand(rcx, Map::kBitFieldOffset), 1728 __ testb(FieldOperand(rcx, Map::kBitFieldOffset),
1734 Immediate(1 << Map::kIsConstructor)); 1729 Immediate(1 << Map::kIsConstructor));
1735 __ j(zero, &new_target_not_constructor, Label::kNear); 1730 __ j(zero, &new_target_not_constructor, Label::kNear);
1736 1731
1737 // 4a. Construct the target with the given new.target and argumentsList. 1732 // 4a. Construct the target with the given new.target and argumentsList.
1738 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); 1733 __ Jump(masm->isolate()->builtins()->ConstructWithArrayLike(),
1734 RelocInfo::CODE_TARGET);
1739 1735
1740 // 4b. The target is not a constructor, throw an appropriate TypeError. 1736 // 4b. The target is not a constructor, throw an appropriate TypeError.
1741 __ bind(&target_not_constructor); 1737 __ bind(&target_not_constructor);
1742 { 1738 {
1743 StackArgumentsAccessor args(rsp, 0); 1739 StackArgumentsAccessor args(rsp, 0);
1744 __ movp(args.GetReceiverOperand(), rdi); 1740 __ movp(args.GetReceiverOperand(), rdi);
1745 __ TailCallRuntime(Runtime::kThrowNotConstructor); 1741 __ TailCallRuntime(Runtime::kThrowNotConstructor);
1746 } 1742 }
1747 1743
1748 // 4c. The new.target is not a constructor, throw an appropriate TypeError. 1744 // 4c. The new.target is not a constructor, throw an appropriate TypeError.
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after
2266 2262
2267 __ bind(&stack_overflow); 2263 __ bind(&stack_overflow);
2268 { 2264 {
2269 FrameScope frame(masm, StackFrame::MANUAL); 2265 FrameScope frame(masm, StackFrame::MANUAL);
2270 __ CallRuntime(Runtime::kThrowStackOverflow); 2266 __ CallRuntime(Runtime::kThrowStackOverflow);
2271 __ int3(); 2267 __ int3();
2272 } 2268 }
2273 } 2269 }
2274 2270
2275 // static 2271 // static
2276 void Builtins::Generate_Apply(MacroAssembler* masm) { 2272 void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm,
2273 Handle<Code> code) {
2277 // ----------- S t a t e ------------- 2274 // ----------- S t a t e -------------
2278 // -- rax : argumentsList
2279 // -- rdi : target 2275 // -- rdi : target
2280 // -- rdx : new.target (checked to be constructor or undefined) 2276 // -- rax : number of parameters on the stack (not including the receiver)
2281 // -- rsp[0] : return address. 2277 // -- rbx : arguments list (a FixedArray)
2282 // -- rsp[8] : thisArgument 2278 // -- rcx : len (number of elements to push from args)
2279 // -- rdx : new.target (for [[Construct]])
2280 // -- rsp[0] : return address
2283 // ----------------------------------- 2281 // -----------------------------------
2284 2282 __ AssertFixedArray(rbx);
2285 // Create the list of arguments from the array-like argumentsList.
2286 {
2287 Label create_arguments, create_array, create_holey_array, create_runtime,
2288 done_create;
2289 __ JumpIfSmi(rax, &create_runtime);
2290
2291 // Load the map of argumentsList into rcx.
2292 __ movp(rcx, FieldOperand(rax, HeapObject::kMapOffset));
2293
2294 // Load native context into rbx.
2295 __ movp(rbx, NativeContextOperand());
2296
2297 // Check if argumentsList is an (unmodified) arguments object.
2298 __ cmpp(rcx, ContextOperand(rbx, Context::SLOPPY_ARGUMENTS_MAP_INDEX));
2299 __ j(equal, &create_arguments);
2300 __ cmpp(rcx, ContextOperand(rbx, Context::STRICT_ARGUMENTS_MAP_INDEX));
2301 __ j(equal, &create_arguments);
2302
2303 // Check if argumentsList is a fast JSArray.
2304 __ CmpInstanceType(rcx, JS_ARRAY_TYPE);
2305 __ j(equal, &create_array);
2306
2307 // Ask the runtime to create the list (actually a FixedArray).
2308 __ bind(&create_runtime);
2309 {
2310 FrameScope scope(masm, StackFrame::INTERNAL);
2311 __ Push(rdi);
2312 __ Push(rdx);
2313 __ Push(rax);
2314 __ CallRuntime(Runtime::kCreateListFromArrayLike);
2315 __ Pop(rdx);
2316 __ Pop(rdi);
2317 __ SmiToInteger32(rbx, FieldOperand(rax, FixedArray::kLengthOffset));
2318 }
2319 __ jmp(&done_create);
2320
2321 // Try to create the list from an arguments object.
2322 __ bind(&create_arguments);
2323 __ movp(rbx, FieldOperand(rax, JSArgumentsObject::kLengthOffset));
2324 __ movp(rcx, FieldOperand(rax, JSObject::kElementsOffset));
2325 __ cmpp(rbx, FieldOperand(rcx, FixedArray::kLengthOffset));
2326 __ j(not_equal, &create_runtime);
2327 __ SmiToInteger32(rbx, rbx);
2328 __ movp(rax, rcx);
2329 __ jmp(&done_create);
2330
2331 __ bind(&create_holey_array);
2332 // For holey JSArrays we need to check that the array prototype chain
2333 // protector is intact and our prototype is the Array.prototype actually.
2334 __ movp(rcx, FieldOperand(rax, HeapObject::kMapOffset));
2335 __ movp(rcx, FieldOperand(rcx, Map::kPrototypeOffset));
2336 __ cmpp(rcx, ContextOperand(rbx, Context::INITIAL_ARRAY_PROTOTYPE_INDEX));
2337 __ j(not_equal, &create_runtime);
2338 __ LoadRoot(rcx, Heap::kArrayProtectorRootIndex);
2339 __ Cmp(FieldOperand(rcx, PropertyCell::kValueOffset),
2340 Smi::FromInt(Isolate::kProtectorValid));
2341 __ j(not_equal, &create_runtime);
2342 __ SmiToInteger32(rbx, FieldOperand(rax, JSArray::kLengthOffset));
2343 __ movp(rax, FieldOperand(rax, JSArray::kElementsOffset));
2344 __ jmp(&done_create);
2345
2346 // Try to create the list from a JSArray object.
2347 __ bind(&create_array);
2348 __ movzxbp(rcx, FieldOperand(rcx, Map::kBitField2Offset));
2349 __ DecodeField<Map::ElementsKindBits>(rcx);
2350 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
2351 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
2352 STATIC_ASSERT(FAST_ELEMENTS == 2);
2353 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
2354 __ cmpl(rcx, Immediate(FAST_HOLEY_SMI_ELEMENTS));
2355 __ j(equal, &create_holey_array);
2356 __ cmpl(rcx, Immediate(FAST_HOLEY_ELEMENTS));
2357 __ j(equal, &create_holey_array);
2358 __ j(above, &create_runtime);
2359 __ SmiToInteger32(rbx, FieldOperand(rax, JSArray::kLengthOffset));
2360 __ movp(rax, FieldOperand(rax, JSArray::kElementsOffset));
2361
2362 __ bind(&done_create);
2363 }
2364 2283
2365 // Check for stack overflow. 2284 // Check for stack overflow.
2366 { 2285 {
2367 // Check the stack for overflow. We are not trying to catch interruptions 2286 // Check the stack for overflow. We are not trying to catch interruptions
2368 // (i.e. debug break and preemption) here, so check the "real stack limit". 2287 // (i.e. debug break and preemption) here, so check the "real stack limit".
2369 Label done; 2288 Label done;
2370 __ LoadRoot(kScratchRegister, Heap::kRealStackLimitRootIndex); 2289 __ LoadRoot(kScratchRegister, Heap::kRealStackLimitRootIndex);
2371 __ movp(rcx, rsp); 2290 __ movp(r8, rsp);
2372 // Make rcx the space we have left. The stack might already be overflowed 2291 // Make r8 the space we have left. The stack might already be overflowed
2373 // here which will cause rcx to become negative. 2292 // here which will cause r8 to become negative.
2374 __ subp(rcx, kScratchRegister); 2293 __ subp(r8, kScratchRegister);
2375 __ sarp(rcx, Immediate(kPointerSizeLog2)); 2294 __ sarp(r8, Immediate(kPointerSizeLog2));
2376 // Check if the arguments will overflow the stack. 2295 // Check if the arguments will overflow the stack.
2377 __ cmpp(rcx, rbx); 2296 __ cmpp(r8, rcx);
2378 __ j(greater, &done, Label::kNear); // Signed comparison. 2297 __ j(greater, &done, Label::kNear); // Signed comparison.
2379 __ TailCallRuntime(Runtime::kThrowStackOverflow); 2298 __ TailCallRuntime(Runtime::kThrowStackOverflow);
2380 __ bind(&done); 2299 __ bind(&done);
2381 } 2300 }
2382 2301
2383 // ----------- S t a t e ------------- 2302 // Push additional arguments onto the stack.
2384 // -- rdi : target
2385 // -- rax : args (a FixedArray built from argumentsList)
2386 // -- rbx : len (number of elements to push from args)
2387 // -- rdx : new.target (checked to be constructor or undefined)
2388 // -- rsp[0] : return address.
2389 // -- rsp[8] : thisArgument
2390 // -----------------------------------
2391
2392 // Push arguments onto the stack (thisArgument is already on the stack).
2393 { 2303 {
2394 __ PopReturnAddressTo(r8); 2304 __ PopReturnAddressTo(r8);
2395 __ Set(rcx, 0); 2305 __ Set(r9, 0);
2396 Label done, push, loop; 2306 Label done, push, loop;
2397 __ bind(&loop); 2307 __ bind(&loop);
2398 __ cmpl(rcx, rbx); 2308 __ cmpl(r9, rcx);
2399 __ j(equal, &done, Label::kNear); 2309 __ j(equal, &done, Label::kNear);
2400 // Turn the hole into undefined as we go. 2310 // Turn the hole into undefined as we go.
2401 __ movp(r9, FieldOperand(rax, rcx, times_pointer_size, 2311 __ movp(r11,
2402 FixedArray::kHeaderSize)); 2312 FieldOperand(rbx, r9, times_pointer_size, FixedArray::kHeaderSize));
2403 __ CompareRoot(r9, Heap::kTheHoleValueRootIndex); 2313 __ CompareRoot(r11, Heap::kTheHoleValueRootIndex);
2404 __ j(not_equal, &push, Label::kNear); 2314 __ j(not_equal, &push, Label::kNear);
2405 __ LoadRoot(r9, Heap::kUndefinedValueRootIndex); 2315 __ LoadRoot(r11, Heap::kUndefinedValueRootIndex);
2406 __ bind(&push); 2316 __ bind(&push);
2407 __ Push(r9); 2317 __ Push(r11);
2408 __ incl(rcx); 2318 __ incl(r9);
2409 __ jmp(&loop); 2319 __ jmp(&loop);
2410 __ bind(&done); 2320 __ bind(&done);
2411 __ PushReturnAddressFrom(r8); 2321 __ PushReturnAddressFrom(r8);
2412 __ Move(rax, rcx); 2322 __ addq(rax, r9);
2413 } 2323 }
2414 2324
2415 // Dispatch to Call or Construct depending on whether new.target is undefined. 2325 // Tail-call to the actual Call or Construct builtin.
2416 { 2326 __ Jump(code, RelocInfo::CODE_TARGET);
2417 __ CompareRoot(rdx, Heap::kUndefinedValueRootIndex);
2418 __ j(equal, masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
2419 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
2420 }
2421 } 2327 }
2422 2328
2423 // static 2329 // static
2424 void Builtins::Generate_ForwardVarargs(MacroAssembler* masm, 2330 void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm,
2425 Handle<Code> code) { 2331 Handle<Code> code) {
2426 // ----------- S t a t e ------------- 2332 // ----------- S t a t e -------------
2427 // -- rax : the number of arguments (not including the receiver) 2333 // -- rax : the number of arguments (not including the receiver)
2428 // -- rdx : the new target (for [[Construct]] calls) 2334 // -- rdx : the new target (for [[Construct]] calls)
2429 // -- rdi : the target to call (can be any Object) 2335 // -- rdi : the target to call (can be any Object)
2430 // -- rcx : start index (to support rest parameters) 2336 // -- rcx : start index (to support rest parameters)
2431 // ----------------------------------- 2337 // -----------------------------------
2432 2338
2433 // Check if we have an arguments adaptor frame below the function frame. 2339 // Check if we have an arguments adaptor frame below the function frame.
2434 Label arguments_adaptor, arguments_done; 2340 Label arguments_adaptor, arguments_done;
2435 __ movp(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 2341 __ movp(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
(...skipping 804 matching lines...) Expand 10 before | Expand all | Expand 10 after
3240 // Now jump to the instructions of the returned code object. 3146 // Now jump to the instructions of the returned code object.
3241 __ jmp(r11); 3147 __ jmp(r11);
3242 } 3148 }
3243 3149
3244 #undef __ 3150 #undef __
3245 3151
3246 } // namespace internal 3152 } // namespace internal
3247 } // namespace v8 3153 } // namespace v8
3248 3154
3249 #endif // V8_TARGET_ARCH_X64 3155 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/builtins/mips64/builtins-mips64.cc ('k') | src/code-factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698