OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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_X64) | 6 #if defined(TARGET_ARCH_X64) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 2070 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2081 const Register left = RAX; | 2081 const Register left = RAX; |
2082 const Register right = RDX; | 2082 const Register right = RDX; |
2083 | 2083 |
2084 __ movq(left, Address(RSP, 2 * kWordSize)); | 2084 __ movq(left, Address(RSP, 2 * kWordSize)); |
2085 __ movq(right, Address(RSP, 1 * kWordSize)); | 2085 __ movq(right, Address(RSP, 1 * kWordSize)); |
2086 GenerateIdenticalWithNumberCheckStub(assembler, left, right); | 2086 GenerateIdenticalWithNumberCheckStub(assembler, left, right); |
2087 __ ret(); | 2087 __ ret(); |
2088 } | 2088 } |
2089 | 2089 |
2090 | 2090 |
| 2091 // Called from megamorphic calls. |
| 2092 // RDI: receiver |
| 2093 // RBX: MegamorphicCache (preserved) |
| 2094 // Result: |
| 2095 // RCX: target entry point |
| 2096 // CODE_REG: target Code |
| 2097 // R10: arguments descriptor |
2091 void StubCode::EmitMegamorphicLookup(Assembler* assembler) { | 2098 void StubCode::EmitMegamorphicLookup(Assembler* assembler) { |
2092 __ LoadTaggedClassIdMayBeSmi(RAX, RDI); | 2099 __ LoadTaggedClassIdMayBeSmi(RAX, RDI); |
2093 // RAX: class ID of the receiver (smi). | 2100 // RAX: class ID of the receiver (smi). |
2094 __ movq(R10, | 2101 __ movq(R10, |
2095 FieldAddress(RBX, MegamorphicCache::arguments_descriptor_offset())); | 2102 FieldAddress(RBX, MegamorphicCache::arguments_descriptor_offset())); |
2096 __ movq(RDI, FieldAddress(RBX, MegamorphicCache::buckets_offset())); | 2103 __ movq(RDI, FieldAddress(RBX, MegamorphicCache::buckets_offset())); |
2097 __ movq(R9, FieldAddress(RBX, MegamorphicCache::mask_offset())); | 2104 __ movq(R9, FieldAddress(RBX, MegamorphicCache::mask_offset())); |
2098 // RDI: cache buckets array. | 2105 // RDI: cache buckets array. |
2099 // RBX: mask. | 2106 // RBX: mask. |
2100 __ movq(RCX, RAX); | 2107 __ movq(RCX, RAX); |
(...skipping 19 matching lines...) Expand all Loading... |
2120 // Call the target found in the cache. For a class id match, this is a | 2127 // Call the target found in the cache. For a class id match, this is a |
2121 // proper target for the given name and arguments descriptor. If the | 2128 // proper target for the given name and arguments descriptor. If the |
2122 // illegal class id was found, the target is a cache miss handler that can | 2129 // illegal class id was found, the target is a cache miss handler that can |
2123 // be invoked as a normal Dart function. | 2130 // be invoked as a normal Dart function. |
2124 __ movq(RAX, FieldAddress(RDI, RCX, TIMES_8, base + kWordSize)); | 2131 __ movq(RAX, FieldAddress(RDI, RCX, TIMES_8, base + kWordSize)); |
2125 __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset())); | 2132 __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset())); |
2126 __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset())); | 2133 __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset())); |
2127 } | 2134 } |
2128 | 2135 |
2129 | 2136 |
2130 // Called from megamorphic calls. | |
2131 // RDI: receiver | |
2132 // RBX: MegamorphicCache (preserved) | |
2133 // Result: | |
2134 // RCX: target entry point | |
2135 // CODE_REG: target Code | |
2136 // R10: arguments descriptor | |
2137 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2137 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
2138 EmitMegamorphicLookup(assembler); | 2138 EmitMegamorphicLookup(assembler); |
2139 __ ret(); | 2139 __ ret(); |
2140 } | 2140 } |
2141 | 2141 |
2142 | 2142 |
2143 // Called from switchable IC calls. | 2143 // Called from switchable IC calls. |
2144 // RDI: receiver | 2144 // RDI: receiver |
2145 // RBX: ICData (preserved) | 2145 // RBX: ICData (preserved) |
2146 // Result: | 2146 // Result: |
2147 // RCX: target entry point | 2147 // RCX: target entry point |
2148 // CODE_REG: target Code object | 2148 // CODE_REG: target Code object |
2149 // R10: arguments descriptor | 2149 // R10: arguments descriptor |
2150 void StubCode::GenerateICLookupStub(Assembler* assembler) { | 2150 static void EmitICLookup(Assembler* assembler, |
| 2151 intptr_t args_checked, |
| 2152 Token::Kind kind) { |
| 2153 if (kind != Token::kILLEGAL) { |
| 2154 __ Comment("Fast Smi op"); |
| 2155 Label not_smi_or_overflow; |
| 2156 |
| 2157 // RDI: Receiver |
| 2158 __ movq(RCX, Address(RSP, + 1 * kWordSize)); |
| 2159 // RCX: Argument |
| 2160 __ movq(R13, RCX); |
| 2161 __ orq(R13, RDI); |
| 2162 __ testq(R13, Immediate(kSmiTagMask)); |
| 2163 __ j(NOT_ZERO, ¬_smi_or_overflow); |
| 2164 __ movq(RAX, RDI); |
| 2165 switch (kind) { |
| 2166 case Token::kADD: { |
| 2167 __ addq(RAX, RCX); |
| 2168 __ j(OVERFLOW, ¬_smi_or_overflow); |
| 2169 break; |
| 2170 } |
| 2171 case Token::kSUB: { |
| 2172 __ subq(RAX, RCX); |
| 2173 __ j(OVERFLOW, ¬_smi_or_overflow); |
| 2174 break; |
| 2175 } |
| 2176 case Token::kEQ: { |
| 2177 Label done, is_true; |
| 2178 __ cmpq(RAX, RCX); |
| 2179 __ j(EQUAL, &is_true, Assembler::kNearJump); |
| 2180 __ LoadObject(RAX, Bool::False()); |
| 2181 __ jmp(&done, Assembler::kNearJump); |
| 2182 __ Bind(&is_true); |
| 2183 __ LoadObject(RAX, Bool::True()); |
| 2184 __ Bind(&done); |
| 2185 break; |
| 2186 } |
| 2187 default: UNIMPLEMENTED(); |
| 2188 } |
| 2189 // Return past the call to lookup result. |
| 2190 intptr_t call_length = 2; // call rcx |
| 2191 __ AddImmediate(Address(RSP, 0), Immediate(call_length)); |
| 2192 __ ret(); |
| 2193 |
| 2194 __ Bind(¬_smi_or_overflow); |
| 2195 } |
| 2196 |
2151 Label loop, found, miss; | 2197 Label loop, found, miss; |
2152 | 2198 |
2153 __ movq(R13, FieldAddress(RBX, ICData::ic_data_offset())); | 2199 __ movq(R13, FieldAddress(RBX, ICData::ic_data_offset())); |
2154 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); | 2200 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); |
2155 __ leaq(R13, FieldAddress(R13, Array::data_offset())); | 2201 __ leaq(R13, FieldAddress(R13, Array::data_offset())); |
2156 // R13: first IC entry | 2202 // R13: first IC entry |
2157 __ LoadTaggedClassIdMayBeSmi(RAX, RDI); | 2203 __ LoadTaggedClassIdMayBeSmi(RAX, RDI); |
2158 // RAX: receiver cid as Smi | 2204 // RAX: receiver cid as Smi |
2159 | 2205 |
2160 __ Bind(&loop); | 2206 __ Bind(&loop); |
2161 __ movq(R9, Address(R13, 0)); | 2207 __ movq(R9, Address(R13, 0)); |
2162 __ cmpq(RAX, R9); | 2208 __ cmpq(RAX, R9); |
2163 __ j(EQUAL, &found, Assembler::kNearJump); | 2209 __ j(EQUAL, &found, Assembler::kNearJump); |
2164 | 2210 |
2165 ASSERT(Smi::RawValue(kIllegalCid) == 0); | 2211 ASSERT(Smi::RawValue(kIllegalCid) == 0); |
2166 __ testq(R9, R9); | 2212 __ testq(R9, R9); |
2167 __ j(ZERO, &miss, Assembler::kNearJump); | 2213 __ j(ZERO, &miss, Assembler::kNearJump); |
2168 | 2214 |
2169 const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize; | 2215 const intptr_t entry_length = |
| 2216 ICData::TestEntryLengthFor(args_checked) * kWordSize; |
2170 __ addq(R13, Immediate(entry_length)); // Next entry. | 2217 __ addq(R13, Immediate(entry_length)); // Next entry. |
2171 __ jmp(&loop); | 2218 __ jmp(&loop); |
2172 | 2219 |
2173 __ Bind(&found); | 2220 __ Bind(&found); |
2174 const intptr_t target_offset = ICData::TargetIndexFor(1) * kWordSize; | 2221 const intptr_t target_offset = |
| 2222 ICData::TargetIndexFor(args_checked) * kWordSize; |
2175 __ movq(RAX, Address(R13, target_offset)); | 2223 __ movq(RAX, Address(R13, target_offset)); |
2176 __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset())); | 2224 __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset())); |
2177 __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset())); | 2225 __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset())); |
2178 __ ret(); | 2226 __ ret(); |
2179 | 2227 |
2180 __ Bind(&miss); | 2228 __ Bind(&miss); |
2181 __ LoadIsolate(RAX); | 2229 __ LoadIsolate(RAX); |
2182 __ movq(CODE_REG, Address(RAX, Isolate::ic_miss_code_offset())); | 2230 __ movq(CODE_REG, Address(RAX, Isolate::ic_miss_code_offset())); |
2183 __ movq(RCX, FieldAddress(CODE_REG, Code::entry_point_offset())); | 2231 __ movq(RCX, FieldAddress(CODE_REG, Code::entry_point_offset())); |
2184 __ ret(); | 2232 __ ret(); |
2185 } | 2233 } |
2186 | 2234 |
| 2235 |
| 2236 void StubCode::GenerateICLookupStub(Assembler* assembler) { |
| 2237 EmitICLookup(assembler, 1, Token::kILLEGAL); |
| 2238 } |
| 2239 |
| 2240 |
| 2241 void StubCode::GenerateICSmiAddLookupStub(Assembler* assembler) { |
| 2242 EmitICLookup(assembler, 2, Token::kADD); |
| 2243 } |
| 2244 |
| 2245 |
| 2246 void StubCode::GenerateICSmiSubLookupStub(Assembler* assembler) { |
| 2247 EmitICLookup(assembler, 2, Token::kSUB); |
| 2248 } |
| 2249 |
| 2250 |
| 2251 void StubCode::GenerateICSmiEqualLookupStub(Assembler* assembler) { |
| 2252 EmitICLookup(assembler, 2, Token::kEQ); |
| 2253 } |
| 2254 |
2187 } // namespace dart | 2255 } // namespace dart |
2188 | 2256 |
2189 #endif // defined TARGET_ARCH_X64 | 2257 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |