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

Side by Side Diff: src/mips/builtins-mips.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/ic/ic-state.cc ('k') | src/mips64/builtins-mips64.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_MIPS 5 #if V8_TARGET_ARCH_MIPS
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 1551 matching lines...) Expand 10 before | Expand all | Expand 10 after
1562 __ mov(sp, fp); 1562 __ mov(sp, fp);
1563 __ MultiPop(fp.bit() | ra.bit()); 1563 __ MultiPop(fp.bit() | ra.bit());
1564 __ sll(t0, a1, kPointerSizeLog2 - kSmiTagSize); 1564 __ sll(t0, a1, kPointerSizeLog2 - kSmiTagSize);
1565 __ Addu(sp, sp, t0); 1565 __ Addu(sp, sp, t0);
1566 // Adjust for the receiver. 1566 // Adjust for the receiver.
1567 __ Addu(sp, sp, Operand(kPointerSize)); 1567 __ Addu(sp, sp, Operand(kPointerSize));
1568 } 1568 }
1569 1569
1570 1570
1571 // static 1571 // static
1572 void Builtins::Generate_CallFunction(MacroAssembler* masm) { 1572 void Builtins::Generate_CallFunction(MacroAssembler* masm,
1573 ConvertReceiverMode mode) {
1573 // ----------- S t a t e ------------- 1574 // ----------- S t a t e -------------
1574 // -- a0 : the number of arguments (not including the receiver) 1575 // -- a0 : the number of arguments (not including the receiver)
1575 // -- a1 : the function to call (checked to be a JSFunction) 1576 // -- a1 : the function to call (checked to be a JSFunction)
1576 // ----------------------------------- 1577 // -----------------------------------
1578 __ AssertFunction(a1);
1577 1579
1578 Label convert, convert_global_proxy, convert_to_object, done_convert; 1580 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList)
1579 __ AssertFunction(a1); 1581 // Check that the function is not a "classConstructor".
1582 Label class_constructor;
1580 __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); 1583 __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
1581 1584 __ lbu(a3, FieldMemOperand(a2, SharedFunctionInfo::kFunctionKindByteOffset));
1582 { 1585 __ And(at, a3, Operand(SharedFunctionInfo::kClassConstructorBitsWithinByte));
1583 Label non_class_constructor; 1586 __ Branch(&class_constructor, ne, at, Operand(zero_reg));
1584 // Check whether the current function is a classConstructor.
1585 __ lbu(a3,
1586 FieldMemOperand(a2, SharedFunctionInfo::kFunctionKindByteOffset));
1587 __ And(at, a3,
1588 Operand(SharedFunctionInfo::kClassConstructorBitsWithinByte));
1589 __ Branch(&non_class_constructor, eq, at, Operand(zero_reg));
1590 // Step: 2, If we call a classConstructor Function throw a TypeError.
1591 {
1592 FrameScope frame(masm, StackFrame::INTERNAL);
1593 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0);
1594 }
1595 __ bind(&non_class_constructor);
1596 }
1597 1587
1598 // Enter the context of the function; ToObject has to run in the function 1588 // Enter the context of the function; ToObject has to run in the function
1599 // context, and we also need to take the global proxy from the function 1589 // context, and we also need to take the global proxy from the function
1600 // context in case of conversion. 1590 // context in case of conversion.
1601 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList)
1602 STATIC_ASSERT(SharedFunctionInfo::kNativeByteOffset == 1591 STATIC_ASSERT(SharedFunctionInfo::kNativeByteOffset ==
1603 SharedFunctionInfo::kStrictModeByteOffset); 1592 SharedFunctionInfo::kStrictModeByteOffset);
1604 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); 1593 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
1605 // We need to convert the receiver for non-native sloppy mode functions. 1594 // We need to convert the receiver for non-native sloppy mode functions.
1595 Label done_convert;
1606 __ lbu(a3, FieldMemOperand(a2, SharedFunctionInfo::kNativeByteOffset)); 1596 __ lbu(a3, FieldMemOperand(a2, SharedFunctionInfo::kNativeByteOffset));
1607 __ And(at, a3, Operand((1 << SharedFunctionInfo::kNativeBitWithinByte) | 1597 __ And(at, a3, Operand((1 << SharedFunctionInfo::kNativeBitWithinByte) |
1608 (1 << SharedFunctionInfo::kStrictModeBitWithinByte))); 1598 (1 << SharedFunctionInfo::kStrictModeBitWithinByte)));
1609 __ Branch(&done_convert, ne, at, Operand(zero_reg)); 1599 __ Branch(&done_convert, ne, at, Operand(zero_reg));
1610 { 1600 {
1611 __ sll(at, a0, kPointerSizeLog2);
1612 __ addu(at, sp, at);
1613 __ lw(a3, MemOperand(at));
1614
1615 // ----------- S t a t e ------------- 1601 // ----------- S t a t e -------------
1616 // -- a0 : the number of arguments (not including the receiver) 1602 // -- a0 : the number of arguments (not including the receiver)
1617 // -- a1 : the function to call (checked to be a JSFunction) 1603 // -- a1 : the function to call (checked to be a JSFunction)
1618 // -- a2 : the shared function info. 1604 // -- a2 : the shared function info.
1619 // -- a3 : the receiver
1620 // -- cp : the function context. 1605 // -- cp : the function context.
1621 // ----------------------------------- 1606 // -----------------------------------
1622 1607
1623 Label convert_receiver; 1608 if (mode == ConvertReceiverMode::kNullOrUndefined) {
1624 __ JumpIfSmi(a3, &convert_to_object);
1625 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
1626 __ GetObjectType(a3, t0, t0);
1627 __ Branch(&done_convert, hs, t0, Operand(FIRST_JS_RECEIVER_TYPE));
1628 __ JumpIfRoot(a3, Heap::kUndefinedValueRootIndex, &convert_global_proxy);
1629 __ JumpIfNotRoot(a3, Heap::kNullValueRootIndex, &convert_to_object);
1630 __ bind(&convert_global_proxy);
1631 {
1632 // Patch receiver to global proxy. 1609 // Patch receiver to global proxy.
1633 __ LoadGlobalProxy(a3); 1610 __ LoadGlobalProxy(a3);
1611 } else {
1612 Label convert_to_object, convert_receiver;
1613 __ sll(at, a0, kPointerSizeLog2);
1614 __ addu(at, sp, at);
1615 __ lw(a3, MemOperand(at));
1616 __ JumpIfSmi(a3, &convert_to_object);
1617 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
1618 __ GetObjectType(a3, t0, t0);
1619 __ Branch(&done_convert, hs, t0, Operand(FIRST_JS_RECEIVER_TYPE));
1620 if (mode != ConvertReceiverMode::kNotNullOrUndefined) {
1621 Label convert_global_proxy;
1622 __ JumpIfRoot(a3, Heap::kUndefinedValueRootIndex,
1623 &convert_global_proxy);
1624 __ JumpIfNotRoot(a3, Heap::kNullValueRootIndex, &convert_to_object);
1625 __ bind(&convert_global_proxy);
1626 {
1627 // Patch receiver to global proxy.
1628 __ LoadGlobalProxy(a3);
1629 }
1630 __ Branch(&convert_receiver);
1631 }
1632 __ bind(&convert_to_object);
1633 {
1634 // Convert receiver using ToObject.
1635 // TODO(bmeurer): Inline the allocation here to avoid building the frame
1636 // in the fast case? (fall back to AllocateInNewSpace?)
1637 FrameScope scope(masm, StackFrame::INTERNAL);
1638 __ sll(a0, a0, kSmiTagSize); // Smi tagged.
1639 __ Push(a0, a1);
1640 __ mov(a0, a3);
1641 ToObjectStub stub(masm->isolate());
1642 __ CallStub(&stub);
1643 __ mov(a3, v0);
1644 __ Pop(a0, a1);
1645 __ sra(a0, a0, kSmiTagSize); // Un-tag.
1646 }
1647 __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
1648 __ bind(&convert_receiver);
1634 } 1649 }
1635 __ Branch(&convert_receiver);
1636 __ bind(&convert_to_object);
1637 {
1638 // Convert receiver using ToObject.
1639 // TODO(bmeurer): Inline the allocation here to avoid building the frame
1640 // in the fast case? (fall back to AllocateInNewSpace?)
1641 FrameScope scope(masm, StackFrame::INTERNAL);
1642 __ sll(a0, a0, kSmiTagSize); // Smi tagged.
1643 __ Push(a0, a1);
1644 __ mov(a0, a3);
1645 ToObjectStub stub(masm->isolate());
1646 __ CallStub(&stub);
1647 __ mov(a3, v0);
1648 __ Pop(a0, a1);
1649 __ sra(a0, a0, kSmiTagSize); // Un-tag.
1650 }
1651 __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
1652 __ bind(&convert_receiver);
1653 __ sll(at, a0, kPointerSizeLog2); 1650 __ sll(at, a0, kPointerSizeLog2);
1654 __ addu(at, sp, at); 1651 __ addu(at, sp, at);
1655 __ sw(a3, MemOperand(at)); 1652 __ sw(a3, MemOperand(at));
1656 } 1653 }
1657 __ bind(&done_convert); 1654 __ bind(&done_convert);
1658 1655
1659 // ----------- S t a t e ------------- 1656 // ----------- S t a t e -------------
1660 // -- a0 : the number of arguments (not including the receiver) 1657 // -- a0 : the number of arguments (not including the receiver)
1661 // -- a1 : the function to call (checked to be a JSFunction) 1658 // -- a1 : the function to call (checked to be a JSFunction)
1662 // -- a2 : the shared function info. 1659 // -- a2 : the shared function info.
1663 // -- cp : the function context. 1660 // -- cp : the function context.
1664 // ----------------------------------- 1661 // -----------------------------------
1665 1662
1666 __ lw(a2, 1663 __ lw(a2,
1667 FieldMemOperand(a2, SharedFunctionInfo::kFormalParameterCountOffset)); 1664 FieldMemOperand(a2, SharedFunctionInfo::kFormalParameterCountOffset));
1668 __ sra(a2, a2, kSmiTagSize); // Un-tag. 1665 __ sra(a2, a2, kSmiTagSize); // Un-tag.
1669 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); 1666 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
1670 ParameterCount actual(a0); 1667 ParameterCount actual(a0);
1671 ParameterCount expected(a2); 1668 ParameterCount expected(a2);
1672 __ InvokeCode(a3, expected, actual, JUMP_FUNCTION, NullCallWrapper()); 1669 __ InvokeCode(a3, expected, actual, JUMP_FUNCTION, NullCallWrapper());
1670
1671 // The function is a "classConstructor", need to raise an exception.
1672 __ bind(&class_constructor);
1673 {
1674 FrameScope frame(masm, StackFrame::INTERNAL);
1675 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0);
1676 }
1673 } 1677 }
1674 1678
1675 1679
1676 // static 1680 // static
1677 void Builtins::Generate_Call(MacroAssembler* masm) { 1681 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
1678 // ----------- S t a t e ------------- 1682 // ----------- S t a t e -------------
1679 // -- a0 : the number of arguments (not including the receiver) 1683 // -- a0 : the number of arguments (not including the receiver)
1680 // -- a1 : the target to call (can be any Object). 1684 // -- a1 : the target to call (can be any Object).
1681 // ----------------------------------- 1685 // -----------------------------------
1682 1686
1683 Label non_callable, non_function, non_smi; 1687 Label non_callable, non_function, non_smi;
1684 __ JumpIfSmi(a1, &non_callable); 1688 __ JumpIfSmi(a1, &non_callable);
1685 __ bind(&non_smi); 1689 __ bind(&non_smi);
1686 __ GetObjectType(a1, t1, t2); 1690 __ GetObjectType(a1, t1, t2);
1687 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET, 1691 __ Jump(masm->isolate()->builtins()->CallFunction(mode),
1688 eq, t2, Operand(JS_FUNCTION_TYPE)); 1692 RelocInfo::CODE_TARGET, eq, t2, Operand(JS_FUNCTION_TYPE));
1689 __ Branch(&non_function, ne, t2, Operand(JS_FUNCTION_PROXY_TYPE)); 1693 __ Branch(&non_function, ne, t2, Operand(JS_FUNCTION_PROXY_TYPE));
1690 1694
1691 // 1. Call to function proxy. 1695 // 1. Call to function proxy.
1692 // TODO(neis): This doesn't match the ES6 spec for [[Call]] on proxies. 1696 // TODO(neis): This doesn't match the ES6 spec for [[Call]] on proxies.
1693 __ lw(a1, FieldMemOperand(a1, JSFunctionProxy::kCallTrapOffset)); 1697 __ lw(a1, FieldMemOperand(a1, JSFunctionProxy::kCallTrapOffset));
1694 __ AssertNotSmi(a1); 1698 __ AssertNotSmi(a1);
1695 __ Branch(&non_smi); 1699 __ Branch(&non_smi);
1696 1700
1697 // 2. Call to something else, which might have a [[Call]] internal method (if 1701 // 2. Call to something else, which might have a [[Call]] internal method (if
1698 // not we raise an exception). 1702 // not we raise an exception).
1699 __ bind(&non_function); 1703 __ bind(&non_function);
1700 // Check if target has a [[Call]] internal method. 1704 // Check if target has a [[Call]] internal method.
1701 __ lbu(t1, FieldMemOperand(t1, Map::kBitFieldOffset)); 1705 __ lbu(t1, FieldMemOperand(t1, Map::kBitFieldOffset));
1702 __ And(t1, t1, Operand(1 << Map::kIsCallable)); 1706 __ And(t1, t1, Operand(1 << Map::kIsCallable));
1703 __ Branch(&non_callable, eq, t1, Operand(zero_reg)); 1707 __ Branch(&non_callable, eq, t1, Operand(zero_reg));
1704 // Overwrite the original receiver with the (original) target. 1708 // Overwrite the original receiver with the (original) target.
1705 __ sll(at, a0, kPointerSizeLog2); 1709 __ sll(at, a0, kPointerSizeLog2);
1706 __ addu(at, sp, at); 1710 __ addu(at, sp, at);
1707 __ sw(a1, MemOperand(at)); 1711 __ sw(a1, MemOperand(at));
1708 // Let the "call_as_function_delegate" take care of the rest. 1712 // Let the "call_as_function_delegate" take care of the rest.
1709 __ LoadGlobalFunction(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, a1); 1713 __ LoadGlobalFunction(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, a1);
1710 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET); 1714 __ Jump(masm->isolate()->builtins()->CallFunction(
1715 ConvertReceiverMode::kNotNullOrUndefined),
1716 RelocInfo::CODE_TARGET);
1711 1717
1712 // 3. Call to something that is not callable. 1718 // 3. Call to something that is not callable.
1713 __ bind(&non_callable); 1719 __ bind(&non_callable);
1714 { 1720 {
1715 FrameScope scope(masm, StackFrame::INTERNAL); 1721 FrameScope scope(masm, StackFrame::INTERNAL);
1716 __ Push(a1); 1722 __ Push(a1);
1717 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1); 1723 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1);
1718 } 1724 }
1719 } 1725 }
1720 1726
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
1956 } 1962 }
1957 } 1963 }
1958 1964
1959 1965
1960 #undef __ 1966 #undef __
1961 1967
1962 } // namespace internal 1968 } // namespace internal
1963 } // namespace v8 1969 } // namespace v8
1964 1970
1965 #endif // V8_TARGET_ARCH_MIPS 1971 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/ic/ic-state.cc ('k') | src/mips64/builtins-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698