| OLD | NEW | 
|---|
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 | 
| 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/bootstrapper.h" | 9 #include "src/bootstrapper.h" | 
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" | 
| (...skipping 2004 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2015   ASM_LOCATION("GenerateRecordCallTarget"); | 2015   ASM_LOCATION("GenerateRecordCallTarget"); | 
| 2016   DCHECK(!AreAliased(scratch1, scratch2, scratch3, argc, function, | 2016   DCHECK(!AreAliased(scratch1, scratch2, scratch3, argc, function, | 
| 2017                      feedback_vector, index, new_target)); | 2017                      feedback_vector, index, new_target)); | 
| 2018   // Cache the called function in a feedback vector slot. Cache states are | 2018   // Cache the called function in a feedback vector slot. Cache states are | 
| 2019   // uninitialized, monomorphic (indicated by a JSFunction), and megamorphic. | 2019   // uninitialized, monomorphic (indicated by a JSFunction), and megamorphic. | 
| 2020   //  argc :            number of arguments to the construct function | 2020   //  argc :            number of arguments to the construct function | 
| 2021   //  function :        the function to call | 2021   //  function :        the function to call | 
| 2022   //  feedback_vector : the feedback vector | 2022   //  feedback_vector : the feedback vector | 
| 2023   //  index :           slot in feedback vector (smi) | 2023   //  index :           slot in feedback vector (smi) | 
| 2024   Label initialize, done, miss, megamorphic, not_array_function; | 2024   Label initialize, done, miss, megamorphic, not_array_function; | 
|  | 2025   Label done_initialize_count, done_increment_count; | 
| 2025 | 2026 | 
| 2026   DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), | 2027   DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), | 
| 2027             masm->isolate()->heap()->megamorphic_symbol()); | 2028             masm->isolate()->heap()->megamorphic_symbol()); | 
| 2028   DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), | 2029   DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), | 
| 2029             masm->isolate()->heap()->uninitialized_symbol()); | 2030             masm->isolate()->heap()->uninitialized_symbol()); | 
| 2030 | 2031 | 
| 2031   // Load the cache state. | 2032   // Load the cache state. | 
| 2032   Register feedback = scratch1; | 2033   Register feedback = scratch1; | 
| 2033   Register feedback_map = scratch2; | 2034   Register feedback_map = scratch2; | 
| 2034   Register feedback_value = scratch3; | 2035   Register feedback_value = scratch3; | 
| 2035   __ Add(feedback, feedback_vector, | 2036   __ Add(feedback, feedback_vector, | 
| 2036          Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 2037          Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 
| 2037   __ Ldr(feedback, FieldMemOperand(feedback, FixedArray::kHeaderSize)); | 2038   __ Ldr(feedback, FieldMemOperand(feedback, FixedArray::kHeaderSize)); | 
| 2038 | 2039 | 
| 2039   // A monomorphic cache hit or an already megamorphic state: invoke the | 2040   // A monomorphic cache hit or an already megamorphic state: invoke the | 
| 2040   // function without changing the state. | 2041   // function without changing the state. | 
| 2041   // We don't know if feedback value is a WeakCell or a Symbol, but it's | 2042   // We don't know if feedback value is a WeakCell or a Symbol, but it's | 
| 2042   // harmless to read at this position in a symbol (see static asserts in | 2043   // harmless to read at this position in a symbol (see static asserts in | 
| 2043   // type-feedback-vector.h). | 2044   // type-feedback-vector.h). | 
| 2044   Label check_allocation_site; | 2045   Label check_allocation_site; | 
| 2045   __ Ldr(feedback_value, FieldMemOperand(feedback, WeakCell::kValueOffset)); | 2046   __ Ldr(feedback_value, FieldMemOperand(feedback, WeakCell::kValueOffset)); | 
| 2046   __ Cmp(function, feedback_value); | 2047   __ Cmp(function, feedback_value); | 
| 2047   __ B(eq, &done); | 2048   __ B(eq, &done_increment_count); | 
| 2048   __ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex); | 2049   __ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex); | 
| 2049   __ B(eq, &done); | 2050   __ B(eq, &done); | 
| 2050   __ Ldr(feedback_map, FieldMemOperand(feedback, HeapObject::kMapOffset)); | 2051   __ Ldr(feedback_map, FieldMemOperand(feedback, HeapObject::kMapOffset)); | 
| 2051   __ CompareRoot(feedback_map, Heap::kWeakCellMapRootIndex); | 2052   __ CompareRoot(feedback_map, Heap::kWeakCellMapRootIndex); | 
| 2052   __ B(ne, &check_allocation_site); | 2053   __ B(ne, &check_allocation_site); | 
| 2053 | 2054 | 
| 2054   // If the weak cell is cleared, we have a new chance to become monomorphic. | 2055   // If the weak cell is cleared, we have a new chance to become monomorphic. | 
| 2055   __ JumpIfSmi(feedback_value, &initialize); | 2056   __ JumpIfSmi(feedback_value, &initialize); | 
| 2056   __ B(&megamorphic); | 2057   __ B(&megamorphic); | 
| 2057 | 2058 | 
| 2058   __ bind(&check_allocation_site); | 2059   __ bind(&check_allocation_site); | 
| 2059   // If we came here, we need to see if we are the array function. | 2060   // If we came here, we need to see if we are the array function. | 
| 2060   // If we didn't have a matching function, and we didn't find the megamorph | 2061   // If we didn't have a matching function, and we didn't find the megamorph | 
| 2061   // sentinel, then we have in the slot either some other function or an | 2062   // sentinel, then we have in the slot either some other function or an | 
| 2062   // AllocationSite. | 2063   // AllocationSite. | 
| 2063   __ JumpIfNotRoot(feedback_map, Heap::kAllocationSiteMapRootIndex, &miss); | 2064   __ JumpIfNotRoot(feedback_map, Heap::kAllocationSiteMapRootIndex, &miss); | 
| 2064 | 2065 | 
| 2065   // Make sure the function is the Array() function | 2066   // Make sure the function is the Array() function | 
| 2066   __ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, scratch1); | 2067   __ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, scratch1); | 
| 2067   __ Cmp(function, scratch1); | 2068   __ Cmp(function, scratch1); | 
| 2068   __ B(ne, &megamorphic); | 2069   __ B(ne, &megamorphic); | 
| 2069   __ B(&done); | 2070   __ B(&done_increment_count); | 
| 2070 | 2071 | 
| 2071   __ Bind(&miss); | 2072   __ Bind(&miss); | 
| 2072 | 2073 | 
| 2073   // A monomorphic miss (i.e, here the cache is not uninitialized) goes | 2074   // A monomorphic miss (i.e, here the cache is not uninitialized) goes | 
| 2074   // megamorphic. | 2075   // megamorphic. | 
| 2075   __ JumpIfRoot(scratch1, Heap::kuninitialized_symbolRootIndex, &initialize); | 2076   __ JumpIfRoot(scratch1, Heap::kuninitialized_symbolRootIndex, &initialize); | 
| 2076   // MegamorphicSentinel is an immortal immovable object (undefined) so no | 2077   // MegamorphicSentinel is an immortal immovable object (undefined) so no | 
| 2077   // write-barrier is needed. | 2078   // write-barrier is needed. | 
| 2078   __ Bind(&megamorphic); | 2079   __ Bind(&megamorphic); | 
| 2079   __ Add(scratch1, feedback_vector, | 2080   __ Add(scratch1, feedback_vector, | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 2090   __ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, scratch1); | 2091   __ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, scratch1); | 
| 2091   __ Cmp(function, scratch1); | 2092   __ Cmp(function, scratch1); | 
| 2092   __ B(ne, ¬_array_function); | 2093   __ B(ne, ¬_array_function); | 
| 2093 | 2094 | 
| 2094   // The target function is the Array constructor, | 2095   // The target function is the Array constructor, | 
| 2095   // Create an AllocationSite if we don't already have it, store it in the | 2096   // Create an AllocationSite if we don't already have it, store it in the | 
| 2096   // slot. | 2097   // slot. | 
| 2097   CreateAllocationSiteStub create_stub(masm->isolate()); | 2098   CreateAllocationSiteStub create_stub(masm->isolate()); | 
| 2098   CallStubInRecordCallTarget(masm, &create_stub, argc, function, | 2099   CallStubInRecordCallTarget(masm, &create_stub, argc, function, | 
| 2099                              feedback_vector, index, new_target); | 2100                              feedback_vector, index, new_target); | 
| 2100   __ B(&done); | 2101   __ B(&done_initialize_count); | 
| 2101 | 2102 | 
| 2102   __ Bind(¬_array_function); | 2103   __ Bind(¬_array_function); | 
| 2103   CreateWeakCellStub weak_cell_stub(masm->isolate()); | 2104   CreateWeakCellStub weak_cell_stub(masm->isolate()); | 
| 2104   CallStubInRecordCallTarget(masm, &weak_cell_stub, argc, function, | 2105   CallStubInRecordCallTarget(masm, &weak_cell_stub, argc, function, | 
| 2105                              feedback_vector, index, new_target); | 2106                              feedback_vector, index, new_target); | 
|  | 2107 | 
|  | 2108   __ bind(&done_initialize_count); | 
|  | 2109   // Initialize the call counter. | 
|  | 2110   __ Mov(scratch1, Operand(Smi::FromInt(1))); | 
|  | 2111   __ Adds(scratch2, feedback_vector, | 
|  | 2112           Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 
|  | 2113   __ Str(scratch1, | 
|  | 2114          FieldMemOperand(scratch2, FixedArray::kHeaderSize + kPointerSize)); | 
|  | 2115   __ b(&done); | 
|  | 2116 | 
|  | 2117   __ bind(&done_increment_count); | 
|  | 2118 | 
|  | 2119   // Increment the call count for monomorphic function calls. | 
|  | 2120   __ Add(scratch1, feedback_vector, | 
|  | 2121          Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 
|  | 2122   __ Add(scratch1, scratch1, Operand(FixedArray::kHeaderSize + kPointerSize)); | 
|  | 2123   __ Ldr(scratch2, FieldMemOperand(scratch1, 0)); | 
|  | 2124   __ Add(scratch2, scratch2, Operand(Smi::FromInt(1))); | 
|  | 2125   __ Str(scratch2, FieldMemOperand(scratch1, 0)); | 
|  | 2126 | 
| 2106   __ Bind(&done); | 2127   __ Bind(&done); | 
| 2107 } | 2128 } | 
| 2108 | 2129 | 
| 2109 | 2130 | 
| 2110 void CallConstructStub::Generate(MacroAssembler* masm) { | 2131 void CallConstructStub::Generate(MacroAssembler* masm) { | 
| 2111   ASM_LOCATION("CallConstructStub::Generate"); | 2132   ASM_LOCATION("CallConstructStub::Generate"); | 
| 2112   // x0 : number of arguments | 2133   // x0 : number of arguments | 
| 2113   // x1 : the function to call | 2134   // x1 : the function to call | 
| 2114   // x2 : feedback vector | 2135   // x2 : feedback vector | 
| 2115   // x3 : slot in feedback vector (Smi, for RecordCallTarget) | 2136   // x3 : slot in feedback vector (Smi, for RecordCallTarget) | 
| (...skipping 3716 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5832                            kStackUnwindSpace, NULL, spill_offset, | 5853                            kStackUnwindSpace, NULL, spill_offset, | 
| 5833                            return_value_operand, NULL); | 5854                            return_value_operand, NULL); | 
| 5834 } | 5855 } | 
| 5835 | 5856 | 
| 5836 #undef __ | 5857 #undef __ | 
| 5837 | 5858 | 
| 5838 }  // namespace internal | 5859 }  // namespace internal | 
| 5839 }  // namespace v8 | 5860 }  // namespace v8 | 
| 5840 | 5861 | 
| 5841 #endif  // V8_TARGET_ARCH_ARM64 | 5862 #endif  // V8_TARGET_ARCH_ARM64 | 
| OLD | NEW | 
|---|