| 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 2023 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2034 } | 2034 } |
| 2035 | 2035 |
| 2036 | 2036 |
| 2037 // Called from megamorphic calls. | 2037 // Called from megamorphic calls. |
| 2038 // RDI: receiver | 2038 // RDI: receiver |
| 2039 // RBX: MegamorphicCache (preserved) | 2039 // RBX: MegamorphicCache (preserved) |
| 2040 // Passed to target: | 2040 // Passed to target: |
| 2041 // CODE_REG: target Code | 2041 // CODE_REG: target Code |
| 2042 // R10: arguments descriptor | 2042 // R10: arguments descriptor |
| 2043 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) { | 2043 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) { |
| 2044 __ NoMonomorphicCheckedEntry(); | |
| 2045 | |
| 2046 // Jump if receiver is a smi. | 2044 // Jump if receiver is a smi. |
| 2047 Label smi_case; | 2045 Label smi_case; |
| 2048 __ testq(RDI, Immediate(kSmiTagMask)); | 2046 __ testq(RDI, Immediate(kSmiTagMask)); |
| 2049 // Jump out of line for smi case. | 2047 // Jump out of line for smi case. |
| 2050 __ j(ZERO, &smi_case, Assembler::kNearJump); | 2048 __ j(ZERO, &smi_case, Assembler::kNearJump); |
| 2051 | 2049 |
| 2052 // Loads the cid of the object. | 2050 // Loads the cid of the object. |
| 2053 __ LoadClassId(RAX, RDI); | 2051 __ LoadClassId(RAX, RDI); |
| 2054 | 2052 |
| 2055 Label cid_loaded; | 2053 Label cid_loaded; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2107 } | 2105 } |
| 2108 | 2106 |
| 2109 | 2107 |
| 2110 // Called from switchable IC calls. | 2108 // Called from switchable IC calls. |
| 2111 // RDI: receiver | 2109 // RDI: receiver |
| 2112 // RBX: ICData (preserved) | 2110 // RBX: ICData (preserved) |
| 2113 // Passed to target: | 2111 // Passed to target: |
| 2114 // CODE_REG: target Code object | 2112 // CODE_REG: target Code object |
| 2115 // R10: arguments descriptor | 2113 // R10: arguments descriptor |
| 2116 void StubCode::GenerateICCallThroughFunctionStub(Assembler* assembler) { | 2114 void StubCode::GenerateICCallThroughFunctionStub(Assembler* assembler) { |
| 2117 __ NoMonomorphicCheckedEntry(); | |
| 2118 | |
| 2119 Label loop, found, miss; | 2115 Label loop, found, miss; |
| 2120 | |
| 2121 __ movq(R13, FieldAddress(RBX, ICData::ic_data_offset())); | 2116 __ movq(R13, FieldAddress(RBX, ICData::ic_data_offset())); |
| 2122 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); | 2117 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); |
| 2123 __ leaq(R13, FieldAddress(R13, Array::data_offset())); | 2118 __ leaq(R13, FieldAddress(R13, Array::data_offset())); |
| 2124 // R13: first IC entry | 2119 // R13: first IC entry |
| 2125 __ LoadTaggedClassIdMayBeSmi(RAX, RDI); | 2120 __ LoadTaggedClassIdMayBeSmi(RAX, RDI); |
| 2126 // RAX: receiver cid as Smi | 2121 // RAX: receiver cid as Smi |
| 2127 | 2122 |
| 2128 __ Bind(&loop); | 2123 __ Bind(&loop); |
| 2129 __ movq(R9, Address(R13, 0)); | 2124 __ movq(R9, Address(R13, 0)); |
| 2130 __ cmpq(RAX, R9); | 2125 __ cmpq(RAX, R9); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2147 | 2142 |
| 2148 __ Bind(&miss); | 2143 __ Bind(&miss); |
| 2149 __ LoadIsolate(RAX); | 2144 __ LoadIsolate(RAX); |
| 2150 __ movq(CODE_REG, Address(RAX, Isolate::ic_miss_code_offset())); | 2145 __ movq(CODE_REG, Address(RAX, Isolate::ic_miss_code_offset())); |
| 2151 __ movq(RCX, FieldAddress(CODE_REG, Code::entry_point_offset())); | 2146 __ movq(RCX, FieldAddress(CODE_REG, Code::entry_point_offset())); |
| 2152 __ jmp(RCX); | 2147 __ jmp(RCX); |
| 2153 } | 2148 } |
| 2154 | 2149 |
| 2155 | 2150 |
| 2156 void StubCode::GenerateICCallThroughCodeStub(Assembler* assembler) { | 2151 void StubCode::GenerateICCallThroughCodeStub(Assembler* assembler) { |
| 2157 __ NoMonomorphicCheckedEntry(); | |
| 2158 | |
| 2159 Label loop, found, miss; | 2152 Label loop, found, miss; |
| 2160 | |
| 2161 __ movq(R13, FieldAddress(RBX, ICData::ic_data_offset())); | 2153 __ movq(R13, FieldAddress(RBX, ICData::ic_data_offset())); |
| 2162 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); | 2154 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); |
| 2163 __ leaq(R13, FieldAddress(R13, Array::data_offset())); | 2155 __ leaq(R13, FieldAddress(R13, Array::data_offset())); |
| 2164 // R13: first IC entry | 2156 // R13: first IC entry |
| 2165 __ LoadTaggedClassIdMayBeSmi(RAX, RDI); | 2157 __ LoadTaggedClassIdMayBeSmi(RAX, RDI); |
| 2166 // RAX: receiver cid as Smi | 2158 // RAX: receiver cid as Smi |
| 2167 | 2159 |
| 2168 __ Bind(&loop); | 2160 __ Bind(&loop); |
| 2169 __ movq(R9, Address(R13, 0)); | 2161 __ movq(R9, Address(R13, 0)); |
| 2170 __ cmpq(RAX, R9); | 2162 __ cmpq(RAX, R9); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2189 __ LoadIsolate(RAX); | 2181 __ LoadIsolate(RAX); |
| 2190 __ movq(CODE_REG, Address(RAX, Isolate::ic_miss_code_offset())); | 2182 __ movq(CODE_REG, Address(RAX, Isolate::ic_miss_code_offset())); |
| 2191 __ movq(RCX, FieldAddress(CODE_REG, Code::entry_point_offset())); | 2183 __ movq(RCX, FieldAddress(CODE_REG, Code::entry_point_offset())); |
| 2192 __ jmp(RCX); | 2184 __ jmp(RCX); |
| 2193 } | 2185 } |
| 2194 | 2186 |
| 2195 | 2187 |
| 2196 // RDI: receiver | 2188 // RDI: receiver |
| 2197 // RBX: UnlinkedCall | 2189 // RBX: UnlinkedCall |
| 2198 void StubCode::GenerateUnlinkedCallStub(Assembler* assembler) { | 2190 void StubCode::GenerateUnlinkedCallStub(Assembler* assembler) { |
| 2199 __ NoMonomorphicCheckedEntry(); | |
| 2200 | |
| 2201 __ EnterStubFrame(); | 2191 __ EnterStubFrame(); |
| 2202 __ pushq(RDI); // Preserve receiver. | 2192 __ pushq(RDI); // Preserve receiver. |
| 2203 | 2193 |
| 2204 __ pushq(Immediate(0)); // Result slot. | 2194 __ pushq(Immediate(0)); // Result slot. |
| 2205 __ pushq(RDI); // Arg0: Receiver | 2195 __ pushq(RDI); // Arg0: Receiver |
| 2206 __ pushq(RBX); // Arg1: UnlinkedCall | 2196 __ pushq(RBX); // Arg1: UnlinkedCall |
| 2207 __ CallRuntime(kUnlinkedCallRuntimeEntry, 2); | 2197 __ CallRuntime(kUnlinkedCallRuntimeEntry, 2); |
| 2208 __ popq(RBX); | 2198 __ popq(RBX); |
| 2209 __ popq(RBX); | 2199 __ popq(RBX); |
| 2210 __ popq(RBX); // result = IC | 2200 __ popq(RBX); // result = IC |
| 2211 | 2201 |
| 2212 __ popq(RDI); // Restore receiver. | 2202 __ popq(RDI); // Restore receiver. |
| 2213 __ LeaveStubFrame(); | 2203 __ LeaveStubFrame(); |
| 2214 | 2204 |
| 2215 __ movq(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset())); | 2205 __ movq(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset())); |
| 2216 __ movq(RCX, FieldAddress(CODE_REG, Code::checked_entry_point_offset())); | 2206 __ movq(RCX, FieldAddress(CODE_REG, Code::checked_entry_point_offset())); |
| 2217 __ jmp(RCX); | 2207 __ jmp(RCX); |
| 2218 } | 2208 } |
| 2219 | 2209 |
| 2220 | 2210 |
| 2221 // Called from switchable IC calls. | 2211 // Called from switchable IC calls. |
| 2222 // RDI: receiver | 2212 // RDI: receiver |
| 2223 // RBX: SingleTargetCache | 2213 // RBX: SingleTargetCache |
| 2224 // Passed to target:: | 2214 // Passed to target:: |
| 2225 // CODE_REG: target Code object | 2215 // CODE_REG: target Code object |
| 2226 void StubCode::GenerateSingleTargetCallStub(Assembler* assembler) { | 2216 void StubCode::GenerateSingleTargetCallStub(Assembler* assembler) { |
| 2227 __ NoMonomorphicCheckedEntry(); | |
| 2228 | |
| 2229 Label miss; | 2217 Label miss; |
| 2230 __ LoadClassIdMayBeSmi(RAX, RDI); | 2218 __ LoadClassIdMayBeSmi(RAX, RDI); |
| 2231 __ movl(R9, FieldAddress(RBX, SingleTargetCache::lower_limit_offset())); | 2219 __ movl(R9, FieldAddress(RBX, SingleTargetCache::lower_limit_offset())); |
| 2232 __ movl(R10, FieldAddress(RBX, SingleTargetCache::upper_limit_offset())); | 2220 __ movl(R10, FieldAddress(RBX, SingleTargetCache::upper_limit_offset())); |
| 2233 __ cmpq(RAX, R9); | 2221 __ cmpq(RAX, R9); |
| 2234 __ j(LESS, &miss, Assembler::kNearJump); | 2222 __ j(LESS, &miss, Assembler::kNearJump); |
| 2235 __ cmpq(RAX, R10); | 2223 __ cmpq(RAX, R10); |
| 2236 __ j(GREATER, &miss, Assembler::kNearJump); | 2224 __ j(GREATER, &miss, Assembler::kNearJump); |
| 2237 __ movq(RCX, FieldAddress(RBX, SingleTargetCache::entry_point_offset())); | 2225 __ movq(RCX, FieldAddress(RBX, SingleTargetCache::entry_point_offset())); |
| 2238 __ movq(CODE_REG, FieldAddress(RBX, SingleTargetCache::target_offset())); | 2226 __ movq(CODE_REG, FieldAddress(RBX, SingleTargetCache::target_offset())); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2279 } | 2267 } |
| 2280 | 2268 |
| 2281 | 2269 |
| 2282 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { | 2270 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { |
| 2283 __ int3(); | 2271 __ int3(); |
| 2284 } | 2272 } |
| 2285 | 2273 |
| 2286 } // namespace dart | 2274 } // namespace dart |
| 2287 | 2275 |
| 2288 #endif // defined TARGET_ARCH_X64 | 2276 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |