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

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

Issue 148343005: A64: Synchronize with r18147. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months 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
« no previous file with comments | « src/x64/ic-x64.cc ('k') | test/cctest/cctest.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // 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
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
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
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
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
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
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
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
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
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
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, &not_smi); 2282 __ JumpIfNotSmi(rax, &not_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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/x64/ic-x64.cc ('k') | test/cctest/cctest.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698