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

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

Issue 136643008: A64: Synchronize with r18256. (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/macro-assembler-x64.cc ('k') | test/cctest/cctest.h » ('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 619 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 thunk_address, 630 thunk_address,
631 callback_arg, 631 callback_arg,
632 argc + kFastApiCallArguments + 1, 632 argc + kFastApiCallArguments + 1,
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(CallStubCompiler* stub_compiler,
641 const ParameterCount& arguments, 641 const ParameterCount& arguments,
642 Register name, 642 Register name,
643 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,
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 // for API (object which is instanceof for the signature). It's 741 // for API (object which is instanceof for the signature). It's
742 // safe to omit it here, as if present, it should be fetched 742 // safe to omit it here, as if present, it should be fetched
743 // by the previous CheckPrototypes. 743 // by the previous CheckPrototypes.
744 ASSERT(depth2 == kInvalidProtoDepth); 744 ASSERT(depth2 == kInvalidProtoDepth);
745 } 745 }
746 746
747 // Invoke function. 747 // Invoke function.
748 if (can_do_fast_api_call) { 748 if (can_do_fast_api_call) {
749 GenerateFastApiCall(masm, optimization, arguments_.immediate()); 749 GenerateFastApiCall(masm, optimization, arguments_.immediate());
750 } else { 750 } else {
751 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
752 ? CALL_AS_FUNCTION
753 : CALL_AS_METHOD;
754 Handle<JSFunction> fun = optimization.constant_function(); 751 Handle<JSFunction> fun = optimization.constant_function();
755 ParameterCount expected(fun); 752 stub_compiler_->GenerateJumpFunctionIgnoreReceiver(fun);
756 __ InvokeFunction(fun, expected, arguments_,
757 JUMP_FUNCTION, NullCallWrapper(), call_kind);
758 } 753 }
759 754
760 // Deferred code for fast API call case---clean preallocated space. 755 // Deferred code for fast API call case---clean preallocated space.
761 if (can_do_fast_api_call) { 756 if (can_do_fast_api_call) {
762 __ bind(&miss_cleanup); 757 __ bind(&miss_cleanup);
763 FreeSpaceForFastApiCall(masm, scratch1); 758 FreeSpaceForFastApiCall(masm, scratch1);
764 __ jmp(miss_label); 759 __ jmp(miss_label);
765 } 760 }
766 761
767 // Invoke a regular function. 762 // Invoke a regular function.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
815 810
816 __ pop(name_); // Restore the name. 811 __ pop(name_); // Restore the name.
817 __ pop(receiver); // Restore the holder. 812 __ pop(receiver); // Restore the holder.
818 // Leave the internal frame. 813 // Leave the internal frame.
819 } 814 }
820 815
821 __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex); 816 __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex);
822 __ j(not_equal, interceptor_succeeded); 817 __ j(not_equal, interceptor_succeeded);
823 } 818 }
824 819
825 StubCompiler* stub_compiler_; 820 CallStubCompiler* stub_compiler_;
826 const ParameterCount& arguments_; 821 const ParameterCount& arguments_;
827 Register name_; 822 Register name_;
828 ExtraICState extra_ic_state_; 823 ExtraICState extra_ic_state_;
829 }; 824 };
830 825
831 826
832 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, 827 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
833 Label* label, 828 Label* label,
834 Handle<Name> name) { 829 Handle<Name> name) {
835 if (!label->is_unused()) { 830 if (!label->is_unused()) {
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after
1530 1525
1531 1526
1532 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { 1527 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) {
1533 if (kind_ == Code::KEYED_CALL_IC) { 1528 if (kind_ == Code::KEYED_CALL_IC) {
1534 __ Cmp(rcx, name); 1529 __ Cmp(rcx, name);
1535 __ j(not_equal, miss); 1530 __ j(not_equal, miss);
1536 } 1531 }
1537 } 1532 }
1538 1533
1539 1534
1535 void CallStubCompiler::GenerateFunctionCheck(Register function,
1536 Register scratch,
1537 Label* miss) {
1538 __ JumpIfSmi(function, miss);
1539 __ CmpObjectType(function, JS_FUNCTION_TYPE, scratch);
1540 __ j(not_equal, miss);
1541 }
1542
1543
1540 void CallStubCompiler::GenerateLoadFunctionFromCell( 1544 void CallStubCompiler::GenerateLoadFunctionFromCell(
1541 Handle<Cell> cell, 1545 Handle<Cell> cell,
1542 Handle<JSFunction> function, 1546 Handle<JSFunction> function,
1543 Label* miss) { 1547 Label* miss) {
1544 // Get the value from the cell. 1548 // Get the value from the cell.
1545 __ Move(rdi, cell); 1549 __ Move(rdi, cell);
1546 __ movq(rdi, FieldOperand(rdi, Cell::kValueOffset)); 1550 __ movq(rdi, FieldOperand(rdi, Cell::kValueOffset));
1547 1551
1548 // Check that the cell contains the same function. 1552 // Check that the cell contains the same function.
1549 if (heap()->InNewSpace(*function)) { 1553 if (heap()->InNewSpace(*function)) {
1550 // We can't embed a pointer to a function in new space so we have 1554 // We can't embed a pointer to a function in new space so we have
1551 // to verify that the shared function info is unchanged. This has 1555 // to verify that the shared function info is unchanged. This has
1552 // the nice side effect that multiple closures based on the same 1556 // the nice side effect that multiple closures based on the same
1553 // function can all use this call IC. Before we load through the 1557 // function can all use this call IC. Before we load through the
1554 // function, we have to verify that it still is a function. 1558 // function, we have to verify that it still is a function.
1555 __ JumpIfSmi(rdi, miss); 1559 GenerateFunctionCheck(rdi, rax, miss);
1556 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rax);
1557 __ j(not_equal, miss);
1558 1560
1559 // Check the shared function info. Make sure it hasn't changed. 1561 // Check the shared function info. Make sure it hasn't changed.
1560 __ Move(rax, Handle<SharedFunctionInfo>(function->shared())); 1562 __ Move(rax, Handle<SharedFunctionInfo>(function->shared()));
1561 __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax); 1563 __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax);
1562 } else { 1564 } else {
1563 __ Cmp(rdi, function); 1565 __ Cmp(rdi, function);
1564 } 1566 }
1565 __ j(not_equal, miss); 1567 __ j(not_equal, miss);
1566 } 1568 }
1567 1569
1568 1570
1569 void CallStubCompiler::GenerateMissBranch() { 1571 void CallStubCompiler::GenerateMissBranch() {
1570 Handle<Code> code = 1572 Handle<Code> code =
1571 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), 1573 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(),
1572 kind_, 1574 kind_,
1573 extra_state_); 1575 extra_state());
1574 __ Jump(code, RelocInfo::CODE_TARGET); 1576 __ Jump(code, RelocInfo::CODE_TARGET);
1575 } 1577 }
1576 1578
1577 1579
1578 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, 1580 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
1579 Handle<JSObject> holder, 1581 Handle<JSObject> holder,
1580 PropertyIndex index, 1582 PropertyIndex index,
1581 Handle<Name> name) { 1583 Handle<Name> name) {
1582 Label miss; 1584 Label miss;
1583 1585
1584 Register reg = HandlerFrontendHeader( 1586 Register reg = HandlerFrontendHeader(
1585 object, holder, name, RECEIVER_MAP_CHECK, &miss); 1587 object, holder, name, RECEIVER_MAP_CHECK, &miss);
1586 1588
1587 GenerateFastPropertyLoad(masm(), rdi, reg, index.is_inobject(holder), 1589 GenerateFastPropertyLoad(masm(), rdi, reg, index.is_inobject(holder),
1588 index.translate(holder), Representation::Tagged()); 1590 index.translate(holder), Representation::Tagged());
1589 1591 GenerateJumpFunction(object, rdi, &miss);
1590 // Check that the function really is a function.
1591 __ JumpIfSmi(rdi, &miss);
1592 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rbx);
1593 __ j(not_equal, &miss);
1594
1595 PatchGlobalProxy(object);
1596
1597 // Invoke the function.
1598 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
1599 ? CALL_AS_FUNCTION
1600 : CALL_AS_METHOD;
1601 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION,
1602 NullCallWrapper(), call_kind);
1603 1592
1604 HandlerFrontendFooter(&miss); 1593 HandlerFrontendFooter(&miss);
1605 1594
1606 // Return the generated code. 1595 // Return the generated code.
1607 return GetCode(Code::FAST, name); 1596 return GetCode(Code::FAST, name);
1608 } 1597 }
1609 1598
1610 1599
1611 Handle<Code> CallStubCompiler::CompileArrayCodeCall( 1600 Handle<Code> CallStubCompiler::CompileArrayCodeCall(
1612 Handle<Object> object, 1601 Handle<Object> object,
(...skipping 28 matching lines...) Expand all
1641 } 1630 }
1642 1631
1643 1632
1644 Handle<Code> CallStubCompiler::CompileArrayPushCall( 1633 Handle<Code> CallStubCompiler::CompileArrayPushCall(
1645 Handle<Object> object, 1634 Handle<Object> object,
1646 Handle<JSObject> holder, 1635 Handle<JSObject> holder,
1647 Handle<Cell> cell, 1636 Handle<Cell> cell,
1648 Handle<JSFunction> function, 1637 Handle<JSFunction> function,
1649 Handle<String> name, 1638 Handle<String> name,
1650 Code::StubType type) { 1639 Code::StubType type) {
1651 // ----------- S t a t e ------------- 1640 // If object is not an array or is observed or sealed, bail out to regular
1652 // -- rcx : name 1641 // call.
1653 // -- rsp[0] : return address
1654 // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
1655 // -- ...
1656 // -- rsp[(argc + 1) * 8] : receiver
1657 // -----------------------------------
1658
1659 // If object is not an array or is observed, bail out to regular call.
1660 if (!object->IsJSArray() || 1642 if (!object->IsJSArray() ||
1661 !cell.is_null() || 1643 !cell.is_null() ||
1662 Handle<JSArray>::cast(object)->map()->is_observed()) { 1644 Handle<JSArray>::cast(object)->map()->is_observed() ||
1645 !Handle<JSArray>::cast(object)->map()->is_extensible()) {
1663 return Handle<Code>::null(); 1646 return Handle<Code>::null();
1664 } 1647 }
1665 1648
1666 Label miss; 1649 Label miss;
1667 1650
1668 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 1651 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1669 1652
1670 const int argc = arguments().immediate(); 1653 const int argc = arguments().immediate();
1671 StackArgumentsAccessor args(rsp, argc); 1654 StackArgumentsAccessor args(rsp, argc);
1672 if (argc == 0) { 1655 if (argc == 0) {
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
1888 } 1871 }
1889 1872
1890 1873
1891 Handle<Code> CallStubCompiler::CompileArrayPopCall( 1874 Handle<Code> CallStubCompiler::CompileArrayPopCall(
1892 Handle<Object> object, 1875 Handle<Object> object,
1893 Handle<JSObject> holder, 1876 Handle<JSObject> holder,
1894 Handle<Cell> cell, 1877 Handle<Cell> cell,
1895 Handle<JSFunction> function, 1878 Handle<JSFunction> function,
1896 Handle<String> name, 1879 Handle<String> name,
1897 Code::StubType type) { 1880 Code::StubType type) {
1898 // If object is not an array or is observed, bail out to regular call. 1881 // If object is not an array or is observed or sealed, bail out to regular
1882 // call.
1899 if (!object->IsJSArray() || 1883 if (!object->IsJSArray() ||
1900 !cell.is_null() || 1884 !cell.is_null() ||
1901 Handle<JSArray>::cast(object)->map()->is_observed()) { 1885 Handle<JSArray>::cast(object)->map()->is_observed() ||
1886 !Handle<JSArray>::cast(object)->map()->is_extensible()) {
1902 return Handle<Code>::null(); 1887 return Handle<Code>::null();
1903 } 1888 }
1904 1889
1905 Label miss, return_undefined, call_builtin; 1890 Label miss, return_undefined, call_builtin;
1906 1891
1907 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 1892 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1908 1893
1909 // Get the elements array of the object. 1894 // Get the elements array of the object.
1910 __ movq(rbx, FieldOperand(rdx, JSArray::kElementsOffset)); 1895 __ movq(rbx, FieldOperand(rdx, JSArray::kElementsOffset));
1911 1896
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1965 Handle<String> name, 1950 Handle<String> name,
1966 Code::StubType type) { 1951 Code::StubType type) {
1967 // If object is not a string, bail out to regular call. 1952 // If object is not a string, bail out to regular call.
1968 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); 1953 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null();
1969 1954
1970 Label miss; 1955 Label miss;
1971 Label name_miss; 1956 Label name_miss;
1972 Label index_out_of_range; 1957 Label index_out_of_range;
1973 Label* index_out_of_range_label = &index_out_of_range; 1958 Label* index_out_of_range_label = &index_out_of_range;
1974 if (kind_ == Code::CALL_IC && 1959 if (kind_ == Code::CALL_IC &&
1975 (CallICBase::StringStubState::decode(extra_state_) == 1960 (CallICBase::StringStubState::decode(extra_state()) ==
1976 DEFAULT_STRING_STUB)) { 1961 DEFAULT_STRING_STUB)) {
1977 index_out_of_range_label = &miss; 1962 index_out_of_range_label = &miss;
1978 } 1963 }
1979 1964
1980 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss); 1965 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss);
1981 1966
1982 Register receiver = rbx; 1967 Register receiver = rbx;
1983 Register index = rdi; 1968 Register index = rdi;
1984 Register result = rax; 1969 Register result = rax;
1985 const int argc = arguments().immediate(); 1970 const int argc = arguments().immediate();
(...skipping 21 matching lines...) Expand all
2007 1992
2008 if (index_out_of_range.is_linked()) { 1993 if (index_out_of_range.is_linked()) {
2009 __ bind(&index_out_of_range); 1994 __ bind(&index_out_of_range);
2010 __ LoadRoot(rax, Heap::kNanValueRootIndex); 1995 __ LoadRoot(rax, Heap::kNanValueRootIndex);
2011 __ ret((argc + 1) * kPointerSize); 1996 __ ret((argc + 1) * kPointerSize);
2012 } 1997 }
2013 1998
2014 __ bind(&miss); 1999 __ bind(&miss);
2015 // Restore function name in rcx. 2000 // Restore function name in rcx.
2016 __ Move(rcx, name); 2001 __ Move(rcx, name);
2017 __ bind(&name_miss); 2002 HandlerFrontendFooter(&name_miss);
2018 GenerateMissBranch();
2019 2003
2020 // Return the generated code. 2004 // Return the generated code.
2021 return GetCode(type, name); 2005 return GetCode(type, name);
2022 } 2006 }
2023 2007
2024 2008
2025 Handle<Code> CallStubCompiler::CompileStringCharAtCall( 2009 Handle<Code> CallStubCompiler::CompileStringCharAtCall(
2026 Handle<Object> object, 2010 Handle<Object> object,
2027 Handle<JSObject> holder, 2011 Handle<JSObject> holder,
2028 Handle<Cell> cell, 2012 Handle<Cell> cell,
2029 Handle<JSFunction> function, 2013 Handle<JSFunction> function,
2030 Handle<String> name, 2014 Handle<String> name,
2031 Code::StubType type) { 2015 Code::StubType type) {
2032 // If object is not a string, bail out to regular call. 2016 // If object is not a string, bail out to regular call.
2033 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); 2017 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null();
2034 2018
2035 const int argc = arguments().immediate(); 2019 const int argc = arguments().immediate();
2036 StackArgumentsAccessor args(rsp, argc); 2020 StackArgumentsAccessor args(rsp, argc);
2037 2021
2038 Label miss; 2022 Label miss;
2039 Label name_miss; 2023 Label name_miss;
2040 Label index_out_of_range; 2024 Label index_out_of_range;
2041 Label* index_out_of_range_label = &index_out_of_range; 2025 Label* index_out_of_range_label = &index_out_of_range;
2042 if (kind_ == Code::CALL_IC && 2026 if (kind_ == Code::CALL_IC &&
2043 (CallICBase::StringStubState::decode(extra_state_) == 2027 (CallICBase::StringStubState::decode(extra_state()) ==
2044 DEFAULT_STRING_STUB)) { 2028 DEFAULT_STRING_STUB)) {
2045 index_out_of_range_label = &miss; 2029 index_out_of_range_label = &miss;
2046 } 2030 }
2047 2031
2048 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss); 2032 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss);
2049 2033
2050 Register receiver = rax; 2034 Register receiver = rax;
2051 Register index = rdi; 2035 Register index = rdi;
2052 Register scratch = rdx; 2036 Register scratch = rdx;
2053 Register result = rax; 2037 Register result = rax;
(...skipping 19 matching lines...) Expand all
2073 generator.GenerateSlow(masm(), call_helper); 2057 generator.GenerateSlow(masm(), call_helper);
2074 2058
2075 if (index_out_of_range.is_linked()) { 2059 if (index_out_of_range.is_linked()) {
2076 __ bind(&index_out_of_range); 2060 __ bind(&index_out_of_range);
2077 __ LoadRoot(rax, Heap::kempty_stringRootIndex); 2061 __ LoadRoot(rax, Heap::kempty_stringRootIndex);
2078 __ ret((argc + 1) * kPointerSize); 2062 __ ret((argc + 1) * kPointerSize);
2079 } 2063 }
2080 __ bind(&miss); 2064 __ bind(&miss);
2081 // Restore function name in rcx. 2065 // Restore function name in rcx.
2082 __ Move(rcx, name); 2066 __ Move(rcx, name);
2083 __ bind(&name_miss); 2067 HandlerFrontendFooter(&name_miss);
2084 GenerateMissBranch();
2085 2068
2086 // Return the generated code. 2069 // Return the generated code.
2087 return GetCode(type, name); 2070 return GetCode(type, name);
2088 } 2071 }
2089 2072
2090 2073
2091 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( 2074 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
2092 Handle<Object> object, 2075 Handle<Object> object,
2093 Handle<JSObject> holder, 2076 Handle<JSObject> holder,
2094 Handle<Cell> cell, 2077 Handle<Cell> cell,
(...skipping 25 matching lines...) Expand all
2120 // Convert the smi code to uint16. 2103 // Convert the smi code to uint16.
2121 __ SmiAndConstant(code, code, Smi::FromInt(0xffff)); 2104 __ SmiAndConstant(code, code, Smi::FromInt(0xffff));
2122 2105
2123 StringCharFromCodeGenerator generator(code, rax); 2106 StringCharFromCodeGenerator generator(code, rax);
2124 generator.GenerateFast(masm()); 2107 generator.GenerateFast(masm());
2125 __ ret(2 * kPointerSize); 2108 __ ret(2 * kPointerSize);
2126 2109
2127 StubRuntimeCallHelper call_helper; 2110 StubRuntimeCallHelper call_helper;
2128 generator.GenerateSlow(masm(), call_helper); 2111 generator.GenerateSlow(masm(), call_helper);
2129 2112
2130 // Tail call the full function. We do not have to patch the receiver
2131 // because the function makes no use of it.
2132 __ bind(&slow); 2113 __ bind(&slow);
2133 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2114 // We do not have to patch the receiver because the function makes no use of
2134 ? CALL_AS_FUNCTION 2115 // it.
2135 : CALL_AS_METHOD; 2116 GenerateJumpFunctionIgnoreReceiver(function);
2136 ParameterCount expected(function);
2137 __ InvokeFunction(function, expected, arguments(),
2138 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2139 2117
2140 HandlerFrontendFooter(&miss); 2118 HandlerFrontendFooter(&miss);
2141 2119
2142 // Return the generated code. 2120 // Return the generated code.
2143 return GetCode(type, name); 2121 return GetCode(type, name);
2144 } 2122 }
2145 2123
2146 2124
2147 Handle<Code> CallStubCompiler::CompileMathFloorCall( 2125 Handle<Code> CallStubCompiler::CompileMathFloorCall(
2148 Handle<Object> object, 2126 Handle<Object> object,
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
2231 // Return a new heap number. 2209 // Return a new heap number.
2232 __ AllocateHeapNumber(rax, rbx, &slow); 2210 __ AllocateHeapNumber(rax, rbx, &slow);
2233 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm0); 2211 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm0);
2234 __ ret(2 * kPointerSize); 2212 __ ret(2 * kPointerSize);
2235 2213
2236 // Return the argument (when it's an already round heap number). 2214 // Return the argument (when it's an already round heap number).
2237 __ bind(&already_round); 2215 __ bind(&already_round);
2238 __ movq(rax, args.GetArgumentOperand(1)); 2216 __ movq(rax, args.GetArgumentOperand(1));
2239 __ ret(2 * kPointerSize); 2217 __ ret(2 * kPointerSize);
2240 2218
2241 // Tail call the full function. We do not have to patch the receiver
2242 // because the function makes no use of it.
2243 __ bind(&slow); 2219 __ bind(&slow);
2244 ParameterCount expected(function); 2220 // We do not have to patch the receiver because the function makes no use of
2245 __ InvokeFunction(function, expected, arguments(), 2221 // it.
2246 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2222 GenerateJumpFunctionIgnoreReceiver(function);
2247 2223
2248 HandlerFrontendFooter(&miss); 2224 HandlerFrontendFooter(&miss);
2249 2225
2250 // Return the generated code. 2226 // Return the generated code.
2251 return GetCode(type, name); 2227 return GetCode(type, name);
2252 } 2228 }
2253 2229
2254 2230
2255 Handle<Code> CallStubCompiler::CompileMathAbsCall( 2231 Handle<Code> CallStubCompiler::CompileMathAbsCall(
2256 Handle<Object> object, 2232 Handle<Object> object,
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2317 __ ret(2 * kPointerSize); 2293 __ ret(2 * kPointerSize);
2318 2294
2319 // If the argument is negative, clear the sign, and return a new 2295 // If the argument is negative, clear the sign, and return a new
2320 // number. We still have the sign mask in rdi. 2296 // number. We still have the sign mask in rdi.
2321 __ bind(&negative_sign); 2297 __ bind(&negative_sign);
2322 __ xor_(rbx, rdi); 2298 __ xor_(rbx, rdi);
2323 __ AllocateHeapNumber(rax, rdx, &slow); 2299 __ AllocateHeapNumber(rax, rdx, &slow);
2324 __ MoveDouble(FieldOperand(rax, HeapNumber::kValueOffset), rbx); 2300 __ MoveDouble(FieldOperand(rax, HeapNumber::kValueOffset), rbx);
2325 __ ret(2 * kPointerSize); 2301 __ ret(2 * kPointerSize);
2326 2302
2327 // Tail call the full function. We do not have to patch the receiver
2328 // because the function makes no use of it.
2329 __ bind(&slow); 2303 __ bind(&slow);
2330 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2304 // We do not have to patch the receiver because the function makes no use of
2331 ? CALL_AS_FUNCTION 2305 // it.
2332 : CALL_AS_METHOD; 2306 GenerateJumpFunctionIgnoreReceiver(function);
2333 ParameterCount expected(function);
2334 __ InvokeFunction(function, expected, arguments(),
2335 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2336 2307
2337 HandlerFrontendFooter(&miss); 2308 HandlerFrontendFooter(&miss);
2338 2309
2339 // Return the generated code. 2310 // Return the generated code.
2340 return GetCode(type, name); 2311 return GetCode(type, name);
2341 } 2312 }
2342 2313
2343 2314
2344 Handle<Code> CallStubCompiler::CompileFastApiCall( 2315 Handle<Code> CallStubCompiler::CompileFastApiCall(
2345 const CallOptimization& optimization, 2316 const CallOptimization& optimization,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2383 // Move the return address on top of the stack. 2354 // Move the return address on top of the stack.
2384 __ movq(rax, 2355 __ movq(rax,
2385 StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize)); 2356 StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize));
2386 __ movq(StackOperandForReturnAddress(0), rax); 2357 __ movq(StackOperandForReturnAddress(0), rax);
2387 2358
2388 GenerateFastApiCall(masm(), optimization, argc); 2359 GenerateFastApiCall(masm(), optimization, argc);
2389 2360
2390 __ bind(&miss); 2361 __ bind(&miss);
2391 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); 2362 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
2392 2363
2393 __ bind(&miss_before_stack_reserved); 2364 HandlerFrontendFooter(&miss_before_stack_reserved);
2394 GenerateMissBranch();
2395 2365
2396 // Return the generated code. 2366 // Return the generated code.
2397 return GetCode(function); 2367 return GetCode(function);
2398 } 2368 }
2399 2369
2400 2370
2401 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { 2371 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
2402 Label success; 2372 Label success;
2403 // Check that the object is a boolean. 2373 // Check that the object is a boolean.
2404 __ CompareRoot(object, Heap::kTrueValueRootIndex); 2374 __ CompareRoot(object, Heap::kTrueValueRootIndex);
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
2492 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); 2462 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2493 reg = CheckPrototypes( 2463 reg = CheckPrototypes(
2494 IC::CurrentTypeOf(prototype, isolate()), 2464 IC::CurrentTypeOf(prototype, isolate()),
2495 rax, holder, rbx, rdx, rdi, name, miss); 2465 rax, holder, rbx, rdx, rdi, name, miss);
2496 } 2466 }
2497 2467
2498 return reg; 2468 return reg;
2499 } 2469 }
2500 2470
2501 2471
2502 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { 2472 void CallStubCompiler::GenerateJumpFunction(Handle<Object> object,
2503 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2473 Register function,
2504 ? CALL_AS_FUNCTION 2474 Label* miss) {
2505 : CALL_AS_METHOD; 2475 // Check that the function really is a function.
2506 ParameterCount expected(function); 2476 GenerateFunctionCheck(function, rbx, miss);
2507 __ InvokeFunction(function, expected, arguments(), 2477
2508 JUMP_FUNCTION, NullCallWrapper(), call_kind); 2478 if (!function.is(rdi)) __ movq(rdi, function);
2479 PatchGlobalProxy(object);
2480
2481 // Invoke the function.
2482 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION,
2483 NullCallWrapper(), call_kind());
2509 } 2484 }
2510 2485
2511 2486
2512 Handle<Code> CallStubCompiler::CompileCallConstant(
2513 Handle<Object> object,
2514 Handle<JSObject> holder,
2515 Handle<Name> name,
2516 CheckType check,
2517 Handle<JSFunction> function) {
2518 if (HasCustomCallGenerator(function)) {
2519 Handle<Code> code = CompileCustomCall(object, holder,
2520 Handle<PropertyCell>::null(),
2521 function, Handle<String>::cast(name),
2522 Code::FAST);
2523 // A null handle means bail out to the regular compiler code below.
2524 if (!code.is_null()) return code;
2525 }
2526
2527 Label miss;
2528 HandlerFrontendHeader(object, holder, name, check, &miss);
2529 PatchGlobalProxy(object);
2530 CompileHandlerBackend(function);
2531 HandlerFrontendFooter(&miss);
2532
2533 // Return the generated code.
2534 return GetCode(function);
2535 }
2536
2537
2538 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, 2487 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
2539 Handle<JSObject> holder, 2488 Handle<JSObject> holder,
2540 Handle<Name> name) { 2489 Handle<Name> name) {
2541 Label miss; 2490 Label miss;
2542 GenerateNameCheck(name, &miss); 2491 GenerateNameCheck(name, &miss);
2543 2492
2544 LookupResult lookup(isolate()); 2493 LookupResult lookup(isolate());
2545 LookupPostInterceptor(holder, name, &lookup); 2494 LookupPostInterceptor(holder, name, &lookup);
2546 2495
2547 // Get the receiver from the stack. 2496 // Get the receiver from the stack.
2548 StackArgumentsAccessor args(rsp, arguments()); 2497 StackArgumentsAccessor args(rsp, arguments());
2549 __ movq(rdx, args.GetReceiverOperand()); 2498 __ movq(rdx, args.GetReceiverOperand());
2550 2499
2551 CallInterceptorCompiler compiler(this, arguments(), rcx, extra_state_); 2500 CallInterceptorCompiler compiler(this, arguments(), rcx, extra_state());
2552 compiler.Compile(masm(), object, holder, name, &lookup, rdx, rbx, rdi, rax, 2501 compiler.Compile(masm(), object, holder, name, &lookup, rdx, rbx, rdi, rax,
2553 &miss); 2502 &miss);
2554 2503
2555 // Restore receiver. 2504 // Restore receiver.
2556 __ movq(rdx, args.GetReceiverOperand()); 2505 __ movq(rdx, args.GetReceiverOperand());
2557 2506
2558 // Check that the function really is a function. 2507 GenerateJumpFunction(object, rax, &miss);
2559 __ JumpIfSmi(rax, &miss);
2560 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx);
2561 __ j(not_equal, &miss);
2562 2508
2563 // Patch the receiver on the stack with the global proxy if 2509 HandlerFrontendFooter(&miss);
2564 // necessary.
2565 if (object->IsGlobalObject()) {
2566 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
2567 __ movq(args.GetReceiverOperand(), rdx);
2568 }
2569
2570 // Invoke the function.
2571 __ movq(rdi, rax);
2572 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2573 ? CALL_AS_FUNCTION
2574 : CALL_AS_METHOD;
2575 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION,
2576 NullCallWrapper(), call_kind);
2577
2578 // Handle load cache miss.
2579 __ bind(&miss);
2580 GenerateMissBranch();
2581 2510
2582 // Return the generated code. 2511 // Return the generated code.
2583 return GetCode(Code::FAST, name); 2512 return GetCode(Code::FAST, name);
2584 } 2513 }
2585 2514
2586 2515
2587 Handle<Code> CallStubCompiler::CompileCallGlobal( 2516 Handle<Code> CallStubCompiler::CompileCallGlobal(
2588 Handle<JSObject> object, 2517 Handle<JSObject> object,
2589 Handle<GlobalObject> holder, 2518 Handle<GlobalObject> holder,
2590 Handle<PropertyCell> cell, 2519 Handle<PropertyCell> cell,
2591 Handle<JSFunction> function, 2520 Handle<JSFunction> function,
2592 Handle<Name> name) { 2521 Handle<Name> name) {
2593 if (HasCustomCallGenerator(function)) { 2522 if (HasCustomCallGenerator(function)) {
2594 Handle<Code> code = CompileCustomCall( 2523 Handle<Code> code = CompileCustomCall(
2595 object, holder, cell, function, Handle<String>::cast(name), 2524 object, holder, cell, function, Handle<String>::cast(name),
2596 Code::NORMAL); 2525 Code::NORMAL);
2597 // A null handle means bail out to the regular compiler code below. 2526 // A null handle means bail out to the regular compiler code below.
2598 if (!code.is_null()) return code; 2527 if (!code.is_null()) return code;
2599 } 2528 }
2600 2529
2601 Label miss; 2530 Label miss;
2602 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 2531 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2532 // Potentially loads a closure that matches the shared function info of the
2533 // function, rather than function.
2603 GenerateLoadFunctionFromCell(cell, function, &miss); 2534 GenerateLoadFunctionFromCell(cell, function, &miss);
2604 PatchGlobalProxy(object);
2605
2606 // Set up the context (function already in rdi).
2607 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
2608
2609 // Jump to the cached code (tail call).
2610 Counters* counters = isolate()->counters(); 2535 Counters* counters = isolate()->counters();
2611 __ IncrementCounter(counters->call_global_inline(), 1); 2536 __ IncrementCounter(counters->call_global_inline(), 1);
2612 ParameterCount expected(function->shared()->formal_parameter_count()); 2537 GenerateJumpFunction(object, rdi, function);
2613 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2614 ? CALL_AS_FUNCTION
2615 : CALL_AS_METHOD;
2616 // We call indirectly through the code field in the function to
2617 // allow recompilation to take effect without changing any of the
2618 // call sites.
2619 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
2620 __ InvokeCode(rdx, expected, arguments(), JUMP_FUNCTION,
2621 NullCallWrapper(), call_kind);
2622
2623 HandlerFrontendFooter(&miss); 2538 HandlerFrontendFooter(&miss);
2624 2539
2625 // Return the generated code. 2540 // Return the generated code.
2626 return GetCode(Code::NORMAL, name); 2541 return GetCode(Code::NORMAL, name);
2627 } 2542 }
2628 2543
2629 2544
2630 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2545 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2631 Handle<JSObject> object, 2546 Handle<JSObject> object,
2632 Handle<JSObject> holder, 2547 Handle<JSObject> holder,
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
2996 // ----------------------------------- 2911 // -----------------------------------
2997 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 2912 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
2998 } 2913 }
2999 2914
3000 2915
3001 #undef __ 2916 #undef __
3002 2917
3003 } } // namespace v8::internal 2918 } } // namespace v8::internal
3004 2919
3005 #endif // V8_TARGET_ARCH_X64 2920 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.cc ('k') | test/cctest/cctest.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698