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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 1895 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1906 | 1906 |
1907 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater) | 1907 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater) |
1908 // tagged as a small integer. | 1908 // tagged as a small integer. |
1909 __ InvokeBuiltin(builtin, JUMP_FUNCTION); | 1909 __ InvokeBuiltin(builtin, JUMP_FUNCTION); |
1910 | 1910 |
1911 __ bind(&miss); | 1911 __ bind(&miss); |
1912 GenerateMiss(masm); | 1912 GenerateMiss(masm); |
1913 } | 1913 } |
1914 | 1914 |
1915 | 1915 |
| 1916 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) { |
| 1917 // eax : number of arguments to the construct function |
| 1918 // ebx : Feedback vector |
| 1919 // edx : slot in feedback vector (Smi) |
| 1920 // edi : the function to call |
| 1921 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1922 |
| 1923 // Arguments register must be smi-tagged to call out. |
| 1924 __ SmiTag(eax); |
| 1925 __ push(eax); |
| 1926 __ push(edi); |
| 1927 __ push(edx); |
| 1928 __ push(ebx); |
| 1929 |
| 1930 __ CallStub(stub); |
| 1931 |
| 1932 __ pop(ebx); |
| 1933 __ pop(edx); |
| 1934 __ pop(edi); |
| 1935 __ pop(eax); |
| 1936 __ SmiUntag(eax); |
| 1937 } |
| 1938 |
| 1939 |
1916 static void GenerateRecordCallTarget(MacroAssembler* masm) { | 1940 static void GenerateRecordCallTarget(MacroAssembler* masm) { |
1917 // Cache the called function in a feedback vector slot. Cache states | 1941 // Cache the called function in a feedback vector slot. Cache states |
1918 // are uninitialized, monomorphic (indicated by a JSFunction), and | 1942 // are uninitialized, monomorphic (indicated by a JSFunction), and |
1919 // megamorphic. | 1943 // megamorphic. |
1920 // eax : number of arguments to the construct function | 1944 // eax : number of arguments to the construct function |
1921 // ebx : Feedback vector | 1945 // ebx : Feedback vector |
1922 // edx : slot in feedback vector (Smi) | 1946 // edx : slot in feedback vector (Smi) |
1923 // edi : the function to call | 1947 // edi : the function to call |
1924 Isolate* isolate = masm->isolate(); | 1948 Isolate* isolate = masm->isolate(); |
1925 Label initialize, done, miss, megamorphic, not_array_function; | 1949 Label initialize, done, miss, megamorphic, not_array_function; |
1926 | 1950 |
1927 // Load the cache state into ecx. | 1951 // Load the cache state into ecx. |
1928 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, | 1952 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, |
1929 FixedArray::kHeaderSize)); | 1953 FixedArray::kHeaderSize)); |
1930 | 1954 |
1931 // A monomorphic cache hit or an already megamorphic state: invoke the | 1955 // A monomorphic cache hit or an already megamorphic state: invoke the |
1932 // function without changing the state. | 1956 // function without changing the state. |
1933 __ cmp(ecx, edi); | 1957 Label check_allocation_site; |
| 1958 __ cmp(edi, FieldOperand(ecx, WeakCell::kValueOffset)); |
1934 __ j(equal, &done, Label::kFar); | 1959 __ j(equal, &done, Label::kFar); |
1935 __ cmp(ecx, Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); | 1960 __ CompareRoot(ecx, Heap::kmegamorphic_symbolRootIndex); |
1936 __ j(equal, &done, Label::kFar); | 1961 __ j(equal, &done, Label::kFar); |
| 1962 __ CompareRoot(FieldOperand(ecx, 0), Heap::kWeakCellMapRootIndex); |
| 1963 __ j(not_equal, FLAG_pretenuring_call_new ? &miss : &check_allocation_site); |
| 1964 |
| 1965 // If edi is not equal to the weak cell value, and the weak cell value is |
| 1966 // cleared, we have a new chance to become monomorphic. |
| 1967 __ JumpIfSmi(FieldOperand(ecx, WeakCell::kValueOffset), &initialize); |
| 1968 __ jmp(&megamorphic); |
1937 | 1969 |
1938 if (!FLAG_pretenuring_call_new) { | 1970 if (!FLAG_pretenuring_call_new) { |
| 1971 __ bind(&check_allocation_site); |
1939 // If we came here, we need to see if we are the array function. | 1972 // If we came here, we need to see if we are the array function. |
1940 // If we didn't have a matching function, and we didn't find the megamorph | 1973 // If we didn't have a matching function, and we didn't find the megamorph |
1941 // sentinel, then we have in the slot either some other function or an | 1974 // sentinel, then we have in the slot either some other function or an |
1942 // AllocationSite. Do a map check on the object in ecx. | 1975 // AllocationSite. Do a map check on the object in ecx. |
1943 Handle<Map> allocation_site_map = isolate->factory()->allocation_site_map(); | 1976 __ CompareRoot(FieldOperand(ecx, 0), Heap::kAllocationSiteMapRootIndex); |
1944 __ cmp(FieldOperand(ecx, 0), Immediate(allocation_site_map)); | |
1945 __ j(not_equal, &miss); | 1977 __ j(not_equal, &miss); |
1946 | 1978 |
1947 // Make sure the function is the Array() function | 1979 // Make sure the function is the Array() function |
1948 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx); | 1980 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx); |
1949 __ cmp(edi, ecx); | 1981 __ cmp(edi, ecx); |
1950 __ j(not_equal, &megamorphic); | 1982 __ j(not_equal, &megamorphic); |
1951 __ jmp(&done, Label::kFar); | 1983 __ jmp(&done, Label::kFar); |
1952 } | 1984 } |
1953 | 1985 |
1954 __ bind(&miss); | 1986 __ bind(&miss); |
1955 | 1987 |
1956 // A monomorphic miss (i.e, here the cache is not uninitialized) goes | 1988 // A monomorphic miss (i.e, here the cache is not uninitialized) goes |
1957 // megamorphic. | 1989 // megamorphic. |
1958 __ cmp(ecx, Immediate(TypeFeedbackVector::UninitializedSentinel(isolate))); | 1990 __ CompareRoot(ecx, Heap::kuninitialized_symbolRootIndex); |
1959 __ j(equal, &initialize); | 1991 __ j(equal, &initialize); |
1960 // MegamorphicSentinel is an immortal immovable object (undefined) so no | 1992 // MegamorphicSentinel is an immortal immovable object (undefined) so no |
1961 // write-barrier is needed. | 1993 // write-barrier is needed. |
1962 __ bind(&megamorphic); | 1994 __ bind(&megamorphic); |
1963 __ mov( | 1995 __ mov( |
1964 FieldOperand(ebx, edx, times_half_pointer_size, FixedArray::kHeaderSize), | 1996 FieldOperand(ebx, edx, times_half_pointer_size, FixedArray::kHeaderSize), |
1965 Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); | 1997 Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); |
1966 __ jmp(&done, Label::kFar); | 1998 __ jmp(&done, Label::kFar); |
1967 | 1999 |
1968 // An uninitialized cache is patched with the function or sentinel to | 2000 // An uninitialized cache is patched with the function or sentinel to |
1969 // indicate the ElementsKind if function is the Array constructor. | 2001 // indicate the ElementsKind if function is the Array constructor. |
1970 __ bind(&initialize); | 2002 __ bind(&initialize); |
1971 if (!FLAG_pretenuring_call_new) { | 2003 if (!FLAG_pretenuring_call_new) { |
1972 // Make sure the function is the Array() function | 2004 // Make sure the function is the Array() function |
1973 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx); | 2005 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx); |
1974 __ cmp(edi, ecx); | 2006 __ cmp(edi, ecx); |
1975 __ j(not_equal, ¬_array_function); | 2007 __ j(not_equal, ¬_array_function); |
1976 | 2008 |
1977 // The target function is the Array constructor, | 2009 // The target function is the Array constructor, |
1978 // Create an AllocationSite if we don't already have it, store it in the | 2010 // Create an AllocationSite if we don't already have it, store it in the |
1979 // slot. | 2011 // slot. |
1980 { | 2012 CreateAllocationSiteStub create_stub(isolate); |
1981 FrameScope scope(masm, StackFrame::INTERNAL); | 2013 CallStubInRecordCallTarget(masm, &create_stub); |
1982 | |
1983 // Arguments register must be smi-tagged to call out. | |
1984 __ SmiTag(eax); | |
1985 __ push(eax); | |
1986 __ push(edi); | |
1987 __ push(edx); | |
1988 __ push(ebx); | |
1989 | |
1990 CreateAllocationSiteStub create_stub(isolate); | |
1991 __ CallStub(&create_stub); | |
1992 | |
1993 __ pop(ebx); | |
1994 __ pop(edx); | |
1995 __ pop(edi); | |
1996 __ pop(eax); | |
1997 __ SmiUntag(eax); | |
1998 } | |
1999 __ jmp(&done); | 2014 __ jmp(&done); |
2000 | 2015 |
2001 __ bind(¬_array_function); | 2016 __ bind(¬_array_function); |
2002 } | 2017 } |
2003 | 2018 |
2004 __ mov(FieldOperand(ebx, edx, times_half_pointer_size, | 2019 CreateWeakCellStub create_stub(isolate); |
2005 FixedArray::kHeaderSize), | 2020 CallStubInRecordCallTarget(masm, &create_stub); |
2006 edi); | |
2007 // We won't need edx or ebx anymore, just save edi | |
2008 __ push(edi); | |
2009 __ push(ebx); | |
2010 __ push(edx); | |
2011 __ RecordWriteArray(ebx, edi, edx, kDontSaveFPRegs, | |
2012 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); | |
2013 __ pop(edx); | |
2014 __ pop(ebx); | |
2015 __ pop(edi); | |
2016 | |
2017 __ bind(&done); | 2021 __ bind(&done); |
2018 } | 2022 } |
2019 | 2023 |
2020 | 2024 |
2021 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { | 2025 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { |
2022 // Do not transform the receiver for strict mode functions. | 2026 // Do not transform the receiver for strict mode functions. |
2023 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 2027 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
2024 __ test_b(FieldOperand(ecx, SharedFunctionInfo::kStrictModeByteOffset), | 2028 __ test_b(FieldOperand(ecx, SharedFunctionInfo::kStrictModeByteOffset), |
2025 1 << SharedFunctionInfo::kStrictModeBitWithinByte); | 2029 1 << SharedFunctionInfo::kStrictModeBitWithinByte); |
2026 __ j(not_equal, cont); | 2030 __ j(not_equal, cont); |
(...skipping 3377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5404 ApiParameterOperand(2), kStackSpace, nullptr, | 5408 ApiParameterOperand(2), kStackSpace, nullptr, |
5405 Operand(ebp, 7 * kPointerSize), NULL); | 5409 Operand(ebp, 7 * kPointerSize), NULL); |
5406 } | 5410 } |
5407 | 5411 |
5408 | 5412 |
5409 #undef __ | 5413 #undef __ |
5410 | 5414 |
5411 } } // namespace v8::internal | 5415 } } // namespace v8::internal |
5412 | 5416 |
5413 #endif // V8_TARGET_ARCH_IA32 | 5417 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |