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_MIPS | 5 #if V8_TARGET_ARCH_MIPS |
6 | 6 |
7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
8 #include "src/api-arguments.h" | 8 #include "src/api-arguments.h" |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 1890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1901 | 1901 |
1902 static void GenerateRecordCallTarget(MacroAssembler* masm) { | 1902 static void GenerateRecordCallTarget(MacroAssembler* masm) { |
1903 // Cache the called function in a feedback vector slot. Cache states | 1903 // Cache the called function in a feedback vector slot. Cache states |
1904 // are uninitialized, monomorphic (indicated by a JSFunction), and | 1904 // are uninitialized, monomorphic (indicated by a JSFunction), and |
1905 // megamorphic. | 1905 // megamorphic. |
1906 // a0 : number of arguments to the construct function | 1906 // a0 : number of arguments to the construct function |
1907 // a1 : the function to call | 1907 // a1 : the function to call |
1908 // a2 : feedback vector | 1908 // a2 : feedback vector |
1909 // a3 : slot in feedback vector (Smi) | 1909 // a3 : slot in feedback vector (Smi) |
1910 Label initialize, done, miss, megamorphic, not_array_function; | 1910 Label initialize, done, miss, megamorphic, not_array_function; |
| 1911 Label done_initialize_count, done_increment_count; |
1911 | 1912 |
1912 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), | 1913 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), |
1913 masm->isolate()->heap()->megamorphic_symbol()); | 1914 masm->isolate()->heap()->megamorphic_symbol()); |
1914 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), | 1915 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), |
1915 masm->isolate()->heap()->uninitialized_symbol()); | 1916 masm->isolate()->heap()->uninitialized_symbol()); |
1916 | 1917 |
1917 // Load the cache state into t2. | 1918 // Load the cache state into t2. |
1918 __ Lsa(t2, a2, a3, kPointerSizeLog2 - kSmiTagSize); | 1919 __ Lsa(t2, a2, a3, kPointerSizeLog2 - kSmiTagSize); |
1919 __ lw(t2, FieldMemOperand(t2, FixedArray::kHeaderSize)); | 1920 __ lw(t2, FieldMemOperand(t2, FixedArray::kHeaderSize)); |
1920 | 1921 |
1921 // A monomorphic cache hit or an already megamorphic state: invoke the | 1922 // A monomorphic cache hit or an already megamorphic state: invoke the |
1922 // function without changing the state. | 1923 // function without changing the state. |
1923 // We don't know if t2 is a WeakCell or a Symbol, but it's harmless to read at | 1924 // We don't know if t2 is a WeakCell or a Symbol, but it's harmless to read at |
1924 // this position in a symbol (see static asserts in type-feedback-vector.h). | 1925 // this position in a symbol (see static asserts in type-feedback-vector.h). |
1925 Label check_allocation_site; | 1926 Label check_allocation_site; |
1926 Register feedback_map = t1; | 1927 Register feedback_map = t1; |
1927 Register weak_value = t4; | 1928 Register weak_value = t4; |
1928 __ lw(weak_value, FieldMemOperand(t2, WeakCell::kValueOffset)); | 1929 __ lw(weak_value, FieldMemOperand(t2, WeakCell::kValueOffset)); |
1929 __ Branch(&done, eq, a1, Operand(weak_value)); | 1930 __ Branch(&done_increment_count, eq, a1, Operand(weak_value)); |
1930 __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex); | 1931 __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex); |
1931 __ Branch(&done, eq, t2, Operand(at)); | 1932 __ Branch(&done, eq, t2, Operand(at)); |
1932 __ lw(feedback_map, FieldMemOperand(t2, HeapObject::kMapOffset)); | 1933 __ lw(feedback_map, FieldMemOperand(t2, HeapObject::kMapOffset)); |
1933 __ LoadRoot(at, Heap::kWeakCellMapRootIndex); | 1934 __ LoadRoot(at, Heap::kWeakCellMapRootIndex); |
1934 __ Branch(&check_allocation_site, ne, feedback_map, Operand(at)); | 1935 __ Branch(&check_allocation_site, ne, feedback_map, Operand(at)); |
1935 | 1936 |
1936 // If the weak cell is cleared, we have a new chance to become monomorphic. | 1937 // If the weak cell is cleared, we have a new chance to become monomorphic. |
1937 __ JumpIfSmi(weak_value, &initialize); | 1938 __ JumpIfSmi(weak_value, &initialize); |
1938 __ jmp(&megamorphic); | 1939 __ jmp(&megamorphic); |
1939 | 1940 |
1940 __ bind(&check_allocation_site); | 1941 __ bind(&check_allocation_site); |
1941 // If we came here, we need to see if we are the array function. | 1942 // If we came here, we need to see if we are the array function. |
1942 // If we didn't have a matching function, and we didn't find the megamorph | 1943 // If we didn't have a matching function, and we didn't find the megamorph |
1943 // sentinel, then we have in the slot either some other function or an | 1944 // sentinel, then we have in the slot either some other function or an |
1944 // AllocationSite. | 1945 // AllocationSite. |
1945 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); | 1946 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); |
1946 __ Branch(&miss, ne, feedback_map, Operand(at)); | 1947 __ Branch(&miss, ne, feedback_map, Operand(at)); |
1947 | 1948 |
1948 // Make sure the function is the Array() function | 1949 // Make sure the function is the Array() function |
1949 __ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, t2); | 1950 __ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, t2); |
1950 __ Branch(&megamorphic, ne, a1, Operand(t2)); | 1951 __ Branch(&megamorphic, ne, a1, Operand(t2)); |
1951 __ jmp(&done); | 1952 __ jmp(&done_increment_count); |
1952 | 1953 |
1953 __ bind(&miss); | 1954 __ bind(&miss); |
1954 | 1955 |
1955 // A monomorphic miss (i.e, here the cache is not uninitialized) goes | 1956 // A monomorphic miss (i.e, here the cache is not uninitialized) goes |
1956 // megamorphic. | 1957 // megamorphic. |
1957 __ LoadRoot(at, Heap::kuninitialized_symbolRootIndex); | 1958 __ LoadRoot(at, Heap::kuninitialized_symbolRootIndex); |
1958 __ Branch(&initialize, eq, t2, Operand(at)); | 1959 __ Branch(&initialize, eq, t2, Operand(at)); |
1959 // MegamorphicSentinel is an immortal immovable object (undefined) so no | 1960 // MegamorphicSentinel is an immortal immovable object (undefined) so no |
1960 // write-barrier is needed. | 1961 // write-barrier is needed. |
1961 __ bind(&megamorphic); | 1962 __ bind(&megamorphic); |
1962 __ Lsa(t2, a2, a3, kPointerSizeLog2 - kSmiTagSize); | 1963 __ Lsa(t2, a2, a3, kPointerSizeLog2 - kSmiTagSize); |
1963 __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex); | 1964 __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex); |
1964 __ sw(at, FieldMemOperand(t2, FixedArray::kHeaderSize)); | 1965 __ sw(at, FieldMemOperand(t2, FixedArray::kHeaderSize)); |
1965 __ jmp(&done); | 1966 __ jmp(&done); |
1966 | 1967 |
1967 // An uninitialized cache is patched with the function. | 1968 // An uninitialized cache is patched with the function. |
1968 __ bind(&initialize); | 1969 __ bind(&initialize); |
1969 // Make sure the function is the Array() function. | 1970 // Make sure the function is the Array() function. |
1970 __ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, t2); | 1971 __ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, t2); |
1971 __ Branch(¬_array_function, ne, a1, Operand(t2)); | 1972 __ Branch(¬_array_function, ne, a1, Operand(t2)); |
1972 | 1973 |
1973 // The target function is the Array constructor, | 1974 // The target function is the Array constructor, |
1974 // Create an AllocationSite if we don't already have it, store it in the | 1975 // Create an AllocationSite if we don't already have it, store it in the |
1975 // slot. | 1976 // slot. |
1976 CreateAllocationSiteStub create_stub(masm->isolate()); | 1977 CreateAllocationSiteStub create_stub(masm->isolate()); |
1977 CallStubInRecordCallTarget(masm, &create_stub); | 1978 CallStubInRecordCallTarget(masm, &create_stub); |
1978 __ Branch(&done); | 1979 __ Branch(&done_initialize_count); |
1979 | 1980 |
1980 __ bind(¬_array_function); | 1981 __ bind(¬_array_function); |
1981 CreateWeakCellStub weak_cell_stub(masm->isolate()); | 1982 CreateWeakCellStub weak_cell_stub(masm->isolate()); |
1982 CallStubInRecordCallTarget(masm, &weak_cell_stub); | 1983 CallStubInRecordCallTarget(masm, &weak_cell_stub); |
| 1984 |
| 1985 __ bind(&done_initialize_count); |
| 1986 // Initialize the call counter. |
| 1987 __ Lsa(at, a2, a3, kPointerSizeLog2 - kSmiTagSize); |
| 1988 __ li(t0, Operand(Smi::FromInt(1))); |
| 1989 __ sw(t0, FieldMemOperand(at, FixedArray::kHeaderSize + kPointerSize)); |
| 1990 __ b(&done); |
| 1991 |
| 1992 __ bind(&done_increment_count); |
| 1993 |
| 1994 // Increment the call count for monomorphic function calls. |
| 1995 __ Lsa(at, a2, a3, kPointerSizeLog2 - kSmiTagSize); |
| 1996 __ lw(t0, FieldMemOperand(at, FixedArray::kHeaderSize + kPointerSize)); |
| 1997 __ Addu(t0, t0, Operand(Smi::FromInt(1))); |
| 1998 __ sw(t0, FieldMemOperand(at, FixedArray::kHeaderSize + kPointerSize)); |
| 1999 |
1983 __ bind(&done); | 2000 __ bind(&done); |
1984 } | 2001 } |
1985 | 2002 |
1986 | 2003 |
1987 void CallConstructStub::Generate(MacroAssembler* masm) { | 2004 void CallConstructStub::Generate(MacroAssembler* masm) { |
1988 // a0 : number of arguments | 2005 // a0 : number of arguments |
1989 // a1 : the function to call | 2006 // a1 : the function to call |
1990 // a2 : feedback vector | 2007 // a2 : feedback vector |
1991 // a3 : slot in feedback vector (Smi, for RecordCallTarget) | 2008 // a3 : slot in feedback vector (Smi, for RecordCallTarget) |
1992 | 2009 |
(...skipping 3621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5614 kStackUnwindSpace, kInvalidStackOffset, | 5631 kStackUnwindSpace, kInvalidStackOffset, |
5615 return_value_operand, NULL); | 5632 return_value_operand, NULL); |
5616 } | 5633 } |
5617 | 5634 |
5618 #undef __ | 5635 #undef __ |
5619 | 5636 |
5620 } // namespace internal | 5637 } // namespace internal |
5621 } // namespace v8 | 5638 } // namespace v8 |
5622 | 5639 |
5623 #endif // V8_TARGET_ARCH_MIPS | 5640 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |