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 |