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_X87 | 5 #if V8_TARGET_ARCH_X87 |
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 1898 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1909 | 1909 |
1910 | 1910 |
1911 static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) { | 1911 static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) { |
1912 __ mov(vector, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 1912 __ mov(vector, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
1913 __ mov(vector, FieldOperand(vector, JSFunction::kSharedFunctionInfoOffset)); | 1913 __ mov(vector, FieldOperand(vector, JSFunction::kSharedFunctionInfoOffset)); |
1914 __ mov(vector, FieldOperand(vector, | 1914 __ mov(vector, FieldOperand(vector, |
1915 SharedFunctionInfo::kFeedbackVectorOffset)); | 1915 SharedFunctionInfo::kFeedbackVectorOffset)); |
1916 } | 1916 } |
1917 | 1917 |
1918 | 1918 |
1919 void CallIC_ArrayStub::Generate(MacroAssembler* masm) { | 1919 void CallICStub::HandleArrayCase(MacroAssembler* masm, Label* miss) { |
1920 // edi - function | 1920 // edi - function |
1921 // edx - slot id | 1921 // edx - slot id |
1922 // ebx - vector | 1922 // ebx - vector |
1923 Label miss; | |
1924 int argc = arg_count(); | |
1925 ParameterCount actual(argc); | |
1926 | |
1927 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx); | 1923 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx); |
1928 __ cmp(edi, ecx); | 1924 __ cmp(edi, ecx); |
1929 __ j(not_equal, &miss); | 1925 __ j(not_equal, miss); |
1930 | 1926 |
1931 __ mov(eax, arg_count()); | 1927 __ mov(eax, arg_count()); |
| 1928 // Reload ecx. |
1932 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, | 1929 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, |
1933 FixedArray::kHeaderSize)); | 1930 FixedArray::kHeaderSize)); |
1934 | 1931 |
1935 // Verify that ecx contains an AllocationSite | |
1936 Factory* factory = masm->isolate()->factory(); | |
1937 __ cmp(FieldOperand(ecx, HeapObject::kMapOffset), | |
1938 factory->allocation_site_map()); | |
1939 __ j(not_equal, &miss); | |
1940 | |
1941 // Increment the call count for monomorphic function calls. | 1932 // Increment the call count for monomorphic function calls. |
1942 __ add(FieldOperand(ebx, edx, times_half_pointer_size, | 1933 __ add(FieldOperand(ebx, edx, times_half_pointer_size, |
1943 FixedArray::kHeaderSize + kPointerSize), | 1934 FixedArray::kHeaderSize + kPointerSize), |
1944 Immediate(Smi::FromInt(CallICNexus::kCallCountIncrement))); | 1935 Immediate(Smi::FromInt(CallICNexus::kCallCountIncrement))); |
1945 | 1936 |
1946 __ mov(ebx, ecx); | 1937 __ mov(ebx, ecx); |
1947 __ mov(edx, edi); | 1938 __ mov(edx, edi); |
1948 ArrayConstructorStub stub(masm->isolate(), arg_count()); | 1939 ArrayConstructorStub stub(masm->isolate(), arg_count()); |
1949 __ TailCallStub(&stub); | 1940 __ TailCallStub(&stub); |
1950 | 1941 |
1951 __ bind(&miss); | 1942 // Unreachable. |
1952 GenerateMiss(masm); | |
1953 | |
1954 // The slow case, we need this no matter what to complete a call after a miss. | |
1955 __ Set(eax, arg_count()); | |
1956 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | |
1957 } | 1943 } |
1958 | 1944 |
1959 | 1945 |
1960 void CallICStub::Generate(MacroAssembler* masm) { | 1946 void CallICStub::Generate(MacroAssembler* masm) { |
1961 // edi - function | 1947 // edi - function |
1962 // edx - slot id | 1948 // edx - slot id |
1963 // ebx - vector | 1949 // ebx - vector |
1964 Isolate* isolate = masm->isolate(); | 1950 Isolate* isolate = masm->isolate(); |
1965 const int with_types_offset = | 1951 const int with_types_offset = |
1966 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); | 1952 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2021 | 2007 |
2022 __ bind(&slow); | 2008 __ bind(&slow); |
2023 EmitSlowCase(isolate, masm, argc); | 2009 EmitSlowCase(isolate, masm, argc); |
2024 | 2010 |
2025 if (CallAsMethod()) { | 2011 if (CallAsMethod()) { |
2026 __ bind(&wrap); | 2012 __ bind(&wrap); |
2027 EmitWrapCase(masm, argc, &cont); | 2013 EmitWrapCase(masm, argc, &cont); |
2028 } | 2014 } |
2029 | 2015 |
2030 __ bind(&extra_checks_or_miss); | 2016 __ bind(&extra_checks_or_miss); |
2031 Label uninitialized, miss; | 2017 Label uninitialized, miss, not_allocation_site; |
2032 | 2018 |
2033 __ cmp(ecx, Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); | 2019 __ cmp(ecx, Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); |
2034 __ j(equal, &slow_start); | 2020 __ j(equal, &slow_start); |
2035 | 2021 |
| 2022 // Check if we have an allocation site. |
| 2023 __ CompareRoot(FieldOperand(ecx, HeapObject::kMapOffset), |
| 2024 Heap::kAllocationSiteMapRootIndex); |
| 2025 __ j(not_equal, ¬_allocation_site); |
| 2026 |
| 2027 // We have an allocation site. |
| 2028 HandleArrayCase(masm, &miss); |
| 2029 |
| 2030 __ bind(¬_allocation_site); |
| 2031 |
2036 // The following cases attempt to handle MISS cases without going to the | 2032 // The following cases attempt to handle MISS cases without going to the |
2037 // runtime. | 2033 // runtime. |
2038 if (FLAG_trace_ic) { | 2034 if (FLAG_trace_ic) { |
2039 __ jmp(&miss); | 2035 __ jmp(&miss); |
2040 } | 2036 } |
2041 | 2037 |
2042 __ cmp(ecx, Immediate(TypeFeedbackVector::UninitializedSentinel(isolate))); | 2038 __ cmp(ecx, Immediate(TypeFeedbackVector::UninitializedSentinel(isolate))); |
2043 __ j(equal, &uninitialized); | 2039 __ j(equal, &uninitialized); |
2044 | 2040 |
2045 // We are going megamorphic. If the feedback is a JSFunction, it is fine | 2041 // We are going megamorphic. If the feedback is a JSFunction, it is fine |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2109 __ jmp(&have_js_function); | 2105 __ jmp(&have_js_function); |
2110 | 2106 |
2111 // Unreachable | 2107 // Unreachable |
2112 __ int3(); | 2108 __ int3(); |
2113 } | 2109 } |
2114 | 2110 |
2115 | 2111 |
2116 void CallICStub::GenerateMiss(MacroAssembler* masm) { | 2112 void CallICStub::GenerateMiss(MacroAssembler* masm) { |
2117 FrameScope scope(masm, StackFrame::INTERNAL); | 2113 FrameScope scope(masm, StackFrame::INTERNAL); |
2118 | 2114 |
2119 // Push the receiver and the function and feedback info. | 2115 // Push the function and feedback info. |
2120 __ push(edi); | 2116 __ push(edi); |
2121 __ push(ebx); | 2117 __ push(ebx); |
2122 __ push(edx); | 2118 __ push(edx); |
2123 | 2119 |
2124 // Call the entry. | 2120 // Call the entry. |
2125 Runtime::FunctionId id = GetICState() == DEFAULT | 2121 __ CallRuntime(Runtime::kCallIC_Miss, 3); |
2126 ? Runtime::kCallIC_Miss | |
2127 : Runtime::kCallIC_Customization_Miss; | |
2128 __ CallRuntime(id, 3); | |
2129 | 2122 |
2130 // Move result to edi and exit the internal frame. | 2123 // Move result to edi and exit the internal frame. |
2131 __ mov(edi, eax); | 2124 __ mov(edi, eax); |
2132 } | 2125 } |
2133 | 2126 |
2134 | 2127 |
2135 bool CEntryStub::NeedsImmovableCode() { | 2128 bool CEntryStub::NeedsImmovableCode() { |
2136 return false; | 2129 return false; |
2137 } | 2130 } |
2138 | 2131 |
(...skipping 2426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4565 } | 4558 } |
4566 | 4559 |
4567 | 4560 |
4568 void CallICTrampolineStub::Generate(MacroAssembler* masm) { | 4561 void CallICTrampolineStub::Generate(MacroAssembler* masm) { |
4569 EmitLoadTypeFeedbackVector(masm, ebx); | 4562 EmitLoadTypeFeedbackVector(masm, ebx); |
4570 CallICStub stub(isolate(), state()); | 4563 CallICStub stub(isolate(), state()); |
4571 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); | 4564 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); |
4572 } | 4565 } |
4573 | 4566 |
4574 | 4567 |
4575 void CallIC_ArrayTrampolineStub::Generate(MacroAssembler* masm) { | |
4576 EmitLoadTypeFeedbackVector(masm, ebx); | |
4577 CallIC_ArrayStub stub(isolate(), state()); | |
4578 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); | |
4579 } | |
4580 | |
4581 | |
4582 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { | 4568 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { |
4583 if (masm->isolate()->function_entry_hook() != NULL) { | 4569 if (masm->isolate()->function_entry_hook() != NULL) { |
4584 ProfileEntryHookStub stub(masm->isolate()); | 4570 ProfileEntryHookStub stub(masm->isolate()); |
4585 masm->CallStub(&stub); | 4571 masm->CallStub(&stub); |
4586 } | 4572 } |
4587 } | 4573 } |
4588 | 4574 |
4589 | 4575 |
4590 void ProfileEntryHookStub::Generate(MacroAssembler* masm) { | 4576 void ProfileEntryHookStub::Generate(MacroAssembler* masm) { |
4591 // Save volatile registers. | 4577 // Save volatile registers. |
(...skipping 902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5494 Operand(ebp, 7 * kPointerSize), NULL); | 5480 Operand(ebp, 7 * kPointerSize), NULL); |
5495 } | 5481 } |
5496 | 5482 |
5497 | 5483 |
5498 #undef __ | 5484 #undef __ |
5499 | 5485 |
5500 } // namespace internal | 5486 } // namespace internal |
5501 } // namespace v8 | 5487 } // namespace v8 |
5502 | 5488 |
5503 #endif // V8_TARGET_ARCH_X87 | 5489 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |