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

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

Issue 1436493002: [builtins] Introduce specialized Call/CallFunction builtins. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 1 month 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/builtins.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 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 1536 matching lines...) Expand 10 before | Expand all | Expand 10 after
1547 __ Ldr(x10, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + 1547 __ Ldr(x10, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp +
1548 kPointerSize))); 1548 kPointerSize)));
1549 __ Mov(jssp, fp); 1549 __ Mov(jssp, fp);
1550 __ Pop(fp, lr); 1550 __ Pop(fp, lr);
1551 __ DropBySMI(x10, kXRegSize); 1551 __ DropBySMI(x10, kXRegSize);
1552 __ Drop(1); 1552 __ Drop(1);
1553 } 1553 }
1554 1554
1555 1555
1556 // static 1556 // static
1557 void Builtins::Generate_CallFunction(MacroAssembler* masm) { 1557 void Builtins::Generate_CallFunction(MacroAssembler* masm,
1558 ConvertReceiverMode mode) {
1558 // ----------- S t a t e ------------- 1559 // ----------- S t a t e -------------
1559 // -- x0 : the number of arguments (not including the receiver) 1560 // -- x0 : the number of arguments (not including the receiver)
1560 // -- x1 : the function to call (checked to be a JSFunction) 1561 // -- x1 : the function to call (checked to be a JSFunction)
1561 // ----------------------------------- 1562 // -----------------------------------
1562 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList)
1563
1564 Label convert, convert_global_proxy, convert_to_object, done_convert;
1565 __ AssertFunction(x1); 1563 __ AssertFunction(x1);
1566 1564
1565 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList)
1566 // Check that function is not a "classConstructor".
1567 Label class_constructor;
1567 __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); 1568 __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
1568 { 1569 __ Ldr(w3, FieldMemOperand(x2, SharedFunctionInfo::kCompilerHintsOffset));
1569 Label non_class_constructor; 1570 __ TestAndBranchIfAnySet(
1570 // Check whether the current function is a classConstructor 1571 w3, (1 << SharedFunctionInfo::kIsDefaultConstructor) |
1571 __ Ldr(w3, FieldMemOperand(x2, SharedFunctionInfo::kCompilerHintsOffset)); 1572 (1 << SharedFunctionInfo::kIsSubclassConstructor) |
1572 __ TestAndBranchIfAllClear( 1573 (1 << SharedFunctionInfo::kIsBaseConstructor),
1573 w3, (1 << SharedFunctionInfo::kIsDefaultConstructor) | 1574 &class_constructor);
1574 (1 << SharedFunctionInfo::kIsSubclassConstructor) |
1575 (1 << SharedFunctionInfo::kIsBaseConstructor),
1576 &non_class_constructor);
1577 // Step: 2, If we call a classConstructor Function throw a TypeError.
1578 {
1579 FrameScope frame(masm, StackFrame::INTERNAL);
1580 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0);
1581 }
1582 __ bind(&non_class_constructor);
1583 }
1584 1575
1585 // Enter the context of the function; ToObject has to run in the function 1576 // Enter the context of the function; ToObject has to run in the function
1586 // context, and we also need to take the global proxy from the function 1577 // context, and we also need to take the global proxy from the function
1587 // context in case of conversion. 1578 // context in case of conversion.
1588 __ Ldr(cp, FieldMemOperand(x1, JSFunction::kContextOffset)); 1579 __ Ldr(cp, FieldMemOperand(x1, JSFunction::kContextOffset));
1589 // We need to convert the receiver for non-native sloppy mode functions. 1580 // We need to convert the receiver for non-native sloppy mode functions.
1581 Label done_convert;
1590 __ TestAndBranchIfAnySet(w3, 1582 __ TestAndBranchIfAnySet(w3,
1591 (1 << SharedFunctionInfo::kNative) | 1583 (1 << SharedFunctionInfo::kNative) |
1592 (1 << SharedFunctionInfo::kStrictModeFunction), 1584 (1 << SharedFunctionInfo::kStrictModeFunction),
1593 &done_convert); 1585 &done_convert);
1594 { 1586 {
1595 __ Peek(x3, Operand(x0, LSL, kXRegSizeLog2));
1596
1597 // ----------- S t a t e ------------- 1587 // ----------- S t a t e -------------
1598 // -- x0 : the number of arguments (not including the receiver) 1588 // -- x0 : the number of arguments (not including the receiver)
1599 // -- x1 : the function to call (checked to be a JSFunction) 1589 // -- x1 : the function to call (checked to be a JSFunction)
1600 // -- x2 : the shared function info. 1590 // -- x2 : the shared function info.
1601 // -- x3 : the receiver
1602 // -- cp : the function context. 1591 // -- cp : the function context.
1603 // ----------------------------------- 1592 // -----------------------------------
1604 1593
1605 Label convert_receiver; 1594 if (mode == ConvertReceiverMode::kNullOrUndefined) {
1606 __ JumpIfSmi(x3, &convert_to_object);
1607 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
1608 __ CompareObjectType(x3, x4, x4, FIRST_JS_RECEIVER_TYPE);
1609 __ B(hs, &done_convert);
1610 __ JumpIfRoot(x3, Heap::kUndefinedValueRootIndex, &convert_global_proxy);
1611 __ JumpIfNotRoot(x3, Heap::kNullValueRootIndex, &convert_to_object);
1612 __ Bind(&convert_global_proxy);
1613 {
1614 // Patch receiver to global proxy. 1595 // Patch receiver to global proxy.
1615 __ LoadGlobalProxy(x3); 1596 __ LoadGlobalProxy(x3);
1597 } else {
1598 Label convert_to_object, convert_receiver;
1599 __ Peek(x3, Operand(x0, LSL, kXRegSizeLog2));
1600 __ JumpIfSmi(x3, &convert_to_object);
1601 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
1602 __ CompareObjectType(x3, x4, x4, FIRST_JS_RECEIVER_TYPE);
1603 __ B(hs, &done_convert);
1604 if (mode != ConvertReceiverMode::kNotNullOrUndefined) {
1605 Label convert_global_proxy;
1606 __ JumpIfRoot(x3, Heap::kUndefinedValueRootIndex,
1607 &convert_global_proxy);
1608 __ JumpIfNotRoot(x3, Heap::kNullValueRootIndex, &convert_to_object);
1609 __ Bind(&convert_global_proxy);
1610 {
1611 // Patch receiver to global proxy.
1612 __ LoadGlobalProxy(x3);
1613 }
1614 __ B(&convert_receiver);
1615 }
1616 __ Bind(&convert_to_object);
1617 {
1618 // Convert receiver using ToObject.
1619 // TODO(bmeurer): Inline the allocation here to avoid building the frame
1620 // in the fast case? (fall back to AllocateInNewSpace?)
1621 FrameScope scope(masm, StackFrame::INTERNAL);
1622 __ SmiTag(x0);
1623 __ Push(x0, x1);
1624 __ Mov(x0, x3);
1625 ToObjectStub stub(masm->isolate());
1626 __ CallStub(&stub);
1627 __ Mov(x3, x0);
1628 __ Pop(x1, x0);
1629 __ SmiUntag(x0);
1630 }
1631 __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
1632 __ Bind(&convert_receiver);
1616 } 1633 }
1617 __ B(&convert_receiver);
1618 __ Bind(&convert_to_object);
1619 {
1620 // Convert receiver using ToObject.
1621 // TODO(bmeurer): Inline the allocation here to avoid building the frame
1622 // in the fast case? (fall back to AllocateInNewSpace?)
1623 FrameScope scope(masm, StackFrame::INTERNAL);
1624 __ SmiTag(x0);
1625 __ Push(x0, x1);
1626 __ Mov(x0, x3);
1627 ToObjectStub stub(masm->isolate());
1628 __ CallStub(&stub);
1629 __ Mov(x3, x0);
1630 __ Pop(x1, x0);
1631 __ SmiUntag(x0);
1632 }
1633 __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
1634 __ Bind(&convert_receiver);
1635 __ Poke(x3, Operand(x0, LSL, kXRegSizeLog2)); 1634 __ Poke(x3, Operand(x0, LSL, kXRegSizeLog2));
1636 } 1635 }
1637 __ Bind(&done_convert); 1636 __ Bind(&done_convert);
1638 1637
1639 // ----------- S t a t e ------------- 1638 // ----------- S t a t e -------------
1640 // -- x0 : the number of arguments (not including the receiver) 1639 // -- x0 : the number of arguments (not including the receiver)
1641 // -- x1 : the function to call (checked to be a JSFunction) 1640 // -- x1 : the function to call (checked to be a JSFunction)
1642 // -- x2 : the shared function info. 1641 // -- x2 : the shared function info.
1643 // -- cp : the function context. 1642 // -- cp : the function context.
1644 // ----------------------------------- 1643 // -----------------------------------
1645 1644
1646 __ Ldrsw( 1645 __ Ldrsw(
1647 x2, FieldMemOperand(x2, SharedFunctionInfo::kFormalParameterCountOffset)); 1646 x2, FieldMemOperand(x2, SharedFunctionInfo::kFormalParameterCountOffset));
1648 __ Ldr(x3, FieldMemOperand(x1, JSFunction::kCodeEntryOffset)); 1647 __ Ldr(x3, FieldMemOperand(x1, JSFunction::kCodeEntryOffset));
1649 ParameterCount actual(x0); 1648 ParameterCount actual(x0);
1650 ParameterCount expected(x2); 1649 ParameterCount expected(x2);
1651 __ InvokeCode(x3, expected, actual, JUMP_FUNCTION, NullCallWrapper()); 1650 __ InvokeCode(x3, expected, actual, JUMP_FUNCTION, NullCallWrapper());
1651
1652 // The function is a "classConstructor", need to raise an exception.
1653 __ bind(&class_constructor);
1654 {
1655 FrameScope frame(masm, StackFrame::INTERNAL);
1656 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0);
1657 }
1652 } 1658 }
1653 1659
1654 1660
1655 // static 1661 // static
1656 void Builtins::Generate_Call(MacroAssembler* masm) { 1662 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
1657 // ----------- S t a t e ------------- 1663 // ----------- S t a t e -------------
1658 // -- x0 : the number of arguments (not including the receiver) 1664 // -- x0 : the number of arguments (not including the receiver)
1659 // -- x1 : the target to call (can be any Object). 1665 // -- x1 : the target to call (can be any Object).
1660 // ----------------------------------- 1666 // -----------------------------------
1661 1667
1662 Label non_callable, non_function, non_smi; 1668 Label non_callable, non_function, non_smi;
1663 __ JumpIfSmi(x1, &non_callable); 1669 __ JumpIfSmi(x1, &non_callable);
1664 __ Bind(&non_smi); 1670 __ Bind(&non_smi);
1665 __ CompareObjectType(x1, x4, x5, JS_FUNCTION_TYPE); 1671 __ CompareObjectType(x1, x4, x5, JS_FUNCTION_TYPE);
1666 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET, 1672 __ Jump(masm->isolate()->builtins()->CallFunction(mode),
1667 eq); 1673 RelocInfo::CODE_TARGET, eq);
1668 __ Cmp(x5, JS_FUNCTION_PROXY_TYPE); 1674 __ Cmp(x5, JS_FUNCTION_PROXY_TYPE);
1669 __ B(ne, &non_function); 1675 __ B(ne, &non_function);
1670 1676
1671 // 1. Call to function proxy. 1677 // 1. Call to function proxy.
1672 // TODO(neis): This doesn't match the ES6 spec for [[Call]] on proxies. 1678 // TODO(neis): This doesn't match the ES6 spec for [[Call]] on proxies.
1673 __ Ldr(x1, FieldMemOperand(x1, JSFunctionProxy::kCallTrapOffset)); 1679 __ Ldr(x1, FieldMemOperand(x1, JSFunctionProxy::kCallTrapOffset));
1674 __ AssertNotSmi(x1); 1680 __ AssertNotSmi(x1);
1675 __ B(&non_smi); 1681 __ B(&non_smi);
1676 1682
1677 // 2. Call to something else, which might have a [[Call]] internal method (if 1683 // 2. Call to something else, which might have a [[Call]] internal method (if
1678 // not we raise an exception). 1684 // not we raise an exception).
1679 __ Bind(&non_function); 1685 __ Bind(&non_function);
1680 // Check if target has a [[Call]] internal method. 1686 // Check if target has a [[Call]] internal method.
1681 __ Ldrb(x4, FieldMemOperand(x4, Map::kBitFieldOffset)); 1687 __ Ldrb(x4, FieldMemOperand(x4, Map::kBitFieldOffset));
1682 __ TestAndBranchIfAllClear(x4, 1 << Map::kIsCallable, &non_callable); 1688 __ TestAndBranchIfAllClear(x4, 1 << Map::kIsCallable, &non_callable);
1683 // Overwrite the original receiver with the (original) target. 1689 // Overwrite the original receiver with the (original) target.
1684 __ Poke(x1, Operand(x0, LSL, kXRegSizeLog2)); 1690 __ Poke(x1, Operand(x0, LSL, kXRegSizeLog2));
1685 // Let the "call_as_function_delegate" take care of the rest. 1691 // Let the "call_as_function_delegate" take care of the rest.
1686 __ LoadGlobalFunction(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, x1); 1692 __ LoadGlobalFunction(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, x1);
1687 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET); 1693 __ Jump(masm->isolate()->builtins()->CallFunction(
1694 ConvertReceiverMode::kNotNullOrUndefined),
1695 RelocInfo::CODE_TARGET);
1688 1696
1689 // 3. Call to something that is not callable. 1697 // 3. Call to something that is not callable.
1690 __ bind(&non_callable); 1698 __ bind(&non_callable);
1691 { 1699 {
1692 FrameScope scope(masm, StackFrame::INTERNAL); 1700 FrameScope scope(masm, StackFrame::INTERNAL);
1693 __ Push(x1); 1701 __ Push(x1);
1694 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1); 1702 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1);
1695 } 1703 }
1696 } 1704 }
1697 1705
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
2017 } 2025 }
2018 } 2026 }
2019 2027
2020 2028
2021 #undef __ 2029 #undef __
2022 2030
2023 } // namespace internal 2031 } // namespace internal
2024 } // namespace v8 2032 } // namespace v8
2025 2033
2026 #endif // V8_TARGET_ARCH_ARM 2034 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/builtins-arm.cc ('k') | src/builtins.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698