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