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 |