| 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 |