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