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

Side by Side Diff: src/x64/stub-cache-x64.cc

Issue 83753002: Use the HandlerFrontendHeader in most call compilers. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: X64 port Created 7 years 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 | Annotate | Revision Log
« src/ia32/stub-cache-ia32.cc ('K') | « src/stub-cache.cc ('k') | no next file » | 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 // 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 1531 matching lines...) Expand 10 before | Expand all | Expand 10 after
1542 1542
1543 1543
1544 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { 1544 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) {
1545 if (kind_ == Code::KEYED_CALL_IC) { 1545 if (kind_ == Code::KEYED_CALL_IC) {
1546 __ Cmp(rcx, name); 1546 __ Cmp(rcx, name);
1547 __ j(not_equal, miss); 1547 __ j(not_equal, miss);
1548 } 1548 }
1549 } 1549 }
1550 1550
1551 1551
1552 void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object,
1553 Handle<JSObject> holder,
1554 Handle<Name> name,
1555 Label* miss) {
1556 ASSERT(holder->IsGlobalObject());
1557
1558 StackArgumentsAccessor args(rsp, arguments());
1559 __ movq(rdx, args.GetReceiverOperand());
1560
1561
1562 // Check that the maps haven't changed.
1563 __ JumpIfSmi(rdx, miss);
1564 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder,
1565 rbx, rax, rdi, name, miss);
1566 }
1567
1568
1569 void CallStubCompiler::GenerateLoadFunctionFromCell( 1552 void CallStubCompiler::GenerateLoadFunctionFromCell(
1570 Handle<Cell> cell, 1553 Handle<Cell> cell,
1571 Handle<JSFunction> function, 1554 Handle<JSFunction> function,
1572 Label* miss) { 1555 Label* miss) {
1573 // Get the value from the cell. 1556 // Get the value from the cell.
1574 __ Move(rdi, cell); 1557 __ Move(rdi, cell);
1575 __ movq(rdi, FieldOperand(rdi, Cell::kValueOffset)); 1558 __ movq(rdi, FieldOperand(rdi, Cell::kValueOffset));
1576 1559
1577 // Check that the cell contains the same function. 1560 // Check that the cell contains the same function.
1578 if (heap()->InNewSpace(*function)) { 1561 if (heap()->InNewSpace(*function)) {
(...skipping 22 matching lines...) Expand all
1601 kind_, 1584 kind_,
1602 extra_state_); 1585 extra_state_);
1603 __ Jump(code, RelocInfo::CODE_TARGET); 1586 __ Jump(code, RelocInfo::CODE_TARGET);
1604 } 1587 }
1605 1588
1606 1589
1607 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, 1590 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
1608 Handle<JSObject> holder, 1591 Handle<JSObject> holder,
1609 PropertyIndex index, 1592 PropertyIndex index,
1610 Handle<Name> name) { 1593 Handle<Name> name) {
1611 // ----------- S t a t e -------------
1612 // rcx : function name
1613 // rsp[0] : return address
1614 // rsp[8] : argument argc
1615 // rsp[16] : argument argc - 1
1616 // ...
1617 // rsp[argc * 8] : argument 1
1618 // rsp[(argc + 1) * 8] : argument 0 = receiver
1619 // -----------------------------------
1620 Label miss; 1594 Label miss;
1621 1595
1622 GenerateNameCheck(name, &miss); 1596 Register reg = HandlerFrontendHeader(
1623 1597 object, holder, name, RECEIVER_MAP_CHECK, &miss);
1624 StackArgumentsAccessor args(rsp, arguments());
1625 __ movq(rdx, args.GetReceiverOperand());
1626
1627 // Check that the receiver isn't a smi.
1628 __ JumpIfSmi(rdx, &miss);
1629
1630 // Do the right check and compute the holder register.
1631 Register reg = CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx,
1632 holder, rbx, rax, rdi, name, &miss);
1633 1598
1634 GenerateFastPropertyLoad(masm(), rdi, reg, index.is_inobject(holder), 1599 GenerateFastPropertyLoad(masm(), rdi, reg, index.is_inobject(holder),
1635 index.translate(holder), Representation::Tagged()); 1600 index.translate(holder), Representation::Tagged());
1636 1601
1637 // Check that the function really is a function. 1602 // Check that the function really is a function.
1638 __ JumpIfSmi(rdi, &miss); 1603 __ JumpIfSmi(rdi, &miss);
1639 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rbx); 1604 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rbx);
1640 __ j(not_equal, &miss); 1605 __ j(not_equal, &miss);
1641 1606
1642 // Patch the receiver on the stack with the global proxy if 1607 PatchGlobalProxy(object);
1643 // necessary.
1644 if (object->IsGlobalObject()) {
1645 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
1646 __ movq(args.GetReceiverOperand(), rdx);
1647 }
1648 1608
1649 // Invoke the function. 1609 // Invoke the function.
1650 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 1610 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
1651 ? CALL_AS_FUNCTION 1611 ? CALL_AS_FUNCTION
1652 : CALL_AS_METHOD; 1612 : CALL_AS_METHOD;
1653 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, 1613 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION,
1654 NullCallWrapper(), call_kind); 1614 NullCallWrapper(), call_kind);
1655 1615
1656 // Handle call cache miss. 1616 HandlerFrontendFooter(&miss);
1657 __ bind(&miss);
1658 GenerateMissBranch();
1659 1617
1660 // Return the generated code. 1618 // Return the generated code.
1661 return GetCode(Code::FAST, name); 1619 return GetCode(Code::FAST, name);
1662 } 1620 }
1663 1621
1664 1622
1665 Handle<Code> CallStubCompiler::CompileArrayCodeCall( 1623 Handle<Code> CallStubCompiler::CompileArrayCodeCall(
1666 Handle<Object> object, 1624 Handle<Object> object,
1667 Handle<JSObject> holder, 1625 Handle<JSObject> holder,
1668 Handle<Cell> cell, 1626 Handle<Cell> cell,
1669 Handle<JSFunction> function, 1627 Handle<JSFunction> function,
1670 Handle<String> name, 1628 Handle<String> name,
1671 Code::StubType type) { 1629 Code::StubType type) {
1672 Label miss; 1630 Label miss;
1673 1631
1674 // Check that function is still array 1632 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1675 const int argc = arguments().immediate(); 1633 if (!cell.is_null()) {
1676 StackArgumentsAccessor args(rsp, argc);
1677 GenerateNameCheck(name, &miss);
1678
1679 if (cell.is_null()) {
1680 __ movq(rdx, args.GetReceiverOperand());
1681
1682 // Check that the receiver isn't a smi.
1683 __ JumpIfSmi(rdx, &miss);
1684 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder,
1685 rbx, rax, rdi, name, &miss);
1686 } else {
1687 ASSERT(cell->value() == *function); 1634 ASSERT(cell->value() == *function);
1688 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
1689 &miss);
1690 GenerateLoadFunctionFromCell(cell, function, &miss); 1635 GenerateLoadFunctionFromCell(cell, function, &miss);
1691 } 1636 }
1692 1637
1693 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); 1638 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite();
1694 site->SetElementsKind(GetInitialFastElementsKind()); 1639 site->SetElementsKind(GetInitialFastElementsKind());
1695 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); 1640 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site);
1641 const int argc = arguments().immediate();
1696 __ movq(rax, Immediate(argc)); 1642 __ movq(rax, Immediate(argc));
1697 __ Move(rbx, site_feedback_cell); 1643 __ Move(rbx, site_feedback_cell);
1698 __ Move(rdi, function); 1644 __ Move(rdi, function);
1699 1645
1700 ArrayConstructorStub stub(isolate()); 1646 ArrayConstructorStub stub(isolate());
1701 __ TailCallStub(&stub); 1647 __ TailCallStub(&stub);
1702 1648
1703 __ bind(&miss); 1649 HandlerFrontendFooter(&miss);
1704 GenerateMissBranch();
1705 1650
1706 // Return the generated code. 1651 // Return the generated code.
1707 return GetCode(type, name); 1652 return GetCode(type, name);
1708 } 1653 }
1709 1654
1710 1655
1711 Handle<Code> CallStubCompiler::CompileArrayPushCall( 1656 Handle<Code> CallStubCompiler::CompileArrayPushCall(
1712 Handle<Object> object, 1657 Handle<Object> object,
1713 Handle<JSObject> holder, 1658 Handle<JSObject> holder,
1714 Handle<Cell> cell, 1659 Handle<Cell> cell,
1715 Handle<JSFunction> function, 1660 Handle<JSFunction> function,
1716 Handle<String> name, 1661 Handle<String> name,
1717 Code::StubType type) { 1662 Code::StubType type) {
1718 // ----------- S t a t e ------------- 1663 // ----------- S t a t e -------------
1719 // -- rcx : name 1664 // -- rcx : name
1720 // -- rsp[0] : return address 1665 // -- rsp[0] : return address
1721 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) 1666 // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
1722 // -- ... 1667 // -- ...
1723 // -- rsp[(argc + 1) * 8] : receiver 1668 // -- rsp[(argc + 1) * 8] : receiver
1724 // ----------------------------------- 1669 // -----------------------------------
1725 1670
1726 // If object is not an array or is observed, bail out to regular call. 1671 // If object is not an array or is observed, bail out to regular call.
1727 if (!object->IsJSArray() || 1672 if (!object->IsJSArray() ||
1728 !cell.is_null() || 1673 !cell.is_null() ||
1729 Handle<JSArray>::cast(object)->map()->is_observed()) { 1674 Handle<JSArray>::cast(object)->map()->is_observed()) {
1730 return Handle<Code>::null(); 1675 return Handle<Code>::null();
1731 } 1676 }
1732 1677
1733 Label miss; 1678 Label miss;
1734 GenerateNameCheck(name, &miss); 1679
1680 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1735 1681
1736 const int argc = arguments().immediate(); 1682 const int argc = arguments().immediate();
1737 StackArgumentsAccessor args(rsp, argc); 1683 StackArgumentsAccessor args(rsp, argc);
1738 __ movq(rdx, args.GetReceiverOperand());
1739
1740 // Check that the receiver isn't a smi.
1741 __ JumpIfSmi(rdx, &miss);
1742
1743 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder,
1744 rbx, rax, rdi, name, &miss);
1745
1746 if (argc == 0) { 1684 if (argc == 0) {
1747 // Noop, return the length. 1685 // Noop, return the length.
1748 __ movq(rax, FieldOperand(rdx, JSArray::kLengthOffset)); 1686 __ movq(rax, FieldOperand(rdx, JSArray::kLengthOffset));
1749 __ ret((argc + 1) * kPointerSize); 1687 __ ret((argc + 1) * kPointerSize);
1750 } else { 1688 } else {
1751 Label call_builtin; 1689 Label call_builtin;
1752 1690
1753 if (argc == 1) { // Otherwise fall through to call builtin. 1691 if (argc == 1) { // Otherwise fall through to call builtin.
1754 Label attempt_to_grow_elements, with_write_barrier, check_double; 1692 Label attempt_to_grow_elements, with_write_barrier, check_double;
1755 1693
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
1948 __ ret((argc + 1) * kPointerSize); 1886 __ ret((argc + 1) * kPointerSize);
1949 } 1887 }
1950 1888
1951 __ bind(&call_builtin); 1889 __ bind(&call_builtin);
1952 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, 1890 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush,
1953 isolate()), 1891 isolate()),
1954 argc + 1, 1892 argc + 1,
1955 1); 1893 1);
1956 } 1894 }
1957 1895
1958 __ bind(&miss); 1896 HandlerFrontendFooter(&miss);
1959 GenerateMissBranch();
1960 1897
1961 // Return the generated code. 1898 // Return the generated code.
1962 return GetCode(type, name); 1899 return GetCode(type, name);
1963 } 1900 }
1964 1901
1965 1902
1966 Handle<Code> CallStubCompiler::CompileArrayPopCall( 1903 Handle<Code> CallStubCompiler::CompileArrayPopCall(
1967 Handle<Object> object, 1904 Handle<Object> object,
1968 Handle<JSObject> holder, 1905 Handle<JSObject> holder,
1969 Handle<Cell> cell, 1906 Handle<Cell> cell,
1970 Handle<JSFunction> function, 1907 Handle<JSFunction> function,
1971 Handle<String> name, 1908 Handle<String> name,
1972 Code::StubType type) { 1909 Code::StubType type) {
1973 // ----------- S t a t e -------------
1974 // -- rcx : name
1975 // -- rsp[0] : return address
1976 // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
1977 // -- ...
1978 // -- rsp[(argc + 1) * 8] : receiver
1979 // -----------------------------------
1980
1981 // If object is not an array or is observed, bail out to regular call. 1910 // If object is not an array or is observed, bail out to regular call.
1982 if (!object->IsJSArray() || 1911 if (!object->IsJSArray() ||
1983 !cell.is_null() || 1912 !cell.is_null() ||
1984 Handle<JSArray>::cast(object)->map()->is_observed()) { 1913 Handle<JSArray>::cast(object)->map()->is_observed()) {
1985 return Handle<Code>::null(); 1914 return Handle<Code>::null();
1986 } 1915 }
1987 1916
1988 Label miss, return_undefined, call_builtin; 1917 Label miss, return_undefined, call_builtin;
1989 GenerateNameCheck(name, &miss);
1990 1918
1991 const int argc = arguments().immediate(); 1919 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1992 StackArgumentsAccessor args(rsp, argc);
1993 __ movq(rdx, args.GetReceiverOperand());
1994
1995 // Check that the receiver isn't a smi.
1996 __ JumpIfSmi(rdx, &miss);
1997
1998 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder,
1999 rbx, rax, rdi, name, &miss);
2000 1920
2001 // Get the elements array of the object. 1921 // Get the elements array of the object.
2002 __ movq(rbx, FieldOperand(rdx, JSArray::kElementsOffset)); 1922 __ movq(rbx, FieldOperand(rdx, JSArray::kElementsOffset));
2003 1923
2004 // Check that the elements are in fast mode and writable. 1924 // Check that the elements are in fast mode and writable.
2005 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), 1925 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset),
2006 Heap::kFixedArrayMapRootIndex); 1926 Heap::kFixedArrayMapRootIndex);
2007 __ j(not_equal, &call_builtin); 1927 __ j(not_equal, &call_builtin);
2008 1928
2009 // Get the array's length into rcx and calculate new length. 1929 // Get the array's length into rcx and calculate new length.
(...skipping 12 matching lines...) Expand all
2022 __ j(equal, &call_builtin); 1942 __ j(equal, &call_builtin);
2023 1943
2024 // Set the array's length. 1944 // Set the array's length.
2025 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rcx); 1945 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rcx);
2026 1946
2027 // Fill with the hole and return original value. 1947 // Fill with the hole and return original value.
2028 __ movq(FieldOperand(rbx, 1948 __ movq(FieldOperand(rbx,
2029 rcx, times_pointer_size, 1949 rcx, times_pointer_size,
2030 FixedArray::kHeaderSize), 1950 FixedArray::kHeaderSize),
2031 r9); 1951 r9);
1952 const int argc = arguments().immediate();
2032 __ ret((argc + 1) * kPointerSize); 1953 __ ret((argc + 1) * kPointerSize);
2033 1954
2034 __ bind(&return_undefined); 1955 __ bind(&return_undefined);
2035 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 1956 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
2036 __ ret((argc + 1) * kPointerSize); 1957 __ ret((argc + 1) * kPointerSize);
2037 1958
2038 __ bind(&call_builtin); 1959 __ bind(&call_builtin);
2039 __ TailCallExternalReference( 1960 __ TailCallExternalReference(
2040 ExternalReference(Builtins::c_ArrayPop, isolate()), 1961 ExternalReference(Builtins::c_ArrayPop, isolate()),
2041 argc + 1, 1962 argc + 1,
2042 1); 1963 1);
2043 1964
2044 __ bind(&miss); 1965 HandlerFrontendFooter(&miss);
2045 GenerateMissBranch();
2046 1966
2047 // Return the generated code. 1967 // Return the generated code.
2048 return GetCode(type, name); 1968 return GetCode(type, name);
2049 } 1969 }
2050 1970
2051 1971
2052 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall( 1972 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
2053 Handle<Object> object, 1973 Handle<Object> object,
2054 Handle<JSObject> holder, 1974 Handle<JSObject> holder,
2055 Handle<Cell> cell, 1975 Handle<Cell> cell,
2056 Handle<JSFunction> function, 1976 Handle<JSFunction> function,
2057 Handle<String> name, 1977 Handle<String> name,
2058 Code::StubType type) { 1978 Code::StubType type) {
2059 // ----------- S t a t e -------------
2060 // -- rcx : function name
2061 // -- rsp[0] : return address
2062 // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
2063 // -- ...
2064 // -- rsp[(argc + 1) * 8] : receiver
2065 // -----------------------------------
2066
2067 // If object is not a string, bail out to regular call. 1979 // If object is not a string, bail out to regular call.
2068 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); 1980 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null();
2069 1981
2070 const int argc = arguments().immediate();
2071 StackArgumentsAccessor args(rsp, argc);
2072
2073 Label miss; 1982 Label miss;
2074 Label name_miss; 1983 Label name_miss;
2075 Label index_out_of_range; 1984 Label index_out_of_range;
2076 Label* index_out_of_range_label = &index_out_of_range; 1985 Label* index_out_of_range_label = &index_out_of_range;
2077 if (kind_ == Code::CALL_IC && 1986 if (kind_ == Code::CALL_IC &&
2078 (CallICBase::StringStubState::decode(extra_state_) == 1987 (CallICBase::StringStubState::decode(extra_state_) ==
2079 DEFAULT_STRING_STUB)) { 1988 DEFAULT_STRING_STUB)) {
2080 index_out_of_range_label = &miss; 1989 index_out_of_range_label = &miss;
2081 } 1990 }
2082 GenerateNameCheck(name, &name_miss);
2083 1991
2084 // Check that the maps starting from the prototype haven't changed. 1992 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss);
2085 GenerateDirectLoadGlobalFunctionPrototype(masm(),
2086 Context::STRING_FUNCTION_INDEX,
2087 rax,
2088 &miss);
2089 ASSERT(!object.is_identical_to(holder));
2090 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2091 CheckPrototypes(
2092 IC::CurrentTypeOf(prototype, isolate()),
2093 rax, holder, rbx, rdx, rdi, name, &miss);
2094 1993
2095 Register receiver = rbx; 1994 Register receiver = rbx;
2096 Register index = rdi; 1995 Register index = rdi;
2097 Register result = rax; 1996 Register result = rax;
1997 const int argc = arguments().immediate();
1998 StackArgumentsAccessor args(rsp, argc);
1999
2098 __ movq(receiver, args.GetReceiverOperand()); 2000 __ movq(receiver, args.GetReceiverOperand());
2099 if (argc > 0) { 2001 if (argc > 0) {
2100 __ movq(index, args.GetArgumentOperand(1)); 2002 __ movq(index, args.GetArgumentOperand(1));
2101 } else { 2003 } else {
2102 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); 2004 __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
2103 } 2005 }
2104 2006
2105 StringCharCodeAtGenerator generator(receiver, 2007 StringCharCodeAtGenerator generator(receiver,
2106 index, 2008 index,
2107 result, 2009 result,
(...skipping 24 matching lines...) Expand all
2132 } 2034 }
2133 2035
2134 2036
2135 Handle<Code> CallStubCompiler::CompileStringCharAtCall( 2037 Handle<Code> CallStubCompiler::CompileStringCharAtCall(
2136 Handle<Object> object, 2038 Handle<Object> object,
2137 Handle<JSObject> holder, 2039 Handle<JSObject> holder,
2138 Handle<Cell> cell, 2040 Handle<Cell> cell,
2139 Handle<JSFunction> function, 2041 Handle<JSFunction> function,
2140 Handle<String> name, 2042 Handle<String> name,
2141 Code::StubType type) { 2043 Code::StubType type) {
2142 // ----------- S t a t e -------------
2143 // -- rcx : function name
2144 // -- rsp[0] : return address
2145 // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
2146 // -- ...
2147 // -- rsp[(argc + 1) * 8] : receiver
2148 // -----------------------------------
2149
2150 // If object is not a string, bail out to regular call. 2044 // If object is not a string, bail out to regular call.
2151 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); 2045 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null();
2152 2046
2153 const int argc = arguments().immediate(); 2047 const int argc = arguments().immediate();
2154 StackArgumentsAccessor args(rsp, argc); 2048 StackArgumentsAccessor args(rsp, argc);
2155 2049
2156 Label miss; 2050 Label miss;
2157 Label name_miss; 2051 Label name_miss;
2158 Label index_out_of_range; 2052 Label index_out_of_range;
2159 Label* index_out_of_range_label = &index_out_of_range; 2053 Label* index_out_of_range_label = &index_out_of_range;
2160 if (kind_ == Code::CALL_IC && 2054 if (kind_ == Code::CALL_IC &&
2161 (CallICBase::StringStubState::decode(extra_state_) == 2055 (CallICBase::StringStubState::decode(extra_state_) ==
2162 DEFAULT_STRING_STUB)) { 2056 DEFAULT_STRING_STUB)) {
2163 index_out_of_range_label = &miss; 2057 index_out_of_range_label = &miss;
2164 } 2058 }
2165 GenerateNameCheck(name, &name_miss);
2166 2059
2167 // Check that the maps starting from the prototype haven't changed. 2060 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss);
2168 GenerateDirectLoadGlobalFunctionPrototype(masm(),
2169 Context::STRING_FUNCTION_INDEX,
2170 rax,
2171 &miss);
2172 ASSERT(!object.is_identical_to(holder));
2173 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2174 CheckPrototypes(
2175 IC::CurrentTypeOf(prototype, isolate()),
2176 rax, holder, rbx, rdx, rdi, name, &miss);
2177 2061
2178 Register receiver = rax; 2062 Register receiver = rax;
2179 Register index = rdi; 2063 Register index = rdi;
2180 Register scratch = rdx; 2064 Register scratch = rdx;
2181 Register result = rax; 2065 Register result = rax;
2182 __ movq(receiver, args.GetReceiverOperand()); 2066 __ movq(receiver, args.GetReceiverOperand());
2183 if (argc > 0) { 2067 if (argc > 0) {
2184 __ movq(index, args.GetArgumentOperand(1)); 2068 __ movq(index, args.GetArgumentOperand(1));
2185 } else { 2069 } else {
2186 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); 2070 __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
(...skipping 29 matching lines...) Expand all
2216 } 2100 }
2217 2101
2218 2102
2219 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( 2103 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
2220 Handle<Object> object, 2104 Handle<Object> object,
2221 Handle<JSObject> holder, 2105 Handle<JSObject> holder,
2222 Handle<Cell> cell, 2106 Handle<Cell> cell,
2223 Handle<JSFunction> function, 2107 Handle<JSFunction> function,
2224 Handle<String> name, 2108 Handle<String> name,
2225 Code::StubType type) { 2109 Code::StubType type) {
2226 // ----------- S t a t e -------------
2227 // -- rcx : function name
2228 // -- rsp[0] : return address
2229 // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
2230 // -- ...
2231 // -- rsp[(argc + 1) * 8] : receiver
2232 // -----------------------------------
2233
2234 // If the object is not a JSObject or we got an unexpected number of 2110 // If the object is not a JSObject or we got an unexpected number of
2235 // arguments, bail out to the regular call. 2111 // arguments, bail out to the regular call.
2236 const int argc = arguments().immediate(); 2112 const int argc = arguments().immediate();
2237 StackArgumentsAccessor args(rsp, argc); 2113 StackArgumentsAccessor args(rsp, argc);
2238 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2114 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2239 2115
2240 Label miss; 2116 Label miss;
2241 GenerateNameCheck(name, &miss);
2242 2117
2243 if (cell.is_null()) { 2118 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2244 __ movq(rdx, args.GetReceiverOperand()); 2119 if (!cell.is_null()) {
2245 __ JumpIfSmi(rdx, &miss);
2246 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder,
2247 rbx, rax, rdi, name, &miss);
2248 } else {
2249 ASSERT(cell->value() == *function); 2120 ASSERT(cell->value() == *function);
2250 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2251 &miss);
2252 GenerateLoadFunctionFromCell(cell, function, &miss); 2121 GenerateLoadFunctionFromCell(cell, function, &miss);
2253 } 2122 }
2254 2123
2255 // Load the char code argument. 2124 // Load the char code argument.
2256 Register code = rbx; 2125 Register code = rbx;
2257 __ movq(code, args.GetArgumentOperand(1)); 2126 __ movq(code, args.GetArgumentOperand(1));
2258 2127
2259 // Check the code is a smi. 2128 // Check the code is a smi.
2260 Label slow; 2129 Label slow;
2261 __ JumpIfNotSmi(code, &slow); 2130 __ JumpIfNotSmi(code, &slow);
(...skipping 11 matching lines...) Expand all
2273 // Tail call the full function. We do not have to patch the receiver 2142 // Tail call the full function. We do not have to patch the receiver
2274 // because the function makes no use of it. 2143 // because the function makes no use of it.
2275 __ bind(&slow); 2144 __ bind(&slow);
2276 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2145 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2277 ? CALL_AS_FUNCTION 2146 ? CALL_AS_FUNCTION
2278 : CALL_AS_METHOD; 2147 : CALL_AS_METHOD;
2279 ParameterCount expected(function); 2148 ParameterCount expected(function);
2280 __ InvokeFunction(function, expected, arguments(), 2149 __ InvokeFunction(function, expected, arguments(),
2281 JUMP_FUNCTION, NullCallWrapper(), call_kind); 2150 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2282 2151
2283 __ bind(&miss); 2152 HandlerFrontendFooter(&miss);
2284 // rcx: function name.
2285 GenerateMissBranch();
2286 2153
2287 // Return the generated code. 2154 // Return the generated code.
2288 return GetCode(type, name); 2155 return GetCode(type, name);
2289 } 2156 }
2290 2157
2291 2158
2292 Handle<Code> CallStubCompiler::CompileMathFloorCall( 2159 Handle<Code> CallStubCompiler::CompileMathFloorCall(
2293 Handle<Object> object, 2160 Handle<Object> object,
2294 Handle<JSObject> holder, 2161 Handle<JSObject> holder,
2295 Handle<Cell> cell, 2162 Handle<Cell> cell,
2296 Handle<JSFunction> function, 2163 Handle<JSFunction> function,
2297 Handle<String> name, 2164 Handle<String> name,
2298 Code::StubType type) { 2165 Code::StubType type) {
2299 // ----------- S t a t e -------------
2300 // -- rcx : name
2301 // -- rsp[0] : return address
2302 // -- rsp[(argc - n) * 4] : arg[n] (zero-based)
2303 // -- ...
2304 // -- rsp[(argc + 1) * 4] : receiver
2305 // -----------------------------------
2306 const int argc = arguments().immediate(); 2166 const int argc = arguments().immediate();
2307 StackArgumentsAccessor args(rsp, argc); 2167 StackArgumentsAccessor args(rsp, argc);
2308 2168
2309 // If the object is not a JSObject or we got an unexpected number of 2169 // If the object is not a JSObject or we got an unexpected number of
2310 // arguments, bail out to the regular call. 2170 // arguments, bail out to the regular call.
2311 if (!object->IsJSObject() || argc != 1) { 2171 if (!object->IsJSObject() || argc != 1) {
2312 return Handle<Code>::null(); 2172 return Handle<Code>::null();
2313 } 2173 }
2314 2174
2315 Label miss; 2175 Label miss, slow;
2316 GenerateNameCheck(name, &miss);
2317 2176
2318 if (cell.is_null()) { 2177 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2319 __ movq(rdx, args.GetReceiverOperand()); 2178 if (!cell.is_null()) {
2320
2321 STATIC_ASSERT(kSmiTag == 0);
2322 __ JumpIfSmi(rdx, &miss);
2323
2324 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder,
2325 rbx, rax, rdi, name, &miss);
2326 } else {
2327 ASSERT(cell->value() == *function); 2179 ASSERT(cell->value() == *function);
2328 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2329 &miss);
2330 GenerateLoadFunctionFromCell(cell, function, &miss); 2180 GenerateLoadFunctionFromCell(cell, function, &miss);
2331 } 2181 }
2332 2182
2333 // Load the (only) argument into rax. 2183 // Load the (only) argument into rax.
2334 __ movq(rax, args.GetArgumentOperand(1)); 2184 __ movq(rax, args.GetArgumentOperand(1));
2335 2185
2336 // Check if the argument is a smi. 2186 // Check if the argument is a smi.
2337 Label smi; 2187 Label smi;
2338 STATIC_ASSERT(kSmiTag == 0); 2188 STATIC_ASSERT(kSmiTag == 0);
2339 __ JumpIfSmi(rax, &smi); 2189 __ JumpIfSmi(rax, &smi);
2340 2190
2341 // Check if the argument is a heap number and load its value into xmm0. 2191 // Check if the argument is a heap number and load its value into xmm0.
2342 Label slow;
2343 __ CheckMap(rax, factory()->heap_number_map(), &slow, DONT_DO_SMI_CHECK); 2192 __ CheckMap(rax, factory()->heap_number_map(), &slow, DONT_DO_SMI_CHECK);
2344 __ movsd(xmm0, FieldOperand(rax, HeapNumber::kValueOffset)); 2193 __ movsd(xmm0, FieldOperand(rax, HeapNumber::kValueOffset));
2345 2194
2346 // Check if the argument is strictly positive. Note this also discards NaN. 2195 // Check if the argument is strictly positive. Note this also discards NaN.
2347 __ xorpd(xmm1, xmm1); 2196 __ xorpd(xmm1, xmm1);
2348 __ ucomisd(xmm0, xmm1); 2197 __ ucomisd(xmm0, xmm1);
2349 __ j(below_equal, &slow); 2198 __ j(below_equal, &slow);
2350 2199
2351 // Do a truncating conversion. 2200 // Do a truncating conversion.
2352 __ cvttsd2si(rax, xmm0); 2201 __ cvttsd2si(rax, xmm0);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
2401 __ movq(rax, args.GetArgumentOperand(1)); 2250 __ movq(rax, args.GetArgumentOperand(1));
2402 __ ret(2 * kPointerSize); 2251 __ ret(2 * kPointerSize);
2403 2252
2404 // Tail call the full function. We do not have to patch the receiver 2253 // Tail call the full function. We do not have to patch the receiver
2405 // because the function makes no use of it. 2254 // because the function makes no use of it.
2406 __ bind(&slow); 2255 __ bind(&slow);
2407 ParameterCount expected(function); 2256 ParameterCount expected(function);
2408 __ InvokeFunction(function, expected, arguments(), 2257 __ InvokeFunction(function, expected, arguments(),
2409 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2258 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
2410 2259
2411 __ bind(&miss); 2260 HandlerFrontendFooter(&miss);
2412 // rcx: function name.
2413 GenerateMissBranch();
2414 2261
2415 // Return the generated code. 2262 // Return the generated code.
2416 return GetCode(type, name); 2263 return GetCode(type, name);
2417 } 2264 }
2418 2265
2419 2266
2420 Handle<Code> CallStubCompiler::CompileMathAbsCall( 2267 Handle<Code> CallStubCompiler::CompileMathAbsCall(
2421 Handle<Object> object, 2268 Handle<Object> object,
2422 Handle<JSObject> holder, 2269 Handle<JSObject> holder,
2423 Handle<Cell> cell, 2270 Handle<Cell> cell,
2424 Handle<JSFunction> function, 2271 Handle<JSFunction> function,
2425 Handle<String> name, 2272 Handle<String> name,
2426 Code::StubType type) { 2273 Code::StubType type) {
2427 // ----------- S t a t e -------------
2428 // -- rcx : function name
2429 // -- rsp[0] : return address
2430 // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
2431 // -- ...
2432 // -- rsp[(argc + 1) * 8] : receiver
2433 // -----------------------------------
2434
2435 // If the object is not a JSObject or we got an unexpected number of 2274 // If the object is not a JSObject or we got an unexpected number of
2436 // arguments, bail out to the regular call. 2275 // arguments, bail out to the regular call.
2437 const int argc = arguments().immediate(); 2276 const int argc = arguments().immediate();
2438 StackArgumentsAccessor args(rsp, argc); 2277 StackArgumentsAccessor args(rsp, argc);
2439 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2278 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2440 2279
2441 Label miss; 2280 Label miss;
2442 GenerateNameCheck(name, &miss);
2443 2281
2444 if (cell.is_null()) { 2282 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2445 __ movq(rdx, args.GetReceiverOperand()); 2283 if (!cell.is_null()) {
2446 __ JumpIfSmi(rdx, &miss);
2447 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder,
2448 rbx, rax, rdi, name, &miss);
2449 } else {
2450 ASSERT(cell->value() == *function); 2284 ASSERT(cell->value() == *function);
2451 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2452 &miss);
2453 GenerateLoadFunctionFromCell(cell, function, &miss); 2285 GenerateLoadFunctionFromCell(cell, function, &miss);
2454 } 2286 }
2287
2455 // Load the (only) argument into rax. 2288 // Load the (only) argument into rax.
2456 __ movq(rax, args.GetArgumentOperand(1)); 2289 __ movq(rax, args.GetArgumentOperand(1));
2457 2290
2458 // Check if the argument is a smi. 2291 // Check if the argument is a smi.
2459 Label not_smi; 2292 Label not_smi;
2460 STATIC_ASSERT(kSmiTag == 0); 2293 STATIC_ASSERT(kSmiTag == 0);
2461 __ JumpIfNotSmi(rax, &not_smi); 2294 __ JumpIfNotSmi(rax, &not_smi);
2462 2295
2463 // Branchless abs implementation, refer to below: 2296 // Branchless abs implementation, refer to below:
2464 // http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs 2297 // http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2506 // Tail call the full function. We do not have to patch the receiver 2339 // Tail call the full function. We do not have to patch the receiver
2507 // because the function makes no use of it. 2340 // because the function makes no use of it.
2508 __ bind(&slow); 2341 __ bind(&slow);
2509 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2342 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2510 ? CALL_AS_FUNCTION 2343 ? CALL_AS_FUNCTION
2511 : CALL_AS_METHOD; 2344 : CALL_AS_METHOD;
2512 ParameterCount expected(function); 2345 ParameterCount expected(function);
2513 __ InvokeFunction(function, expected, arguments(), 2346 __ InvokeFunction(function, expected, arguments(),
2514 JUMP_FUNCTION, NullCallWrapper(), call_kind); 2347 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2515 2348
2516 __ bind(&miss); 2349 HandlerFrontendFooter(&miss);
2517 // rcx: function name.
2518 GenerateMissBranch();
2519 2350
2520 // Return the generated code. 2351 // Return the generated code.
2521 return GetCode(type, name); 2352 return GetCode(type, name);
2522 } 2353 }
2523 2354
2524 2355
2525 Handle<Code> CallStubCompiler::CompileFastApiCall( 2356 Handle<Code> CallStubCompiler::CompileFastApiCall(
2526 const CallOptimization& optimization, 2357 const CallOptimization& optimization,
2527 Handle<Object> object, 2358 Handle<Object> object,
2528 Handle<JSObject> holder, 2359 Handle<JSObject> holder,
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
2583 Label success; 2414 Label success;
2584 // Check that the object is a boolean. 2415 // Check that the object is a boolean.
2585 __ CompareRoot(object, Heap::kTrueValueRootIndex); 2416 __ CompareRoot(object, Heap::kTrueValueRootIndex);
2586 __ j(equal, &success); 2417 __ j(equal, &success);
2587 __ CompareRoot(object, Heap::kFalseValueRootIndex); 2418 __ CompareRoot(object, Heap::kFalseValueRootIndex);
2588 __ j(not_equal, miss); 2419 __ j(not_equal, miss);
2589 __ bind(&success); 2420 __ bind(&success);
2590 } 2421 }
2591 2422
2592 2423
2593 void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object, 2424 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) {
2594 Handle<JSObject> holder, 2425 if (object->IsGlobalObject()) {
2595 Handle<Name> name, 2426 StackArgumentsAccessor args(rsp, arguments());
2596 CheckType check) { 2427 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
2597 // ----------- S t a t e ------------- 2428 __ movq(args.GetReceiverOperand(), rdx);
2598 // rcx : function name 2429 }
2599 // rsp[0] : return address 2430 }
2600 // rsp[8] : argument argc 2431
2601 // rsp[16] : argument argc - 1 2432
2602 // ... 2433 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object,
2603 // rsp[argc * 8] : argument 1 2434 Handle<JSObject> holder,
2604 // rsp[(argc + 1) * 8] : argument 0 = receiver 2435 Handle<Name> name,
2605 // ----------------------------------- 2436 CheckType check,
2606 Label miss; 2437 Label* miss) {
2607 GenerateNameCheck(name, &miss); 2438 GenerateNameCheck(name, miss);
2439
2440 Register reg = rdx;
2608 2441
2609 StackArgumentsAccessor args(rsp, arguments()); 2442 StackArgumentsAccessor args(rsp, arguments());
2610 __ movq(rdx, args.GetReceiverOperand()); 2443 __ movq(reg, args.GetReceiverOperand());
2611 2444
2612 // Check that the receiver isn't a smi. 2445 // Check that the receiver isn't a smi.
2613 if (check != NUMBER_CHECK) { 2446 if (check != NUMBER_CHECK) {
2614 __ JumpIfSmi(rdx, &miss); 2447 __ JumpIfSmi(reg, miss);
2615 } 2448 }
2616 2449
2617 // Make sure that it's okay not to patch the on stack receiver 2450 // Make sure that it's okay not to patch the on stack receiver
2618 // unless we're doing a receiver map check. 2451 // unless we're doing a receiver map check.
2619 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); 2452 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
2620 2453
2621 Counters* counters = isolate()->counters(); 2454 Counters* counters = isolate()->counters();
2622 switch (check) { 2455 switch (check) {
2623 case RECEIVER_MAP_CHECK: 2456 case RECEIVER_MAP_CHECK:
2624 __ IncrementCounter(counters->call_const(), 1); 2457 __ IncrementCounter(counters->call_const(), 1);
2625 2458
2626 // Check that the maps haven't changed. 2459 // Check that the maps haven't changed.
2627 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder, 2460 reg = CheckPrototypes(IC::CurrentTypeOf(object, isolate()), reg, holder,
2628 rbx, rax, rdi, name, &miss); 2461 rbx, rax, rdi, name, miss);
2629
2630 // Patch the receiver on the stack with the global proxy if
2631 // necessary.
2632 if (object->IsGlobalObject()) {
2633 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
2634 __ movq(args.GetReceiverOperand(), rdx);
2635 }
2636 break; 2462 break;
2637 2463
2638 case STRING_CHECK: { 2464 case STRING_CHECK: {
2639 // Check that the object is a string. 2465 // Check that the object is a string.
2640 __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rax); 2466 __ CmpObjectType(reg, FIRST_NONSTRING_TYPE, rax);
2641 __ j(above_equal, &miss); 2467 __ j(above_equal, miss);
2642 // Check that the maps starting from the prototype haven't changed. 2468 // Check that the maps starting from the prototype haven't changed.
2643 GenerateDirectLoadGlobalFunctionPrototype( 2469 GenerateDirectLoadGlobalFunctionPrototype(
2644 masm(), Context::STRING_FUNCTION_INDEX, rax, &miss); 2470 masm(), Context::STRING_FUNCTION_INDEX, rax, miss);
2645 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2646 CheckPrototypes(
2647 IC::CurrentTypeOf(prototype, isolate()),
2648 rax, holder, rbx, rdx, rdi, name, &miss);
2649 break; 2471 break;
2650 } 2472 }
2651 case SYMBOL_CHECK: { 2473 case SYMBOL_CHECK: {
2652 // Check that the object is a symbol. 2474 // Check that the object is a symbol.
2653 __ CmpObjectType(rdx, SYMBOL_TYPE, rax); 2475 __ CmpObjectType(reg, SYMBOL_TYPE, rax);
2654 __ j(not_equal, &miss); 2476 __ j(not_equal, miss);
2655 // Check that the maps starting from the prototype haven't changed. 2477 // Check that the maps starting from the prototype haven't changed.
2656 GenerateDirectLoadGlobalFunctionPrototype( 2478 GenerateDirectLoadGlobalFunctionPrototype(
2657 masm(), Context::SYMBOL_FUNCTION_INDEX, rax, &miss); 2479 masm(), Context::SYMBOL_FUNCTION_INDEX, rax, miss);
2658 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2659 CheckPrototypes(
2660 IC::CurrentTypeOf(prototype, isolate()),
2661 rax, holder, rbx, rdx, rdi, name, &miss);
2662 break; 2480 break;
2663 } 2481 }
2664 case NUMBER_CHECK: { 2482 case NUMBER_CHECK: {
2665 Label fast; 2483 Label fast;
2666 // Check that the object is a smi or a heap number. 2484 // Check that the object is a smi or a heap number.
2667 __ JumpIfSmi(rdx, &fast); 2485 __ JumpIfSmi(reg, &fast);
2668 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rax); 2486 __ CmpObjectType(reg, HEAP_NUMBER_TYPE, rax);
2669 __ j(not_equal, &miss); 2487 __ j(not_equal, miss);
2670 __ bind(&fast); 2488 __ bind(&fast);
2671 // Check that the maps starting from the prototype haven't changed. 2489 // Check that the maps starting from the prototype haven't changed.
2672 GenerateDirectLoadGlobalFunctionPrototype( 2490 GenerateDirectLoadGlobalFunctionPrototype(
2673 masm(), Context::NUMBER_FUNCTION_INDEX, rax, &miss); 2491 masm(), Context::NUMBER_FUNCTION_INDEX, rax, miss);
2674 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2675 CheckPrototypes(
2676 IC::CurrentTypeOf(prototype, isolate()),
2677 rax, holder, rbx, rdx, rdi, name, &miss);
2678 break; 2492 break;
2679 } 2493 }
2680 case BOOLEAN_CHECK: { 2494 case BOOLEAN_CHECK: {
2681 GenerateBooleanCheck(rdx, &miss); 2495 GenerateBooleanCheck(reg, miss);
2682 // Check that the maps starting from the prototype haven't changed. 2496 // Check that the maps starting from the prototype haven't changed.
2683 GenerateDirectLoadGlobalFunctionPrototype( 2497 GenerateDirectLoadGlobalFunctionPrototype(
2684 masm(), Context::BOOLEAN_FUNCTION_INDEX, rax, &miss); 2498 masm(), Context::BOOLEAN_FUNCTION_INDEX, rax, miss);
2685 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2686 CheckPrototypes(
2687 IC::CurrentTypeOf(prototype, isolate()),
2688 rax, holder, rbx, rdx, rdi, name, &miss);
2689 break; 2499 break;
2690 } 2500 }
2691 } 2501 }
2692 2502
2693 Label success; 2503 if (check != RECEIVER_MAP_CHECK) {
2694 __ jmp(&success); 2504 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2505 reg = CheckPrototypes(
2506 IC::CurrentTypeOf(prototype, isolate()),
2507 rax, holder, rbx, rdx, rdi, name, miss);
2508 }
2695 2509
2696 // Handle call cache miss. 2510 return reg;
2697 __ bind(&miss);
2698 GenerateMissBranch();
2699
2700 __ bind(&success);
2701 } 2511 }
2702 2512
2703 2513
2704 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { 2514 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) {
2705 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2515 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2706 ? CALL_AS_FUNCTION 2516 ? CALL_AS_FUNCTION
2707 : CALL_AS_METHOD; 2517 : CALL_AS_METHOD;
2708 ParameterCount expected(function); 2518 ParameterCount expected(function);
2709 __ InvokeFunction(function, expected, arguments(), 2519 __ InvokeFunction(function, expected, arguments(),
2710 JUMP_FUNCTION, NullCallWrapper(), call_kind); 2520 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2711 } 2521 }
2712 2522
2713 2523
2714 Handle<Code> CallStubCompiler::CompileCallConstant( 2524 Handle<Code> CallStubCompiler::CompileCallConstant(
2715 Handle<Object> object, 2525 Handle<Object> object,
2716 Handle<JSObject> holder, 2526 Handle<JSObject> holder,
2717 Handle<Name> name, 2527 Handle<Name> name,
2718 CheckType check, 2528 CheckType check,
2719 Handle<JSFunction> function) { 2529 Handle<JSFunction> function) {
2720 if (HasCustomCallGenerator(function)) { 2530 if (HasCustomCallGenerator(function)) {
2721 Handle<Code> code = CompileCustomCall(object, holder, 2531 Handle<Code> code = CompileCustomCall(object, holder,
2722 Handle<PropertyCell>::null(), 2532 Handle<PropertyCell>::null(),
2723 function, Handle<String>::cast(name), 2533 function, Handle<String>::cast(name),
2724 Code::FAST); 2534 Code::FAST);
2725 // A null handle means bail out to the regular compiler code below. 2535 // A null handle means bail out to the regular compiler code below.
2726 if (!code.is_null()) return code; 2536 if (!code.is_null()) return code;
2727 } 2537 }
2728 2538
2729 CompileHandlerFrontend(object, holder, name, check); 2539 Label miss;
2540 HandlerFrontendHeader(object, holder, name, check, &miss);
2541 PatchGlobalProxy(object);
2730 CompileHandlerBackend(function); 2542 CompileHandlerBackend(function);
2543 HandlerFrontendFooter(&miss);
2731 2544
2732 // Return the generated code. 2545 // Return the generated code.
2733 return GetCode(function); 2546 return GetCode(function);
2734 } 2547 }
2735 2548
2736 2549
2737 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, 2550 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
2738 Handle<JSObject> holder, 2551 Handle<JSObject> holder,
2739 Handle<Name> name) { 2552 Handle<Name> name) {
2740 // ----------- S t a t e -------------
2741 // rcx : function name
2742 // rsp[0] : return address
2743 // rsp[8] : argument argc
2744 // rsp[16] : argument argc - 1
2745 // ...
2746 // rsp[argc * 8] : argument 1
2747 // rsp[(argc + 1) * 8] : argument 0 = receiver
2748 // -----------------------------------
2749 Label miss; 2553 Label miss;
2750 GenerateNameCheck(name, &miss); 2554 GenerateNameCheck(name, &miss);
2751 2555
2752
2753 LookupResult lookup(isolate()); 2556 LookupResult lookup(isolate());
2754 LookupPostInterceptor(holder, name, &lookup); 2557 LookupPostInterceptor(holder, name, &lookup);
2755 2558
2756 // Get the receiver from the stack. 2559 // Get the receiver from the stack.
2757 StackArgumentsAccessor args(rsp, arguments()); 2560 StackArgumentsAccessor args(rsp, arguments());
2758 __ movq(rdx, args.GetReceiverOperand()); 2561 __ movq(rdx, args.GetReceiverOperand());
2759 2562
2760 CallInterceptorCompiler compiler(this, arguments(), rcx, extra_state_); 2563 CallInterceptorCompiler compiler(this, arguments(), rcx, extra_state_);
2761 compiler.Compile(masm(), object, holder, name, &lookup, rdx, rbx, rdi, rax, 2564 compiler.Compile(masm(), object, holder, name, &lookup, rdx, rbx, rdi, rax,
2762 &miss); 2565 &miss);
2763 2566
2764 // Restore receiver. 2567 // Restore receiver.
2765 __ movq(rdx, args.GetReceiverOperand()); 2568 __ movq(rdx, args.GetReceiverOperand());
2766 2569
2767 // Check that the function really is a function. 2570 // Check that the function really is a function.
2768 __ JumpIfSmi(rax, &miss); 2571 __ JumpIfSmi(rax, &miss);
2769 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); 2572 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx);
2770 __ j(not_equal, &miss); 2573 __ j(not_equal, &miss);
2771 2574
2772 // Patch the receiver on the stack with the global proxy if 2575 // Patch the receiver on the stack with the global proxy if
2773 // necessary. 2576 // necessary.
2774 if (object->IsGlobalObject()) { 2577 if (object->IsGlobalObject()) {
Igor Sheludko 2013/11/28 12:54:27 Looks like PatchGlobalProxy(object);
2775 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 2578 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
2776 __ movq(args.GetReceiverOperand(), rdx); 2579 __ movq(args.GetReceiverOperand(), rdx);
2777 } 2580 }
2778 2581
2779 // Invoke the function. 2582 // Invoke the function.
2780 __ movq(rdi, rax); 2583 __ movq(rdi, rax);
2781 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2584 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2782 ? CALL_AS_FUNCTION 2585 ? CALL_AS_FUNCTION
2783 : CALL_AS_METHOD; 2586 : CALL_AS_METHOD;
2784 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, 2587 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION,
2785 NullCallWrapper(), call_kind); 2588 NullCallWrapper(), call_kind);
2786 2589
2787 // Handle load cache miss. 2590 // Handle load cache miss.
2788 __ bind(&miss); 2591 __ bind(&miss);
2789 GenerateMissBranch(); 2592 GenerateMissBranch();
2790 2593
2791 // Return the generated code. 2594 // Return the generated code.
2792 return GetCode(Code::FAST, name); 2595 return GetCode(Code::FAST, name);
2793 } 2596 }
2794 2597
2795 2598
2796 Handle<Code> CallStubCompiler::CompileCallGlobal( 2599 Handle<Code> CallStubCompiler::CompileCallGlobal(
2797 Handle<JSObject> object, 2600 Handle<JSObject> object,
2798 Handle<GlobalObject> holder, 2601 Handle<GlobalObject> holder,
2799 Handle<PropertyCell> cell, 2602 Handle<PropertyCell> cell,
2800 Handle<JSFunction> function, 2603 Handle<JSFunction> function,
2801 Handle<Name> name) { 2604 Handle<Name> name) {
2802 // ----------- S t a t e -------------
2803 // rcx : function name
2804 // rsp[0] : return address
2805 // rsp[8] : argument argc
2806 // rsp[16] : argument argc - 1
2807 // ...
2808 // rsp[argc * 8] : argument 1
2809 // rsp[(argc + 1) * 8] : argument 0 = receiver
2810 // -----------------------------------
2811
2812 if (HasCustomCallGenerator(function)) { 2605 if (HasCustomCallGenerator(function)) {
2813 Handle<Code> code = CompileCustomCall( 2606 Handle<Code> code = CompileCustomCall(
2814 object, holder, cell, function, Handle<String>::cast(name), 2607 object, holder, cell, function, Handle<String>::cast(name),
2815 Code::NORMAL); 2608 Code::NORMAL);
2816 // A null handle means bail out to the regular compiler code below. 2609 // A null handle means bail out to the regular compiler code below.
2817 if (!code.is_null()) return code; 2610 if (!code.is_null()) return code;
2818 } 2611 }
2819 2612
2820 Label miss; 2613 Label miss;
2821 GenerateNameCheck(name, &miss); 2614 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2822
2823 StackArgumentsAccessor args(rsp, arguments());
2824 GenerateGlobalReceiverCheck(object, holder, name, &miss);
2825 GenerateLoadFunctionFromCell(cell, function, &miss); 2615 GenerateLoadFunctionFromCell(cell, function, &miss);
2826 2616 PatchGlobalProxy(object);
2827 // Patch the receiver on the stack with the global proxy.
2828 if (object->IsGlobalObject()) {
2829 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
2830 __ movq(args.GetReceiverOperand(), rdx);
2831 }
2832 2617
2833 // Set up the context (function already in rdi). 2618 // Set up the context (function already in rdi).
2834 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 2619 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
2835 2620
2836 // Jump to the cached code (tail call). 2621 // Jump to the cached code (tail call).
2837 Counters* counters = isolate()->counters(); 2622 Counters* counters = isolate()->counters();
2838 __ IncrementCounter(counters->call_global_inline(), 1); 2623 __ IncrementCounter(counters->call_global_inline(), 1);
2839 ParameterCount expected(function->shared()->formal_parameter_count()); 2624 ParameterCount expected(function->shared()->formal_parameter_count());
2840 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2625 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2841 ? CALL_AS_FUNCTION 2626 ? CALL_AS_FUNCTION
2842 : CALL_AS_METHOD; 2627 : CALL_AS_METHOD;
2843 // We call indirectly through the code field in the function to 2628 // We call indirectly through the code field in the function to
2844 // allow recompilation to take effect without changing any of the 2629 // allow recompilation to take effect without changing any of the
2845 // call sites. 2630 // call sites.
2846 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 2631 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
2847 __ InvokeCode(rdx, expected, arguments(), JUMP_FUNCTION, 2632 __ InvokeCode(rdx, expected, arguments(), JUMP_FUNCTION,
2848 NullCallWrapper(), call_kind); 2633 NullCallWrapper(), call_kind);
2849 2634
2850 // Handle call cache miss. 2635 HandlerFrontendFooter(&miss);
2851 __ bind(&miss);
2852 __ IncrementCounter(counters->call_global_inline_miss(), 1);
2853 GenerateMissBranch();
2854 2636
2855 // Return the generated code. 2637 // Return the generated code.
2856 return GetCode(Code::NORMAL, name); 2638 return GetCode(Code::NORMAL, name);
2857 } 2639 }
2858 2640
2859 2641
2860 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2642 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2861 Handle<JSObject> object, 2643 Handle<JSObject> object,
2862 Handle<JSObject> holder, 2644 Handle<JSObject> holder,
2863 Handle<Name> name, 2645 Handle<Name> name,
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
3227 // ----------------------------------- 3009 // -----------------------------------
3228 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 3010 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
3229 } 3011 }
3230 3012
3231 3013
3232 #undef __ 3014 #undef __
3233 3015
3234 } } // namespace v8::internal 3016 } } // namespace v8::internal
3235 3017
3236 #endif // V8_TARGET_ARCH_X64 3018 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/ia32/stub-cache-ia32.cc ('K') | « src/stub-cache.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698