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