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

Side by Side Diff: src/arm/builtins-arm.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 | « 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 1541 matching lines...) Expand 10 before | Expand all | Expand 10 after
1552 __ ldr(r1, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + 1552 __ ldr(r1, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp +
1553 kPointerSize))); 1553 kPointerSize)));
1554 1554
1555 __ LeaveFrame(StackFrame::ARGUMENTS_ADAPTOR); 1555 __ LeaveFrame(StackFrame::ARGUMENTS_ADAPTOR);
1556 __ add(sp, sp, Operand::PointerOffsetFromSmiKey(r1)); 1556 __ add(sp, sp, Operand::PointerOffsetFromSmiKey(r1));
1557 __ add(sp, sp, Operand(kPointerSize)); // adjust for receiver 1557 __ add(sp, sp, Operand(kPointerSize)); // adjust for receiver
1558 } 1558 }
1559 1559
1560 1560
1561 // static 1561 // static
1562 void Builtins::Generate_CallFunction(MacroAssembler* masm) { 1562 void Builtins::Generate_CallFunction(MacroAssembler* masm,
1563 ConvertReceiverMode mode) {
1563 // ----------- S t a t e ------------- 1564 // ----------- S t a t e -------------
1564 // -- r0 : the number of arguments (not including the receiver) 1565 // -- r0 : the number of arguments (not including the receiver)
1565 // -- r1 : the function to call (checked to be a JSFunction) 1566 // -- r1 : the function to call (checked to be a JSFunction)
1566 // ----------------------------------- 1567 // -----------------------------------
1568 __ AssertFunction(r1);
1569
1567 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) 1570 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList)
1568 1571 // Check that the function is not a "classConstructor".
1569 Label convert, convert_global_proxy, convert_to_object, done_convert; 1572 Label class_constructor;
1570 __ AssertFunction(r1);
1571 __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); 1573 __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1572 { 1574 __ ldrb(r3, FieldMemOperand(r2, SharedFunctionInfo::kFunctionKindByteOffset));
1573 Label non_class_constructor; 1575 __ tst(r3, Operand(SharedFunctionInfo::kClassConstructorBitsWithinByte));
1574 // Check whether the current function is a classConstructor. 1576 __ b(ne, &class_constructor);
1575 __ ldrb(r3,
1576 FieldMemOperand(r2, SharedFunctionInfo::kFunctionKindByteOffset));
1577 __ tst(r3, Operand(SharedFunctionInfo::kClassConstructorBitsWithinByte));
1578 __ b(eq, &non_class_constructor);
1579 // Step: 2, If we call a classConstructor Function throw a TypeError.
1580 {
1581 FrameScope frame(masm, StackFrame::INTERNAL);
1582 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0);
1583 }
1584 __ bind(&non_class_constructor);
1585 }
1586 1577
1587 // Enter the context of the function; ToObject has to run in the function 1578 // Enter the context of the function; ToObject has to run in the function
1588 // context, and we also need to take the global proxy from the function 1579 // context, and we also need to take the global proxy from the function
1589 // context in case of conversion. 1580 // context in case of conversion.
1590 STATIC_ASSERT(SharedFunctionInfo::kNativeByteOffset == 1581 STATIC_ASSERT(SharedFunctionInfo::kNativeByteOffset ==
1591 SharedFunctionInfo::kStrictModeByteOffset); 1582 SharedFunctionInfo::kStrictModeByteOffset);
1592 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); 1583 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
1593 // We need to convert the receiver for non-native sloppy mode functions. 1584 // We need to convert the receiver for non-native sloppy mode functions.
1585 Label done_convert;
1594 __ ldrb(r3, FieldMemOperand(r2, SharedFunctionInfo::kNativeByteOffset)); 1586 __ ldrb(r3, FieldMemOperand(r2, SharedFunctionInfo::kNativeByteOffset));
1595 __ tst(r3, Operand((1 << SharedFunctionInfo::kNativeBitWithinByte) | 1587 __ tst(r3, Operand((1 << SharedFunctionInfo::kNativeBitWithinByte) |
1596 (1 << SharedFunctionInfo::kStrictModeBitWithinByte))); 1588 (1 << SharedFunctionInfo::kStrictModeBitWithinByte)));
1597 __ b(ne, &done_convert); 1589 __ b(ne, &done_convert);
1598 { 1590 {
1599 __ ldr(r3, MemOperand(sp, r0, LSL, kPointerSizeLog2));
1600
1601 // ----------- S t a t e ------------- 1591 // ----------- S t a t e -------------
1602 // -- r0 : the number of arguments (not including the receiver) 1592 // -- r0 : the number of arguments (not including the receiver)
1603 // -- r1 : the function to call (checked to be a JSFunction) 1593 // -- r1 : the function to call (checked to be a JSFunction)
1604 // -- r2 : the shared function info. 1594 // -- r2 : the shared function info.
1605 // -- r3 : the receiver
1606 // -- cp : the function context. 1595 // -- cp : the function context.
1607 // ----------------------------------- 1596 // -----------------------------------
1608 1597
1609 Label convert_receiver; 1598 if (mode == ConvertReceiverMode::kNullOrUndefined) {
1610 __ JumpIfSmi(r3, &convert_to_object);
1611 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
1612 __ CompareObjectType(r3, r4, r4, FIRST_JS_RECEIVER_TYPE);
1613 __ b(hs, &done_convert);
1614 __ JumpIfRoot(r3, Heap::kUndefinedValueRootIndex, &convert_global_proxy);
1615 __ JumpIfNotRoot(r3, Heap::kNullValueRootIndex, &convert_to_object);
1616 __ bind(&convert_global_proxy);
1617 {
1618 // Patch receiver to global proxy. 1599 // Patch receiver to global proxy.
1619 __ LoadGlobalProxy(r3); 1600 __ LoadGlobalProxy(r3);
1601 } else {
1602 Label convert_to_object, convert_receiver;
1603 __ ldr(r3, MemOperand(sp, r0, LSL, kPointerSizeLog2));
1604 __ JumpIfSmi(r3, &convert_to_object);
1605 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
1606 __ CompareObjectType(r3, r4, r4, FIRST_JS_RECEIVER_TYPE);
1607 __ b(hs, &done_convert);
1608 if (mode != ConvertReceiverMode::kNotNullOrUndefined) {
1609 Label convert_global_proxy;
1610 __ JumpIfRoot(r3, Heap::kUndefinedValueRootIndex,
1611 &convert_global_proxy);
1612 __ JumpIfNotRoot(r3, Heap::kNullValueRootIndex, &convert_to_object);
1613 __ bind(&convert_global_proxy);
1614 {
1615 // Patch receiver to global proxy.
1616 __ LoadGlobalProxy(r3);
1617 }
1618 __ b(&convert_receiver);
1619 }
1620 __ bind(&convert_to_object);
1621 {
1622 // Convert receiver using ToObject.
1623 // TODO(bmeurer): Inline the allocation here to avoid building the frame
1624 // in the fast case? (fall back to AllocateInNewSpace?)
1625 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
1626 __ SmiTag(r0);
1627 __ Push(r0, r1);
1628 __ mov(r0, r3);
1629 ToObjectStub stub(masm->isolate());
1630 __ CallStub(&stub);
1631 __ mov(r3, r0);
1632 __ Pop(r0, r1);
1633 __ SmiUntag(r0);
1634 }
1635 __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1636 __ bind(&convert_receiver);
1620 } 1637 }
1621 __ b(&convert_receiver);
1622 __ bind(&convert_to_object);
1623 {
1624 // Convert receiver using ToObject.
1625 // TODO(bmeurer): Inline the allocation here to avoid building the frame
1626 // in the fast case? (fall back to AllocateInNewSpace?)
1627 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
1628 __ SmiTag(r0);
1629 __ Push(r0, r1);
1630 __ mov(r0, r3);
1631 ToObjectStub stub(masm->isolate());
1632 __ CallStub(&stub);
1633 __ mov(r3, r0);
1634 __ Pop(r0, r1);
1635 __ SmiUntag(r0);
1636 }
1637 __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1638 __ bind(&convert_receiver);
1639 __ str(r3, MemOperand(sp, r0, LSL, kPointerSizeLog2)); 1638 __ str(r3, MemOperand(sp, r0, LSL, kPointerSizeLog2));
1640 } 1639 }
1641 __ bind(&done_convert); 1640 __ bind(&done_convert);
1642 1641
1643 // ----------- S t a t e ------------- 1642 // ----------- S t a t e -------------
1644 // -- r0 : the number of arguments (not including the receiver) 1643 // -- r0 : the number of arguments (not including the receiver)
1645 // -- r1 : the function to call (checked to be a JSFunction) 1644 // -- r1 : the function to call (checked to be a JSFunction)
1646 // -- r2 : the shared function info. 1645 // -- r2 : the shared function info.
1647 // -- cp : the function context. 1646 // -- cp : the function context.
1648 // ----------------------------------- 1647 // -----------------------------------
1649 1648
1650 __ ldr(r2, 1649 __ ldr(r2,
1651 FieldMemOperand(r2, SharedFunctionInfo::kFormalParameterCountOffset)); 1650 FieldMemOperand(r2, SharedFunctionInfo::kFormalParameterCountOffset));
1652 __ SmiUntag(r2); 1651 __ SmiUntag(r2);
1653 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); 1652 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
1654 ParameterCount actual(r0); 1653 ParameterCount actual(r0);
1655 ParameterCount expected(r2); 1654 ParameterCount expected(r2);
1656 __ InvokeCode(r3, expected, actual, JUMP_FUNCTION, NullCallWrapper()); 1655 __ InvokeCode(r3, expected, actual, JUMP_FUNCTION, NullCallWrapper());
1656
1657 // The function is a "classConstructor", need to raise an exception.
1658 __ bind(&class_constructor);
1659 {
1660 FrameScope frame(masm, StackFrame::INTERNAL);
1661 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0);
1662 }
1657 } 1663 }
1658 1664
1659 1665
1660 // static 1666 // static
1661 void Builtins::Generate_Call(MacroAssembler* masm) { 1667 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
1662 // ----------- S t a t e ------------- 1668 // ----------- S t a t e -------------
1663 // -- r0 : the number of arguments (not including the receiver) 1669 // -- r0 : the number of arguments (not including the receiver)
1664 // -- r1 : the target to call (can be any Object). 1670 // -- r1 : the target to call (can be any Object).
1665 // ----------------------------------- 1671 // -----------------------------------
1666 1672
1667 Label non_callable, non_function, non_smi; 1673 Label non_callable, non_function, non_smi;
1668 __ JumpIfSmi(r1, &non_callable); 1674 __ JumpIfSmi(r1, &non_callable);
1669 __ bind(&non_smi); 1675 __ bind(&non_smi);
1670 __ CompareObjectType(r1, r4, r5, JS_FUNCTION_TYPE); 1676 __ CompareObjectType(r1, r4, r5, JS_FUNCTION_TYPE);
1671 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET, 1677 __ Jump(masm->isolate()->builtins()->CallFunction(mode),
1672 eq); 1678 RelocInfo::CODE_TARGET, eq);
1673 __ cmp(r5, Operand(JS_FUNCTION_PROXY_TYPE)); 1679 __ cmp(r5, Operand(JS_FUNCTION_PROXY_TYPE));
1674 __ b(ne, &non_function); 1680 __ b(ne, &non_function);
1675 1681
1676 // 1. Call to function proxy. 1682 // 1. Call to function proxy.
1677 // TODO(neis): This doesn't match the ES6 spec for [[Call]] on proxies. 1683 // TODO(neis): This doesn't match the ES6 spec for [[Call]] on proxies.
1678 __ ldr(r1, FieldMemOperand(r1, JSFunctionProxy::kCallTrapOffset)); 1684 __ ldr(r1, FieldMemOperand(r1, JSFunctionProxy::kCallTrapOffset));
1679 __ AssertNotSmi(r1); 1685 __ AssertNotSmi(r1);
1680 __ b(&non_smi); 1686 __ b(&non_smi);
1681 1687
1682 // 2. Call to something else, which might have a [[Call]] internal method (if 1688 // 2. Call to something else, which might have a [[Call]] internal method (if
1683 // not we raise an exception). 1689 // not we raise an exception).
1684 __ bind(&non_function); 1690 __ bind(&non_function);
1685 // Check if target has a [[Call]] internal method. 1691 // Check if target has a [[Call]] internal method.
1686 __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset)); 1692 __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset));
1687 __ tst(r4, Operand(1 << Map::kIsCallable)); 1693 __ tst(r4, Operand(1 << Map::kIsCallable));
1688 __ b(eq, &non_callable); 1694 __ b(eq, &non_callable);
1689 // Overwrite the original receiver the (original) target. 1695 // Overwrite the original receiver the (original) target.
1690 __ str(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); 1696 __ str(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2));
1691 // Let the "call_as_function_delegate" take care of the rest. 1697 // Let the "call_as_function_delegate" take care of the rest.
1692 __ LoadGlobalFunction(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, r1); 1698 __ LoadGlobalFunction(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, r1);
1693 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET); 1699 __ Jump(masm->isolate()->builtins()->CallFunction(
1700 ConvertReceiverMode::kNotNullOrUndefined),
1701 RelocInfo::CODE_TARGET);
1694 1702
1695 // 3. Call to something that is not callable. 1703 // 3. Call to something that is not callable.
1696 __ bind(&non_callable); 1704 __ bind(&non_callable);
1697 { 1705 {
1698 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); 1706 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
1699 __ Push(r1); 1707 __ Push(r1);
1700 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1); 1708 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1);
1701 } 1709 }
1702 } 1710 }
1703 1711
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
1928 } 1936 }
1929 } 1937 }
1930 1938
1931 1939
1932 #undef __ 1940 #undef __
1933 1941
1934 } // namespace internal 1942 } // namespace internal
1935 } // namespace v8 1943 } // namespace v8
1936 1944
1937 #endif // V8_TARGET_ARCH_ARM 1945 #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