Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 2083 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2094 __ LoadFromOffset(left, SP, 1 * kWordSize); | 2094 __ LoadFromOffset(left, SP, 1 * kWordSize); |
| 2095 __ LoadFromOffset(right, SP, 0 * kWordSize); | 2095 __ LoadFromOffset(right, SP, 0 * kWordSize); |
| 2096 GenerateIdenticalWithNumberCheckStub(assembler, left, right); | 2096 GenerateIdenticalWithNumberCheckStub(assembler, left, right); |
| 2097 __ ret(); | 2097 __ ret(); |
| 2098 } | 2098 } |
| 2099 | 2099 |
| 2100 | 2100 |
| 2101 void StubCode::EmitMegamorphicLookup(Assembler* assembler) { | 2101 void StubCode::EmitMegamorphicLookup(Assembler* assembler) { |
| 2102 __ LoadTaggedClassIdMayBeSmi(R0, R0); | 2102 __ LoadTaggedClassIdMayBeSmi(R0, R0); |
| 2103 // R0: class ID of the receiver (smi). | 2103 // R0: class ID of the receiver (smi). |
| 2104 __ ldr(R4, FieldAddress(R5, MegamorphicCache::arguments_descriptor_offset())); | |
| 2105 __ ldr(R2, FieldAddress(R5, MegamorphicCache::buckets_offset())); | 2104 __ ldr(R2, FieldAddress(R5, MegamorphicCache::buckets_offset())); |
| 2106 __ ldr(R1, FieldAddress(R5, MegamorphicCache::mask_offset())); | 2105 __ ldr(R1, FieldAddress(R5, MegamorphicCache::mask_offset())); |
| 2107 // R2: cache buckets array. | 2106 // R2: cache buckets array. |
| 2108 // R1: mask. | 2107 // R1: mask. |
| 2109 __ LoadImmediate(TMP, MegamorphicCache::kSpreadFactor); | 2108 |
| 2110 __ mul(R3, R0, TMP); | 2109 // Compute the table index. |
| 2110 ASSERT(MegamorphicCache::kSpreadFactor == 7); | |
| 2111 // Use lsl and sub to multiply with 7 == 8 - 1. | |
| 2112 __ LslImmediate(R3, R0, 3); | |
| 2113 __ sub(R3, R3, Operand(R0)); | |
| 2111 // R3: probe. | 2114 // R3: probe. |
| 2112 | 2115 |
| 2113 Label loop, update, load_target_function; | 2116 Label loop, update, load_target_function; |
| 2114 __ b(&loop); | 2117 __ b(&loop); |
| 2115 | 2118 |
| 2116 __ Bind(&update); | 2119 __ Bind(&update); |
| 2117 __ add(R3, R3, Operand(Smi::RawValue(1))); | 2120 __ add(R3, R3, Operand(Smi::RawValue(1))); |
| 2118 __ Bind(&loop); | 2121 __ Bind(&loop); |
| 2119 __ and_(R3, R3, Operand(R1)); | 2122 __ and_(R3, R3, Operand(R1)); |
| 2120 const intptr_t base = Array::data_offset(); | 2123 const intptr_t base = Array::data_offset(); |
| 2121 // R3 is smi tagged, but table entries are 16 bytes, so LSL 3. | 2124 // R3 is smi tagged, but table entries are 16 bytes, so LSL 3. |
| 2122 __ add(TMP, R2, Operand(R3, LSL, 3)); | 2125 __ add(TMP, R2, Operand(R3, LSL, 3)); |
| 2123 __ ldr(R6, FieldAddress(TMP, base)); | 2126 __ ldr(R6, FieldAddress(TMP, base)); |
| 2124 | 2127 |
| 2125 ASSERT(kIllegalCid == 0); | 2128 ASSERT(kIllegalCid == 0); |
| 2126 __ tst(R6, Operand(R6)); | 2129 __ tst(R6, Operand(R6)); |
| 2127 __ b(&load_target_function, EQ); | 2130 __ b(&load_target_function, EQ); |
| 2128 __ CompareRegisters(R6, R0); | 2131 __ CompareRegisters(R6, R0); |
| 2129 __ b(&update, NE); | 2132 __ b(&update, NE); |
| 2130 | 2133 |
| 2131 __ Bind(&load_target_function); | 2134 __ Bind(&load_target_function); |
| 2132 // Call the target found in the cache. For a class id match, this is a | 2135 // Call the target found in the cache. For a class id match, this is a |
| 2133 // proper target for the given name and arguments descriptor. If the | 2136 // proper target for the given name and arguments descriptor. If the |
| 2134 // illegal class id was found, the target is a cache miss handler that can | 2137 // illegal class id was found, the target is a cache miss handler that can |
| 2135 // be invoked as a normal Dart function. | 2138 // be invoked as a normal Dart function. |
| 2136 __ add(TMP, R2, Operand(R3, LSL, 3)); | 2139 __ add(TMP, R2, Operand(R3, LSL, 3)); |
| 2137 __ ldr(R0, FieldAddress(TMP, base + kWordSize)); | 2140 __ ldr(R0, FieldAddress(TMP, base + kWordSize)); |
| 2141 __ ldr(R4, FieldAddress(R5, MegamorphicCache::arguments_descriptor_offset())); | |
| 2138 __ ldr(R1, FieldAddress(R0, Function::entry_point_offset())); | 2142 __ ldr(R1, FieldAddress(R0, Function::entry_point_offset())); |
| 2139 __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset())); | 2143 __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset())); |
| 2140 } | 2144 } |
| 2141 | 2145 |
| 2142 | 2146 |
| 2143 // Called from megamorphic calls. | 2147 // Called from megamorphic calls. |
| 2144 // R0: receiver | 2148 // R0: receiver |
| 2145 // R5: MegamorphicCache (preserved) | 2149 // R5: MegamorphicCache (preserved) |
| 2146 // Result: | 2150 // Result: |
| 2147 // R1: target entry point | 2151 // R1: target entry point |
| 2148 // CODE_REG: target Code | 2152 // CODE_REG: target Code |
| 2149 // R4: arguments descriptor | 2153 // R4: arguments descriptor |
| 2150 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2154 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
| 2151 EmitMegamorphicLookup(assembler); | 2155 __ LoadTaggedClassIdMayBeSmi(R0, R0); |
|
Florian Schneider
2016/07/07 18:20:15
Maybe make this avoid the null-load like on x64.
| |
| 2156 // R0: class ID of the receiver (smi). | |
| 2157 __ ldr(R2, FieldAddress(R5, MegamorphicCache::buckets_offset())); | |
| 2158 __ ldr(R1, FieldAddress(R5, MegamorphicCache::mask_offset())); | |
| 2159 // R2: cache buckets array. | |
| 2160 // R1: mask. | |
| 2161 | |
| 2162 // Compute the table index. | |
| 2163 ASSERT(MegamorphicCache::kSpreadFactor == 7); | |
| 2164 // Use lsl and sub to multiply with 7 == 8 - 1. | |
| 2165 __ LslImmediate(R3, R0, 3); | |
| 2166 __ sub(R3, R3, Operand(R0)); | |
| 2167 // R3: probe. | |
| 2168 Label loop; | |
| 2169 __ Bind(&loop); | |
| 2170 __ and_(R3, R3, Operand(R1)); | |
| 2171 | |
| 2172 const intptr_t base = Array::data_offset(); | |
| 2173 // R3 is smi tagged, but table entries are 16 bytes, so LSL 3. | |
| 2174 __ add(TMP, R2, Operand(R3, LSL, 3)); | |
| 2175 __ ldr(R6, FieldAddress(TMP, base)); | |
| 2176 Label probe_failed; | |
| 2177 __ CompareRegisters(R6, R0); | |
| 2178 __ b(&probe_failed, NE); | |
| 2179 | |
| 2180 Label load_target; | |
| 2181 __ Bind(&load_target); | |
| 2182 // Call the target found in the cache. For a class id match, this is a | |
| 2183 // proper target for the given name and arguments descriptor. If the | |
| 2184 // illegal class id was found, the target is a cache miss handler that can | |
| 2185 // be invoked as a normal Dart function. | |
| 2186 __ ldr(R0, FieldAddress(TMP, base + kWordSize)); | |
| 2187 __ ldr(R4, FieldAddress(R5, MegamorphicCache::arguments_descriptor_offset())); | |
| 2188 __ ldr(R1, FieldAddress(R0, Function::entry_point_offset())); | |
| 2189 __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset())); | |
| 2152 __ ret(); | 2190 __ ret(); |
| 2191 | |
| 2192 // Probe failed, check if it is a miss. | |
| 2193 __ Bind(&probe_failed); | |
| 2194 ASSERT(kIllegalCid == 0); | |
| 2195 __ tst(R6, Operand(R6)); | |
| 2196 __ b(&load_target, EQ); // branch if miss. | |
| 2197 | |
| 2198 // Try next extry in the table. | |
| 2199 __ AddImmediate(R3, R3, Smi::RawValue(1)); | |
| 2200 __ b(&loop); | |
| 2153 } | 2201 } |
| 2154 | 2202 |
| 2155 | 2203 |
| 2156 // Called from switchable IC calls. | 2204 // Called from switchable IC calls. |
| 2157 // R0: receiver | 2205 // R0: receiver |
| 2158 // R5: ICData (preserved) | 2206 // R5: ICData (preserved) |
| 2159 // Result: | 2207 // Result: |
| 2160 // R1: target entry point | 2208 // R1: target entry point |
| 2161 // CODE_REG: target Code object | 2209 // CODE_REG: target Code object |
| 2162 // R4: arguments descriptor | 2210 // R4: arguments descriptor |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2230 } | 2278 } |
| 2231 | 2279 |
| 2232 | 2280 |
| 2233 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { | 2281 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { |
| 2234 __ brk(0); | 2282 __ brk(0); |
| 2235 } | 2283 } |
| 2236 | 2284 |
| 2237 } // namespace dart | 2285 } // namespace dart |
| 2238 | 2286 |
| 2239 #endif // defined TARGET_ARCH_ARM64 | 2287 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |