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_X87 | 7 #if V8_TARGET_ARCH_X87 |
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 1882 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1893 | 1893 |
1894 // Unreachable. | 1894 // Unreachable. |
1895 __ int3(); | 1895 __ int3(); |
1896 } | 1896 } |
1897 | 1897 |
1898 | 1898 |
1899 void CallICStub::Generate(MacroAssembler* masm) { | 1899 void CallICStub::Generate(MacroAssembler* masm) { |
1900 // edi - function | 1900 // edi - function |
1901 // edx - slot id | 1901 // edx - slot id |
1902 Isolate* isolate = masm->isolate(); | 1902 Isolate* isolate = masm->isolate(); |
| 1903 const int with_types_offset = |
| 1904 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); |
| 1905 const int generic_offset = |
| 1906 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); |
1903 Label extra_checks_or_miss, slow_start; | 1907 Label extra_checks_or_miss, slow_start; |
1904 Label slow, non_function, wrap, cont; | 1908 Label slow, non_function, wrap, cont; |
1905 Label have_js_function; | 1909 Label have_js_function; |
1906 int argc = arg_count(); | 1910 int argc = arg_count(); |
1907 ParameterCount actual(argc); | 1911 ParameterCount actual(argc); |
1908 | 1912 |
1909 EmitLoadTypeFeedbackVector(masm, ebx); | 1913 EmitLoadTypeFeedbackVector(masm, ebx); |
1910 | 1914 |
1911 // The checks. First, does edi match the recorded monomorphic target? | 1915 // The checks. First, does edi match the recorded monomorphic target? |
1912 __ cmp(edi, FieldOperand(ebx, edx, times_half_pointer_size, | 1916 __ cmp(edi, FieldOperand(ebx, edx, times_half_pointer_size, |
(...skipping 19 matching lines...) Expand all Loading... |
1932 | 1936 |
1933 __ bind(&slow); | 1937 __ bind(&slow); |
1934 EmitSlowCase(isolate, masm, argc, &non_function); | 1938 EmitSlowCase(isolate, masm, argc, &non_function); |
1935 | 1939 |
1936 if (CallAsMethod()) { | 1940 if (CallAsMethod()) { |
1937 __ bind(&wrap); | 1941 __ bind(&wrap); |
1938 EmitWrapCase(masm, argc, &cont); | 1942 EmitWrapCase(masm, argc, &cont); |
1939 } | 1943 } |
1940 | 1944 |
1941 __ bind(&extra_checks_or_miss); | 1945 __ bind(&extra_checks_or_miss); |
1942 Label miss; | 1946 Label uninitialized, miss; |
1943 | 1947 |
1944 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, | 1948 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, |
1945 FixedArray::kHeaderSize)); | 1949 FixedArray::kHeaderSize)); |
1946 __ cmp(ecx, Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); | 1950 __ cmp(ecx, Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); |
1947 __ j(equal, &slow_start); | 1951 __ j(equal, &slow_start); |
| 1952 |
| 1953 // The following cases attempt to handle MISS cases without going to the |
| 1954 // runtime. |
| 1955 if (FLAG_trace_ic) { |
| 1956 __ jmp(&miss); |
| 1957 } |
| 1958 |
1948 __ cmp(ecx, Immediate(TypeFeedbackVector::UninitializedSentinel(isolate))); | 1959 __ cmp(ecx, Immediate(TypeFeedbackVector::UninitializedSentinel(isolate))); |
| 1960 __ j(equal, &uninitialized); |
| 1961 |
| 1962 // We are going megamorphic. If the feedback is a JSFunction, it is fine |
| 1963 // to handle it here. More complex cases are dealt with in the runtime. |
| 1964 __ AssertNotSmi(ecx); |
| 1965 __ CmpObjectType(ecx, JS_FUNCTION_TYPE, ecx); |
| 1966 __ j(not_equal, &miss); |
| 1967 __ mov( |
| 1968 FieldOperand(ebx, edx, times_half_pointer_size, FixedArray::kHeaderSize), |
| 1969 Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); |
| 1970 // We have to update statistics for runtime profiling. |
| 1971 __ sub(FieldOperand(ebx, with_types_offset), Immediate(Smi::FromInt(1))); |
| 1972 __ add(FieldOperand(ebx, generic_offset), Immediate(Smi::FromInt(1))); |
| 1973 __ jmp(&slow_start); |
| 1974 |
| 1975 __ bind(&uninitialized); |
| 1976 |
| 1977 // We are going monomorphic, provided we actually have a JSFunction. |
| 1978 __ JumpIfSmi(edi, &miss); |
| 1979 |
| 1980 // Goto miss case if we do not have a function. |
| 1981 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); |
| 1982 __ j(not_equal, &miss); |
| 1983 |
| 1984 // Make sure the function is not the Array() function, which requires special |
| 1985 // behavior on MISS. |
| 1986 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx); |
| 1987 __ cmp(edi, ecx); |
1949 __ j(equal, &miss); | 1988 __ j(equal, &miss); |
1950 | 1989 |
1951 if (!FLAG_trace_ic) { | 1990 // Update stats. |
1952 // We are going megamorphic. If the feedback is a JSFunction, it is fine | 1991 __ add(FieldOperand(ebx, with_types_offset), Immediate(Smi::FromInt(1))); |
1953 // to handle it here. More complex cases are dealt with in the runtime. | |
1954 __ AssertNotSmi(ecx); | |
1955 __ CmpObjectType(ecx, JS_FUNCTION_TYPE, ecx); | |
1956 __ j(not_equal, &miss); | |
1957 __ mov(FieldOperand(ebx, edx, times_half_pointer_size, | |
1958 FixedArray::kHeaderSize), | |
1959 Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); | |
1960 // We have to update statistics for runtime profiling. | |
1961 const int with_types_offset = | |
1962 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); | |
1963 __ sub(FieldOperand(ebx, with_types_offset), Immediate(Smi::FromInt(1))); | |
1964 const int generic_offset = | |
1965 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); | |
1966 __ add(FieldOperand(ebx, generic_offset), Immediate(Smi::FromInt(1))); | |
1967 __ jmp(&slow_start); | |
1968 } | |
1969 | 1992 |
1970 // We are here because tracing is on or we are going monomorphic. | 1993 // Store the function. |
| 1994 __ mov( |
| 1995 FieldOperand(ebx, edx, times_half_pointer_size, FixedArray::kHeaderSize), |
| 1996 edi); |
| 1997 |
| 1998 // Update the write barrier. |
| 1999 __ mov(eax, edi); |
| 2000 __ RecordWriteArray(ebx, eax, edx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, |
| 2001 OMIT_SMI_CHECK); |
| 2002 __ jmp(&have_js_function); |
| 2003 |
| 2004 // We are here because tracing is on or we encountered a MISS case we can't |
| 2005 // handle here. |
1971 __ bind(&miss); | 2006 __ bind(&miss); |
1972 GenerateMiss(masm); | 2007 GenerateMiss(masm); |
1973 | 2008 |
1974 // the slow case | 2009 // the slow case |
1975 __ bind(&slow_start); | 2010 __ bind(&slow_start); |
1976 | 2011 |
1977 // Check that the function really is a JavaScript function. | 2012 // Check that the function really is a JavaScript function. |
1978 __ JumpIfSmi(edi, &non_function); | 2013 __ JumpIfSmi(edi, &non_function); |
1979 | 2014 |
1980 // Goto slow case if we do not have a function. | 2015 // Goto slow case if we do not have a function. |
(...skipping 2438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4419 Operand(ebp, 7 * kPointerSize), | 4454 Operand(ebp, 7 * kPointerSize), |
4420 NULL); | 4455 NULL); |
4421 } | 4456 } |
4422 | 4457 |
4423 | 4458 |
4424 #undef __ | 4459 #undef __ |
4425 | 4460 |
4426 } } // namespace v8::internal | 4461 } } // namespace v8::internal |
4427 | 4462 |
4428 #endif // V8_TARGET_ARCH_X87 | 4463 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |