| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 633 return_value_operand, | 633 return_value_operand, |
| 634 restore_context ? &context_restore_operand : NULL); | 634 restore_context ? &context_restore_operand : NULL); |
| 635 } | 635 } |
| 636 | 636 |
| 637 | 637 |
| 638 class CallInterceptorCompiler BASE_EMBEDDED { | 638 class CallInterceptorCompiler BASE_EMBEDDED { |
| 639 public: | 639 public: |
| 640 CallInterceptorCompiler(StubCompiler* stub_compiler, | 640 CallInterceptorCompiler(StubCompiler* stub_compiler, |
| 641 const ParameterCount& arguments, | 641 const ParameterCount& arguments, |
| 642 Register name, | 642 Register name, |
| 643 Code::ExtraICState extra_ic_state) | 643 ExtraICState extra_ic_state) |
| 644 : stub_compiler_(stub_compiler), | 644 : stub_compiler_(stub_compiler), |
| 645 arguments_(arguments), | 645 arguments_(arguments), |
| 646 name_(name), | 646 name_(name), |
| 647 extra_ic_state_(extra_ic_state) {} | 647 extra_ic_state_(extra_ic_state) {} |
| 648 | 648 |
| 649 void Compile(MacroAssembler* masm, | 649 void Compile(MacroAssembler* masm, |
| 650 Handle<JSObject> object, | 650 Handle<JSObject> object, |
| 651 Handle<JSObject> holder, | 651 Handle<JSObject> holder, |
| 652 Handle<Name> name, | 652 Handle<Name> name, |
| 653 LookupResult* lookup, | 653 LookupResult* lookup, |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 818 // Leave the internal frame. | 818 // Leave the internal frame. |
| 819 } | 819 } |
| 820 | 820 |
| 821 __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex); | 821 __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex); |
| 822 __ j(not_equal, interceptor_succeeded); | 822 __ j(not_equal, interceptor_succeeded); |
| 823 } | 823 } |
| 824 | 824 |
| 825 StubCompiler* stub_compiler_; | 825 StubCompiler* stub_compiler_; |
| 826 const ParameterCount& arguments_; | 826 const ParameterCount& arguments_; |
| 827 Register name_; | 827 Register name_; |
| 828 Code::ExtraICState extra_ic_state_; | 828 ExtraICState extra_ic_state_; |
| 829 }; | 829 }; |
| 830 | 830 |
| 831 | 831 |
| 832 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, | 832 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, |
| 833 Label* label, | 833 Label* label, |
| 834 Handle<Name> name) { | 834 Handle<Name> name) { |
| 835 if (!label->is_unused()) { | 835 if (!label->is_unused()) { |
| 836 __ bind(label); | 836 __ bind(label); |
| 837 __ Move(this->name(), name); | 837 __ Move(this->name(), name); |
| 838 } | 838 } |
| (...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1530 | 1530 |
| 1531 | 1531 |
| 1532 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { | 1532 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { |
| 1533 if (kind_ == Code::KEYED_CALL_IC) { | 1533 if (kind_ == Code::KEYED_CALL_IC) { |
| 1534 __ Cmp(rcx, name); | 1534 __ Cmp(rcx, name); |
| 1535 __ j(not_equal, miss); | 1535 __ j(not_equal, miss); |
| 1536 } | 1536 } |
| 1537 } | 1537 } |
| 1538 | 1538 |
| 1539 | 1539 |
| 1540 void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object, | |
| 1541 Handle<JSObject> holder, | |
| 1542 Handle<Name> name, | |
| 1543 Label* miss) { | |
| 1544 ASSERT(holder->IsGlobalObject()); | |
| 1545 | |
| 1546 StackArgumentsAccessor args(rsp, arguments()); | |
| 1547 __ movq(rdx, args.GetReceiverOperand()); | |
| 1548 | |
| 1549 | |
| 1550 // Check that the maps haven't changed. | |
| 1551 __ JumpIfSmi(rdx, miss); | |
| 1552 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder, | |
| 1553 rbx, rax, rdi, name, miss); | |
| 1554 } | |
| 1555 | |
| 1556 | |
| 1557 void CallStubCompiler::GenerateLoadFunctionFromCell( | 1540 void CallStubCompiler::GenerateLoadFunctionFromCell( |
| 1558 Handle<Cell> cell, | 1541 Handle<Cell> cell, |
| 1559 Handle<JSFunction> function, | 1542 Handle<JSFunction> function, |
| 1560 Label* miss) { | 1543 Label* miss) { |
| 1561 // Get the value from the cell. | 1544 // Get the value from the cell. |
| 1562 __ Move(rdi, cell); | 1545 __ Move(rdi, cell); |
| 1563 __ movq(rdi, FieldOperand(rdi, Cell::kValueOffset)); | 1546 __ movq(rdi, FieldOperand(rdi, Cell::kValueOffset)); |
| 1564 | 1547 |
| 1565 // Check that the cell contains the same function. | 1548 // Check that the cell contains the same function. |
| 1566 if (heap()->InNewSpace(*function)) { | 1549 if (heap()->InNewSpace(*function)) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1589 kind_, | 1572 kind_, |
| 1590 extra_state_); | 1573 extra_state_); |
| 1591 __ Jump(code, RelocInfo::CODE_TARGET); | 1574 __ Jump(code, RelocInfo::CODE_TARGET); |
| 1592 } | 1575 } |
| 1593 | 1576 |
| 1594 | 1577 |
| 1595 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, | 1578 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, |
| 1596 Handle<JSObject> holder, | 1579 Handle<JSObject> holder, |
| 1597 PropertyIndex index, | 1580 PropertyIndex index, |
| 1598 Handle<Name> name) { | 1581 Handle<Name> name) { |
| 1599 // ----------- S t a t e ------------- | |
| 1600 // rcx : function name | |
| 1601 // rsp[0] : return address | |
| 1602 // rsp[8] : argument argc | |
| 1603 // rsp[16] : argument argc - 1 | |
| 1604 // ... | |
| 1605 // rsp[argc * 8] : argument 1 | |
| 1606 // rsp[(argc + 1) * 8] : argument 0 = receiver | |
| 1607 // ----------------------------------- | |
| 1608 Label miss; | 1582 Label miss; |
| 1609 | 1583 |
| 1610 GenerateNameCheck(name, &miss); | 1584 Register reg = HandlerFrontendHeader( |
| 1611 | 1585 object, holder, name, RECEIVER_MAP_CHECK, &miss); |
| 1612 StackArgumentsAccessor args(rsp, arguments()); | |
| 1613 __ movq(rdx, args.GetReceiverOperand()); | |
| 1614 | |
| 1615 // Check that the receiver isn't a smi. | |
| 1616 __ JumpIfSmi(rdx, &miss); | |
| 1617 | |
| 1618 // Do the right check and compute the holder register. | |
| 1619 Register reg = CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, | |
| 1620 holder, rbx, rax, rdi, name, &miss); | |
| 1621 | 1586 |
| 1622 GenerateFastPropertyLoad(masm(), rdi, reg, index.is_inobject(holder), | 1587 GenerateFastPropertyLoad(masm(), rdi, reg, index.is_inobject(holder), |
| 1623 index.translate(holder), Representation::Tagged()); | 1588 index.translate(holder), Representation::Tagged()); |
| 1624 | 1589 |
| 1625 // Check that the function really is a function. | 1590 // Check that the function really is a function. |
| 1626 __ JumpIfSmi(rdi, &miss); | 1591 __ JumpIfSmi(rdi, &miss); |
| 1627 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rbx); | 1592 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rbx); |
| 1628 __ j(not_equal, &miss); | 1593 __ j(not_equal, &miss); |
| 1629 | 1594 |
| 1630 // Patch the receiver on the stack with the global proxy if | 1595 PatchGlobalProxy(object); |
| 1631 // necessary. | |
| 1632 if (object->IsGlobalObject()) { | |
| 1633 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); | |
| 1634 __ movq(args.GetReceiverOperand(), rdx); | |
| 1635 } | |
| 1636 | 1596 |
| 1637 // Invoke the function. | 1597 // Invoke the function. |
| 1638 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 1598 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
| 1639 ? CALL_AS_FUNCTION | 1599 ? CALL_AS_FUNCTION |
| 1640 : CALL_AS_METHOD; | 1600 : CALL_AS_METHOD; |
| 1641 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, | 1601 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, |
| 1642 NullCallWrapper(), call_kind); | 1602 NullCallWrapper(), call_kind); |
| 1643 | 1603 |
| 1644 // Handle call cache miss. | 1604 HandlerFrontendFooter(&miss); |
| 1645 __ bind(&miss); | |
| 1646 GenerateMissBranch(); | |
| 1647 | 1605 |
| 1648 // Return the generated code. | 1606 // Return the generated code. |
| 1649 return GetCode(Code::FAST, name); | 1607 return GetCode(Code::FAST, name); |
| 1650 } | 1608 } |
| 1651 | 1609 |
| 1652 | 1610 |
| 1653 Handle<Code> CallStubCompiler::CompileArrayCodeCall( | 1611 Handle<Code> CallStubCompiler::CompileArrayCodeCall( |
| 1654 Handle<Object> object, | 1612 Handle<Object> object, |
| 1655 Handle<JSObject> holder, | 1613 Handle<JSObject> holder, |
| 1656 Handle<Cell> cell, | 1614 Handle<Cell> cell, |
| 1657 Handle<JSFunction> function, | 1615 Handle<JSFunction> function, |
| 1658 Handle<String> name, | 1616 Handle<String> name, |
| 1659 Code::StubType type) { | 1617 Code::StubType type) { |
| 1660 Label miss; | 1618 Label miss; |
| 1661 | 1619 |
| 1662 // Check that function is still array | 1620 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); |
| 1663 const int argc = arguments().immediate(); | 1621 if (!cell.is_null()) { |
| 1664 StackArgumentsAccessor args(rsp, argc); | |
| 1665 GenerateNameCheck(name, &miss); | |
| 1666 | |
| 1667 if (cell.is_null()) { | |
| 1668 __ movq(rdx, args.GetReceiverOperand()); | |
| 1669 | |
| 1670 // Check that the receiver isn't a smi. | |
| 1671 __ JumpIfSmi(rdx, &miss); | |
| 1672 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder, | |
| 1673 rbx, rax, rdi, name, &miss); | |
| 1674 } else { | |
| 1675 ASSERT(cell->value() == *function); | 1622 ASSERT(cell->value() == *function); |
| 1676 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | |
| 1677 &miss); | |
| 1678 GenerateLoadFunctionFromCell(cell, function, &miss); | 1623 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 1679 } | 1624 } |
| 1680 | 1625 |
| 1681 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); | 1626 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); |
| 1682 site->SetElementsKind(GetInitialFastElementsKind()); | 1627 site->SetElementsKind(GetInitialFastElementsKind()); |
| 1683 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); | 1628 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); |
| 1629 const int argc = arguments().immediate(); |
| 1684 __ movq(rax, Immediate(argc)); | 1630 __ movq(rax, Immediate(argc)); |
| 1685 __ Move(rbx, site_feedback_cell); | 1631 __ Move(rbx, site_feedback_cell); |
| 1686 __ Move(rdi, function); | 1632 __ Move(rdi, function); |
| 1687 | 1633 |
| 1688 ArrayConstructorStub stub(isolate()); | 1634 ArrayConstructorStub stub(isolate()); |
| 1689 __ TailCallStub(&stub); | 1635 __ TailCallStub(&stub); |
| 1690 | 1636 |
| 1691 __ bind(&miss); | 1637 HandlerFrontendFooter(&miss); |
| 1692 GenerateMissBranch(); | |
| 1693 | 1638 |
| 1694 // Return the generated code. | 1639 // Return the generated code. |
| 1695 return GetCode(type, name); | 1640 return GetCode(type, name); |
| 1696 } | 1641 } |
| 1697 | 1642 |
| 1698 | 1643 |
| 1699 Handle<Code> CallStubCompiler::CompileArrayPushCall( | 1644 Handle<Code> CallStubCompiler::CompileArrayPushCall( |
| 1700 Handle<Object> object, | 1645 Handle<Object> object, |
| 1701 Handle<JSObject> holder, | 1646 Handle<JSObject> holder, |
| 1702 Handle<Cell> cell, | 1647 Handle<Cell> cell, |
| 1703 Handle<JSFunction> function, | 1648 Handle<JSFunction> function, |
| 1704 Handle<String> name, | 1649 Handle<String> name, |
| 1705 Code::StubType type) { | 1650 Code::StubType type) { |
| 1706 // ----------- S t a t e ------------- | 1651 // ----------- S t a t e ------------- |
| 1707 // -- rcx : name | 1652 // -- rcx : name |
| 1708 // -- rsp[0] : return address | 1653 // -- rsp[0] : return address |
| 1709 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1654 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
| 1710 // -- ... | 1655 // -- ... |
| 1711 // -- rsp[(argc + 1) * 8] : receiver | 1656 // -- rsp[(argc + 1) * 8] : receiver |
| 1712 // ----------------------------------- | 1657 // ----------------------------------- |
| 1713 | 1658 |
| 1714 // If object is not an array or is observed, bail out to regular call. | 1659 // If object is not an array or is observed, bail out to regular call. |
| 1715 if (!object->IsJSArray() || | 1660 if (!object->IsJSArray() || |
| 1716 !cell.is_null() || | 1661 !cell.is_null() || |
| 1717 Handle<JSArray>::cast(object)->map()->is_observed()) { | 1662 Handle<JSArray>::cast(object)->map()->is_observed()) { |
| 1718 return Handle<Code>::null(); | 1663 return Handle<Code>::null(); |
| 1719 } | 1664 } |
| 1720 | 1665 |
| 1721 Label miss; | 1666 Label miss; |
| 1722 GenerateNameCheck(name, &miss); | 1667 |
| 1668 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); |
| 1723 | 1669 |
| 1724 const int argc = arguments().immediate(); | 1670 const int argc = arguments().immediate(); |
| 1725 StackArgumentsAccessor args(rsp, argc); | 1671 StackArgumentsAccessor args(rsp, argc); |
| 1726 __ movq(rdx, args.GetReceiverOperand()); | |
| 1727 | |
| 1728 // Check that the receiver isn't a smi. | |
| 1729 __ JumpIfSmi(rdx, &miss); | |
| 1730 | |
| 1731 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder, | |
| 1732 rbx, rax, rdi, name, &miss); | |
| 1733 | |
| 1734 if (argc == 0) { | 1672 if (argc == 0) { |
| 1735 // Noop, return the length. | 1673 // Noop, return the length. |
| 1736 __ movq(rax, FieldOperand(rdx, JSArray::kLengthOffset)); | 1674 __ movq(rax, FieldOperand(rdx, JSArray::kLengthOffset)); |
| 1737 __ ret((argc + 1) * kPointerSize); | 1675 __ ret((argc + 1) * kPointerSize); |
| 1738 } else { | 1676 } else { |
| 1739 Label call_builtin; | 1677 Label call_builtin; |
| 1740 | 1678 |
| 1741 if (argc == 1) { // Otherwise fall through to call builtin. | 1679 if (argc == 1) { // Otherwise fall through to call builtin. |
| 1742 Label attempt_to_grow_elements, with_write_barrier, check_double; | 1680 Label attempt_to_grow_elements, with_write_barrier, check_double; |
| 1743 | 1681 |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1936 __ ret((argc + 1) * kPointerSize); | 1874 __ ret((argc + 1) * kPointerSize); |
| 1937 } | 1875 } |
| 1938 | 1876 |
| 1939 __ bind(&call_builtin); | 1877 __ bind(&call_builtin); |
| 1940 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, | 1878 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, |
| 1941 isolate()), | 1879 isolate()), |
| 1942 argc + 1, | 1880 argc + 1, |
| 1943 1); | 1881 1); |
| 1944 } | 1882 } |
| 1945 | 1883 |
| 1946 __ bind(&miss); | 1884 HandlerFrontendFooter(&miss); |
| 1947 GenerateMissBranch(); | |
| 1948 | 1885 |
| 1949 // Return the generated code. | 1886 // Return the generated code. |
| 1950 return GetCode(type, name); | 1887 return GetCode(type, name); |
| 1951 } | 1888 } |
| 1952 | 1889 |
| 1953 | 1890 |
| 1954 Handle<Code> CallStubCompiler::CompileArrayPopCall( | 1891 Handle<Code> CallStubCompiler::CompileArrayPopCall( |
| 1955 Handle<Object> object, | 1892 Handle<Object> object, |
| 1956 Handle<JSObject> holder, | 1893 Handle<JSObject> holder, |
| 1957 Handle<Cell> cell, | 1894 Handle<Cell> cell, |
| 1958 Handle<JSFunction> function, | 1895 Handle<JSFunction> function, |
| 1959 Handle<String> name, | 1896 Handle<String> name, |
| 1960 Code::StubType type) { | 1897 Code::StubType type) { |
| 1961 // ----------- S t a t e ------------- | |
| 1962 // -- rcx : name | |
| 1963 // -- rsp[0] : return address | |
| 1964 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | |
| 1965 // -- ... | |
| 1966 // -- rsp[(argc + 1) * 8] : receiver | |
| 1967 // ----------------------------------- | |
| 1968 | |
| 1969 // If object is not an array or is observed, bail out to regular call. | 1898 // If object is not an array or is observed, bail out to regular call. |
| 1970 if (!object->IsJSArray() || | 1899 if (!object->IsJSArray() || |
| 1971 !cell.is_null() || | 1900 !cell.is_null() || |
| 1972 Handle<JSArray>::cast(object)->map()->is_observed()) { | 1901 Handle<JSArray>::cast(object)->map()->is_observed()) { |
| 1973 return Handle<Code>::null(); | 1902 return Handle<Code>::null(); |
| 1974 } | 1903 } |
| 1975 | 1904 |
| 1976 Label miss, return_undefined, call_builtin; | 1905 Label miss, return_undefined, call_builtin; |
| 1977 GenerateNameCheck(name, &miss); | |
| 1978 | 1906 |
| 1979 const int argc = arguments().immediate(); | 1907 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); |
| 1980 StackArgumentsAccessor args(rsp, argc); | |
| 1981 __ movq(rdx, args.GetReceiverOperand()); | |
| 1982 | |
| 1983 // Check that the receiver isn't a smi. | |
| 1984 __ JumpIfSmi(rdx, &miss); | |
| 1985 | |
| 1986 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder, | |
| 1987 rbx, rax, rdi, name, &miss); | |
| 1988 | 1908 |
| 1989 // Get the elements array of the object. | 1909 // Get the elements array of the object. |
| 1990 __ movq(rbx, FieldOperand(rdx, JSArray::kElementsOffset)); | 1910 __ movq(rbx, FieldOperand(rdx, JSArray::kElementsOffset)); |
| 1991 | 1911 |
| 1992 // Check that the elements are in fast mode and writable. | 1912 // Check that the elements are in fast mode and writable. |
| 1993 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), | 1913 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), |
| 1994 Heap::kFixedArrayMapRootIndex); | 1914 Heap::kFixedArrayMapRootIndex); |
| 1995 __ j(not_equal, &call_builtin); | 1915 __ j(not_equal, &call_builtin); |
| 1996 | 1916 |
| 1997 // Get the array's length into rcx and calculate new length. | 1917 // Get the array's length into rcx and calculate new length. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2010 __ j(equal, &call_builtin); | 1930 __ j(equal, &call_builtin); |
| 2011 | 1931 |
| 2012 // Set the array's length. | 1932 // Set the array's length. |
| 2013 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rcx); | 1933 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rcx); |
| 2014 | 1934 |
| 2015 // Fill with the hole and return original value. | 1935 // Fill with the hole and return original value. |
| 2016 __ movq(FieldOperand(rbx, | 1936 __ movq(FieldOperand(rbx, |
| 2017 rcx, times_pointer_size, | 1937 rcx, times_pointer_size, |
| 2018 FixedArray::kHeaderSize), | 1938 FixedArray::kHeaderSize), |
| 2019 r9); | 1939 r9); |
| 1940 const int argc = arguments().immediate(); |
| 2020 __ ret((argc + 1) * kPointerSize); | 1941 __ ret((argc + 1) * kPointerSize); |
| 2021 | 1942 |
| 2022 __ bind(&return_undefined); | 1943 __ bind(&return_undefined); |
| 2023 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); | 1944 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); |
| 2024 __ ret((argc + 1) * kPointerSize); | 1945 __ ret((argc + 1) * kPointerSize); |
| 2025 | 1946 |
| 2026 __ bind(&call_builtin); | 1947 __ bind(&call_builtin); |
| 2027 __ TailCallExternalReference( | 1948 __ TailCallExternalReference( |
| 2028 ExternalReference(Builtins::c_ArrayPop, isolate()), | 1949 ExternalReference(Builtins::c_ArrayPop, isolate()), |
| 2029 argc + 1, | 1950 argc + 1, |
| 2030 1); | 1951 1); |
| 2031 | 1952 |
| 2032 __ bind(&miss); | 1953 HandlerFrontendFooter(&miss); |
| 2033 GenerateMissBranch(); | |
| 2034 | 1954 |
| 2035 // Return the generated code. | 1955 // Return the generated code. |
| 2036 return GetCode(type, name); | 1956 return GetCode(type, name); |
| 2037 } | 1957 } |
| 2038 | 1958 |
| 2039 | 1959 |
| 2040 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall( | 1960 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall( |
| 2041 Handle<Object> object, | 1961 Handle<Object> object, |
| 2042 Handle<JSObject> holder, | 1962 Handle<JSObject> holder, |
| 2043 Handle<Cell> cell, | 1963 Handle<Cell> cell, |
| 2044 Handle<JSFunction> function, | 1964 Handle<JSFunction> function, |
| 2045 Handle<String> name, | 1965 Handle<String> name, |
| 2046 Code::StubType type) { | 1966 Code::StubType type) { |
| 2047 // ----------- S t a t e ------------- | |
| 2048 // -- rcx : function name | |
| 2049 // -- rsp[0] : return address | |
| 2050 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | |
| 2051 // -- ... | |
| 2052 // -- rsp[(argc + 1) * 8] : receiver | |
| 2053 // ----------------------------------- | |
| 2054 | |
| 2055 // If object is not a string, bail out to regular call. | 1967 // If object is not a string, bail out to regular call. |
| 2056 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); | 1968 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); |
| 2057 | 1969 |
| 2058 const int argc = arguments().immediate(); | |
| 2059 StackArgumentsAccessor args(rsp, argc); | |
| 2060 | |
| 2061 Label miss; | 1970 Label miss; |
| 2062 Label name_miss; | 1971 Label name_miss; |
| 2063 Label index_out_of_range; | 1972 Label index_out_of_range; |
| 2064 Label* index_out_of_range_label = &index_out_of_range; | 1973 Label* index_out_of_range_label = &index_out_of_range; |
| 2065 if (kind_ == Code::CALL_IC && | 1974 if (kind_ == Code::CALL_IC && |
| 2066 (CallICBase::StringStubState::decode(extra_state_) == | 1975 (CallICBase::StringStubState::decode(extra_state_) == |
| 2067 DEFAULT_STRING_STUB)) { | 1976 DEFAULT_STRING_STUB)) { |
| 2068 index_out_of_range_label = &miss; | 1977 index_out_of_range_label = &miss; |
| 2069 } | 1978 } |
| 2070 GenerateNameCheck(name, &name_miss); | |
| 2071 | 1979 |
| 2072 // Check that the maps starting from the prototype haven't changed. | 1980 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss); |
| 2073 GenerateDirectLoadGlobalFunctionPrototype(masm(), | |
| 2074 Context::STRING_FUNCTION_INDEX, | |
| 2075 rax, | |
| 2076 &miss); | |
| 2077 ASSERT(!object.is_identical_to(holder)); | |
| 2078 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); | |
| 2079 CheckPrototypes( | |
| 2080 IC::CurrentTypeOf(prototype, isolate()), | |
| 2081 rax, holder, rbx, rdx, rdi, name, &miss); | |
| 2082 | 1981 |
| 2083 Register receiver = rbx; | 1982 Register receiver = rbx; |
| 2084 Register index = rdi; | 1983 Register index = rdi; |
| 2085 Register result = rax; | 1984 Register result = rax; |
| 1985 const int argc = arguments().immediate(); |
| 1986 StackArgumentsAccessor args(rsp, argc); |
| 1987 |
| 2086 __ movq(receiver, args.GetReceiverOperand()); | 1988 __ movq(receiver, args.GetReceiverOperand()); |
| 2087 if (argc > 0) { | 1989 if (argc > 0) { |
| 2088 __ movq(index, args.GetArgumentOperand(1)); | 1990 __ movq(index, args.GetArgumentOperand(1)); |
| 2089 } else { | 1991 } else { |
| 2090 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); | 1992 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); |
| 2091 } | 1993 } |
| 2092 | 1994 |
| 2093 StringCharCodeAtGenerator generator(receiver, | 1995 StringCharCodeAtGenerator generator(receiver, |
| 2094 index, | 1996 index, |
| 2095 result, | 1997 result, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2120 } | 2022 } |
| 2121 | 2023 |
| 2122 | 2024 |
| 2123 Handle<Code> CallStubCompiler::CompileStringCharAtCall( | 2025 Handle<Code> CallStubCompiler::CompileStringCharAtCall( |
| 2124 Handle<Object> object, | 2026 Handle<Object> object, |
| 2125 Handle<JSObject> holder, | 2027 Handle<JSObject> holder, |
| 2126 Handle<Cell> cell, | 2028 Handle<Cell> cell, |
| 2127 Handle<JSFunction> function, | 2029 Handle<JSFunction> function, |
| 2128 Handle<String> name, | 2030 Handle<String> name, |
| 2129 Code::StubType type) { | 2031 Code::StubType type) { |
| 2130 // ----------- S t a t e ------------- | |
| 2131 // -- rcx : function name | |
| 2132 // -- rsp[0] : return address | |
| 2133 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | |
| 2134 // -- ... | |
| 2135 // -- rsp[(argc + 1) * 8] : receiver | |
| 2136 // ----------------------------------- | |
| 2137 | |
| 2138 // If object is not a string, bail out to regular call. | 2032 // If object is not a string, bail out to regular call. |
| 2139 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); | 2033 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); |
| 2140 | 2034 |
| 2141 const int argc = arguments().immediate(); | 2035 const int argc = arguments().immediate(); |
| 2142 StackArgumentsAccessor args(rsp, argc); | 2036 StackArgumentsAccessor args(rsp, argc); |
| 2143 | 2037 |
| 2144 Label miss; | 2038 Label miss; |
| 2145 Label name_miss; | 2039 Label name_miss; |
| 2146 Label index_out_of_range; | 2040 Label index_out_of_range; |
| 2147 Label* index_out_of_range_label = &index_out_of_range; | 2041 Label* index_out_of_range_label = &index_out_of_range; |
| 2148 if (kind_ == Code::CALL_IC && | 2042 if (kind_ == Code::CALL_IC && |
| 2149 (CallICBase::StringStubState::decode(extra_state_) == | 2043 (CallICBase::StringStubState::decode(extra_state_) == |
| 2150 DEFAULT_STRING_STUB)) { | 2044 DEFAULT_STRING_STUB)) { |
| 2151 index_out_of_range_label = &miss; | 2045 index_out_of_range_label = &miss; |
| 2152 } | 2046 } |
| 2153 GenerateNameCheck(name, &name_miss); | |
| 2154 | 2047 |
| 2155 // Check that the maps starting from the prototype haven't changed. | 2048 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss); |
| 2156 GenerateDirectLoadGlobalFunctionPrototype(masm(), | |
| 2157 Context::STRING_FUNCTION_INDEX, | |
| 2158 rax, | |
| 2159 &miss); | |
| 2160 ASSERT(!object.is_identical_to(holder)); | |
| 2161 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); | |
| 2162 CheckPrototypes( | |
| 2163 IC::CurrentTypeOf(prototype, isolate()), | |
| 2164 rax, holder, rbx, rdx, rdi, name, &miss); | |
| 2165 | 2049 |
| 2166 Register receiver = rax; | 2050 Register receiver = rax; |
| 2167 Register index = rdi; | 2051 Register index = rdi; |
| 2168 Register scratch = rdx; | 2052 Register scratch = rdx; |
| 2169 Register result = rax; | 2053 Register result = rax; |
| 2170 __ movq(receiver, args.GetReceiverOperand()); | 2054 __ movq(receiver, args.GetReceiverOperand()); |
| 2171 if (argc > 0) { | 2055 if (argc > 0) { |
| 2172 __ movq(index, args.GetArgumentOperand(1)); | 2056 __ movq(index, args.GetArgumentOperand(1)); |
| 2173 } else { | 2057 } else { |
| 2174 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); | 2058 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2204 } | 2088 } |
| 2205 | 2089 |
| 2206 | 2090 |
| 2207 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( | 2091 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( |
| 2208 Handle<Object> object, | 2092 Handle<Object> object, |
| 2209 Handle<JSObject> holder, | 2093 Handle<JSObject> holder, |
| 2210 Handle<Cell> cell, | 2094 Handle<Cell> cell, |
| 2211 Handle<JSFunction> function, | 2095 Handle<JSFunction> function, |
| 2212 Handle<String> name, | 2096 Handle<String> name, |
| 2213 Code::StubType type) { | 2097 Code::StubType type) { |
| 2214 // ----------- S t a t e ------------- | |
| 2215 // -- rcx : function name | |
| 2216 // -- rsp[0] : return address | |
| 2217 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | |
| 2218 // -- ... | |
| 2219 // -- rsp[(argc + 1) * 8] : receiver | |
| 2220 // ----------------------------------- | |
| 2221 | |
| 2222 // If the object is not a JSObject or we got an unexpected number of | 2098 // If the object is not a JSObject or we got an unexpected number of |
| 2223 // arguments, bail out to the regular call. | 2099 // arguments, bail out to the regular call. |
| 2224 const int argc = arguments().immediate(); | 2100 const int argc = arguments().immediate(); |
| 2225 StackArgumentsAccessor args(rsp, argc); | 2101 StackArgumentsAccessor args(rsp, argc); |
| 2226 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); | 2102 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); |
| 2227 | 2103 |
| 2228 Label miss; | 2104 Label miss; |
| 2229 GenerateNameCheck(name, &miss); | |
| 2230 | 2105 |
| 2231 if (cell.is_null()) { | 2106 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); |
| 2232 __ movq(rdx, args.GetReceiverOperand()); | 2107 if (!cell.is_null()) { |
| 2233 __ JumpIfSmi(rdx, &miss); | |
| 2234 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder, | |
| 2235 rbx, rax, rdi, name, &miss); | |
| 2236 } else { | |
| 2237 ASSERT(cell->value() == *function); | 2108 ASSERT(cell->value() == *function); |
| 2238 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | |
| 2239 &miss); | |
| 2240 GenerateLoadFunctionFromCell(cell, function, &miss); | 2109 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 2241 } | 2110 } |
| 2242 | 2111 |
| 2243 // Load the char code argument. | 2112 // Load the char code argument. |
| 2244 Register code = rbx; | 2113 Register code = rbx; |
| 2245 __ movq(code, args.GetArgumentOperand(1)); | 2114 __ movq(code, args.GetArgumentOperand(1)); |
| 2246 | 2115 |
| 2247 // Check the code is a smi. | 2116 // Check the code is a smi. |
| 2248 Label slow; | 2117 Label slow; |
| 2249 __ JumpIfNotSmi(code, &slow); | 2118 __ JumpIfNotSmi(code, &slow); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2261 // Tail call the full function. We do not have to patch the receiver | 2130 // Tail call the full function. We do not have to patch the receiver |
| 2262 // because the function makes no use of it. | 2131 // because the function makes no use of it. |
| 2263 __ bind(&slow); | 2132 __ bind(&slow); |
| 2264 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2133 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
| 2265 ? CALL_AS_FUNCTION | 2134 ? CALL_AS_FUNCTION |
| 2266 : CALL_AS_METHOD; | 2135 : CALL_AS_METHOD; |
| 2267 ParameterCount expected(function); | 2136 ParameterCount expected(function); |
| 2268 __ InvokeFunction(function, expected, arguments(), | 2137 __ InvokeFunction(function, expected, arguments(), |
| 2269 JUMP_FUNCTION, NullCallWrapper(), call_kind); | 2138 JUMP_FUNCTION, NullCallWrapper(), call_kind); |
| 2270 | 2139 |
| 2271 __ bind(&miss); | 2140 HandlerFrontendFooter(&miss); |
| 2272 // rcx: function name. | |
| 2273 GenerateMissBranch(); | |
| 2274 | 2141 |
| 2275 // Return the generated code. | 2142 // Return the generated code. |
| 2276 return GetCode(type, name); | 2143 return GetCode(type, name); |
| 2277 } | 2144 } |
| 2278 | 2145 |
| 2279 | 2146 |
| 2280 Handle<Code> CallStubCompiler::CompileMathFloorCall( | 2147 Handle<Code> CallStubCompiler::CompileMathFloorCall( |
| 2281 Handle<Object> object, | 2148 Handle<Object> object, |
| 2282 Handle<JSObject> holder, | 2149 Handle<JSObject> holder, |
| 2283 Handle<Cell> cell, | 2150 Handle<Cell> cell, |
| 2284 Handle<JSFunction> function, | 2151 Handle<JSFunction> function, |
| 2285 Handle<String> name, | 2152 Handle<String> name, |
| 2286 Code::StubType type) { | 2153 Code::StubType type) { |
| 2287 // ----------- S t a t e ------------- | |
| 2288 // -- rcx : name | |
| 2289 // -- rsp[0] : return address | |
| 2290 // -- rsp[(argc - n) * 4] : arg[n] (zero-based) | |
| 2291 // -- ... | |
| 2292 // -- rsp[(argc + 1) * 4] : receiver | |
| 2293 // ----------------------------------- | |
| 2294 const int argc = arguments().immediate(); | 2154 const int argc = arguments().immediate(); |
| 2295 StackArgumentsAccessor args(rsp, argc); | 2155 StackArgumentsAccessor args(rsp, argc); |
| 2296 | 2156 |
| 2297 // If the object is not a JSObject or we got an unexpected number of | 2157 // If the object is not a JSObject or we got an unexpected number of |
| 2298 // arguments, bail out to the regular call. | 2158 // arguments, bail out to the regular call. |
| 2299 if (!object->IsJSObject() || argc != 1) { | 2159 if (!object->IsJSObject() || argc != 1) { |
| 2300 return Handle<Code>::null(); | 2160 return Handle<Code>::null(); |
| 2301 } | 2161 } |
| 2302 | 2162 |
| 2303 Label miss; | 2163 Label miss, slow; |
| 2304 GenerateNameCheck(name, &miss); | |
| 2305 | 2164 |
| 2306 if (cell.is_null()) { | 2165 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); |
| 2307 __ movq(rdx, args.GetReceiverOperand()); | 2166 if (!cell.is_null()) { |
| 2308 | |
| 2309 STATIC_ASSERT(kSmiTag == 0); | |
| 2310 __ JumpIfSmi(rdx, &miss); | |
| 2311 | |
| 2312 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder, | |
| 2313 rbx, rax, rdi, name, &miss); | |
| 2314 } else { | |
| 2315 ASSERT(cell->value() == *function); | 2167 ASSERT(cell->value() == *function); |
| 2316 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | |
| 2317 &miss); | |
| 2318 GenerateLoadFunctionFromCell(cell, function, &miss); | 2168 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 2319 } | 2169 } |
| 2320 | 2170 |
| 2321 // Load the (only) argument into rax. | 2171 // Load the (only) argument into rax. |
| 2322 __ movq(rax, args.GetArgumentOperand(1)); | 2172 __ movq(rax, args.GetArgumentOperand(1)); |
| 2323 | 2173 |
| 2324 // Check if the argument is a smi. | 2174 // Check if the argument is a smi. |
| 2325 Label smi; | 2175 Label smi; |
| 2326 STATIC_ASSERT(kSmiTag == 0); | 2176 STATIC_ASSERT(kSmiTag == 0); |
| 2327 __ JumpIfSmi(rax, &smi); | 2177 __ JumpIfSmi(rax, &smi); |
| 2328 | 2178 |
| 2329 // Check if the argument is a heap number and load its value into xmm0. | 2179 // Check if the argument is a heap number and load its value into xmm0. |
| 2330 Label slow; | |
| 2331 __ CheckMap(rax, factory()->heap_number_map(), &slow, DONT_DO_SMI_CHECK); | 2180 __ CheckMap(rax, factory()->heap_number_map(), &slow, DONT_DO_SMI_CHECK); |
| 2332 __ movsd(xmm0, FieldOperand(rax, HeapNumber::kValueOffset)); | 2181 __ movsd(xmm0, FieldOperand(rax, HeapNumber::kValueOffset)); |
| 2333 | 2182 |
| 2334 // Check if the argument is strictly positive. Note this also discards NaN. | 2183 // Check if the argument is strictly positive. Note this also discards NaN. |
| 2335 __ xorpd(xmm1, xmm1); | 2184 __ xorpd(xmm1, xmm1); |
| 2336 __ ucomisd(xmm0, xmm1); | 2185 __ ucomisd(xmm0, xmm1); |
| 2337 __ j(below_equal, &slow); | 2186 __ j(below_equal, &slow); |
| 2338 | 2187 |
| 2339 // Do a truncating conversion. | 2188 // Do a truncating conversion. |
| 2340 __ cvttsd2si(rax, xmm0); | 2189 __ cvttsd2si(rax, xmm0); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2389 __ movq(rax, args.GetArgumentOperand(1)); | 2238 __ movq(rax, args.GetArgumentOperand(1)); |
| 2390 __ ret(2 * kPointerSize); | 2239 __ ret(2 * kPointerSize); |
| 2391 | 2240 |
| 2392 // Tail call the full function. We do not have to patch the receiver | 2241 // Tail call the full function. We do not have to patch the receiver |
| 2393 // because the function makes no use of it. | 2242 // because the function makes no use of it. |
| 2394 __ bind(&slow); | 2243 __ bind(&slow); |
| 2395 ParameterCount expected(function); | 2244 ParameterCount expected(function); |
| 2396 __ InvokeFunction(function, expected, arguments(), | 2245 __ InvokeFunction(function, expected, arguments(), |
| 2397 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | 2246 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); |
| 2398 | 2247 |
| 2399 __ bind(&miss); | 2248 HandlerFrontendFooter(&miss); |
| 2400 // rcx: function name. | |
| 2401 GenerateMissBranch(); | |
| 2402 | 2249 |
| 2403 // Return the generated code. | 2250 // Return the generated code. |
| 2404 return GetCode(type, name); | 2251 return GetCode(type, name); |
| 2405 } | 2252 } |
| 2406 | 2253 |
| 2407 | 2254 |
| 2408 Handle<Code> CallStubCompiler::CompileMathAbsCall( | 2255 Handle<Code> CallStubCompiler::CompileMathAbsCall( |
| 2409 Handle<Object> object, | 2256 Handle<Object> object, |
| 2410 Handle<JSObject> holder, | 2257 Handle<JSObject> holder, |
| 2411 Handle<Cell> cell, | 2258 Handle<Cell> cell, |
| 2412 Handle<JSFunction> function, | 2259 Handle<JSFunction> function, |
| 2413 Handle<String> name, | 2260 Handle<String> name, |
| 2414 Code::StubType type) { | 2261 Code::StubType type) { |
| 2415 // ----------- S t a t e ------------- | |
| 2416 // -- rcx : function name | |
| 2417 // -- rsp[0] : return address | |
| 2418 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | |
| 2419 // -- ... | |
| 2420 // -- rsp[(argc + 1) * 8] : receiver | |
| 2421 // ----------------------------------- | |
| 2422 | |
| 2423 // If the object is not a JSObject or we got an unexpected number of | 2262 // If the object is not a JSObject or we got an unexpected number of |
| 2424 // arguments, bail out to the regular call. | 2263 // arguments, bail out to the regular call. |
| 2425 const int argc = arguments().immediate(); | 2264 const int argc = arguments().immediate(); |
| 2426 StackArgumentsAccessor args(rsp, argc); | 2265 StackArgumentsAccessor args(rsp, argc); |
| 2427 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); | 2266 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); |
| 2428 | 2267 |
| 2429 Label miss; | 2268 Label miss; |
| 2430 GenerateNameCheck(name, &miss); | |
| 2431 | 2269 |
| 2432 if (cell.is_null()) { | 2270 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); |
| 2433 __ movq(rdx, args.GetReceiverOperand()); | 2271 if (!cell.is_null()) { |
| 2434 __ JumpIfSmi(rdx, &miss); | |
| 2435 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder, | |
| 2436 rbx, rax, rdi, name, &miss); | |
| 2437 } else { | |
| 2438 ASSERT(cell->value() == *function); | 2272 ASSERT(cell->value() == *function); |
| 2439 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | |
| 2440 &miss); | |
| 2441 GenerateLoadFunctionFromCell(cell, function, &miss); | 2273 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 2442 } | 2274 } |
| 2275 |
| 2443 // Load the (only) argument into rax. | 2276 // Load the (only) argument into rax. |
| 2444 __ movq(rax, args.GetArgumentOperand(1)); | 2277 __ movq(rax, args.GetArgumentOperand(1)); |
| 2445 | 2278 |
| 2446 // Check if the argument is a smi. | 2279 // Check if the argument is a smi. |
| 2447 Label not_smi; | 2280 Label not_smi; |
| 2448 STATIC_ASSERT(kSmiTag == 0); | 2281 STATIC_ASSERT(kSmiTag == 0); |
| 2449 __ JumpIfNotSmi(rax, ¬_smi); | 2282 __ JumpIfNotSmi(rax, ¬_smi); |
| 2450 | 2283 |
| 2451 // Branchless abs implementation, refer to below: | 2284 // Branchless abs implementation, refer to below: |
| 2452 // http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs | 2285 // http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2494 // Tail call the full function. We do not have to patch the receiver | 2327 // Tail call the full function. We do not have to patch the receiver |
| 2495 // because the function makes no use of it. | 2328 // because the function makes no use of it. |
| 2496 __ bind(&slow); | 2329 __ bind(&slow); |
| 2497 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2330 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
| 2498 ? CALL_AS_FUNCTION | 2331 ? CALL_AS_FUNCTION |
| 2499 : CALL_AS_METHOD; | 2332 : CALL_AS_METHOD; |
| 2500 ParameterCount expected(function); | 2333 ParameterCount expected(function); |
| 2501 __ InvokeFunction(function, expected, arguments(), | 2334 __ InvokeFunction(function, expected, arguments(), |
| 2502 JUMP_FUNCTION, NullCallWrapper(), call_kind); | 2335 JUMP_FUNCTION, NullCallWrapper(), call_kind); |
| 2503 | 2336 |
| 2504 __ bind(&miss); | 2337 HandlerFrontendFooter(&miss); |
| 2505 // rcx: function name. | |
| 2506 GenerateMissBranch(); | |
| 2507 | 2338 |
| 2508 // Return the generated code. | 2339 // Return the generated code. |
| 2509 return GetCode(type, name); | 2340 return GetCode(type, name); |
| 2510 } | 2341 } |
| 2511 | 2342 |
| 2512 | 2343 |
| 2513 Handle<Code> CallStubCompiler::CompileFastApiCall( | 2344 Handle<Code> CallStubCompiler::CompileFastApiCall( |
| 2514 const CallOptimization& optimization, | 2345 const CallOptimization& optimization, |
| 2515 Handle<Object> object, | 2346 Handle<Object> object, |
| 2516 Handle<JSObject> holder, | 2347 Handle<JSObject> holder, |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2571 Label success; | 2402 Label success; |
| 2572 // Check that the object is a boolean. | 2403 // Check that the object is a boolean. |
| 2573 __ CompareRoot(object, Heap::kTrueValueRootIndex); | 2404 __ CompareRoot(object, Heap::kTrueValueRootIndex); |
| 2574 __ j(equal, &success); | 2405 __ j(equal, &success); |
| 2575 __ CompareRoot(object, Heap::kFalseValueRootIndex); | 2406 __ CompareRoot(object, Heap::kFalseValueRootIndex); |
| 2576 __ j(not_equal, miss); | 2407 __ j(not_equal, miss); |
| 2577 __ bind(&success); | 2408 __ bind(&success); |
| 2578 } | 2409 } |
| 2579 | 2410 |
| 2580 | 2411 |
| 2581 void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object, | 2412 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) { |
| 2582 Handle<JSObject> holder, | 2413 if (object->IsGlobalObject()) { |
| 2583 Handle<Name> name, | 2414 StackArgumentsAccessor args(rsp, arguments()); |
| 2584 CheckType check) { | 2415 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); |
| 2585 // ----------- S t a t e ------------- | 2416 __ movq(args.GetReceiverOperand(), rdx); |
| 2586 // rcx : function name | 2417 } |
| 2587 // rsp[0] : return address | 2418 } |
| 2588 // rsp[8] : argument argc | 2419 |
| 2589 // rsp[16] : argument argc - 1 | 2420 |
| 2590 // ... | 2421 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object, |
| 2591 // rsp[argc * 8] : argument 1 | 2422 Handle<JSObject> holder, |
| 2592 // rsp[(argc + 1) * 8] : argument 0 = receiver | 2423 Handle<Name> name, |
| 2593 // ----------------------------------- | 2424 CheckType check, |
| 2594 Label miss; | 2425 Label* miss) { |
| 2595 GenerateNameCheck(name, &miss); | 2426 GenerateNameCheck(name, miss); |
| 2427 |
| 2428 Register reg = rdx; |
| 2596 | 2429 |
| 2597 StackArgumentsAccessor args(rsp, arguments()); | 2430 StackArgumentsAccessor args(rsp, arguments()); |
| 2598 __ movq(rdx, args.GetReceiverOperand()); | 2431 __ movq(reg, args.GetReceiverOperand()); |
| 2599 | 2432 |
| 2600 // Check that the receiver isn't a smi. | 2433 // Check that the receiver isn't a smi. |
| 2601 if (check != NUMBER_CHECK) { | 2434 if (check != NUMBER_CHECK) { |
| 2602 __ JumpIfSmi(rdx, &miss); | 2435 __ JumpIfSmi(reg, miss); |
| 2603 } | 2436 } |
| 2604 | 2437 |
| 2605 // Make sure that it's okay not to patch the on stack receiver | 2438 // Make sure that it's okay not to patch the on stack receiver |
| 2606 // unless we're doing a receiver map check. | 2439 // unless we're doing a receiver map check. |
| 2607 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); | 2440 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); |
| 2608 | 2441 |
| 2609 Counters* counters = isolate()->counters(); | 2442 Counters* counters = isolate()->counters(); |
| 2610 switch (check) { | 2443 switch (check) { |
| 2611 case RECEIVER_MAP_CHECK: | 2444 case RECEIVER_MAP_CHECK: |
| 2612 __ IncrementCounter(counters->call_const(), 1); | 2445 __ IncrementCounter(counters->call_const(), 1); |
| 2613 | 2446 |
| 2614 // Check that the maps haven't changed. | 2447 // Check that the maps haven't changed. |
| 2615 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder, | 2448 reg = CheckPrototypes(IC::CurrentTypeOf(object, isolate()), reg, holder, |
| 2616 rbx, rax, rdi, name, &miss); | 2449 rbx, rax, rdi, name, miss); |
| 2617 | |
| 2618 // Patch the receiver on the stack with the global proxy if | |
| 2619 // necessary. | |
| 2620 if (object->IsGlobalObject()) { | |
| 2621 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); | |
| 2622 __ movq(args.GetReceiverOperand(), rdx); | |
| 2623 } | |
| 2624 break; | 2450 break; |
| 2625 | 2451 |
| 2626 case STRING_CHECK: { | 2452 case STRING_CHECK: { |
| 2627 // Check that the object is a string. | 2453 // Check that the object is a string. |
| 2628 __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rax); | 2454 __ CmpObjectType(reg, FIRST_NONSTRING_TYPE, rax); |
| 2629 __ j(above_equal, &miss); | 2455 __ j(above_equal, miss); |
| 2630 // Check that the maps starting from the prototype haven't changed. | 2456 // Check that the maps starting from the prototype haven't changed. |
| 2631 GenerateDirectLoadGlobalFunctionPrototype( | 2457 GenerateDirectLoadGlobalFunctionPrototype( |
| 2632 masm(), Context::STRING_FUNCTION_INDEX, rax, &miss); | 2458 masm(), Context::STRING_FUNCTION_INDEX, rax, miss); |
| 2633 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); | |
| 2634 CheckPrototypes( | |
| 2635 IC::CurrentTypeOf(prototype, isolate()), | |
| 2636 rax, holder, rbx, rdx, rdi, name, &miss); | |
| 2637 break; | 2459 break; |
| 2638 } | 2460 } |
| 2639 case SYMBOL_CHECK: { | 2461 case SYMBOL_CHECK: { |
| 2640 // Check that the object is a symbol. | 2462 // Check that the object is a symbol. |
| 2641 __ CmpObjectType(rdx, SYMBOL_TYPE, rax); | 2463 __ CmpObjectType(reg, SYMBOL_TYPE, rax); |
| 2642 __ j(not_equal, &miss); | 2464 __ j(not_equal, miss); |
| 2643 // Check that the maps starting from the prototype haven't changed. | 2465 // Check that the maps starting from the prototype haven't changed. |
| 2644 GenerateDirectLoadGlobalFunctionPrototype( | 2466 GenerateDirectLoadGlobalFunctionPrototype( |
| 2645 masm(), Context::SYMBOL_FUNCTION_INDEX, rax, &miss); | 2467 masm(), Context::SYMBOL_FUNCTION_INDEX, rax, miss); |
| 2646 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); | |
| 2647 CheckPrototypes( | |
| 2648 IC::CurrentTypeOf(prototype, isolate()), | |
| 2649 rax, holder, rbx, rdx, rdi, name, &miss); | |
| 2650 break; | 2468 break; |
| 2651 } | 2469 } |
| 2652 case NUMBER_CHECK: { | 2470 case NUMBER_CHECK: { |
| 2653 Label fast; | 2471 Label fast; |
| 2654 // Check that the object is a smi or a heap number. | 2472 // Check that the object is a smi or a heap number. |
| 2655 __ JumpIfSmi(rdx, &fast); | 2473 __ JumpIfSmi(reg, &fast); |
| 2656 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rax); | 2474 __ CmpObjectType(reg, HEAP_NUMBER_TYPE, rax); |
| 2657 __ j(not_equal, &miss); | 2475 __ j(not_equal, miss); |
| 2658 __ bind(&fast); | 2476 __ bind(&fast); |
| 2659 // Check that the maps starting from the prototype haven't changed. | 2477 // Check that the maps starting from the prototype haven't changed. |
| 2660 GenerateDirectLoadGlobalFunctionPrototype( | 2478 GenerateDirectLoadGlobalFunctionPrototype( |
| 2661 masm(), Context::NUMBER_FUNCTION_INDEX, rax, &miss); | 2479 masm(), Context::NUMBER_FUNCTION_INDEX, rax, miss); |
| 2662 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); | |
| 2663 CheckPrototypes( | |
| 2664 IC::CurrentTypeOf(prototype, isolate()), | |
| 2665 rax, holder, rbx, rdx, rdi, name, &miss); | |
| 2666 break; | 2480 break; |
| 2667 } | 2481 } |
| 2668 case BOOLEAN_CHECK: { | 2482 case BOOLEAN_CHECK: { |
| 2669 GenerateBooleanCheck(rdx, &miss); | 2483 GenerateBooleanCheck(reg, miss); |
| 2670 // Check that the maps starting from the prototype haven't changed. | 2484 // Check that the maps starting from the prototype haven't changed. |
| 2671 GenerateDirectLoadGlobalFunctionPrototype( | 2485 GenerateDirectLoadGlobalFunctionPrototype( |
| 2672 masm(), Context::BOOLEAN_FUNCTION_INDEX, rax, &miss); | 2486 masm(), Context::BOOLEAN_FUNCTION_INDEX, rax, miss); |
| 2673 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); | |
| 2674 CheckPrototypes( | |
| 2675 IC::CurrentTypeOf(prototype, isolate()), | |
| 2676 rax, holder, rbx, rdx, rdi, name, &miss); | |
| 2677 break; | 2487 break; |
| 2678 } | 2488 } |
| 2679 } | 2489 } |
| 2680 | 2490 |
| 2681 Label success; | 2491 if (check != RECEIVER_MAP_CHECK) { |
| 2682 __ jmp(&success); | 2492 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
| 2493 reg = CheckPrototypes( |
| 2494 IC::CurrentTypeOf(prototype, isolate()), |
| 2495 rax, holder, rbx, rdx, rdi, name, miss); |
| 2496 } |
| 2683 | 2497 |
| 2684 // Handle call cache miss. | 2498 return reg; |
| 2685 __ bind(&miss); | |
| 2686 GenerateMissBranch(); | |
| 2687 | |
| 2688 __ bind(&success); | |
| 2689 } | 2499 } |
| 2690 | 2500 |
| 2691 | 2501 |
| 2692 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { | 2502 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { |
| 2693 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2503 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
| 2694 ? CALL_AS_FUNCTION | 2504 ? CALL_AS_FUNCTION |
| 2695 : CALL_AS_METHOD; | 2505 : CALL_AS_METHOD; |
| 2696 ParameterCount expected(function); | 2506 ParameterCount expected(function); |
| 2697 __ InvokeFunction(function, expected, arguments(), | 2507 __ InvokeFunction(function, expected, arguments(), |
| 2698 JUMP_FUNCTION, NullCallWrapper(), call_kind); | 2508 JUMP_FUNCTION, NullCallWrapper(), call_kind); |
| 2699 } | 2509 } |
| 2700 | 2510 |
| 2701 | 2511 |
| 2702 Handle<Code> CallStubCompiler::CompileCallConstant( | 2512 Handle<Code> CallStubCompiler::CompileCallConstant( |
| 2703 Handle<Object> object, | 2513 Handle<Object> object, |
| 2704 Handle<JSObject> holder, | 2514 Handle<JSObject> holder, |
| 2705 Handle<Name> name, | 2515 Handle<Name> name, |
| 2706 CheckType check, | 2516 CheckType check, |
| 2707 Handle<JSFunction> function) { | 2517 Handle<JSFunction> function) { |
| 2708 if (HasCustomCallGenerator(function)) { | 2518 if (HasCustomCallGenerator(function)) { |
| 2709 Handle<Code> code = CompileCustomCall(object, holder, | 2519 Handle<Code> code = CompileCustomCall(object, holder, |
| 2710 Handle<PropertyCell>::null(), | 2520 Handle<PropertyCell>::null(), |
| 2711 function, Handle<String>::cast(name), | 2521 function, Handle<String>::cast(name), |
| 2712 Code::FAST); | 2522 Code::FAST); |
| 2713 // A null handle means bail out to the regular compiler code below. | 2523 // A null handle means bail out to the regular compiler code below. |
| 2714 if (!code.is_null()) return code; | 2524 if (!code.is_null()) return code; |
| 2715 } | 2525 } |
| 2716 | 2526 |
| 2717 CompileHandlerFrontend(object, holder, name, check); | 2527 Label miss; |
| 2528 HandlerFrontendHeader(object, holder, name, check, &miss); |
| 2529 PatchGlobalProxy(object); |
| 2718 CompileHandlerBackend(function); | 2530 CompileHandlerBackend(function); |
| 2531 HandlerFrontendFooter(&miss); |
| 2719 | 2532 |
| 2720 // Return the generated code. | 2533 // Return the generated code. |
| 2721 return GetCode(function); | 2534 return GetCode(function); |
| 2722 } | 2535 } |
| 2723 | 2536 |
| 2724 | 2537 |
| 2725 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, | 2538 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, |
| 2726 Handle<JSObject> holder, | 2539 Handle<JSObject> holder, |
| 2727 Handle<Name> name) { | 2540 Handle<Name> name) { |
| 2728 // ----------- S t a t e ------------- | |
| 2729 // rcx : function name | |
| 2730 // rsp[0] : return address | |
| 2731 // rsp[8] : argument argc | |
| 2732 // rsp[16] : argument argc - 1 | |
| 2733 // ... | |
| 2734 // rsp[argc * 8] : argument 1 | |
| 2735 // rsp[(argc + 1) * 8] : argument 0 = receiver | |
| 2736 // ----------------------------------- | |
| 2737 Label miss; | 2541 Label miss; |
| 2738 GenerateNameCheck(name, &miss); | 2542 GenerateNameCheck(name, &miss); |
| 2739 | 2543 |
| 2740 | |
| 2741 LookupResult lookup(isolate()); | 2544 LookupResult lookup(isolate()); |
| 2742 LookupPostInterceptor(holder, name, &lookup); | 2545 LookupPostInterceptor(holder, name, &lookup); |
| 2743 | 2546 |
| 2744 // Get the receiver from the stack. | 2547 // Get the receiver from the stack. |
| 2745 StackArgumentsAccessor args(rsp, arguments()); | 2548 StackArgumentsAccessor args(rsp, arguments()); |
| 2746 __ movq(rdx, args.GetReceiverOperand()); | 2549 __ movq(rdx, args.GetReceiverOperand()); |
| 2747 | 2550 |
| 2748 CallInterceptorCompiler compiler(this, arguments(), rcx, extra_state_); | 2551 CallInterceptorCompiler compiler(this, arguments(), rcx, extra_state_); |
| 2749 compiler.Compile(masm(), object, holder, name, &lookup, rdx, rbx, rdi, rax, | 2552 compiler.Compile(masm(), object, holder, name, &lookup, rdx, rbx, rdi, rax, |
| 2750 &miss); | 2553 &miss); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2780 return GetCode(Code::FAST, name); | 2583 return GetCode(Code::FAST, name); |
| 2781 } | 2584 } |
| 2782 | 2585 |
| 2783 | 2586 |
| 2784 Handle<Code> CallStubCompiler::CompileCallGlobal( | 2587 Handle<Code> CallStubCompiler::CompileCallGlobal( |
| 2785 Handle<JSObject> object, | 2588 Handle<JSObject> object, |
| 2786 Handle<GlobalObject> holder, | 2589 Handle<GlobalObject> holder, |
| 2787 Handle<PropertyCell> cell, | 2590 Handle<PropertyCell> cell, |
| 2788 Handle<JSFunction> function, | 2591 Handle<JSFunction> function, |
| 2789 Handle<Name> name) { | 2592 Handle<Name> name) { |
| 2790 // ----------- S t a t e ------------- | |
| 2791 // rcx : function name | |
| 2792 // rsp[0] : return address | |
| 2793 // rsp[8] : argument argc | |
| 2794 // rsp[16] : argument argc - 1 | |
| 2795 // ... | |
| 2796 // rsp[argc * 8] : argument 1 | |
| 2797 // rsp[(argc + 1) * 8] : argument 0 = receiver | |
| 2798 // ----------------------------------- | |
| 2799 | |
| 2800 if (HasCustomCallGenerator(function)) { | 2593 if (HasCustomCallGenerator(function)) { |
| 2801 Handle<Code> code = CompileCustomCall( | 2594 Handle<Code> code = CompileCustomCall( |
| 2802 object, holder, cell, function, Handle<String>::cast(name), | 2595 object, holder, cell, function, Handle<String>::cast(name), |
| 2803 Code::NORMAL); | 2596 Code::NORMAL); |
| 2804 // A null handle means bail out to the regular compiler code below. | 2597 // A null handle means bail out to the regular compiler code below. |
| 2805 if (!code.is_null()) return code; | 2598 if (!code.is_null()) return code; |
| 2806 } | 2599 } |
| 2807 | 2600 |
| 2808 Label miss; | 2601 Label miss; |
| 2809 GenerateNameCheck(name, &miss); | 2602 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); |
| 2810 | |
| 2811 StackArgumentsAccessor args(rsp, arguments()); | |
| 2812 GenerateGlobalReceiverCheck(object, holder, name, &miss); | |
| 2813 GenerateLoadFunctionFromCell(cell, function, &miss); | 2603 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 2814 | 2604 PatchGlobalProxy(object); |
| 2815 // Patch the receiver on the stack with the global proxy. | |
| 2816 if (object->IsGlobalObject()) { | |
| 2817 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); | |
| 2818 __ movq(args.GetReceiverOperand(), rdx); | |
| 2819 } | |
| 2820 | 2605 |
| 2821 // Set up the context (function already in rdi). | 2606 // Set up the context (function already in rdi). |
| 2822 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); | 2607 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
| 2823 | 2608 |
| 2824 // Jump to the cached code (tail call). | 2609 // Jump to the cached code (tail call). |
| 2825 Counters* counters = isolate()->counters(); | 2610 Counters* counters = isolate()->counters(); |
| 2826 __ IncrementCounter(counters->call_global_inline(), 1); | 2611 __ IncrementCounter(counters->call_global_inline(), 1); |
| 2827 ParameterCount expected(function->shared()->formal_parameter_count()); | 2612 ParameterCount expected(function->shared()->formal_parameter_count()); |
| 2828 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2613 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
| 2829 ? CALL_AS_FUNCTION | 2614 ? CALL_AS_FUNCTION |
| 2830 : CALL_AS_METHOD; | 2615 : CALL_AS_METHOD; |
| 2831 // We call indirectly through the code field in the function to | 2616 // We call indirectly through the code field in the function to |
| 2832 // allow recompilation to take effect without changing any of the | 2617 // allow recompilation to take effect without changing any of the |
| 2833 // call sites. | 2618 // call sites. |
| 2834 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); | 2619 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); |
| 2835 __ InvokeCode(rdx, expected, arguments(), JUMP_FUNCTION, | 2620 __ InvokeCode(rdx, expected, arguments(), JUMP_FUNCTION, |
| 2836 NullCallWrapper(), call_kind); | 2621 NullCallWrapper(), call_kind); |
| 2837 | 2622 |
| 2838 // Handle call cache miss. | 2623 HandlerFrontendFooter(&miss); |
| 2839 __ bind(&miss); | |
| 2840 __ IncrementCounter(counters->call_global_inline_miss(), 1); | |
| 2841 GenerateMissBranch(); | |
| 2842 | 2624 |
| 2843 // Return the generated code. | 2625 // Return the generated code. |
| 2844 return GetCode(Code::NORMAL, name); | 2626 return GetCode(Code::NORMAL, name); |
| 2845 } | 2627 } |
| 2846 | 2628 |
| 2847 | 2629 |
| 2848 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 2630 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
| 2849 Handle<JSObject> object, | 2631 Handle<JSObject> object, |
| 2850 Handle<JSObject> holder, | 2632 Handle<JSObject> holder, |
| 2851 Handle<Name> name, | 2633 Handle<Name> name, |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2935 #define __ ACCESS_MASM(masm()) | 2717 #define __ ACCESS_MASM(masm()) |
| 2936 | 2718 |
| 2937 | 2719 |
| 2938 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( | 2720 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( |
| 2939 Handle<JSObject> object, | 2721 Handle<JSObject> object, |
| 2940 Handle<Name> name) { | 2722 Handle<Name> name) { |
| 2941 __ PopReturnAddressTo(scratch1()); | 2723 __ PopReturnAddressTo(scratch1()); |
| 2942 __ push(receiver()); | 2724 __ push(receiver()); |
| 2943 __ push(this->name()); | 2725 __ push(this->name()); |
| 2944 __ push(value()); | 2726 __ push(value()); |
| 2945 __ Push(Smi::FromInt(strict_mode())); | |
| 2946 __ PushReturnAddressFrom(scratch1()); | 2727 __ PushReturnAddressFrom(scratch1()); |
| 2947 | 2728 |
| 2948 // Do tail-call to the runtime system. | 2729 // Do tail-call to the runtime system. |
| 2949 ExternalReference store_ic_property = | 2730 ExternalReference store_ic_property = |
| 2950 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); | 2731 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); |
| 2951 __ TailCallExternalReference(store_ic_property, 4, 1); | 2732 __ TailCallExternalReference(store_ic_property, 3, 1); |
| 2952 | 2733 |
| 2953 // Return the generated code. | 2734 // Return the generated code. |
| 2954 return GetCode(kind(), Code::FAST, name); | 2735 return GetCode(kind(), Code::FAST, name); |
| 2955 } | 2736 } |
| 2956 | 2737 |
| 2957 | 2738 |
| 2958 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( | 2739 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( |
| 2959 MapHandleList* receiver_maps, | 2740 MapHandleList* receiver_maps, |
| 2960 CodeHandleList* handler_stubs, | 2741 CodeHandleList* handler_stubs, |
| 2961 MapHandleList* transitioned_maps) { | 2742 MapHandleList* transitioned_maps) { |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3215 // ----------------------------------- | 2996 // ----------------------------------- |
| 3216 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 2997 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
| 3217 } | 2998 } |
| 3218 | 2999 |
| 3219 | 3000 |
| 3220 #undef __ | 3001 #undef __ |
| 3221 | 3002 |
| 3222 } } // namespace v8::internal | 3003 } } // namespace v8::internal |
| 3223 | 3004 |
| 3224 #endif // V8_TARGET_ARCH_X64 | 3005 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |