| 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 2080 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2091 Assembler* assembler) { | 2091 Assembler* assembler) { |
| 2092 const Register left = R1; | 2092 const Register left = R1; |
| 2093 const Register right = R0; | 2093 const Register right = R0; |
| 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) { | |
| 2102 __ LoadTaggedClassIdMayBeSmi(R0, R0); | |
| 2103 // R0: class ID of the receiver (smi). | |
| 2104 __ ldr(R2, FieldAddress(R5, MegamorphicCache::buckets_offset())); | |
| 2105 __ ldr(R1, FieldAddress(R5, MegamorphicCache::mask_offset())); | |
| 2106 // R2: cache buckets array. | |
| 2107 // R1: mask. | |
| 2108 | |
| 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)); | |
| 2114 // R3: probe. | |
| 2115 | |
| 2116 Label loop, update, load_target_function; | |
| 2117 __ b(&loop); | |
| 2118 | |
| 2119 __ Bind(&update); | |
| 2120 __ add(R3, R3, Operand(Smi::RawValue(1))); | |
| 2121 __ Bind(&loop); | |
| 2122 __ and_(R3, R3, Operand(R1)); | |
| 2123 const intptr_t base = Array::data_offset(); | |
| 2124 // R3 is smi tagged, but table entries are 16 bytes, so LSL 3. | |
| 2125 __ add(TMP, R2, Operand(R3, LSL, 3)); | |
| 2126 __ ldr(R6, FieldAddress(TMP, base)); | |
| 2127 | |
| 2128 ASSERT(kIllegalCid == 0); | |
| 2129 __ tst(R6, Operand(R6)); | |
| 2130 __ b(&load_target_function, EQ); | |
| 2131 __ CompareRegisters(R6, R0); | |
| 2132 __ b(&update, NE); | |
| 2133 | |
| 2134 __ Bind(&load_target_function); | |
| 2135 // Call the target found in the cache. For a class id match, this is a | |
| 2136 // proper target for the given name and arguments descriptor. If the | |
| 2137 // illegal class id was found, the target is a cache miss handler that can | |
| 2138 // be invoked as a normal Dart function. | |
| 2139 __ add(TMP, R2, Operand(R3, LSL, 3)); | |
| 2140 __ ldr(R0, FieldAddress(TMP, base + kWordSize)); | |
| 2141 __ ldr(R4, FieldAddress(R5, MegamorphicCache::arguments_descriptor_offset())); | |
| 2142 __ ldr(R1, FieldAddress(R0, Function::entry_point_offset())); | |
| 2143 __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset())); | |
| 2144 } | |
| 2145 | |
| 2146 | |
| 2147 // Called from megamorphic calls. | 2101 // Called from megamorphic calls. |
| 2148 // R0: receiver | 2102 // R0: receiver |
| 2149 // R5: MegamorphicCache (preserved) | 2103 // R5: MegamorphicCache (preserved) |
| 2150 // Result: | 2104 // Result: |
| 2151 // R1: target entry point | 2105 // R1: target entry point |
| 2152 // CODE_REG: target Code | 2106 // CODE_REG: target Code |
| 2153 // R4: arguments descriptor | 2107 // R4: arguments descriptor |
| 2154 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2108 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
| 2155 __ LoadTaggedClassIdMayBeSmi(R0, R0); | 2109 // Jump if receiver is a smi. |
| 2156 // R0: class ID of the receiver (smi). | 2110 Label smi_case; |
| 2111 __ TestImmediate(R0, kSmiTagMask); |
| 2112 __ b(&smi_case, EQ); |
| 2113 |
| 2114 // Loads the cid of the object. |
| 2115 __ LoadClassId(R0, R0); |
| 2116 |
| 2117 Label cid_loaded; |
| 2118 __ Bind(&cid_loaded); |
| 2157 __ ldr(R2, FieldAddress(R5, MegamorphicCache::buckets_offset())); | 2119 __ ldr(R2, FieldAddress(R5, MegamorphicCache::buckets_offset())); |
| 2158 __ ldr(R1, FieldAddress(R5, MegamorphicCache::mask_offset())); | 2120 __ ldr(R1, FieldAddress(R5, MegamorphicCache::mask_offset())); |
| 2159 // R2: cache buckets array. | 2121 // R2: cache buckets array. |
| 2160 // R1: mask. | 2122 // R1: mask. |
| 2161 | 2123 |
| 2124 // Make the cid into a smi. |
| 2125 __ SmiTag(R0); |
| 2126 // R0: class ID of the receiver (smi). |
| 2127 |
| 2162 // Compute the table index. | 2128 // Compute the table index. |
| 2163 ASSERT(MegamorphicCache::kSpreadFactor == 7); | 2129 ASSERT(MegamorphicCache::kSpreadFactor == 7); |
| 2164 // Use lsl and sub to multiply with 7 == 8 - 1. | 2130 // Use lsl and sub to multiply with 7 == 8 - 1. |
| 2165 __ LslImmediate(R3, R0, 3); | 2131 __ LslImmediate(R3, R0, 3); |
| 2166 __ sub(R3, R3, Operand(R0)); | 2132 __ sub(R3, R3, Operand(R0)); |
| 2167 // R3: probe. | 2133 // R3: probe. |
| 2168 Label loop; | 2134 Label loop; |
| 2169 __ Bind(&loop); | 2135 __ Bind(&loop); |
| 2170 __ and_(R3, R3, Operand(R1)); | 2136 __ and_(R3, R3, Operand(R1)); |
| 2171 | 2137 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2191 | 2157 |
| 2192 // Probe failed, check if it is a miss. | 2158 // Probe failed, check if it is a miss. |
| 2193 __ Bind(&probe_failed); | 2159 __ Bind(&probe_failed); |
| 2194 ASSERT(kIllegalCid == 0); | 2160 ASSERT(kIllegalCid == 0); |
| 2195 __ tst(R6, Operand(R6)); | 2161 __ tst(R6, Operand(R6)); |
| 2196 __ b(&load_target, EQ); // branch if miss. | 2162 __ b(&load_target, EQ); // branch if miss. |
| 2197 | 2163 |
| 2198 // Try next extry in the table. | 2164 // Try next extry in the table. |
| 2199 __ AddImmediate(R3, R3, Smi::RawValue(1)); | 2165 __ AddImmediate(R3, R3, Smi::RawValue(1)); |
| 2200 __ b(&loop); | 2166 __ b(&loop); |
| 2167 |
| 2168 // Load cid for the Smi case. |
| 2169 __ Bind(&smi_case); |
| 2170 __ LoadImmediate(R0, kSmiCid); |
| 2171 __ b(&cid_loaded); |
| 2201 } | 2172 } |
| 2202 | 2173 |
| 2203 | 2174 |
| 2204 // Called from switchable IC calls. | 2175 // Called from switchable IC calls. |
| 2205 // R0: receiver | 2176 // R0: receiver |
| 2206 // R5: ICData (preserved) | 2177 // R5: ICData (preserved) |
| 2207 // Result: | 2178 // Result: |
| 2208 // R1: target entry point | 2179 // R1: target entry point |
| 2209 // CODE_REG: target Code object | 2180 // CODE_REG: target Code object |
| 2210 // R4: arguments descriptor | 2181 // R4: arguments descriptor |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2278 } | 2249 } |
| 2279 | 2250 |
| 2280 | 2251 |
| 2281 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { | 2252 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { |
| 2282 __ brk(0); | 2253 __ brk(0); |
| 2283 } | 2254 } |
| 2284 | 2255 |
| 2285 } // namespace dart | 2256 } // namespace dart |
| 2286 | 2257 |
| 2287 #endif // defined TARGET_ARCH_ARM64 | 2258 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |