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/assembler_macros.h" | |
10 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
11 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
12 #include "vm/flow_graph_compiler.h" | 11 #include "vm/flow_graph_compiler.h" |
13 #include "vm/instructions.h" | 12 #include "vm/instructions.h" |
14 #include "vm/object_store.h" | 13 #include "vm/object_store.h" |
15 #include "vm/pages.h" | 14 #include "vm/pages.h" |
16 #include "vm/resolver.h" | 15 #include "vm/resolver.h" |
17 #include "vm/scavenger.h" | 16 #include "vm/scavenger.h" |
18 #include "vm/stub_code.h" | 17 #include "vm/stub_code.h" |
19 | 18 |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 __ LeaveFrame(); | 179 __ LeaveFrame(); |
181 __ ret(); | 180 __ ret(); |
182 } | 181 } |
183 | 182 |
184 | 183 |
185 // Input parameters: | 184 // Input parameters: |
186 // R10: arguments descriptor array. | 185 // R10: arguments descriptor array. |
187 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 186 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
188 const Immediate& raw_null = | 187 const Immediate& raw_null = |
189 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 188 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
190 AssemblerMacros::EnterStubFrame(assembler); | 189 __ EnterStubFrame(); |
191 __ pushq(R10); // Preserve arguments descriptor array. | 190 __ pushq(R10); // Preserve arguments descriptor array. |
192 __ pushq(raw_null); // Setup space on stack for return value. | 191 __ pushq(raw_null); // Setup space on stack for return value. |
193 __ CallRuntime(kPatchStaticCallRuntimeEntry); | 192 __ CallRuntime(kPatchStaticCallRuntimeEntry); |
194 __ popq(RAX); // Get Code object result. | 193 __ popq(RAX); // Get Code object result. |
195 __ popq(R10); // Restore arguments descriptor array. | 194 __ popq(R10); // Restore arguments descriptor array. |
196 // Remove the stub frame as we are about to jump to the dart function. | 195 // Remove the stub frame as we are about to jump to the dart function. |
197 __ LeaveFrame(); | 196 __ LeaveFrame(); |
198 | 197 |
199 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); | 198 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); |
200 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 199 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
201 __ jmp(RBX); | 200 __ jmp(RBX); |
202 } | 201 } |
203 | 202 |
204 | 203 |
205 // Called from a static call only when an invalid code has been entered | 204 // Called from a static call only when an invalid code has been entered |
206 // (invalid because its function was optimized or deoptimized). | 205 // (invalid because its function was optimized or deoptimized). |
207 // R10: arguments descriptor array. | 206 // R10: arguments descriptor array. |
208 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { | 207 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { |
209 const Immediate& raw_null = | 208 const Immediate& raw_null = |
210 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 209 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
211 AssemblerMacros::EnterStubFrame(assembler); | 210 __ EnterStubFrame(); |
212 __ pushq(R10); // Preserve arguments descriptor array. | 211 __ pushq(R10); // Preserve arguments descriptor array. |
213 __ pushq(raw_null); // Setup space on stack for return value. | 212 __ pushq(raw_null); // Setup space on stack for return value. |
214 __ CallRuntime(kFixCallersTargetRuntimeEntry); | 213 __ CallRuntime(kFixCallersTargetRuntimeEntry); |
215 __ popq(RAX); // Get Code object. | 214 __ popq(RAX); // Get Code object. |
216 __ popq(R10); // Restore arguments descriptor array. | 215 __ popq(R10); // Restore arguments descriptor array. |
217 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); | 216 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); |
218 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 217 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
219 __ LeaveFrame(); | 218 __ LeaveFrame(); |
220 __ jmp(RAX); | 219 __ jmp(RAX); |
221 __ int3(); | 220 __ int3(); |
(...skipping 28 matching lines...) Expand all Loading... |
250 } | 249 } |
251 | 250 |
252 | 251 |
253 // Input parameters: | 252 // Input parameters: |
254 // RBX: ic-data. | 253 // RBX: ic-data. |
255 // R10: arguments descriptor array. | 254 // R10: arguments descriptor array. |
256 // Note: The receiver object is the first argument to the function being | 255 // Note: The receiver object is the first argument to the function being |
257 // called, the stub accesses the receiver from this location directly | 256 // called, the stub accesses the receiver from this location directly |
258 // when trying to resolve the call. | 257 // when trying to resolve the call. |
259 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { | 258 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { |
260 AssemblerMacros::EnterStubFrame(assembler); | 259 __ EnterStubFrame(); |
261 | 260 |
262 const Immediate& raw_null = | 261 const Immediate& raw_null = |
263 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 262 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
264 __ pushq(raw_null); // Space for the return value. | 263 __ pushq(raw_null); // Space for the return value. |
265 | 264 |
266 // Push the receiver as an argument. Load the smi-tagged argument | 265 // Push the receiver as an argument. Load the smi-tagged argument |
267 // count into R13 to index the receiver in the stack. There are | 266 // count into R13 to index the receiver in the stack. There are |
268 // three words (null, stub's pc marker, saved fp) above the return | 267 // three words (null, stub's pc marker, saved fp) above the return |
269 // address. | 268 // address. |
270 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 269 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 // Restore result into RBX. | 379 // Restore result into RBX. |
381 __ movq(RBX, Address(RBP, -1 * kWordSize)); | 380 __ movq(RBX, Address(RBP, -1 * kWordSize)); |
382 } | 381 } |
383 // Code above cannot cause GC. | 382 // Code above cannot cause GC. |
384 __ LeaveFrame(); | 383 __ LeaveFrame(); |
385 __ movq(RBP, RAX); | 384 __ movq(RBP, RAX); |
386 | 385 |
387 // Frame is fully rewritten at this point and it is safe to perform a GC. | 386 // Frame is fully rewritten at this point and it is safe to perform a GC. |
388 // Materialize any objects that were deferred by FillFrame because they | 387 // Materialize any objects that were deferred by FillFrame because they |
389 // require allocation. | 388 // require allocation. |
390 AssemblerMacros::EnterStubFrame(assembler); | 389 __ EnterStubFrame(); |
391 if (preserve_rax) { | 390 if (preserve_rax) { |
392 __ pushq(RBX); // Preserve result, it will be GC-d here. | 391 __ pushq(RBX); // Preserve result, it will be GC-d here. |
393 } | 392 } |
394 __ CallRuntime(kDeoptimizeMaterializeDoublesRuntimeEntry); | 393 __ CallRuntime(kDeoptimizeMaterializeDoublesRuntimeEntry); |
395 if (preserve_rax) { | 394 if (preserve_rax) { |
396 __ popq(RAX); // Restore result. | 395 __ popq(RAX); // Restore result. |
397 } | 396 } |
398 __ LeaveFrame(); | 397 __ LeaveFrame(); |
399 | 398 |
400 __ ret(); | 399 __ ret(); |
(...skipping 11 matching lines...) Expand all Loading... |
412 GenerateDeoptimizationSequence(assembler, true); // Preserve RAX. | 411 GenerateDeoptimizationSequence(assembler, true); // Preserve RAX. |
413 } | 412 } |
414 | 413 |
415 | 414 |
416 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { | 415 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { |
417 GenerateDeoptimizationSequence(assembler, false); // Don't preserve RAX. | 416 GenerateDeoptimizationSequence(assembler, false); // Don't preserve RAX. |
418 } | 417 } |
419 | 418 |
420 | 419 |
421 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { | 420 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { |
422 AssemblerMacros::EnterStubFrame(assembler); | 421 __ EnterStubFrame(); |
423 // Load the receiver into RAX. The argument count in the arguments | 422 // Load the receiver into RAX. The argument count in the arguments |
424 // descriptor in R10 is a smi. | 423 // descriptor in R10 is a smi. |
425 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 424 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
426 // Two words (saved fp, stub's pc marker) in the stack above the return | 425 // Two words (saved fp, stub's pc marker) in the stack above the return |
427 // address. | 426 // address. |
428 __ movq(RAX, Address(RSP, RAX, TIMES_4, 2 * kWordSize)); | 427 __ movq(RAX, Address(RSP, RAX, TIMES_4, 2 * kWordSize)); |
429 // Preserve IC data and arguments descriptor. | 428 // Preserve IC data and arguments descriptor. |
430 __ pushq(RBX); | 429 __ pushq(RBX); |
431 __ pushq(R10); | 430 __ pushq(R10); |
432 | 431 |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
570 // RAX: new object. | 569 // RAX: new object. |
571 // R10: Array length as Smi (preserved for the caller.) | 570 // R10: Array length as Smi (preserved for the caller.) |
572 __ ret(); | 571 __ ret(); |
573 } | 572 } |
574 | 573 |
575 // Unable to allocate the array using the fast inline code, just call | 574 // Unable to allocate the array using the fast inline code, just call |
576 // into the runtime. | 575 // into the runtime. |
577 __ Bind(&slow_case); | 576 __ Bind(&slow_case); |
578 // Create a stub frame as we are pushing some objects on the stack before | 577 // Create a stub frame as we are pushing some objects on the stack before |
579 // calling into the runtime. | 578 // calling into the runtime. |
580 AssemblerMacros::EnterStubFrame(assembler); | 579 __ EnterStubFrame(); |
581 __ pushq(raw_null); // Setup space on stack for return value. | 580 __ pushq(raw_null); // Setup space on stack for return value. |
582 __ pushq(R10); // Array length as Smi. | 581 __ pushq(R10); // Array length as Smi. |
583 __ pushq(RBX); // Element type. | 582 __ pushq(RBX); // Element type. |
584 __ CallRuntime(kAllocateArrayRuntimeEntry); | 583 __ CallRuntime(kAllocateArrayRuntimeEntry); |
585 __ popq(RAX); // Pop element type argument. | 584 __ popq(RAX); // Pop element type argument. |
586 __ popq(R10); // Pop array length argument. | 585 __ popq(R10); // Pop array length argument. |
587 __ popq(RAX); // Pop return value from return slot. | 586 __ popq(RAX); // Pop return value from return slot. |
588 __ LeaveFrame(); | 587 __ LeaveFrame(); |
589 __ ret(); | 588 __ ret(); |
590 } | 589 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
626 __ movq(CTX, FieldAddress(R13, Closure::context_offset())); | 625 __ movq(CTX, FieldAddress(R13, Closure::context_offset())); |
627 | 626 |
628 // Load closure function code in RAX. | 627 // Load closure function code in RAX. |
629 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); | 628 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); |
630 __ cmpq(RAX, raw_null); | 629 __ cmpq(RAX, raw_null); |
631 Label function_compiled; | 630 Label function_compiled; |
632 __ j(NOT_EQUAL, &function_compiled, Assembler::kNearJump); | 631 __ j(NOT_EQUAL, &function_compiled, Assembler::kNearJump); |
633 | 632 |
634 // Create a stub frame as we are pushing some objects on the stack before | 633 // Create a stub frame as we are pushing some objects on the stack before |
635 // calling into the runtime. | 634 // calling into the runtime. |
636 AssemblerMacros::EnterStubFrame(assembler); | 635 __ EnterStubFrame(); |
637 | 636 |
638 __ pushq(R10); // Preserve arguments descriptor array. | 637 __ pushq(R10); // Preserve arguments descriptor array. |
639 __ pushq(RBX); // Preserve read-only function object argument. | 638 __ pushq(RBX); // Preserve read-only function object argument. |
640 __ CallRuntime(kCompileFunctionRuntimeEntry); | 639 __ CallRuntime(kCompileFunctionRuntimeEntry); |
641 __ popq(RBX); // Restore read-only function object argument in RBX. | 640 __ popq(RBX); // Restore read-only function object argument in RBX. |
642 __ popq(R10); // Restore arguments descriptor array. | 641 __ popq(R10); // Restore arguments descriptor array. |
643 // Restore RAX. | 642 // Restore RAX. |
644 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); | 643 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); |
645 | 644 |
646 // Remove the stub frame as we are about to jump to the closure function. | 645 // Remove the stub frame as we are about to jump to the closure function. |
(...skipping 11 matching lines...) Expand all Loading... |
658 __ Bind(¬_closure); | 657 __ Bind(¬_closure); |
659 // Call runtime to attempt to resolve and invoke a call method on a | 658 // Call runtime to attempt to resolve and invoke a call method on a |
660 // non-closure object, passing the non-closure object and its arguments array, | 659 // non-closure object, passing the non-closure object and its arguments array, |
661 // returning here. | 660 // returning here. |
662 // If no call method exists, throw a NoSuchMethodError. | 661 // If no call method exists, throw a NoSuchMethodError. |
663 // R13: non-closure object. | 662 // R13: non-closure object. |
664 // R10: arguments descriptor array. | 663 // R10: arguments descriptor array. |
665 | 664 |
666 // Create a stub frame as we are pushing some objects on the stack before | 665 // Create a stub frame as we are pushing some objects on the stack before |
667 // calling into the runtime. | 666 // calling into the runtime. |
668 AssemblerMacros::EnterStubFrame(assembler); | 667 __ EnterStubFrame(); |
669 | 668 |
670 __ pushq(raw_null); // Setup space on stack for result from call. | 669 __ pushq(raw_null); // Setup space on stack for result from call. |
671 __ pushq(R10); // Arguments descriptor. | 670 __ pushq(R10); // Arguments descriptor. |
672 // Load smi-tagged arguments array length, including the non-closure. | 671 // Load smi-tagged arguments array length, including the non-closure. |
673 __ movq(R10, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 672 __ movq(R10, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
674 // See stack layout below explaining "wordSize * 5" offset. | 673 // See stack layout below explaining "wordSize * 5" offset. |
675 PushArgumentsArray(assembler, (kWordSize * 5)); | 674 PushArgumentsArray(assembler, (kWordSize * 5)); |
676 | 675 |
677 // Stack: | 676 // Stack: |
678 // TOS + 0: Argument array. | 677 // TOS + 0: Argument array. |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
921 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); | 920 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); |
922 } | 921 } |
923 | 922 |
924 // Done allocating and initializing the context. | 923 // Done allocating and initializing the context. |
925 // RAX: new object. | 924 // RAX: new object. |
926 __ ret(); | 925 __ ret(); |
927 | 926 |
928 __ Bind(&slow_case); | 927 __ Bind(&slow_case); |
929 } | 928 } |
930 // Create a stub frame. | 929 // Create a stub frame. |
931 AssemblerMacros::EnterStubFrame(assembler); | 930 __ EnterStubFrame(); |
932 __ pushq(raw_null); // Setup space on stack for the return value. | 931 __ pushq(raw_null); // Setup space on stack for the return value. |
933 __ SmiTag(R10); | 932 __ SmiTag(R10); |
934 __ pushq(R10); // Push number of context variables. | 933 __ pushq(R10); // Push number of context variables. |
935 __ CallRuntime(kAllocateContextRuntimeEntry); // Allocate context. | 934 __ CallRuntime(kAllocateContextRuntimeEntry); // Allocate context. |
936 __ popq(RAX); // Pop number of context variables argument. | 935 __ popq(RAX); // Pop number of context variables argument. |
937 __ popq(RAX); // Pop the new context object. | 936 __ popq(RAX); // Pop the new context object. |
938 // RAX: new object | 937 // RAX: new object |
939 // Restore the frame pointer. | 938 // Restore the frame pointer. |
940 __ LeaveFrame(); | 939 __ LeaveFrame(); |
941 __ ret(); | 940 __ ret(); |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1140 __ addq(RAX, Immediate(kHeapObjectTag)); | 1139 __ addq(RAX, Immediate(kHeapObjectTag)); |
1141 __ ret(); | 1140 __ ret(); |
1142 | 1141 |
1143 __ Bind(&slow_case); | 1142 __ Bind(&slow_case); |
1144 } | 1143 } |
1145 if (is_cls_parameterized) { | 1144 if (is_cls_parameterized) { |
1146 __ movq(RAX, Address(RSP, kObjectTypeArgumentsOffset)); | 1145 __ movq(RAX, Address(RSP, kObjectTypeArgumentsOffset)); |
1147 __ movq(RDX, Address(RSP, kInstantiatorTypeArgumentsOffset)); | 1146 __ movq(RDX, Address(RSP, kInstantiatorTypeArgumentsOffset)); |
1148 } | 1147 } |
1149 // Create a stub frame. | 1148 // Create a stub frame. |
1150 AssemblerMacros::EnterStubFrame(assembler); | 1149 __ EnterStubFrame(); |
1151 __ pushq(raw_null); // Setup space on stack for return value. | 1150 __ pushq(raw_null); // Setup space on stack for return value. |
1152 __ PushObject(cls); // Push class of object to be allocated. | 1151 __ PushObject(cls); // Push class of object to be allocated. |
1153 if (is_cls_parameterized) { | 1152 if (is_cls_parameterized) { |
1154 __ pushq(RAX); // Push type arguments of object to be allocated. | 1153 __ pushq(RAX); // Push type arguments of object to be allocated. |
1155 __ pushq(RDX); // Push type arguments of instantiator. | 1154 __ pushq(RDX); // Push type arguments of instantiator. |
1156 } else { | 1155 } else { |
1157 __ pushq(raw_null); // Push null type arguments. | 1156 __ pushq(raw_null); // Push null type arguments. |
1158 __ pushq(Immediate(Smi::RawValue(StubCode::kNoInstantiator))); | 1157 __ pushq(Immediate(Smi::RawValue(StubCode::kNoInstantiator))); |
1159 } | 1158 } |
1160 __ CallRuntime(kAllocateObjectRuntimeEntry); // Allocate object. | 1159 __ CallRuntime(kAllocateObjectRuntimeEntry); // Allocate object. |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1282 | 1281 |
1283 __ Bind(&slow_case); | 1282 __ Bind(&slow_case); |
1284 } | 1283 } |
1285 if (has_type_arguments) { | 1284 if (has_type_arguments) { |
1286 __ movq(RCX, Address(RSP, kTypeArgumentsOffset)); | 1285 __ movq(RCX, Address(RSP, kTypeArgumentsOffset)); |
1287 } | 1286 } |
1288 if (is_implicit_instance_closure) { | 1287 if (is_implicit_instance_closure) { |
1289 __ movq(RAX, Address(RSP, kReceiverOffset)); | 1288 __ movq(RAX, Address(RSP, kReceiverOffset)); |
1290 } | 1289 } |
1291 // Create the stub frame. | 1290 // Create the stub frame. |
1292 AssemblerMacros::EnterStubFrame(assembler); | 1291 __ EnterStubFrame(); |
1293 __ pushq(raw_null); // Setup space on stack for the return value. | 1292 __ pushq(raw_null); // Setup space on stack for the return value. |
1294 __ PushObject(func); | 1293 __ PushObject(func); |
1295 if (is_implicit_static_closure) { | 1294 if (is_implicit_static_closure) { |
1296 __ CallRuntime(kAllocateImplicitStaticClosureRuntimeEntry); | 1295 __ CallRuntime(kAllocateImplicitStaticClosureRuntimeEntry); |
1297 } else { | 1296 } else { |
1298 if (is_implicit_instance_closure) { | 1297 if (is_implicit_instance_closure) { |
1299 __ pushq(RAX); // Receiver. | 1298 __ pushq(RAX); // Receiver. |
1300 } | 1299 } |
1301 if (has_type_arguments) { | 1300 if (has_type_arguments) { |
1302 __ pushq(RCX); // Push type arguments of closure to be allocated. | 1301 __ pushq(RCX); // Push type arguments of closure to be allocated. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1334 // R10 : arguments descriptor array. | 1333 // R10 : arguments descriptor array. |
1335 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { | 1334 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { |
1336 // The target function was not found, so invoke method | 1335 // The target function was not found, so invoke method |
1337 // "dynamic noSuchMethod(InvocationMirror invocation)". | 1336 // "dynamic noSuchMethod(InvocationMirror invocation)". |
1338 const Immediate& raw_null = | 1337 const Immediate& raw_null = |
1339 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1338 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
1340 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 1339 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
1341 __ movq(RAX, Address(RBP, R13, TIMES_4, kWordSize)); // Get receiver. | 1340 __ movq(RAX, Address(RBP, R13, TIMES_4, kWordSize)); // Get receiver. |
1342 | 1341 |
1343 // Create a stub frame. | 1342 // Create a stub frame. |
1344 AssemblerMacros::EnterStubFrame(assembler); | 1343 __ EnterStubFrame(); |
1345 | 1344 |
1346 __ pushq(raw_null); // Setup space on stack for result from noSuchMethod. | 1345 __ pushq(raw_null); // Setup space on stack for result from noSuchMethod. |
1347 __ pushq(RAX); // Receiver. | 1346 __ pushq(RAX); // Receiver. |
1348 __ pushq(RBX); // IC data array. | 1347 __ pushq(RBX); // IC data array. |
1349 __ pushq(R10); // Arguments descriptor array. | 1348 __ pushq(R10); // Arguments descriptor array. |
1350 | 1349 |
1351 __ movq(R10, R13); // Smi-tagged arguments array length. | 1350 __ movq(R10, R13); // Smi-tagged arguments array length. |
1352 // See stack layout below explaining "wordSize * 10" offset. | 1351 // See stack layout below explaining "wordSize * 10" offset. |
1353 PushArgumentsArray(assembler, (kWordSize * 10)); | 1352 PushArgumentsArray(assembler, (kWordSize * 10)); |
1354 | 1353 |
(...skipping 23 matching lines...) Expand all Loading... |
1378 __ LeaveFrame(); | 1377 __ LeaveFrame(); |
1379 __ ret(); | 1378 __ ret(); |
1380 } | 1379 } |
1381 | 1380 |
1382 | 1381 |
1383 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { | 1382 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { |
1384 Register argdesc_reg = R10; | 1383 Register argdesc_reg = R10; |
1385 Register ic_reg = RBX; | 1384 Register ic_reg = RBX; |
1386 Register func_reg = RDI; | 1385 Register func_reg = RDI; |
1387 if (FLAG_trace_optimized_ic_calls) { | 1386 if (FLAG_trace_optimized_ic_calls) { |
1388 AssemblerMacros::EnterStubFrame(assembler); | 1387 __ EnterStubFrame(); |
1389 __ pushq(func_reg); // Preserve | 1388 __ pushq(func_reg); // Preserve |
1390 __ pushq(argdesc_reg); // Preserve. | 1389 __ pushq(argdesc_reg); // Preserve. |
1391 __ pushq(ic_reg); // Preserve. | 1390 __ pushq(ic_reg); // Preserve. |
1392 __ pushq(ic_reg); // Argument. | 1391 __ pushq(ic_reg); // Argument. |
1393 __ pushq(func_reg); // Argument. | 1392 __ pushq(func_reg); // Argument. |
1394 __ CallRuntime(kTraceICCallRuntimeEntry); | 1393 __ CallRuntime(kTraceICCallRuntimeEntry); |
1395 __ popq(RAX); // Discard argument; | 1394 __ popq(RAX); // Discard argument; |
1396 __ popq(RAX); // Discard argument; | 1395 __ popq(RAX); // Discard argument; |
1397 __ popq(ic_reg); // Restore. | 1396 __ popq(ic_reg); // Restore. |
1398 __ popq(argdesc_reg); // Restore. | 1397 __ popq(argdesc_reg); // Restore. |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1515 __ cmpq(R13, Immediate(Smi::RawValue(kIllegalCid))); // Done? | 1514 __ cmpq(R13, Immediate(Smi::RawValue(kIllegalCid))); // Done? |
1516 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); | 1515 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); |
1517 | 1516 |
1518 // IC miss. | 1517 // IC miss. |
1519 const Immediate& raw_null = | 1518 const Immediate& raw_null = |
1520 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1519 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
1521 // Compute address of arguments (first read number of arguments from | 1520 // Compute address of arguments (first read number of arguments from |
1522 // arguments descriptor array and then compute address on the stack). | 1521 // arguments descriptor array and then compute address on the stack). |
1523 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 1522 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
1524 __ leaq(RAX, Address(RSP, RAX, TIMES_4, 0)); // RAX is Smi. | 1523 __ leaq(RAX, Address(RSP, RAX, TIMES_4, 0)); // RAX is Smi. |
1525 AssemblerMacros::EnterStubFrame(assembler); | 1524 __ EnterStubFrame(); |
1526 __ pushq(R10); // Preserve arguments descriptor array. | 1525 __ pushq(R10); // Preserve arguments descriptor array. |
1527 __ pushq(RBX); // Preserve IC data object. | 1526 __ pushq(RBX); // Preserve IC data object. |
1528 __ pushq(raw_null); // Setup space on stack for result (target code object). | 1527 __ pushq(raw_null); // Setup space on stack for result (target code object). |
1529 // Push call arguments. | 1528 // Push call arguments. |
1530 for (intptr_t i = 0; i < num_args; i++) { | 1529 for (intptr_t i = 0; i < num_args; i++) { |
1531 __ movq(RCX, Address(RAX, -kWordSize * i)); | 1530 __ movq(RCX, Address(RAX, -kWordSize * i)); |
1532 __ pushq(RCX); | 1531 __ pushq(RCX); |
1533 } | 1532 } |
1534 __ pushq(RBX); // Pass IC data object. | 1533 __ pushq(RBX); // Pass IC data object. |
1535 __ pushq(R10); // Pass arguments descriptor array. | 1534 __ pushq(R10); // Pass arguments descriptor array. |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1663 // that does not check/count function invocations. | 1662 // that does not check/count function invocations. |
1664 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) { | 1663 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) { |
1665 GenerateNArgsCheckInlineCacheStub(assembler, 1); | 1664 GenerateNArgsCheckInlineCacheStub(assembler, 1); |
1666 } | 1665 } |
1667 | 1666 |
1668 // R10: Arguments descriptor array. | 1667 // R10: Arguments descriptor array. |
1669 // TOS(0): return address (Dart code). | 1668 // TOS(0): return address (Dart code). |
1670 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { | 1669 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { |
1671 const Immediate& raw_null = | 1670 const Immediate& raw_null = |
1672 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1671 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
1673 AssemblerMacros::EnterStubFrame(assembler); | 1672 __ EnterStubFrame(); |
1674 __ pushq(R10); // Preserve arguments descriptor. | 1673 __ pushq(R10); // Preserve arguments descriptor. |
1675 __ pushq(raw_null); // Room for result. | 1674 __ pushq(raw_null); // Room for result. |
1676 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); | 1675 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); |
1677 __ popq(RAX); // Code object. | 1676 __ popq(RAX); // Code object. |
1678 __ popq(R10); // Restore arguments descriptor. | 1677 __ popq(R10); // Restore arguments descriptor. |
1679 __ LeaveFrame(); | 1678 __ LeaveFrame(); |
1680 | 1679 |
1681 // Now call the static function. The breakpoint handler function | 1680 // Now call the static function. The breakpoint handler function |
1682 // ensures that the call target is compiled. | 1681 // ensures that the call target is compiled. |
1683 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); | 1682 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); |
1684 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 1683 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
1685 __ jmp(RBX); | 1684 __ jmp(RBX); |
1686 } | 1685 } |
1687 | 1686 |
1688 | 1687 |
1689 // TOS(0): return address (Dart code). | 1688 // TOS(0): return address (Dart code). |
1690 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { | 1689 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { |
1691 AssemblerMacros::EnterStubFrame(assembler); | 1690 __ EnterStubFrame(); |
1692 __ pushq(RAX); | 1691 __ pushq(RAX); |
1693 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry); | 1692 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry); |
1694 __ popq(RAX); | 1693 __ popq(RAX); |
1695 __ LeaveFrame(); | 1694 __ LeaveFrame(); |
1696 | 1695 |
1697 __ popq(R11); // discard return address of call to this stub. | 1696 __ popq(R11); // discard return address of call to this stub. |
1698 __ LeaveFrame(); | 1697 __ LeaveFrame(); |
1699 __ ret(); | 1698 __ ret(); |
1700 } | 1699 } |
1701 | 1700 |
1702 | 1701 |
1703 // RBX: Inline cache data array. | 1702 // RBX: Inline cache data array. |
1704 // R10: Arguments descriptor array. | 1703 // R10: Arguments descriptor array. |
1705 // TOS(0): return address (Dart code). | 1704 // TOS(0): return address (Dart code). |
1706 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { | 1705 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { |
1707 AssemblerMacros::EnterStubFrame(assembler); | 1706 __ EnterStubFrame(); |
1708 __ pushq(RBX); | 1707 __ pushq(RBX); |
1709 __ pushq(R10); | 1708 __ pushq(R10); |
1710 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry); | 1709 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry); |
1711 __ popq(R10); | 1710 __ popq(R10); |
1712 __ popq(RBX); | 1711 __ popq(RBX); |
1713 __ LeaveFrame(); | 1712 __ LeaveFrame(); |
1714 | 1713 |
1715 // Find out which dispatch stub to call. | 1714 // Find out which dispatch stub to call. |
1716 Label test_two, test_three, test_four; | 1715 Label test_two, test_three, test_four; |
1717 __ movq(RCX, FieldAddress(RBX, ICData::num_args_tested_offset())); | 1716 __ movq(RCX, FieldAddress(RBX, ICData::num_args_tested_offset())); |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1963 __ Bind(¬_smi); | 1962 __ Bind(¬_smi); |
1964 __ LoadClassId(RAX, RAX); | 1963 __ LoadClassId(RAX, RAX); |
1965 __ SmiTag(RAX); | 1964 __ SmiTag(RAX); |
1966 __ ret(); | 1965 __ ret(); |
1967 | 1966 |
1968 __ Bind(&update_ic_data); | 1967 __ Bind(&update_ic_data); |
1969 | 1968 |
1970 // RCX: ICData | 1969 // RCX: ICData |
1971 __ movq(RAX, Address(RSP, 1 * kWordSize)); | 1970 __ movq(RAX, Address(RSP, 1 * kWordSize)); |
1972 __ movq(R13, Address(RSP, 2 * kWordSize)); | 1971 __ movq(R13, Address(RSP, 2 * kWordSize)); |
1973 AssemblerMacros::EnterStubFrame(assembler); | 1972 __ EnterStubFrame(); |
1974 __ pushq(R13); // arg 0 | 1973 __ pushq(R13); // arg 0 |
1975 __ pushq(RAX); // arg 1 | 1974 __ pushq(RAX); // arg 1 |
1976 __ PushObject(Symbols::EqualOperator()); // Target's name. | 1975 __ PushObject(Symbols::EqualOperator()); // Target's name. |
1977 __ pushq(RBX); // ICData | 1976 __ pushq(RBX); // ICData |
1978 __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry); | 1977 __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry); |
1979 __ Drop(4); | 1978 __ Drop(4); |
1980 __ LeaveFrame(); | 1979 __ LeaveFrame(); |
1981 | 1980 |
1982 __ jmp(&compute_result, Assembler::kNearJump); | 1981 __ jmp(&compute_result, Assembler::kNearJump); |
1983 } | 1982 } |
1984 | 1983 |
1985 // Calls to the runtime to optimize the given function. | 1984 // Calls to the runtime to optimize the given function. |
1986 // RDI: function to be reoptimized. | 1985 // RDI: function to be reoptimized. |
1987 // R10: argument descriptor (preserved). | 1986 // R10: argument descriptor (preserved). |
1988 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { | 1987 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { |
1989 const Immediate& raw_null = | 1988 const Immediate& raw_null = |
1990 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1989 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
1991 AssemblerMacros::EnterStubFrame(assembler); | 1990 __ EnterStubFrame(); |
1992 __ pushq(R10); | 1991 __ pushq(R10); |
1993 __ pushq(raw_null); // Setup space on stack for return value. | 1992 __ pushq(raw_null); // Setup space on stack for return value. |
1994 __ pushq(RDI); | 1993 __ pushq(RDI); |
1995 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry); | 1994 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry); |
1996 __ popq(RAX); // Disard argument. | 1995 __ popq(RAX); // Disard argument. |
1997 __ popq(RAX); // Get Code object. | 1996 __ popq(RAX); // Get Code object. |
1998 __ popq(R10); // Restore argument descriptor. | 1997 __ popq(R10); // Restore argument descriptor. |
1999 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); | 1998 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); |
2000 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 1999 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
2001 __ LeaveFrame(); | 2000 __ LeaveFrame(); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2075 __ cmpq(left, right); | 2074 __ cmpq(left, right); |
2076 __ Bind(&done); | 2075 __ Bind(&done); |
2077 __ popq(right); | 2076 __ popq(right); |
2078 __ popq(left); | 2077 __ popq(left); |
2079 __ ret(); | 2078 __ ret(); |
2080 } | 2079 } |
2081 | 2080 |
2082 } // namespace dart | 2081 } // namespace dart |
2083 | 2082 |
2084 #endif // defined TARGET_ARCH_X64 | 2083 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |