| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 |
| 6 | 6 |
| 7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
| 9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
| 10 #include "src/ic/handler-compiler.h" | 10 #include "src/ic/handler-compiler.h" |
| (...skipping 1858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1869 __ jmp(&done_no_smi_convert); | 1869 __ jmp(&done_no_smi_convert); |
| 1870 | 1870 |
| 1871 __ bind(&done); | 1871 __ bind(&done); |
| 1872 __ Integer32ToSmi(rdx, rdx); | 1872 __ Integer32ToSmi(rdx, rdx); |
| 1873 | 1873 |
| 1874 __ bind(&done_no_smi_convert); | 1874 __ bind(&done_no_smi_convert); |
| 1875 } | 1875 } |
| 1876 | 1876 |
| 1877 | 1877 |
| 1878 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { | 1878 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { |
| 1879 // ----------- S t a t e ------------- | |
| 1880 // -- rdi : the function to call | |
| 1881 // -- rdx : the function's shared function info | |
| 1882 // ----------------------------------- | |
| 1883 // Assume that SharedFunctionInfo is already loaded into rdx. | |
| 1884 // Do not transform the receiver for strict mode functions. | 1879 // Do not transform the receiver for strict mode functions. |
| 1885 __ testb(FieldOperand(rdx, SharedFunctionInfo::kStrictModeByteOffset), | 1880 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
| 1881 __ testb(FieldOperand(rcx, SharedFunctionInfo::kStrictModeByteOffset), |
| 1886 Immediate(1 << SharedFunctionInfo::kStrictModeBitWithinByte)); | 1882 Immediate(1 << SharedFunctionInfo::kStrictModeBitWithinByte)); |
| 1887 __ j(not_equal, cont); | 1883 __ j(not_equal, cont); |
| 1888 | 1884 |
| 1889 // Do not transform the receiver for natives. | 1885 // Do not transform the receiver for natives. |
| 1890 __ testb(FieldOperand(rdx, SharedFunctionInfo::kNativeByteOffset), | 1886 // SharedFunctionInfo is already loaded into rcx. |
| 1887 __ testb(FieldOperand(rcx, SharedFunctionInfo::kNativeByteOffset), |
| 1891 Immediate(1 << SharedFunctionInfo::kNativeBitWithinByte)); | 1888 Immediate(1 << SharedFunctionInfo::kNativeBitWithinByte)); |
| 1892 __ j(not_equal, cont); | 1889 __ j(not_equal, cont); |
| 1893 } | 1890 } |
| 1894 | 1891 |
| 1895 | 1892 |
| 1896 static void EmitSlowCase(MacroAssembler* masm, StackArgumentsAccessor* args, | 1893 static void EmitSlowCase(MacroAssembler* masm, StackArgumentsAccessor* args, |
| 1897 int argc) { | 1894 int argc) { |
| 1898 __ Set(rax, argc); | 1895 __ Set(rax, argc); |
| 1899 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 1896 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 1900 } | 1897 } |
| 1901 | 1898 |
| 1902 | 1899 |
| 1903 static void EmitWrapCase(MacroAssembler* masm, | 1900 static void EmitWrapCase(MacroAssembler* masm, |
| 1904 StackArgumentsAccessor* args, | 1901 StackArgumentsAccessor* args, |
| 1905 Label* cont) { | 1902 Label* cont) { |
| 1906 // Wrap the receiver and patch it back onto the stack. | 1903 // Wrap the receiver and patch it back onto the stack. |
| 1907 { FrameScope frame_scope(masm, StackFrame::INTERNAL); | 1904 { FrameScope frame_scope(masm, StackFrame::INTERNAL); |
| 1908 __ Push(rdi); | 1905 __ Push(rdi); |
| 1909 ToObjectStub stub(masm->isolate()); | 1906 ToObjectStub stub(masm->isolate()); |
| 1910 __ CallStub(&stub); | 1907 __ CallStub(&stub); |
| 1911 __ Pop(rdi); | 1908 __ Pop(rdi); |
| 1912 } | 1909 } |
| 1913 __ movp(args->GetReceiverOperand(), rax); | 1910 __ movp(args->GetReceiverOperand(), rax); |
| 1914 __ jmp(cont); | 1911 __ jmp(cont); |
| 1915 } | 1912 } |
| 1916 | 1913 |
| 1917 | 1914 |
| 1918 static void EmitClassConstructorCallCheck(MacroAssembler* masm) { | |
| 1919 // ----------- S t a t e ------------- | |
| 1920 // -- rdi : the function to call | |
| 1921 // -- rdx : the function's shared function info | |
| 1922 // ----------------------------------- | |
| 1923 // ClassConstructor Check: ES6 section 9.2.1 [[Call]] | |
| 1924 Label non_class_constructor; | |
| 1925 // Check whether the current function is a classConstructor | |
| 1926 __ testb(FieldOperand(rdx, SharedFunctionInfo::kFunctionKindByteOffset), | |
| 1927 Immediate(SharedFunctionInfo::kClassConstructorBitsWithinByte)); | |
| 1928 __ j(zero, &non_class_constructor, Label::kNear); | |
| 1929 // If we call a classConstructor Function throw a TypeError | |
| 1930 // indirectly via the CallFunction builtin. | |
| 1931 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET); | |
| 1932 __ bind(&non_class_constructor); | |
| 1933 } | |
| 1934 | |
| 1935 | |
| 1936 static void CallFunctionNoFeedback(MacroAssembler* masm, | 1915 static void CallFunctionNoFeedback(MacroAssembler* masm, |
| 1937 int argc, bool needs_checks, | 1916 int argc, bool needs_checks, |
| 1938 bool call_as_method) { | 1917 bool call_as_method) { |
| 1939 // ----------- S t a t e ------------- | 1918 // rdi : the function to call |
| 1940 // -- rdi : the function to call | |
| 1941 // ----------------------------------- | |
| 1942 | 1919 |
| 1943 // wrap_and_call can only be true if we are compiling a monomorphic method. | 1920 // wrap_and_call can only be true if we are compiling a monomorphic method. |
| 1944 Label slow, wrap, cont; | 1921 Label slow, wrap, cont; |
| 1945 StackArgumentsAccessor args(rsp, argc); | 1922 StackArgumentsAccessor args(rsp, argc); |
| 1946 | 1923 |
| 1947 if (needs_checks) { | 1924 if (needs_checks) { |
| 1948 // Check that the function really is a JavaScript function. | 1925 // Check that the function really is a JavaScript function. |
| 1949 __ JumpIfSmi(rdi, &slow); | 1926 __ JumpIfSmi(rdi, &slow); |
| 1950 | 1927 |
| 1951 // Goto slow case if we do not have a function. | 1928 // Goto slow case if we do not have a function. |
| 1952 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); | 1929 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); |
| 1953 __ j(not_equal, &slow); | 1930 __ j(not_equal, &slow); |
| 1954 } | 1931 } |
| 1955 | 1932 |
| 1956 __ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); | |
| 1957 EmitClassConstructorCallCheck(masm); | |
| 1958 | |
| 1959 // Fast-case: Just invoke the function. | 1933 // Fast-case: Just invoke the function. |
| 1960 ParameterCount actual(argc); | 1934 ParameterCount actual(argc); |
| 1961 | 1935 |
| 1962 if (call_as_method) { | 1936 if (call_as_method) { |
| 1963 if (needs_checks) { | 1937 if (needs_checks) { |
| 1964 EmitContinueIfStrictOrNative(masm, &cont); | 1938 EmitContinueIfStrictOrNative(masm, &cont); |
| 1965 } | 1939 } |
| 1966 | 1940 |
| 1967 // Load the receiver from the stack. | 1941 // Load the receiver from the stack. |
| 1968 __ movp(rax, args.GetReceiverOperand()); | 1942 __ movp(rax, args.GetReceiverOperand()); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2066 Smi::FromInt(CallICNexus::kCallCountIncrement)); | 2040 Smi::FromInt(CallICNexus::kCallCountIncrement)); |
| 2067 | 2041 |
| 2068 __ movp(rbx, rcx); | 2042 __ movp(rbx, rcx); |
| 2069 __ movp(rdx, rdi); | 2043 __ movp(rdx, rdi); |
| 2070 ArrayConstructorStub stub(masm->isolate(), arg_count()); | 2044 ArrayConstructorStub stub(masm->isolate(), arg_count()); |
| 2071 __ TailCallStub(&stub); | 2045 __ TailCallStub(&stub); |
| 2072 } | 2046 } |
| 2073 | 2047 |
| 2074 | 2048 |
| 2075 void CallICStub::Generate(MacroAssembler* masm) { | 2049 void CallICStub::Generate(MacroAssembler* masm) { |
| 2076 // ----------- S t a t e ------------- | 2050 // rdi - function |
| 2077 // -- rdi - function | 2051 // rdx - slot id |
| 2078 // -- rdx - slot id | 2052 // rbx - vector |
| 2079 // -- rbx - vector | |
| 2080 // ----------------------------------- | |
| 2081 Isolate* isolate = masm->isolate(); | 2053 Isolate* isolate = masm->isolate(); |
| 2082 const int with_types_offset = | 2054 const int with_types_offset = |
| 2083 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); | 2055 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); |
| 2084 const int generic_offset = | 2056 const int generic_offset = |
| 2085 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); | 2057 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); |
| 2086 Label extra_checks_or_miss, slow_start; | 2058 Label extra_checks_or_miss, slow_start; |
| 2087 Label slow, wrap, cont; | 2059 Label slow, wrap, cont; |
| 2088 Label have_js_function; | 2060 Label have_js_function; |
| 2089 int argc = arg_count(); | 2061 int argc = arg_count(); |
| 2090 StackArgumentsAccessor args(rsp, argc); | 2062 StackArgumentsAccessor args(rsp, argc); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2115 // The compare above could have been a SMI/SMI comparison. Guard against this | 2087 // The compare above could have been a SMI/SMI comparison. Guard against this |
| 2116 // convincing us that we have a monomorphic JSFunction. | 2088 // convincing us that we have a monomorphic JSFunction. |
| 2117 __ JumpIfSmi(rdi, &extra_checks_or_miss); | 2089 __ JumpIfSmi(rdi, &extra_checks_or_miss); |
| 2118 | 2090 |
| 2119 // Increment the call count for monomorphic function calls. | 2091 // Increment the call count for monomorphic function calls. |
| 2120 __ SmiAddConstant(FieldOperand(rbx, rdx, times_pointer_size, | 2092 __ SmiAddConstant(FieldOperand(rbx, rdx, times_pointer_size, |
| 2121 FixedArray::kHeaderSize + kPointerSize), | 2093 FixedArray::kHeaderSize + kPointerSize), |
| 2122 Smi::FromInt(CallICNexus::kCallCountIncrement)); | 2094 Smi::FromInt(CallICNexus::kCallCountIncrement)); |
| 2123 | 2095 |
| 2124 __ bind(&have_js_function); | 2096 __ bind(&have_js_function); |
| 2125 | |
| 2126 __ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); | |
| 2127 EmitClassConstructorCallCheck(masm); | |
| 2128 | |
| 2129 if (CallAsMethod()) { | 2097 if (CallAsMethod()) { |
| 2130 EmitContinueIfStrictOrNative(masm, &cont); | 2098 EmitContinueIfStrictOrNative(masm, &cont); |
| 2131 | 2099 |
| 2132 // Load the receiver from the stack. | 2100 // Load the receiver from the stack. |
| 2133 __ movp(rax, args.GetReceiverOperand()); | 2101 __ movp(rax, args.GetReceiverOperand()); |
| 2134 | 2102 |
| 2135 __ JumpIfSmi(rax, &wrap); | 2103 __ JumpIfSmi(rax, &wrap); |
| 2136 | 2104 |
| 2137 __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx); | 2105 __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx); |
| 2138 __ j(below, &wrap); | 2106 __ j(below, &wrap); |
| (...skipping 3488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5627 kStackSpace, nullptr, return_value_operand, NULL); | 5595 kStackSpace, nullptr, return_value_operand, NULL); |
| 5628 } | 5596 } |
| 5629 | 5597 |
| 5630 | 5598 |
| 5631 #undef __ | 5599 #undef __ |
| 5632 | 5600 |
| 5633 } // namespace internal | 5601 } // namespace internal |
| 5634 } // namespace v8 | 5602 } // namespace v8 |
| 5635 | 5603 |
| 5636 #endif // V8_TARGET_ARCH_X64 | 5604 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |