OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 1885 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1896 __ TailCallRuntime( | 1896 __ TailCallRuntime( |
1897 is_strong(strength()) ? Runtime::kCompare_Strong : Runtime::kCompare, 3, | 1897 is_strong(strength()) ? Runtime::kCompare_Strong : Runtime::kCompare, 3, |
1898 1); | 1898 1); |
1899 } | 1899 } |
1900 | 1900 |
1901 __ bind(&miss); | 1901 __ bind(&miss); |
1902 GenerateMiss(masm); | 1902 GenerateMiss(masm); |
1903 } | 1903 } |
1904 | 1904 |
1905 | 1905 |
1906 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub, | 1906 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) { |
1907 bool is_super) { | |
1908 // eax : number of arguments to the construct function | 1907 // eax : number of arguments to the construct function |
1909 // ebx : feedback vector | 1908 // ebx : feedback vector |
1910 // edx : slot in feedback vector (Smi) | 1909 // edx : slot in feedback vector (Smi) |
1911 // edi : the function to call | 1910 // edi : the function to call |
1912 // esp[0]: original receiver (for IsSuperConstructorCall) | |
1913 if (is_super) { | |
1914 __ pop(ecx); | |
1915 } | |
1916 | 1911 |
1917 { | 1912 { |
1918 FrameScope scope(masm, StackFrame::INTERNAL); | 1913 FrameScope scope(masm, StackFrame::INTERNAL); |
1919 | 1914 |
1920 // Number-of-arguments register must be smi-tagged to call out. | 1915 // Number-of-arguments register must be smi-tagged to call out. |
1921 __ SmiTag(eax); | 1916 __ SmiTag(eax); |
1922 __ push(eax); | 1917 __ push(eax); |
1923 __ push(edi); | 1918 __ push(edi); |
1924 __ push(edx); | 1919 __ push(edx); |
1925 __ push(ebx); | 1920 __ push(ebx); |
1926 if (is_super) { | |
1927 __ push(ecx); | |
1928 } | |
1929 | 1921 |
1930 __ CallStub(stub); | 1922 __ CallStub(stub); |
1931 | 1923 |
1932 if (is_super) { | |
1933 __ pop(ecx); | |
1934 } | |
1935 __ pop(ebx); | 1924 __ pop(ebx); |
1936 __ pop(edx); | 1925 __ pop(edx); |
1937 __ pop(edi); | 1926 __ pop(edi); |
1938 __ pop(eax); | 1927 __ pop(eax); |
1939 __ SmiUntag(eax); | 1928 __ SmiUntag(eax); |
1940 } | 1929 } |
1941 | |
1942 if (is_super) { | |
1943 __ push(ecx); | |
1944 } | |
1945 } | 1930 } |
1946 | 1931 |
1947 | 1932 |
1948 static void GenerateRecordCallTarget(MacroAssembler* masm, bool is_super) { | 1933 static void GenerateRecordCallTarget(MacroAssembler* masm) { |
1949 // Cache the called function in a feedback vector slot. Cache states | 1934 // Cache the called function in a feedback vector slot. Cache states |
1950 // are uninitialized, monomorphic (indicated by a JSFunction), and | 1935 // are uninitialized, monomorphic (indicated by a JSFunction), and |
1951 // megamorphic. | 1936 // megamorphic. |
1952 // eax : number of arguments to the construct function | 1937 // eax : number of arguments to the construct function |
1953 // ebx : feedback vector | 1938 // ebx : feedback vector |
1954 // edx : slot in feedback vector (Smi) | 1939 // edx : slot in feedback vector (Smi) |
1955 // edi : the function to call | 1940 // edi : the function to call |
1956 // esp[0]: original receiver (for IsSuperConstructorCall) | |
1957 Isolate* isolate = masm->isolate(); | 1941 Isolate* isolate = masm->isolate(); |
1958 Label initialize, done, miss, megamorphic, not_array_function; | 1942 Label initialize, done, miss, megamorphic, not_array_function; |
1959 | 1943 |
1960 // Load the cache state into ecx. | 1944 // Load the cache state into ecx. |
1961 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, | 1945 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, |
1962 FixedArray::kHeaderSize)); | 1946 FixedArray::kHeaderSize)); |
1963 | 1947 |
1964 // A monomorphic cache hit or an already megamorphic state: invoke the | 1948 // A monomorphic cache hit or an already megamorphic state: invoke the |
1965 // function without changing the state. | 1949 // function without changing the state. |
1966 // We don't know if ecx is a WeakCell or a Symbol, but it's harmless to read | 1950 // We don't know if ecx is a WeakCell or a Symbol, but it's harmless to read |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2012 __ bind(&initialize); | 1996 __ bind(&initialize); |
2013 // Make sure the function is the Array() function | 1997 // Make sure the function is the Array() function |
2014 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx); | 1998 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx); |
2015 __ cmp(edi, ecx); | 1999 __ cmp(edi, ecx); |
2016 __ j(not_equal, ¬_array_function); | 2000 __ j(not_equal, ¬_array_function); |
2017 | 2001 |
2018 // The target function is the Array constructor, | 2002 // The target function is the Array constructor, |
2019 // Create an AllocationSite if we don't already have it, store it in the | 2003 // Create an AllocationSite if we don't already have it, store it in the |
2020 // slot. | 2004 // slot. |
2021 CreateAllocationSiteStub create_stub(isolate); | 2005 CreateAllocationSiteStub create_stub(isolate); |
2022 CallStubInRecordCallTarget(masm, &create_stub, is_super); | 2006 CallStubInRecordCallTarget(masm, &create_stub); |
2023 __ jmp(&done); | 2007 __ jmp(&done); |
2024 | 2008 |
2025 __ bind(¬_array_function); | 2009 __ bind(¬_array_function); |
2026 CreateWeakCellStub weak_cell_stub(isolate); | 2010 CreateWeakCellStub weak_cell_stub(isolate); |
2027 CallStubInRecordCallTarget(masm, &weak_cell_stub, is_super); | 2011 CallStubInRecordCallTarget(masm, &weak_cell_stub); |
2028 __ bind(&done); | 2012 __ bind(&done); |
2029 } | 2013 } |
2030 | 2014 |
2031 | 2015 |
2032 void CallConstructStub::Generate(MacroAssembler* masm) { | 2016 void CallConstructStub::Generate(MacroAssembler* masm) { |
2033 // eax : number of arguments | 2017 // eax : number of arguments |
2034 // ebx : feedback vector | 2018 // ebx : feedback vector |
2035 // ecx : new target (for IsSuperConstructorCall) | |
2036 // edx : slot in feedback vector (Smi, for RecordCallTarget) | 2019 // edx : slot in feedback vector (Smi, for RecordCallTarget) |
2037 // edi : constructor function | 2020 // edi : constructor function |
2038 | 2021 |
2039 if (IsSuperConstructorCall()) { | |
2040 __ push(ecx); | |
2041 } | |
2042 | |
2043 Label non_function; | 2022 Label non_function; |
2044 // Check that function is not a smi. | 2023 // Check that function is not a smi. |
2045 __ JumpIfSmi(edi, &non_function); | 2024 __ JumpIfSmi(edi, &non_function); |
2046 // Check that function is a JSFunction. | 2025 // Check that function is a JSFunction. |
2047 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); | 2026 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); |
2048 __ j(not_equal, &non_function); | 2027 __ j(not_equal, &non_function); |
2049 | 2028 |
2050 if (RecordCallTarget()) { | 2029 GenerateRecordCallTarget(masm); |
2051 GenerateRecordCallTarget(masm, IsSuperConstructorCall()); | |
2052 | 2030 |
2053 Label feedback_register_initialized; | 2031 Label feedback_register_initialized; |
2054 // Put the AllocationSite from the feedback vector into ebx, or undefined. | 2032 // Put the AllocationSite from the feedback vector into ebx, or undefined. |
2055 __ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size, | 2033 __ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size, |
2056 FixedArray::kHeaderSize)); | 2034 FixedArray::kHeaderSize)); |
2057 Handle<Map> allocation_site_map = | 2035 Handle<Map> allocation_site_map = isolate()->factory()->allocation_site_map(); |
2058 isolate()->factory()->allocation_site_map(); | 2036 __ cmp(FieldOperand(ebx, 0), Immediate(allocation_site_map)); |
2059 __ cmp(FieldOperand(ebx, 0), Immediate(allocation_site_map)); | 2037 __ j(equal, &feedback_register_initialized); |
2060 __ j(equal, &feedback_register_initialized); | 2038 __ mov(ebx, isolate()->factory()->undefined_value()); |
2061 __ mov(ebx, isolate()->factory()->undefined_value()); | 2039 __ bind(&feedback_register_initialized); |
2062 __ bind(&feedback_register_initialized); | |
2063 | 2040 |
2064 __ AssertUndefinedOrAllocationSite(ebx); | 2041 __ AssertUndefinedOrAllocationSite(ebx); |
2065 } | |
2066 | 2042 |
2067 if (IsSuperConstructorCall()) { | 2043 // Pass new target to construct stub. |
2068 __ pop(edx); | 2044 __ mov(edx, edi); |
2069 } else { | |
2070 // Pass new target to construct stub. | |
2071 __ mov(edx, edi); | |
2072 } | |
2073 | 2045 |
2074 // Tail call to the function-specific construct stub (still in the caller | 2046 // Tail call to the function-specific construct stub (still in the caller |
2075 // context at this point). | 2047 // context at this point). |
2076 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 2048 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
2077 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset)); | 2049 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset)); |
2078 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); | 2050 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); |
2079 __ jmp(ecx); | 2051 __ jmp(ecx); |
2080 | 2052 |
2081 __ bind(&non_function); | 2053 __ bind(&non_function); |
2082 if (IsSuperConstructorCall()) __ Drop(1); | |
2083 __ mov(edx, edi); | 2054 __ mov(edx, edi); |
2084 __ Jump(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 2055 __ Jump(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
2085 } | 2056 } |
2086 | 2057 |
2087 | 2058 |
2088 void CallICStub::HandleArrayCase(MacroAssembler* masm, Label* miss) { | 2059 void CallICStub::HandleArrayCase(MacroAssembler* masm, Label* miss) { |
2089 // edi - function | 2060 // edi - function |
2090 // edx - slot id | 2061 // edx - slot id |
2091 // ebx - vector | 2062 // ebx - vector |
2092 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx); | 2063 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx); |
(...skipping 3578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5671 Operand(ebp, 7 * kPointerSize), NULL); | 5642 Operand(ebp, 7 * kPointerSize), NULL); |
5672 } | 5643 } |
5673 | 5644 |
5674 | 5645 |
5675 #undef __ | 5646 #undef __ |
5676 | 5647 |
5677 } // namespace internal | 5648 } // namespace internal |
5678 } // namespace v8 | 5649 } // namespace v8 |
5679 | 5650 |
5680 #endif // V8_TARGET_ARCH_IA32 | 5651 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |