| 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 |