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

Side by Side Diff: runtime/vm/stub_code_arm64.cc

Issue 2226893002: Optimize AOT's switchable calls for the monomorphic case. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: sync Created 4 years, 4 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 | « runtime/vm/stub_code_arm.cc ('k') | runtime/vm/stub_code_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 (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" 5 #include "vm/globals.h"
6 #if defined(TARGET_ARCH_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/code_generator.h" 9 #include "vm/code_generator.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 2014 matching lines...) Expand 10 before | Expand all | Expand 10 after
2025 __ LoadFromOffset(right, SP, 0 * kWordSize); 2025 __ LoadFromOffset(right, SP, 0 * kWordSize);
2026 GenerateIdenticalWithNumberCheckStub(assembler, left, right); 2026 GenerateIdenticalWithNumberCheckStub(assembler, left, right);
2027 __ ret(); 2027 __ ret();
2028 } 2028 }
2029 2029
2030 2030
2031 // Called from megamorphic calls. 2031 // Called from megamorphic calls.
2032 // R0: receiver 2032 // R0: receiver
2033 // R5: MegamorphicCache (preserved) 2033 // R5: MegamorphicCache (preserved)
2034 // Result: 2034 // Result:
2035 // R1: target entry point
2036 // CODE_REG: target Code 2035 // CODE_REG: target Code
2037 // R4: arguments descriptor 2036 // R4: arguments descriptor
2038 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { 2037 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
2038 __ NoMonomorphicCheckedEntry();
2039
2039 // Jump if receiver is a smi. 2040 // Jump if receiver is a smi.
2040 Label smi_case; 2041 Label smi_case;
2041 __ TestImmediate(R0, kSmiTagMask); 2042 __ TestImmediate(R0, kSmiTagMask);
2042 __ b(&smi_case, EQ); 2043 __ b(&smi_case, EQ);
2043 2044
2044 // Loads the cid of the object. 2045 // Loads the cid of the object.
2045 __ LoadClassId(R0, R0); 2046 __ LoadClassId(R0, R0);
2046 2047
2047 Label cid_loaded; 2048 Label cid_loaded;
2048 __ Bind(&cid_loaded); 2049 __ Bind(&cid_loaded);
(...skipping 27 matching lines...) Expand all
2076 Label load_target; 2077 Label load_target;
2077 __ Bind(&load_target); 2078 __ Bind(&load_target);
2078 // Call the target found in the cache. For a class id match, this is a 2079 // Call the target found in the cache. For a class id match, this is a
2079 // proper target for the given name and arguments descriptor. If the 2080 // proper target for the given name and arguments descriptor. If the
2080 // illegal class id was found, the target is a cache miss handler that can 2081 // illegal class id was found, the target is a cache miss handler that can
2081 // be invoked as a normal Dart function. 2082 // be invoked as a normal Dart function.
2082 __ ldr(R0, FieldAddress(TMP, base + kWordSize)); 2083 __ ldr(R0, FieldAddress(TMP, base + kWordSize));
2083 __ ldr(R4, FieldAddress(R5, MegamorphicCache::arguments_descriptor_offset())); 2084 __ ldr(R4, FieldAddress(R5, MegamorphicCache::arguments_descriptor_offset()));
2084 __ ldr(R1, FieldAddress(R0, Function::entry_point_offset())); 2085 __ ldr(R1, FieldAddress(R0, Function::entry_point_offset()));
2085 __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset())); 2086 __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
2086 __ ret(); 2087 __ br(R1);
2087 2088
2088 // Probe failed, check if it is a miss. 2089 // Probe failed, check if it is a miss.
2089 __ Bind(&probe_failed); 2090 __ Bind(&probe_failed);
2090 ASSERT(kIllegalCid == 0); 2091 ASSERT(kIllegalCid == 0);
2091 __ tst(R6, Operand(R6)); 2092 __ tst(R6, Operand(R6));
2092 __ b(&load_target, EQ); // branch if miss. 2093 __ b(&load_target, EQ); // branch if miss.
2093 2094
2094 // Try next extry in the table. 2095 // Try next extry in the table.
2095 __ AddImmediate(R3, R3, Smi::RawValue(1)); 2096 __ AddImmediate(R3, R3, Smi::RawValue(1));
2096 __ b(&loop); 2097 __ b(&loop);
2097 2098
2098 // Load cid for the Smi case. 2099 // Load cid for the Smi case.
2099 __ Bind(&smi_case); 2100 __ Bind(&smi_case);
2100 __ LoadImmediate(R0, kSmiCid); 2101 __ LoadImmediate(R0, kSmiCid);
2101 __ b(&cid_loaded); 2102 __ b(&cid_loaded);
2102 } 2103 }
2103 2104
2104 2105
2105 // Called from switchable IC calls. 2106 // Called from switchable IC calls.
2106 // R0: receiver 2107 // R0: receiver
2107 // R5: ICData (preserved) 2108 // R5: ICData (preserved)
2108 // Result: 2109 // Result:
2109 // R1: target entry point
2110 // CODE_REG: target Code object 2110 // CODE_REG: target Code object
2111 // R4: arguments descriptor 2111 // R4: arguments descriptor
2112 void StubCode::GenerateICLookupThroughFunctionStub(Assembler* assembler) { 2112 void StubCode::GenerateICLookupThroughFunctionStub(Assembler* assembler) {
2113 __ NoMonomorphicCheckedEntry();
2114
2113 Label loop, found, miss; 2115 Label loop, found, miss;
2114 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset())); 2116 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
2115 __ ldr(R8, FieldAddress(R5, ICData::ic_data_offset())); 2117 __ ldr(R8, FieldAddress(R5, ICData::ic_data_offset()));
2116 __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag); 2118 __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag);
2117 // R8: first IC entry 2119 // R8: first IC entry
2118 __ LoadTaggedClassIdMayBeSmi(R1, R0); 2120 __ LoadTaggedClassIdMayBeSmi(R1, R0);
2119 // R1: receiver cid as Smi 2121 // R1: receiver cid as Smi
2120 2122
2121 __ Bind(&loop); 2123 __ Bind(&loop);
2122 __ ldr(R2, Address(R8, 0)); 2124 __ ldr(R2, Address(R8, 0));
2123 __ cmp(R1, Operand(R2)); 2125 __ cmp(R1, Operand(R2));
2124 __ b(&found, EQ); 2126 __ b(&found, EQ);
2125 __ CompareImmediate(R2, Smi::RawValue(kIllegalCid)); 2127 __ CompareImmediate(R2, Smi::RawValue(kIllegalCid));
2126 __ b(&miss, EQ); 2128 __ b(&miss, EQ);
2127 2129
2128 const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize; 2130 const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize;
2129 __ AddImmediate(R8, R8, entry_length); // Next entry. 2131 __ AddImmediate(R8, R8, entry_length); // Next entry.
2130 __ b(&loop); 2132 __ b(&loop);
2131 2133
2132 __ Bind(&found); 2134 __ Bind(&found);
2133 const intptr_t target_offset = ICData::TargetIndexFor(1) * kWordSize; 2135 const intptr_t target_offset = ICData::TargetIndexFor(1) * kWordSize;
2134 __ ldr(R0, Address(R8, target_offset)); 2136 __ ldr(R0, Address(R8, target_offset));
2135 __ ldr(R1, FieldAddress(R0, Function::entry_point_offset())); 2137 __ ldr(R1, FieldAddress(R0, Function::entry_point_offset()));
2136 __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset())); 2138 __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
2137 __ ret(); 2139 __ br(R1);
2138 2140
2139 __ Bind(&miss); 2141 __ Bind(&miss);
2140 __ LoadIsolate(R2); 2142 __ LoadIsolate(R2);
2141 __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset())); 2143 __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset()));
2142 __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset())); 2144 __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset()));
2143 __ ret(); 2145 __ br(R1);
2144 } 2146 }
2145 2147
2146 2148
2147 void StubCode::GenerateICLookupThroughCodeStub(Assembler* assembler) { 2149 void StubCode::GenerateICLookupThroughCodeStub(Assembler* assembler) {
2150 __ NoMonomorphicCheckedEntry();
2151
2148 Label loop, found, miss; 2152 Label loop, found, miss;
2149 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset())); 2153 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
2150 __ ldr(R8, FieldAddress(R5, ICData::ic_data_offset())); 2154 __ ldr(R8, FieldAddress(R5, ICData::ic_data_offset()));
2151 __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag); 2155 __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag);
2152 // R8: first IC entry 2156 // R8: first IC entry
2153 __ LoadTaggedClassIdMayBeSmi(R1, R0); 2157 __ LoadTaggedClassIdMayBeSmi(R1, R0);
2154 // R1: receiver cid as Smi 2158 // R1: receiver cid as Smi
2155 2159
2156 __ Bind(&loop); 2160 __ Bind(&loop);
2157 __ ldr(R2, Address(R8, 0)); 2161 __ ldr(R2, Address(R8, 0));
2158 __ cmp(R1, Operand(R2)); 2162 __ cmp(R1, Operand(R2));
2159 __ b(&found, EQ); 2163 __ b(&found, EQ);
2160 __ CompareImmediate(R2, Smi::RawValue(kIllegalCid)); 2164 __ CompareImmediate(R2, Smi::RawValue(kIllegalCid));
2161 __ b(&miss, EQ); 2165 __ b(&miss, EQ);
2162 2166
2163 const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize; 2167 const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize;
2164 __ AddImmediate(R8, R8, entry_length); // Next entry. 2168 __ AddImmediate(R8, R8, entry_length); // Next entry.
2165 __ b(&loop); 2169 __ b(&loop);
2166 2170
2167 __ Bind(&found); 2171 __ Bind(&found);
2168 const intptr_t code_offset = ICData::CodeIndexFor(1) * kWordSize; 2172 const intptr_t code_offset = ICData::CodeIndexFor(1) * kWordSize;
2169 const intptr_t entry_offset = ICData::EntryPointIndexFor(1) * kWordSize; 2173 const intptr_t entry_offset = ICData::EntryPointIndexFor(1) * kWordSize;
2170 __ ldr(R1, Address(R8, entry_offset)); 2174 __ ldr(R1, Address(R8, entry_offset));
2171 __ ldr(CODE_REG, Address(R8, code_offset)); 2175 __ ldr(CODE_REG, Address(R8, code_offset));
2172 __ ret(); 2176 __ br(R1);
2173 2177
2174 __ Bind(&miss); 2178 __ Bind(&miss);
2175 __ LoadIsolate(R2); 2179 __ LoadIsolate(R2);
2176 __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset())); 2180 __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset()));
2177 __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset())); 2181 __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset()));
2178 __ ret(); 2182 __ br(R1);
2179 } 2183 }
2180 2184
2181 2185
2186 // Called from the monomorphic checked entry.
2187 // R0: receiver
2188 void StubCode::GenerateMonomorphicMissStub(Assembler* assembler) {
2189 __ EnterStubFrame();
2190 __ Push(R0); // Preserve receiver.
2191
2192 __ PushObject(Object::null_object()); // Result.
2193 __ Push(R0); // Arg0: Receiver
2194 __ CallRuntime(kMonomorphicMissRuntimeEntry, 1);
2195 __ Drop(1);
2196 __ Pop(R5); // result = IC
2197
2198 __ Pop(R0); // Restore receiver.
2199 __ LeaveStubFrame();
2200
2201 __ ldr(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset()));
2202 __ ldr(R1, FieldAddress(CODE_REG, Code::checked_entry_point_offset()));
2203 __ br(R1);
2204 }
2205
2206
2182 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { 2207 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) {
2183 __ brk(0); 2208 __ brk(0);
2184 } 2209 }
2185 2210
2186 } // namespace dart 2211 } // namespace dart
2187 2212
2188 #endif // defined TARGET_ARCH_ARM64 2213 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/stub_code_arm.cc ('k') | runtime/vm/stub_code_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698