Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(75)

Side by Side Diff: src/arm64/code-stubs-arm64.cc

Issue 2325083003: Record call counts also for megamorphic calls. (Closed)
Patch Set: Code comments. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/arm/code-stubs-arm.cc ('k') | src/ia32/code-stubs-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1977 matching lines...) Expand 10 before | Expand all | Expand 10 after
1988 __ Ldr(x4, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); 1988 __ Ldr(x4, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
1989 __ Ldr(x4, FieldMemOperand(x4, SharedFunctionInfo::kConstructStubOffset)); 1989 __ Ldr(x4, FieldMemOperand(x4, SharedFunctionInfo::kConstructStubOffset));
1990 __ Add(x4, x4, Code::kHeaderSize - kHeapObjectTag); 1990 __ Add(x4, x4, Code::kHeaderSize - kHeapObjectTag);
1991 __ Br(x4); 1991 __ Br(x4);
1992 1992
1993 __ Bind(&non_function); 1993 __ Bind(&non_function);
1994 __ Mov(x3, function); 1994 __ Mov(x3, function);
1995 __ Jump(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 1995 __ Jump(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
1996 } 1996 }
1997 1997
1998 // Note: feedback_vector and slot are clobbered after the call.
1999 static void IncrementCallCount(MacroAssembler* masm, Register feedback_vector,
2000 Register slot) {
2001 __ Add(feedback_vector, feedback_vector,
2002 Operand::UntagSmiAndScale(slot, kPointerSizeLog2));
2003 __ Add(feedback_vector, feedback_vector,
2004 Operand(FixedArray::kHeaderSize + kPointerSize));
2005 __ Ldr(slot, FieldMemOperand(feedback_vector, 0));
2006 __ Add(slot, slot, Operand(Smi::FromInt(1)));
2007 __ Str(slot, FieldMemOperand(feedback_vector, 0));
2008 }
1998 2009
1999 void CallICStub::HandleArrayCase(MacroAssembler* masm, Label* miss) { 2010 void CallICStub::HandleArrayCase(MacroAssembler* masm, Label* miss) {
2000 // x1 - function 2011 // x1 - function
2001 // x3 - slot id 2012 // x3 - slot id
2002 // x2 - vector 2013 // x2 - vector
2003 // x4 - allocation site (loaded from vector[slot]) 2014 // x4 - allocation site (loaded from vector[slot])
2004 Register function = x1; 2015 Register function = x1;
2005 Register feedback_vector = x2; 2016 Register feedback_vector = x2;
2006 Register index = x3; 2017 Register index = x3;
2007 Register allocation_site = x4; 2018 Register allocation_site = x4;
2008 Register scratch = x5; 2019 Register scratch = x5;
2009 2020
2010 __ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, scratch); 2021 __ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, scratch);
2011 __ Cmp(function, scratch); 2022 __ Cmp(function, scratch);
2012 __ B(ne, miss); 2023 __ B(ne, miss);
2013 2024
2014 __ Mov(x0, Operand(arg_count())); 2025 __ Mov(x0, Operand(arg_count()));
2015 2026
2016 // Increment the call count for monomorphic function calls. 2027 // Increment the call count for monomorphic function calls.
2017 __ Add(feedback_vector, feedback_vector, 2028 IncrementCallCount(masm, feedback_vector, index);
2018 Operand::UntagSmiAndScale(index, kPointerSizeLog2));
2019 __ Add(feedback_vector, feedback_vector,
2020 Operand(FixedArray::kHeaderSize + kPointerSize));
2021 __ Ldr(index, FieldMemOperand(feedback_vector, 0));
2022 __ Add(index, index, Operand(Smi::FromInt(1)));
2023 __ Str(index, FieldMemOperand(feedback_vector, 0));
2024 2029
2025 // Set up arguments for the array constructor stub. 2030 // Set up arguments for the array constructor stub.
2026 Register allocation_site_arg = feedback_vector; 2031 Register allocation_site_arg = feedback_vector;
2027 Register new_target_arg = index; 2032 Register new_target_arg = index;
2028 __ Mov(allocation_site_arg, allocation_site); 2033 __ Mov(allocation_site_arg, allocation_site);
2029 __ Mov(new_target_arg, function); 2034 __ Mov(new_target_arg, function);
2030 ArrayConstructorStub stub(masm->isolate(), arg_count()); 2035 ArrayConstructorStub stub(masm->isolate(), arg_count());
2031 __ TailCallStub(&stub); 2036 __ TailCallStub(&stub);
2032 } 2037 }
2033 2038
2034 2039
2035 void CallICStub::Generate(MacroAssembler* masm) { 2040 void CallICStub::Generate(MacroAssembler* masm) {
2036 ASM_LOCATION("CallICStub"); 2041 ASM_LOCATION("CallICStub");
2037 2042
2038 // x1 - function 2043 // x1 - function
2039 // x3 - slot id (Smi) 2044 // x3 - slot id (Smi)
2040 // x2 - vector 2045 // x2 - vector
2041 Label extra_checks_or_miss, call, call_function; 2046 Label extra_checks_or_miss, call, call_function, call_count_incremented;
2042 int argc = arg_count(); 2047 int argc = arg_count();
2043 ParameterCount actual(argc); 2048 ParameterCount actual(argc);
2044 2049
2045 Register function = x1; 2050 Register function = x1;
2046 Register feedback_vector = x2; 2051 Register feedback_vector = x2;
2047 Register index = x3; 2052 Register index = x3;
2048 2053
2049 // The checks. First, does x1 match the recorded monomorphic target? 2054 // The checks. First, does x1 match the recorded monomorphic target?
2050 __ Add(x4, feedback_vector, 2055 __ Add(x4, feedback_vector,
2051 Operand::UntagSmiAndScale(index, kPointerSizeLog2)); 2056 Operand::UntagSmiAndScale(index, kPointerSizeLog2));
(...skipping 14 matching lines...) Expand all
2066 WeakCell::kValueOffset == Symbol::kHashFieldSlot); 2071 WeakCell::kValueOffset == Symbol::kHashFieldSlot);
2067 2072
2068 __ Ldr(x5, FieldMemOperand(x4, WeakCell::kValueOffset)); 2073 __ Ldr(x5, FieldMemOperand(x4, WeakCell::kValueOffset));
2069 __ Cmp(x5, function); 2074 __ Cmp(x5, function);
2070 __ B(ne, &extra_checks_or_miss); 2075 __ B(ne, &extra_checks_or_miss);
2071 2076
2072 // The compare above could have been a SMI/SMI comparison. Guard against this 2077 // The compare above could have been a SMI/SMI comparison. Guard against this
2073 // convincing us that we have a monomorphic JSFunction. 2078 // convincing us that we have a monomorphic JSFunction.
2074 __ JumpIfSmi(function, &extra_checks_or_miss); 2079 __ JumpIfSmi(function, &extra_checks_or_miss);
2075 2080
2081 __ Bind(&call_function);
2082
2076 // Increment the call count for monomorphic function calls. 2083 // Increment the call count for monomorphic function calls.
2077 __ Add(feedback_vector, feedback_vector, 2084 IncrementCallCount(masm, feedback_vector, index);
2078 Operand::UntagSmiAndScale(index, kPointerSizeLog2));
2079 __ Add(feedback_vector, feedback_vector,
2080 Operand(FixedArray::kHeaderSize + kPointerSize));
2081 __ Ldr(index, FieldMemOperand(feedback_vector, 0));
2082 __ Add(index, index, Operand(Smi::FromInt(1)));
2083 __ Str(index, FieldMemOperand(feedback_vector, 0));
2084 2085
2085 __ Bind(&call_function);
2086 __ Mov(x0, argc); 2086 __ Mov(x0, argc);
2087 __ Jump(masm->isolate()->builtins()->CallFunction(convert_mode(), 2087 __ Jump(masm->isolate()->builtins()->CallFunction(convert_mode(),
2088 tail_call_mode()), 2088 tail_call_mode()),
2089 RelocInfo::CODE_TARGET); 2089 RelocInfo::CODE_TARGET);
2090 2090
2091 __ bind(&extra_checks_or_miss); 2091 __ bind(&extra_checks_or_miss);
2092 Label uninitialized, miss, not_allocation_site; 2092 Label uninitialized, miss, not_allocation_site;
2093 2093
2094 __ JumpIfRoot(x4, Heap::kmegamorphic_symbolRootIndex, &call); 2094 __ JumpIfRoot(x4, Heap::kmegamorphic_symbolRootIndex, &call);
2095 2095
2096 __ Ldr(x5, FieldMemOperand(x4, HeapObject::kMapOffset)); 2096 __ Ldr(x5, FieldMemOperand(x4, HeapObject::kMapOffset));
2097 __ JumpIfNotRoot(x5, Heap::kAllocationSiteMapRootIndex, &not_allocation_site); 2097 __ JumpIfNotRoot(x5, Heap::kAllocationSiteMapRootIndex, &not_allocation_site);
2098 2098
2099 HandleArrayCase(masm, &miss); 2099 HandleArrayCase(masm, &miss);
2100 2100
2101 __ bind(&not_allocation_site); 2101 __ bind(&not_allocation_site);
2102 2102
2103 // The following cases attempt to handle MISS cases without going to the 2103 // The following cases attempt to handle MISS cases without going to the
2104 // runtime. 2104 // runtime.
2105 if (FLAG_trace_ic) { 2105 if (FLAG_trace_ic) {
2106 __ jmp(&miss); 2106 __ jmp(&miss);
2107 } 2107 }
2108 2108
2109 // TODO(mvstanton): the code below is effectively disabled. Investigate.
2109 __ JumpIfRoot(x4, Heap::kuninitialized_symbolRootIndex, &miss); 2110 __ JumpIfRoot(x4, Heap::kuninitialized_symbolRootIndex, &miss);
2110 2111
2111 // We are going megamorphic. If the feedback is a JSFunction, it is fine 2112 // We are going megamorphic. If the feedback is a JSFunction, it is fine
2112 // to handle it here. More complex cases are dealt with in the runtime. 2113 // to handle it here. More complex cases are dealt with in the runtime.
2113 __ AssertNotSmi(x4); 2114 __ AssertNotSmi(x4);
2114 __ JumpIfNotObjectType(x4, x5, x5, JS_FUNCTION_TYPE, &miss); 2115 __ JumpIfNotObjectType(x4, x5, x5, JS_FUNCTION_TYPE, &miss);
2115 __ Add(x4, feedback_vector, 2116 __ Add(x4, feedback_vector,
2116 Operand::UntagSmiAndScale(index, kPointerSizeLog2)); 2117 Operand::UntagSmiAndScale(index, kPointerSizeLog2));
2117 __ LoadRoot(x5, Heap::kmegamorphic_symbolRootIndex); 2118 __ LoadRoot(x5, Heap::kmegamorphic_symbolRootIndex);
2118 __ Str(x5, FieldMemOperand(x4, FixedArray::kHeaderSize)); 2119 __ Str(x5, FieldMemOperand(x4, FixedArray::kHeaderSize));
2119 2120
2120 __ Bind(&call); 2121 __ Bind(&call);
2122
2123 // Increment the call count for megamorphic function calls.
2124 IncrementCallCount(masm, feedback_vector, index);
2125
2126 __ Bind(&call_count_incremented);
2121 __ Mov(x0, argc); 2127 __ Mov(x0, argc);
2122 __ Jump(masm->isolate()->builtins()->Call(convert_mode(), tail_call_mode()), 2128 __ Jump(masm->isolate()->builtins()->Call(convert_mode(), tail_call_mode()),
2123 RelocInfo::CODE_TARGET); 2129 RelocInfo::CODE_TARGET);
2124 2130
2125 __ bind(&uninitialized); 2131 __ bind(&uninitialized);
2126 2132
2127 // We are going monomorphic, provided we actually have a JSFunction. 2133 // We are going monomorphic, provided we actually have a JSFunction.
2128 __ JumpIfSmi(function, &miss); 2134 __ JumpIfSmi(function, &miss);
2129 2135
2130 // Goto miss case if we do not have a function. 2136 // Goto miss case if we do not have a function.
2131 __ JumpIfNotObjectType(function, x5, x5, JS_FUNCTION_TYPE, &miss); 2137 __ JumpIfNotObjectType(function, x5, x5, JS_FUNCTION_TYPE, &miss);
2132 2138
2133 // Make sure the function is not the Array() function, which requires special 2139 // Make sure the function is not the Array() function, which requires special
2134 // behavior on MISS. 2140 // behavior on MISS.
2135 __ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, x5); 2141 __ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, x5);
2136 __ Cmp(function, x5); 2142 __ Cmp(function, x5);
2137 __ B(eq, &miss); 2143 __ B(eq, &miss);
2138 2144
2139 // Make sure the function belongs to the same native context. 2145 // Make sure the function belongs to the same native context.
2140 __ Ldr(x4, FieldMemOperand(function, JSFunction::kContextOffset)); 2146 __ Ldr(x4, FieldMemOperand(function, JSFunction::kContextOffset));
2141 __ Ldr(x4, ContextMemOperand(x4, Context::NATIVE_CONTEXT_INDEX)); 2147 __ Ldr(x4, ContextMemOperand(x4, Context::NATIVE_CONTEXT_INDEX));
2142 __ Ldr(x5, NativeContextMemOperand()); 2148 __ Ldr(x5, NativeContextMemOperand());
2143 __ Cmp(x4, x5); 2149 __ Cmp(x4, x5);
2144 __ B(ne, &miss); 2150 __ B(ne, &miss);
2145 2151
2146 // Initialize the call counter.
2147 __ Mov(x5, Smi::FromInt(1));
2148 __ Adds(x4, feedback_vector,
2149 Operand::UntagSmiAndScale(index, kPointerSizeLog2));
2150 __ Str(x5, FieldMemOperand(x4, FixedArray::kHeaderSize + kPointerSize));
2151
2152 // Store the function. Use a stub since we need a frame for allocation. 2152 // Store the function. Use a stub since we need a frame for allocation.
2153 // x2 - vector 2153 // x2 - vector
2154 // x3 - slot 2154 // x3 - slot
2155 // x1 - function 2155 // x1 - function
2156 { 2156 {
2157 FrameScope scope(masm, StackFrame::INTERNAL); 2157 FrameScope scope(masm, StackFrame::INTERNAL);
2158 CreateWeakCellStub create_stub(masm->isolate()); 2158 CreateWeakCellStub create_stub(masm->isolate());
2159 __ Push(feedback_vector, index);
2160
2159 __ Push(cp, function); 2161 __ Push(cp, function);
2160 __ CallStub(&create_stub); 2162 __ CallStub(&create_stub);
2161 __ Pop(cp, function); 2163 __ Pop(cp, function);
2164
2165 __ Pop(feedback_vector, index);
2162 } 2166 }
2163 2167
2164 __ B(&call_function); 2168 __ B(&call_function);
2165 2169
2166 // We are here because tracing is on or we encountered a MISS case we can't 2170 // We are here because tracing is on or we encountered a MISS case we can't
2167 // handle here. 2171 // handle here.
2168 __ bind(&miss); 2172 __ bind(&miss);
2169 GenerateMiss(masm); 2173 GenerateMiss(masm);
2170 2174
2171 __ B(&call); 2175 // The runtime increments the call count in the vector for us.
2176 __ B(&call_count_incremented);
2172 } 2177 }
2173 2178
2174 2179
2175 void CallICStub::GenerateMiss(MacroAssembler* masm) { 2180 void CallICStub::GenerateMiss(MacroAssembler* masm) {
2176 ASM_LOCATION("CallICStub[Miss]"); 2181 ASM_LOCATION("CallICStub[Miss]");
2177 2182
2178 FrameScope scope(masm, StackFrame::INTERNAL); 2183 FrameScope scope(masm, StackFrame::INTERNAL);
2179 2184
2180 // Push the receiver and the function and feedback info. 2185 // Push the receiver and the function and feedback info.
2181 __ Push(x1, x2, x3); 2186 __ Push(x1, x2, x3);
(...skipping 3360 matching lines...) Expand 10 before | Expand all | Expand 10 after
5542 kStackUnwindSpace, NULL, spill_offset, 5547 kStackUnwindSpace, NULL, spill_offset,
5543 return_value_operand, NULL); 5548 return_value_operand, NULL);
5544 } 5549 }
5545 5550
5546 #undef __ 5551 #undef __
5547 5552
5548 } // namespace internal 5553 } // namespace internal
5549 } // namespace v8 5554 } // namespace v8
5550 5555
5551 #endif // V8_TARGET_ARCH_ARM64 5556 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.cc ('k') | src/ia32/code-stubs-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698