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

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: . 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
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 2018 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 2035 // R1: target entry point
2036 // CODE_REG: target Code 2036 // CODE_REG: target Code
2037 // R4: arguments descriptor 2037 // R4: arguments descriptor
2038 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { 2038 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
2039 __ NoMonomorphicCheckedEntry();
2040
2039 // Jump if receiver is a smi. 2041 // Jump if receiver is a smi.
2040 Label smi_case; 2042 Label smi_case;
2041 __ TestImmediate(R0, kSmiTagMask); 2043 __ TestImmediate(R0, kSmiTagMask);
2042 __ b(&smi_case, EQ); 2044 __ b(&smi_case, EQ);
2043 2045
2044 // Loads the cid of the object. 2046 // Loads the cid of the object.
2045 __ LoadClassId(R0, R0); 2047 __ LoadClassId(R0, R0);
2046 2048
2047 Label cid_loaded; 2049 Label cid_loaded;
2048 __ Bind(&cid_loaded); 2050 __ Bind(&cid_loaded);
(...skipping 27 matching lines...) Expand all
2076 Label load_target; 2078 Label load_target;
2077 __ Bind(&load_target); 2079 __ Bind(&load_target);
2078 // Call the target found in the cache. For a class id match, this is a 2080 // 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 2081 // 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 2082 // illegal class id was found, the target is a cache miss handler that can
2081 // be invoked as a normal Dart function. 2083 // be invoked as a normal Dart function.
2082 __ ldr(R0, FieldAddress(TMP, base + kWordSize)); 2084 __ ldr(R0, FieldAddress(TMP, base + kWordSize));
2083 __ ldr(R4, FieldAddress(R5, MegamorphicCache::arguments_descriptor_offset())); 2085 __ ldr(R4, FieldAddress(R5, MegamorphicCache::arguments_descriptor_offset()));
2084 __ ldr(R1, FieldAddress(R0, Function::entry_point_offset())); 2086 __ ldr(R1, FieldAddress(R0, Function::entry_point_offset()));
2085 __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset())); 2087 __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
2086 __ ret(); 2088 __ br(R1);
2087 2089
2088 // Probe failed, check if it is a miss. 2090 // Probe failed, check if it is a miss.
2089 __ Bind(&probe_failed); 2091 __ Bind(&probe_failed);
2090 ASSERT(kIllegalCid == 0); 2092 ASSERT(kIllegalCid == 0);
2091 __ tst(R6, Operand(R6)); 2093 __ tst(R6, Operand(R6));
2092 __ b(&load_target, EQ); // branch if miss. 2094 __ b(&load_target, EQ); // branch if miss.
2093 2095
2094 // Try next extry in the table. 2096 // Try next extry in the table.
2095 __ AddImmediate(R3, R3, Smi::RawValue(1)); 2097 __ AddImmediate(R3, R3, Smi::RawValue(1));
2096 __ b(&loop); 2098 __ b(&loop);
2097 2099
2098 // Load cid for the Smi case. 2100 // Load cid for the Smi case.
2099 __ Bind(&smi_case); 2101 __ Bind(&smi_case);
2100 __ LoadImmediate(R0, kSmiCid); 2102 __ LoadImmediate(R0, kSmiCid);
2101 __ b(&cid_loaded); 2103 __ b(&cid_loaded);
2102 } 2104 }
2103 2105
2104 2106
2105 // Called from switchable IC calls. 2107 // Called from switchable IC calls.
2106 // R0: receiver 2108 // R0: receiver
2107 // R5: ICData (preserved) 2109 // R5: ICData (preserved)
2108 // Result: 2110 // Result:
2109 // R1: target entry point 2111 // R1: target entry point
2110 // CODE_REG: target Code object 2112 // CODE_REG: target Code object
2111 // R4: arguments descriptor 2113 // R4: arguments descriptor
2112 void StubCode::GenerateICLookupThroughFunctionStub(Assembler* assembler) { 2114 void StubCode::GenerateICLookupThroughFunctionStub(Assembler* assembler) {
2115 __ NoMonomorphicCheckedEntry();
2116
2113 Label loop, found, miss; 2117 Label loop, found, miss;
2114 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset())); 2118 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
2115 __ ldr(R8, FieldAddress(R5, ICData::ic_data_offset())); 2119 __ ldr(R8, FieldAddress(R5, ICData::ic_data_offset()));
2116 __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag); 2120 __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag);
2117 // R8: first IC entry 2121 // R8: first IC entry
2118 __ LoadTaggedClassIdMayBeSmi(R1, R0); 2122 __ LoadTaggedClassIdMayBeSmi(R1, R0);
2119 // R1: receiver cid as Smi 2123 // R1: receiver cid as Smi
2120 2124
2121 __ Bind(&loop); 2125 __ Bind(&loop);
2122 __ ldr(R2, Address(R8, 0)); 2126 __ ldr(R2, Address(R8, 0));
2123 __ cmp(R1, Operand(R2)); 2127 __ cmp(R1, Operand(R2));
2124 __ b(&found, EQ); 2128 __ b(&found, EQ);
2125 __ CompareImmediate(R2, Smi::RawValue(kIllegalCid)); 2129 __ CompareImmediate(R2, Smi::RawValue(kIllegalCid));
2126 __ b(&miss, EQ); 2130 __ b(&miss, EQ);
2127 2131
2128 const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize; 2132 const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize;
2129 __ AddImmediate(R8, R8, entry_length); // Next entry. 2133 __ AddImmediate(R8, R8, entry_length); // Next entry.
2130 __ b(&loop); 2134 __ b(&loop);
2131 2135
2132 __ Bind(&found); 2136 __ Bind(&found);
2133 const intptr_t target_offset = ICData::TargetIndexFor(1) * kWordSize; 2137 const intptr_t target_offset = ICData::TargetIndexFor(1) * kWordSize;
2134 __ ldr(R0, Address(R8, target_offset)); 2138 __ ldr(R0, Address(R8, target_offset));
2135 __ ldr(R1, FieldAddress(R0, Function::entry_point_offset())); 2139 __ ldr(R1, FieldAddress(R0, Function::entry_point_offset()));
2136 __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset())); 2140 __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
2137 __ ret(); 2141 __ br(R1);
2138 2142
2139 __ Bind(&miss); 2143 __ Bind(&miss);
2140 __ LoadIsolate(R2); 2144 __ LoadIsolate(R2);
2141 __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset())); 2145 __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset()));
2142 __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset())); 2146 __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset()));
2143 __ ret(); 2147 __ br(R1);
2144 } 2148 }
2145 2149
2146 2150
2147 void StubCode::GenerateICLookupThroughCodeStub(Assembler* assembler) { 2151 void StubCode::GenerateICLookupThroughCodeStub(Assembler* assembler) {
2152 __ NoMonomorphicCheckedEntry();
2153
2148 Label loop, found, miss; 2154 Label loop, found, miss;
2149 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset())); 2155 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
2150 __ ldr(R8, FieldAddress(R5, ICData::ic_data_offset())); 2156 __ ldr(R8, FieldAddress(R5, ICData::ic_data_offset()));
2151 __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag); 2157 __ AddImmediate(R8, R8, Array::data_offset() - kHeapObjectTag);
2152 // R8: first IC entry 2158 // R8: first IC entry
2153 __ LoadTaggedClassIdMayBeSmi(R1, R0); 2159 __ LoadTaggedClassIdMayBeSmi(R1, R0);
2154 // R1: receiver cid as Smi 2160 // R1: receiver cid as Smi
2155 2161
2156 __ Bind(&loop); 2162 __ Bind(&loop);
2157 __ ldr(R2, Address(R8, 0)); 2163 __ ldr(R2, Address(R8, 0));
2158 __ cmp(R1, Operand(R2)); 2164 __ cmp(R1, Operand(R2));
2159 __ b(&found, EQ); 2165 __ b(&found, EQ);
2160 __ CompareImmediate(R2, Smi::RawValue(kIllegalCid)); 2166 __ CompareImmediate(R2, Smi::RawValue(kIllegalCid));
2161 __ b(&miss, EQ); 2167 __ b(&miss, EQ);
2162 2168
2163 const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize; 2169 const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize;
2164 __ AddImmediate(R8, R8, entry_length); // Next entry. 2170 __ AddImmediate(R8, R8, entry_length); // Next entry.
2165 __ b(&loop); 2171 __ b(&loop);
2166 2172
2167 __ Bind(&found); 2173 __ Bind(&found);
2168 const intptr_t code_offset = ICData::CodeIndexFor(1) * kWordSize; 2174 const intptr_t code_offset = ICData::CodeIndexFor(1) * kWordSize;
2169 const intptr_t entry_offset = ICData::EntryPointIndexFor(1) * kWordSize; 2175 const intptr_t entry_offset = ICData::EntryPointIndexFor(1) * kWordSize;
2170 __ ldr(R1, Address(R8, entry_offset)); 2176 __ ldr(R1, Address(R8, entry_offset));
2171 __ ldr(CODE_REG, Address(R8, code_offset)); 2177 __ ldr(CODE_REG, Address(R8, code_offset));
2172 __ ret(); 2178 __ br(R1);
2173 2179
2174 __ Bind(&miss); 2180 __ Bind(&miss);
2175 __ LoadIsolate(R2); 2181 __ LoadIsolate(R2);
2176 __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset())); 2182 __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset()));
2177 __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset())); 2183 __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset()));
2178 __ ret(); 2184 __ br(R1);
2179 } 2185 }
2180 2186
2181 2187
2188 // Called from switchable IC calls.
2189 // R0: receiver
2190
2191 void StubCode::GenerateMonomorphicMissStub(Assembler* assembler) {
2192 __ EnterStubFrame();
2193 __ Push(R0); // Preserve receiver.
2194
2195 __ PushObject(Object::null_object()); // Result.
2196 __ Push(R0); // Arg0: Receiver / stub out
2197 __ CallRuntime(kMonomorphicMissRuntimeEntry, 1);
2198 __ Pop(CODE_REG);
2199 __ Pop(R5); // result = IC
2200
2201 __ Pop(R0); // Restore receiver.
2202 __ LeaveStubFrame();
2203
2204 __ ldr(R1, FieldAddress(CODE_REG, Code::checked_entry_point_offset()));
2205 __ br(R1);
2206 }
2207
2208
2182 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { 2209 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) {
2183 __ brk(0); 2210 __ brk(0);
2184 } 2211 }
2185 2212
2186 } // namespace dart 2213 } // namespace dart
2187 2214
2188 #endif // defined TARGET_ARCH_ARM64 2215 #endif // defined TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698