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 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 __ ret(); | 254 __ ret(); |
255 } | 255 } |
256 | 256 |
257 | 257 |
258 // Input parameters: | 258 // Input parameters: |
259 // R10: arguments descriptor array. | 259 // R10: arguments descriptor array. |
260 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 260 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
261 __ EnterStubFrame(); | 261 __ EnterStubFrame(); |
262 __ pushq(R10); // Preserve arguments descriptor array. | 262 __ pushq(R10); // Preserve arguments descriptor array. |
263 // Setup space on stack for return value. | 263 // Setup space on stack for return value. |
264 __ PushObject(Object::null_object()); | 264 __ pushq(Immediate(0)); |
265 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); | 265 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); |
266 __ popq(CODE_REG); // Get Code object result. | 266 __ popq(CODE_REG); // Get Code object result. |
267 __ popq(R10); // Restore arguments descriptor array. | 267 __ popq(R10); // Restore arguments descriptor array. |
268 // Remove the stub frame as we are about to jump to the dart function. | 268 // Remove the stub frame as we are about to jump to the dart function. |
269 __ LeaveStubFrame(); | 269 __ LeaveStubFrame(); |
270 | 270 |
271 __ movq(RBX, FieldAddress(CODE_REG, Code::entry_point_offset())); | 271 __ movq(RBX, FieldAddress(CODE_REG, Code::entry_point_offset())); |
272 __ jmp(RBX); | 272 __ jmp(RBX); |
273 } | 273 } |
274 | 274 |
275 | 275 |
276 // Called from a static call only when an invalid code has been entered | 276 // Called from a static call only when an invalid code has been entered |
277 // (invalid because its function was optimized or deoptimized). | 277 // (invalid because its function was optimized or deoptimized). |
278 // R10: arguments descriptor array. | 278 // R10: arguments descriptor array. |
279 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { | 279 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { |
280 // Load code pointer to this stub from the thread: | 280 // Load code pointer to this stub from the thread: |
281 // The one that is passed in, is not correct - it points to the code object | 281 // The one that is passed in, is not correct - it points to the code object |
282 // that needs to be replaced. | 282 // that needs to be replaced. |
283 __ movq(CODE_REG, Address(THR, Thread::fix_callers_target_code_offset())); | 283 __ movq(CODE_REG, Address(THR, Thread::fix_callers_target_code_offset())); |
284 __ EnterStubFrame(); | 284 __ EnterStubFrame(); |
285 __ pushq(R10); // Preserve arguments descriptor array. | 285 __ pushq(R10); // Preserve arguments descriptor array. |
286 // Setup space on stack for return value. | 286 // Setup space on stack for return value. |
287 __ PushObject(Object::null_object()); | 287 __ pushq(Immediate(0)); |
288 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); | 288 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); |
289 __ popq(CODE_REG); // Get Code object. | 289 __ popq(CODE_REG); // Get Code object. |
290 __ popq(R10); // Restore arguments descriptor array. | 290 __ popq(R10); // Restore arguments descriptor array. |
291 __ movq(RAX, FieldAddress(CODE_REG, Code::entry_point_offset())); | 291 __ movq(RAX, FieldAddress(CODE_REG, Code::entry_point_offset())); |
292 __ LeaveStubFrame(); | 292 __ LeaveStubFrame(); |
293 __ jmp(RAX); | 293 __ jmp(RAX); |
294 __ int3(); | 294 __ int3(); |
295 } | 295 } |
296 | 296 |
297 | 297 |
298 // Called from object allocate instruction when the allocation stub has been | 298 // Called from object allocate instruction when the allocation stub has been |
299 // disabled. | 299 // disabled. |
300 void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) { | 300 void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) { |
301 // Load code pointer to this stub from the thread: | 301 // Load code pointer to this stub from the thread: |
302 // The one that is passed in, is not correct - it points to the code object | 302 // The one that is passed in, is not correct - it points to the code object |
303 // that needs to be replaced. | 303 // that needs to be replaced. |
304 __ movq(CODE_REG, Address(THR, Thread::fix_allocation_stub_code_offset())); | 304 __ movq(CODE_REG, Address(THR, Thread::fix_allocation_stub_code_offset())); |
305 __ EnterStubFrame(); | 305 __ EnterStubFrame(); |
306 // Setup space on stack for return value. | 306 // Setup space on stack for return value. |
307 __ PushObject(Object::null_object()); | 307 __ pushq(Immediate(0)); |
308 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); | 308 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); |
309 __ popq(CODE_REG); // Get Code object. | 309 __ popq(CODE_REG); // Get Code object. |
310 __ movq(RAX, FieldAddress(CODE_REG, Code::entry_point_offset())); | 310 __ movq(RAX, FieldAddress(CODE_REG, Code::entry_point_offset())); |
311 __ LeaveStubFrame(); | 311 __ LeaveStubFrame(); |
312 __ jmp(RAX); | 312 __ jmp(RAX); |
313 __ int3(); | 313 __ int3(); |
314 } | 314 } |
315 | 315 |
316 | 316 |
317 // Input parameters: | 317 // Input parameters: |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
498 __ Comment("NoSuchMethodDispatch"); | 498 __ Comment("NoSuchMethodDispatch"); |
499 // When lazily generated invocation dispatchers are disabled, the | 499 // When lazily generated invocation dispatchers are disabled, the |
500 // miss-handler may return null. | 500 // miss-handler may return null. |
501 __ CompareObject(RAX, Object::null_object()); | 501 __ CompareObject(RAX, Object::null_object()); |
502 __ j(NOT_EQUAL, call_target_function); | 502 __ j(NOT_EQUAL, call_target_function); |
503 __ EnterStubFrame(); | 503 __ EnterStubFrame(); |
504 // Load the receiver. | 504 // Load the receiver. |
505 __ movq(RDI, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 505 __ movq(RDI, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
506 __ movq(RAX, Address( | 506 __ movq(RAX, Address( |
507 RBP, RDI, TIMES_HALF_WORD_SIZE, kParamEndSlotFromFp * kWordSize)); | 507 RBP, RDI, TIMES_HALF_WORD_SIZE, kParamEndSlotFromFp * kWordSize)); |
508 __ PushObject(Object::null_object()); // Setup space on stack for result. | 508 __ pushq(Immediate(0)); // Setup space on stack for result. |
509 __ pushq(RAX); // Receiver. | 509 __ pushq(RAX); // Receiver. |
510 __ pushq(RBX); // ICData/MegamorphicCache. | 510 __ pushq(RBX); // ICData/MegamorphicCache. |
511 __ pushq(R10); // Arguments descriptor array. | 511 __ pushq(R10); // Arguments descriptor array. |
512 __ movq(R10, RDI); | 512 __ movq(R10, RDI); |
513 // EDX: Smi-tagged arguments array length. | 513 // EDX: Smi-tagged arguments array length. |
514 PushArgumentsArray(assembler); | 514 PushArgumentsArray(assembler); |
515 const intptr_t kNumArgs = 4; | 515 const intptr_t kNumArgs = 4; |
516 __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs); | 516 __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs); |
517 __ Drop(4); | 517 __ Drop(4); |
518 __ popq(RAX); // Return value. | 518 __ popq(RAX); // Return value. |
519 __ LeaveStubFrame(); | 519 __ LeaveStubFrame(); |
520 __ ret(); | 520 __ ret(); |
521 } | 521 } |
522 | 522 |
523 | 523 |
524 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { | 524 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { |
525 __ EnterStubFrame(); | 525 __ EnterStubFrame(); |
526 // Load the receiver into RAX. The argument count in the arguments | 526 // Load the receiver into RAX. The argument count in the arguments |
527 // descriptor in R10 is a smi. | 527 // descriptor in R10 is a smi. |
528 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 528 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
529 // Three words (saved pp, saved fp, stub's pc marker) | 529 // Three words (saved pp, saved fp, stub's pc marker) |
530 // in the stack above the return address. | 530 // in the stack above the return address. |
531 __ movq(RAX, Address(RSP, RAX, TIMES_4, | 531 __ movq(RAX, Address(RSP, RAX, TIMES_4, |
532 kSavedAboveReturnAddress * kWordSize)); | 532 kSavedAboveReturnAddress * kWordSize)); |
533 // Preserve IC data and arguments descriptor. | 533 // Preserve IC data and arguments descriptor. |
534 __ pushq(RBX); | 534 __ pushq(RBX); |
535 __ pushq(R10); | 535 __ pushq(R10); |
536 | 536 |
537 // Space for the result of the runtime call. | 537 // Space for the result of the runtime call. |
538 __ PushObject(Object::null_object()); | 538 __ pushq(Immediate(0)); |
539 __ pushq(RAX); // Receiver. | 539 __ pushq(RAX); // Receiver. |
540 __ pushq(RBX); // IC data. | 540 __ pushq(RBX); // IC data. |
541 __ pushq(R10); // Arguments descriptor. | 541 __ pushq(R10); // Arguments descriptor. |
542 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); | 542 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); |
543 // Discard arguments. | 543 // Discard arguments. |
544 __ popq(RAX); | 544 __ popq(RAX); |
545 __ popq(RAX); | 545 __ popq(RAX); |
546 __ popq(RAX); | 546 __ popq(RAX); |
547 __ popq(RAX); // Return value from the runtime call (function). | 547 __ popq(RAX); // Return value from the runtime call (function). |
548 __ popq(R10); // Restore arguments descriptor. | 548 __ popq(R10); // Restore arguments descriptor. |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
675 __ Bind(&done); | 675 __ Bind(&done); |
676 __ ret(); // returns the newly allocated object in RAX. | 676 __ ret(); // returns the newly allocated object in RAX. |
677 | 677 |
678 // Unable to allocate the array using the fast inline code, just call | 678 // Unable to allocate the array using the fast inline code, just call |
679 // into the runtime. | 679 // into the runtime. |
680 __ Bind(&slow_case); | 680 __ Bind(&slow_case); |
681 // Create a stub frame as we are pushing some objects on the stack before | 681 // Create a stub frame as we are pushing some objects on the stack before |
682 // calling into the runtime. | 682 // calling into the runtime. |
683 __ EnterStubFrame(); | 683 __ EnterStubFrame(); |
684 // Setup space on stack for return value. | 684 // Setup space on stack for return value. |
685 __ PushObject(Object::null_object()); | 685 __ pushq(Immediate(0)); |
686 __ pushq(R10); // Array length as Smi. | 686 __ pushq(R10); // Array length as Smi. |
687 __ pushq(RBX); // Element type. | 687 __ pushq(RBX); // Element type. |
688 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); | 688 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); |
689 __ popq(RAX); // Pop element type argument. | 689 __ popq(RAX); // Pop element type argument. |
690 __ popq(R10); // Pop array length argument. | 690 __ popq(R10); // Pop array length argument. |
691 __ popq(RAX); // Pop return value from return slot. | 691 __ popq(RAX); // Pop return value from return slot. |
692 __ LeaveStubFrame(); | 692 __ LeaveStubFrame(); |
693 __ ret(); | 693 __ ret(); |
694 } | 694 } |
695 | 695 |
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1161 // RSP : points to return address. | 1161 // RSP : points to return address. |
1162 // RSP + 8 : address of last argument. | 1162 // RSP + 8 : address of last argument. |
1163 // R10 : arguments descriptor array. | 1163 // R10 : arguments descriptor array. |
1164 void StubCode::GenerateCallClosureNoSuchMethodStub(Assembler* assembler) { | 1164 void StubCode::GenerateCallClosureNoSuchMethodStub(Assembler* assembler) { |
1165 __ EnterStubFrame(); | 1165 __ EnterStubFrame(); |
1166 | 1166 |
1167 // Load the receiver. | 1167 // Load the receiver. |
1168 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 1168 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
1169 __ movq(RAX, Address(RBP, R13, TIMES_4, kParamEndSlotFromFp * kWordSize)); | 1169 __ movq(RAX, Address(RBP, R13, TIMES_4, kParamEndSlotFromFp * kWordSize)); |
1170 | 1170 |
1171 __ LoadObject(R12, Object::null_object()); | 1171 __ pushq(Immediate(0)); // Result slot. |
1172 __ pushq(R12); // Setup space on stack for result from noSuchMethod. | |
1173 __ pushq(RAX); // Receiver. | 1172 __ pushq(RAX); // Receiver. |
1174 __ pushq(R10); // Arguments descriptor array. | 1173 __ pushq(R10); // Arguments descriptor array. |
1175 | 1174 |
1176 __ movq(R10, R13); // Smi-tagged arguments array length. | 1175 __ movq(R10, R13); // Smi-tagged arguments array length. |
1177 PushArgumentsArray(assembler); | 1176 PushArgumentsArray(assembler); |
1178 | 1177 |
1179 const intptr_t kNumArgs = 3; | 1178 const intptr_t kNumArgs = 3; |
1180 __ CallRuntime(kInvokeClosureNoSuchMethodRuntimeEntry, kNumArgs); | 1179 __ CallRuntime(kInvokeClosureNoSuchMethodRuntimeEntry, kNumArgs); |
1181 // noSuchMethod on closures always throws an error, so it will never return. | 1180 // noSuchMethod on closures always throws an error, so it will never return. |
1182 __ int3(); | 1181 __ int3(); |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1393 | 1392 |
1394 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize; | 1393 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize; |
1395 __ addq(R13, Immediate(entry_size)); // Next entry. | 1394 __ addq(R13, Immediate(entry_size)); // Next entry. |
1396 __ movq(R9, Address(R13, 0)); // Next class ID. | 1395 __ movq(R9, Address(R13, 0)); // Next class ID. |
1397 | 1396 |
1398 __ Bind(&test); | 1397 __ Bind(&test); |
1399 __ cmpq(R9, Immediate(Smi::RawValue(kIllegalCid))); // Done? | 1398 __ cmpq(R9, Immediate(Smi::RawValue(kIllegalCid))); // Done? |
1400 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); | 1399 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); |
1401 | 1400 |
1402 __ Comment("IC miss"); | 1401 __ Comment("IC miss"); |
1403 __ LoadObject(R13, Object::null_object()); | |
1404 // Compute address of arguments (first read number of arguments from | 1402 // Compute address of arguments (first read number of arguments from |
1405 // arguments descriptor array and then compute address on the stack). | 1403 // arguments descriptor array and then compute address on the stack). |
1406 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 1404 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
1407 __ leaq(RAX, Address(RSP, RAX, TIMES_4, 0)); // RAX is Smi. | 1405 __ leaq(RAX, Address(RSP, RAX, TIMES_4, 0)); // RAX is Smi. |
1408 __ EnterStubFrame(); | 1406 __ EnterStubFrame(); |
1409 __ pushq(R10); // Preserve arguments descriptor array. | 1407 __ pushq(R10); // Preserve arguments descriptor array. |
1410 __ pushq(RBX); // Preserve IC data object. | 1408 __ pushq(RBX); // Preserve IC data object. |
1411 __ pushq(R13); // Setup space on stack for result (target code object). | 1409 __ pushq(Immediate(0)); // Result slot. |
1412 // Push call arguments. | 1410 // Push call arguments. |
1413 for (intptr_t i = 0; i < num_args; i++) { | 1411 for (intptr_t i = 0; i < num_args; i++) { |
1414 __ movq(RCX, Address(RAX, -kWordSize * i)); | 1412 __ movq(RCX, Address(RAX, -kWordSize * i)); |
1415 __ pushq(RCX); | 1413 __ pushq(RCX); |
1416 } | 1414 } |
1417 __ pushq(RBX); // Pass IC data object. | 1415 __ pushq(RBX); // Pass IC data object. |
1418 __ CallRuntime(handle_ic_miss, num_args + 1); | 1416 __ CallRuntime(handle_ic_miss, num_args + 1); |
1419 // Remove the call arguments pushed earlier, including the IC data object. | 1417 // Remove the call arguments pushed earlier, including the IC data object. |
1420 for (intptr_t i = 0; i < num_args + 1; i++) { | 1418 for (intptr_t i = 0; i < num_args + 1; i++) { |
1421 __ popq(RAX); | 1419 __ popq(RAX); |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1660 __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset())); | 1658 __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset())); |
1661 __ movq(RAX, FieldAddress(RAX, Function::entry_point_offset())); | 1659 __ movq(RAX, FieldAddress(RAX, Function::entry_point_offset())); |
1662 __ jmp(RAX); | 1660 __ jmp(RAX); |
1663 } | 1661 } |
1664 | 1662 |
1665 | 1663 |
1666 // RBX: Contains an ICData. | 1664 // RBX: Contains an ICData. |
1667 // TOS(0): return address (Dart code). | 1665 // TOS(0): return address (Dart code). |
1668 void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) { | 1666 void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) { |
1669 __ EnterStubFrame(); | 1667 __ EnterStubFrame(); |
1670 // Preserve IC data. | 1668 __ pushq(RBX); // Preserve IC data. |
1671 __ pushq(RBX); | 1669 __ pushq(Immediate(0)); // Result slot. |
1672 // Room for result. Debugger stub returns address of the | |
1673 // unpatched runtime stub. | |
1674 __ LoadObject(R12, Object::null_object()); | |
1675 __ pushq(R12); // Room for result. | |
1676 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); | 1670 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); |
1677 __ popq(CODE_REG); // Address of original. | 1671 __ popq(CODE_REG); // Original stub. |
1678 __ popq(RBX); // Restore IC data. | 1672 __ popq(RBX); // Restore IC data. |
1679 __ LeaveStubFrame(); | 1673 __ LeaveStubFrame(); |
1680 | 1674 |
1681 __ movq(RAX, FieldAddress(CODE_REG, Code::entry_point_offset())); | 1675 __ movq(RAX, FieldAddress(CODE_REG, Code::entry_point_offset())); |
1682 __ jmp(RAX); // Jump to original stub. | 1676 __ jmp(RAX); // Jump to original stub. |
1683 } | 1677 } |
1684 | 1678 |
1685 | 1679 |
1686 // TOS(0): return address (Dart code). | 1680 // TOS(0): return address (Dart code). |
1687 void StubCode::GenerateRuntimeCallBreakpointStub(Assembler* assembler) { | 1681 void StubCode::GenerateRuntimeCallBreakpointStub(Assembler* assembler) { |
1688 __ EnterStubFrame(); | 1682 __ EnterStubFrame(); |
1689 // Room for result. Debugger stub returns address of the | 1683 __ pushq(Immediate(0)); // Result slot. |
1690 // unpatched runtime stub. | |
1691 __ LoadObject(R12, Object::null_object()); | |
1692 __ pushq(R12); // Room for result. | |
1693 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); | 1684 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); |
1694 __ popq(CODE_REG); // Address of original. | 1685 __ popq(CODE_REG); // Original stub. |
1695 __ LeaveStubFrame(); | 1686 __ LeaveStubFrame(); |
1696 | 1687 |
1697 __ movq(RAX, FieldAddress(CODE_REG, Code::entry_point_offset())); | 1688 __ movq(RAX, FieldAddress(CODE_REG, Code::entry_point_offset())); |
1698 __ jmp(RAX); // Jump to original stub. | 1689 __ jmp(RAX); // Jump to original stub. |
1699 } | 1690 } |
1700 | 1691 |
1701 | 1692 |
1702 // Called only from unoptimized code. | 1693 // Called only from unoptimized code. |
1703 void StubCode::GenerateDebugStepCheckStub(Assembler* assembler) { | 1694 void StubCode::GenerateDebugStepCheckStub(Assembler* assembler) { |
1704 // Check single stepping. | 1695 // Check single stepping. |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1876 Immediate(0)); | 1867 Immediate(0)); |
1877 __ jmp(CallingConventions::kArg1Reg); // Jump to the exception handler code. | 1868 __ jmp(CallingConventions::kArg1Reg); // Jump to the exception handler code. |
1878 } | 1869 } |
1879 | 1870 |
1880 | 1871 |
1881 // Calls to the runtime to optimize the given function. | 1872 // Calls to the runtime to optimize the given function. |
1882 // RDI: function to be reoptimized. | 1873 // RDI: function to be reoptimized. |
1883 // R10: argument descriptor (preserved). | 1874 // R10: argument descriptor (preserved). |
1884 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { | 1875 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { |
1885 __ EnterStubFrame(); | 1876 __ EnterStubFrame(); |
1886 __ LoadObject(R12, Object::null_object()); | 1877 __ pushq(R10); // Preserve args descriptor. |
1887 __ pushq(R10); | 1878 __ pushq(Immediate(0)); // Result slot. |
1888 __ pushq(R12); // Setup space on stack for return value. | 1879 __ pushq(RDI); // Arg0: function to optimize |
1889 __ pushq(RDI); | |
1890 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); | 1880 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); |
1891 __ popq(RAX); // Disard argument. | 1881 __ popq(RAX); // Disard argument. |
1892 __ popq(CODE_REG); // Get Code object. | 1882 __ popq(CODE_REG); // Get Code object. |
1893 __ popq(R10); // Restore argument descriptor. | 1883 __ popq(R10); // Restore argument descriptor. |
1894 __ movq(RAX, FieldAddress(CODE_REG, Code::entry_point_offset())); | 1884 __ movq(RAX, FieldAddress(CODE_REG, Code::entry_point_offset())); |
1895 __ LeaveStubFrame(); | 1885 __ LeaveStubFrame(); |
1896 __ jmp(RAX); | 1886 __ jmp(RAX); |
1897 __ int3(); | 1887 __ int3(); |
1898 } | 1888 } |
1899 | 1889 |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2168 | 2158 |
2169 | 2159 |
2170 // RDI: receiver | 2160 // RDI: receiver |
2171 // RBX: UnlinkedCall | 2161 // RBX: UnlinkedCall |
2172 void StubCode::GenerateUnlinkedCallStub(Assembler* assembler) { | 2162 void StubCode::GenerateUnlinkedCallStub(Assembler* assembler) { |
2173 __ NoMonomorphicCheckedEntry(); | 2163 __ NoMonomorphicCheckedEntry(); |
2174 | 2164 |
2175 __ EnterStubFrame(); | 2165 __ EnterStubFrame(); |
2176 __ pushq(RDI); // Preserve receiver. | 2166 __ pushq(RDI); // Preserve receiver. |
2177 | 2167 |
2178 __ PushObject(Object::null_object()); // Result. | 2168 __ pushq(Immediate(0)); // Result slot. |
2179 __ pushq(RDI); // Arg0: Receiver | 2169 __ pushq(RDI); // Arg0: Receiver |
2180 __ pushq(RBX); // Arg1: UnlinkedCall | 2170 __ pushq(RBX); // Arg1: UnlinkedCall |
2181 __ CallRuntime(kUnlinkedCallRuntimeEntry, 2); | 2171 __ CallRuntime(kUnlinkedCallRuntimeEntry, 2); |
2182 __ popq(RBX); | 2172 __ popq(RBX); |
2183 __ popq(RBX); | 2173 __ popq(RBX); |
2184 __ popq(RBX); // result = IC | 2174 __ popq(RBX); // result = IC |
2185 | 2175 |
2186 __ popq(RDI); // Restore receiver. | 2176 __ popq(RDI); // Restore receiver. |
2187 __ LeaveStubFrame(); | 2177 __ LeaveStubFrame(); |
2188 | 2178 |
2189 __ movq(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset())); | 2179 __ movq(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset())); |
2190 __ movq(RCX, FieldAddress(CODE_REG, Code::checked_entry_point_offset())); | 2180 __ movq(RCX, FieldAddress(CODE_REG, Code::checked_entry_point_offset())); |
(...skipping 18 matching lines...) Expand all Loading... |
2209 __ cmpq(RAX, R10); | 2199 __ cmpq(RAX, R10); |
2210 __ j(GREATER, &miss, Assembler::kNearJump); | 2200 __ j(GREATER, &miss, Assembler::kNearJump); |
2211 __ movq(RCX, FieldAddress(RBX, SingleTargetCache::entry_point_offset())); | 2201 __ movq(RCX, FieldAddress(RBX, SingleTargetCache::entry_point_offset())); |
2212 __ movq(CODE_REG, FieldAddress(RBX, SingleTargetCache::target_offset())); | 2202 __ movq(CODE_REG, FieldAddress(RBX, SingleTargetCache::target_offset())); |
2213 __ jmp(RCX); | 2203 __ jmp(RCX); |
2214 | 2204 |
2215 __ Bind(&miss); | 2205 __ Bind(&miss); |
2216 __ EnterStubFrame(); | 2206 __ EnterStubFrame(); |
2217 __ pushq(RDI); // Preserve receiver. | 2207 __ pushq(RDI); // Preserve receiver. |
2218 | 2208 |
2219 __ PushObject(Object::null_object()); // Result. | 2209 __ pushq(Immediate(0)); // Result slot. |
2220 __ pushq(RDI); // Arg0: Receiver | 2210 __ pushq(RDI); // Arg0: Receiver |
2221 __ CallRuntime(kSingleTargetMissRuntimeEntry, 1); | 2211 __ CallRuntime(kSingleTargetMissRuntimeEntry, 1); |
2222 __ popq(RBX); | 2212 __ popq(RBX); |
2223 __ popq(RBX); // result = IC | 2213 __ popq(RBX); // result = IC |
2224 | 2214 |
2225 __ popq(RDI); // Restore receiver. | 2215 __ popq(RDI); // Restore receiver. |
2226 __ LeaveStubFrame(); | 2216 __ LeaveStubFrame(); |
2227 | 2217 |
2228 __ movq(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset())); | 2218 __ movq(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset())); |
2229 __ movq(RCX, FieldAddress(CODE_REG, Code::checked_entry_point_offset())); | 2219 __ movq(RCX, FieldAddress(CODE_REG, Code::checked_entry_point_offset())); |
2230 __ jmp(RCX); | 2220 __ jmp(RCX); |
2231 } | 2221 } |
2232 | 2222 |
2233 | 2223 |
2234 // Called from the monomorphic checked entry. | 2224 // Called from the monomorphic checked entry. |
2235 // RDI: receiver | 2225 // RDI: receiver |
2236 void StubCode::GenerateMonomorphicMissStub(Assembler* assembler) { | 2226 void StubCode::GenerateMonomorphicMissStub(Assembler* assembler) { |
2237 __ EnterStubFrame(); | 2227 __ EnterStubFrame(); |
2238 __ pushq(RDI); // Preserve receiver. | 2228 __ pushq(RDI); // Preserve receiver. |
2239 | 2229 |
2240 __ PushObject(Object::null_object()); // Result. | 2230 __ pushq(Immediate(0)); // Result slot. |
2241 __ pushq(RDI); // Arg0: Receiver | 2231 __ pushq(RDI); // Arg0: Receiver |
2242 __ CallRuntime(kMonomorphicMissRuntimeEntry, 1); | 2232 __ CallRuntime(kMonomorphicMissRuntimeEntry, 1); |
2243 __ popq(RBX); | 2233 __ popq(RBX); |
2244 __ popq(RBX); // result = IC | 2234 __ popq(RBX); // result = IC |
2245 | 2235 |
2246 __ popq(RDI); // Restore receiver. | 2236 __ popq(RDI); // Restore receiver. |
2247 __ LeaveStubFrame(); | 2237 __ LeaveStubFrame(); |
2248 | 2238 |
2249 __ movq(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset())); | 2239 __ movq(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset())); |
2250 __ movq(RCX, FieldAddress(CODE_REG, Code::checked_entry_point_offset())); | 2240 __ movq(RCX, FieldAddress(CODE_REG, Code::checked_entry_point_offset())); |
2251 __ jmp(RCX); | 2241 __ jmp(RCX); |
2252 } | 2242 } |
2253 | 2243 |
2254 | 2244 |
2255 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { | 2245 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { |
2256 __ int3(); | 2246 __ int3(); |
2257 } | 2247 } |
2258 | 2248 |
2259 } // namespace dart | 2249 } // namespace dart |
2260 | 2250 |
2261 #endif // defined TARGET_ARCH_X64 | 2251 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |