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 1914 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1925 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); | 1925 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); |
1926 const int generic_offset = | 1926 const int generic_offset = |
1927 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); | 1927 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); |
1928 Label extra_checks_or_miss, slow_start; | 1928 Label extra_checks_or_miss, slow_start; |
1929 Label slow, non_function, wrap, cont; | 1929 Label slow, non_function, wrap, cont; |
1930 Label have_js_function; | 1930 Label have_js_function; |
1931 int argc = arg_count(); | 1931 int argc = arg_count(); |
1932 ParameterCount actual(argc); | 1932 ParameterCount actual(argc); |
1933 | 1933 |
1934 // The checks. First, does edi match the recorded monomorphic target? | 1934 // The checks. First, does edi match the recorded monomorphic target? |
1935 __ cmp(edi, FieldOperand(ebx, edx, times_half_pointer_size, | 1935 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, |
1936 FixedArray::kHeaderSize)); | 1936 FixedArray::kHeaderSize)); |
| 1937 |
| 1938 // We don't know that we have a weak cell. We might have a private symbol |
| 1939 // or an AllocationSite, but the memory is safe to examine. |
| 1940 // AllocationSite::kTransitionInfoOffset - contains a Smi or pointer to |
| 1941 // FixedArray. |
| 1942 // WeakCell::kValueOffset - contains a JSFunction or Smi(0) |
| 1943 // Symbol::kHashFieldSlot - if the low bit is 1, then the hash is not |
| 1944 // computed, meaning that it can't appear to be a pointer. If the low bit is |
| 1945 // 0, then hash is computed, but the 0 bit prevents the field from appearing |
| 1946 // to be a pointer. |
| 1947 STATIC_ASSERT(WeakCell::kSize >= kPointerSize); |
| 1948 STATIC_ASSERT(AllocationSite::kTransitionInfoOffset == |
| 1949 WeakCell::kValueOffset && |
| 1950 WeakCell::kValueOffset == Symbol::kHashFieldSlot); |
| 1951 |
| 1952 __ cmp(edi, FieldOperand(ecx, WeakCell::kValueOffset)); |
1937 __ j(not_equal, &extra_checks_or_miss); | 1953 __ j(not_equal, &extra_checks_or_miss); |
1938 | 1954 |
| 1955 // The compare above could have been a SMI/SMI comparison. Guard against this |
| 1956 // convincing us that we have a monomorphic JSFunction. |
| 1957 __ JumpIfSmi(edi, &extra_checks_or_miss); |
| 1958 |
1939 __ bind(&have_js_function); | 1959 __ bind(&have_js_function); |
1940 if (CallAsMethod()) { | 1960 if (CallAsMethod()) { |
1941 EmitContinueIfStrictOrNative(masm, &cont); | 1961 EmitContinueIfStrictOrNative(masm, &cont); |
1942 | 1962 |
1943 // Load the receiver from the stack. | 1963 // Load the receiver from the stack. |
1944 __ mov(eax, Operand(esp, (argc + 1) * kPointerSize)); | 1964 __ mov(eax, Operand(esp, (argc + 1) * kPointerSize)); |
1945 | 1965 |
1946 __ JumpIfSmi(eax, &wrap); | 1966 __ JumpIfSmi(eax, &wrap); |
1947 | 1967 |
1948 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx); | 1968 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx); |
1949 __ j(below, &wrap); | 1969 __ j(below, &wrap); |
1950 | 1970 |
1951 __ bind(&cont); | 1971 __ bind(&cont); |
1952 } | 1972 } |
1953 | 1973 |
1954 __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper()); | 1974 __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper()); |
1955 | 1975 |
1956 __ bind(&slow); | 1976 __ bind(&slow); |
1957 EmitSlowCase(isolate, masm, argc, &non_function); | 1977 EmitSlowCase(isolate, masm, argc, &non_function); |
1958 | 1978 |
1959 if (CallAsMethod()) { | 1979 if (CallAsMethod()) { |
1960 __ bind(&wrap); | 1980 __ bind(&wrap); |
1961 EmitWrapCase(masm, argc, &cont); | 1981 EmitWrapCase(masm, argc, &cont); |
1962 } | 1982 } |
1963 | 1983 |
1964 __ bind(&extra_checks_or_miss); | 1984 __ bind(&extra_checks_or_miss); |
1965 Label uninitialized, miss; | 1985 Label uninitialized, miss; |
1966 | 1986 |
1967 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, | |
1968 FixedArray::kHeaderSize)); | |
1969 __ cmp(ecx, Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); | 1987 __ cmp(ecx, Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); |
1970 __ j(equal, &slow_start); | 1988 __ j(equal, &slow_start); |
1971 | 1989 |
1972 // The following cases attempt to handle MISS cases without going to the | 1990 // The following cases attempt to handle MISS cases without going to the |
1973 // runtime. | 1991 // runtime. |
1974 if (FLAG_trace_ic) { | 1992 if (FLAG_trace_ic) { |
1975 __ jmp(&miss); | 1993 __ jmp(&miss); |
1976 } | 1994 } |
1977 | 1995 |
1978 __ cmp(ecx, Immediate(TypeFeedbackVector::UninitializedSentinel(isolate))); | 1996 __ cmp(ecx, Immediate(TypeFeedbackVector::UninitializedSentinel(isolate))); |
(...skipping 23 matching lines...) Expand all Loading... |
2002 | 2020 |
2003 // Make sure the function is not the Array() function, which requires special | 2021 // Make sure the function is not the Array() function, which requires special |
2004 // behavior on MISS. | 2022 // behavior on MISS. |
2005 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx); | 2023 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx); |
2006 __ cmp(edi, ecx); | 2024 __ cmp(edi, ecx); |
2007 __ j(equal, &miss); | 2025 __ j(equal, &miss); |
2008 | 2026 |
2009 // Update stats. | 2027 // Update stats. |
2010 __ add(FieldOperand(ebx, with_types_offset), Immediate(Smi::FromInt(1))); | 2028 __ add(FieldOperand(ebx, with_types_offset), Immediate(Smi::FromInt(1))); |
2011 | 2029 |
2012 // Store the function. | 2030 // Store the function. Use a stub since we need a frame for allocation. |
2013 __ mov( | 2031 // ebx - vector |
2014 FieldOperand(ebx, edx, times_half_pointer_size, FixedArray::kHeaderSize), | 2032 // edx - slot |
2015 edi); | 2033 // edi - function |
| 2034 { |
| 2035 FrameScope scope(masm, StackFrame::INTERNAL); |
| 2036 CreateWeakCellStub create_stub(isolate); |
| 2037 __ push(edi); |
| 2038 __ CallStub(&create_stub); |
| 2039 __ pop(edi); |
| 2040 } |
2016 | 2041 |
2017 // Update the write barrier. | |
2018 __ mov(eax, edi); | |
2019 __ RecordWriteArray(ebx, eax, edx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, | |
2020 OMIT_SMI_CHECK); | |
2021 __ jmp(&have_js_function); | 2042 __ jmp(&have_js_function); |
2022 | 2043 |
2023 // We are here because tracing is on or we encountered a MISS case we can't | 2044 // We are here because tracing is on or we encountered a MISS case we can't |
2024 // handle here. | 2045 // handle here. |
2025 __ bind(&miss); | 2046 __ bind(&miss); |
2026 GenerateMiss(masm); | 2047 GenerateMiss(masm); |
2027 | 2048 |
2028 // the slow case | 2049 // the slow case |
2029 __ bind(&slow_start); | 2050 __ bind(&slow_start); |
2030 | 2051 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2066 } | 2087 } |
2067 | 2088 |
2068 | 2089 |
2069 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { | 2090 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { |
2070 CEntryStub::GenerateAheadOfTime(isolate); | 2091 CEntryStub::GenerateAheadOfTime(isolate); |
2071 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate); | 2092 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate); |
2072 StubFailureTrampolineStub::GenerateAheadOfTime(isolate); | 2093 StubFailureTrampolineStub::GenerateAheadOfTime(isolate); |
2073 // It is important that the store buffer overflow stubs are generated first. | 2094 // It is important that the store buffer overflow stubs are generated first. |
2074 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); | 2095 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); |
2075 CreateAllocationSiteStub::GenerateAheadOfTime(isolate); | 2096 CreateAllocationSiteStub::GenerateAheadOfTime(isolate); |
| 2097 CreateWeakCellStub::GenerateAheadOfTime(isolate); |
2076 BinaryOpICStub::GenerateAheadOfTime(isolate); | 2098 BinaryOpICStub::GenerateAheadOfTime(isolate); |
2077 BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate); | 2099 BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate); |
2078 } | 2100 } |
2079 | 2101 |
2080 | 2102 |
2081 void CodeStub::GenerateFPStubs(Isolate* isolate) { | 2103 void CodeStub::GenerateFPStubs(Isolate* isolate) { |
2082 CEntryStub save_doubles(isolate, 1, kSaveFPRegs); | 2104 CEntryStub save_doubles(isolate, 1, kSaveFPRegs); |
2083 // Stubs might already be in the snapshot, detect that and don't regenerate, | 2105 // Stubs might already be in the snapshot, detect that and don't regenerate, |
2084 // which would lead to code stub initialization state being messed up. | 2106 // which would lead to code stub initialization state being messed up. |
2085 Code* save_doubles_code; | 2107 Code* save_doubles_code; |
(...skipping 2650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4736 ApiParameterOperand(2), kStackSpace, nullptr, | 4758 ApiParameterOperand(2), kStackSpace, nullptr, |
4737 Operand(ebp, 7 * kPointerSize), NULL); | 4759 Operand(ebp, 7 * kPointerSize), NULL); |
4738 } | 4760 } |
4739 | 4761 |
4740 | 4762 |
4741 #undef __ | 4763 #undef __ |
4742 | 4764 |
4743 } } // namespace v8::internal | 4765 } } // namespace v8::internal |
4744 | 4766 |
4745 #endif // V8_TARGET_ARCH_X87 | 4767 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |