| 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 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 __ movq(RAX, Address(R12, 0)); | 374 __ movq(RAX, Address(R12, 0)); |
| 375 __ movq(Address(RBX, 0), RAX); | 375 __ movq(Address(RBX, 0), RAX); |
| 376 __ addq(RBX, Immediate(kWordSize)); | 376 __ addq(RBX, Immediate(kWordSize)); |
| 377 __ subq(R12, Immediate(kWordSize)); | 377 __ subq(R12, Immediate(kWordSize)); |
| 378 __ Bind(&loop_condition); | 378 __ Bind(&loop_condition); |
| 379 __ decq(R10); | 379 __ decq(R10); |
| 380 __ j(POSITIVE, &loop, Assembler::kNearJump); | 380 __ j(POSITIVE, &loop, Assembler::kNearJump); |
| 381 } | 381 } |
| 382 | 382 |
| 383 | 383 |
| 384 // Input parameters: | |
| 385 // RBX: ic-data. | |
| 386 // R10: arguments descriptor array. | |
| 387 // Note: The receiver object is the first argument to the function being | |
| 388 // called, the stub accesses the receiver from this location directly | |
| 389 // when trying to resolve the call. | |
| 390 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { | |
| 391 __ EnterStubFrame(); | |
| 392 __ PushObject(Object::null_object(), PP); // Space for the return value. | |
| 393 | |
| 394 // Push the receiver as an argument. Load the smi-tagged argument | |
| 395 // count into R13 to index the receiver in the stack. There are | |
| 396 // four words (null, stub's pc marker, saved pp, saved fp) above the return | |
| 397 // address. | |
| 398 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | |
| 399 __ pushq(Address(RSP, R13, TIMES_4, (4 * kWordSize))); | |
| 400 | |
| 401 __ pushq(RBX); // Pass IC data object. | |
| 402 __ pushq(R10); // Pass arguments descriptor array. | |
| 403 | |
| 404 // Pass the call's arguments array. | |
| 405 __ movq(R10, R13); // Smi-tagged arguments array length. | |
| 406 PushArgumentsArray(assembler); | |
| 407 | |
| 408 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry, 4); | |
| 409 | |
| 410 // Remove arguments. | |
| 411 __ Drop(4); | |
| 412 __ popq(RAX); // Get result into RAX. | |
| 413 __ LeaveStubFrame(); | |
| 414 __ ret(); | |
| 415 } | |
| 416 | |
| 417 | |
| 418 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, | 384 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, |
| 419 intptr_t deopt_reason, | 385 intptr_t deopt_reason, |
| 420 uword saved_registers_address); | 386 uword saved_registers_address); |
| 421 | 387 |
| 422 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp); | 388 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp); |
| 423 | 389 |
| 424 | 390 |
| 425 // Used by eager and lazy deoptimization. Preserve result in RAX if necessary. | 391 // Used by eager and lazy deoptimization. Preserve result in RAX if necessary. |
| 426 // This stub translates optimized frame into unoptimized frame. The optimized | 392 // This stub translates optimized frame into unoptimized frame. The optimized |
| 427 // frame can contain values in registers and on stack, the unoptimized | 393 // frame can contain values in registers and on stack, the unoptimized |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 571 // Space for the result of the runtime call. | 537 // Space for the result of the runtime call. |
| 572 __ PushObject(Object::null_object(), PP); | 538 __ PushObject(Object::null_object(), PP); |
| 573 __ pushq(RAX); // Receiver. | 539 __ pushq(RAX); // Receiver. |
| 574 __ pushq(RBX); // IC data. | 540 __ pushq(RBX); // IC data. |
| 575 __ pushq(R10); // Arguments descriptor. | 541 __ pushq(R10); // Arguments descriptor. |
| 576 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); | 542 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); |
| 577 // Discard arguments. | 543 // Discard arguments. |
| 578 __ popq(RAX); | 544 __ popq(RAX); |
| 579 __ popq(RAX); | 545 __ popq(RAX); |
| 580 __ popq(RAX); | 546 __ popq(RAX); |
| 581 __ popq(RAX); // Return value from the runtime call (instructions). | 547 __ popq(RAX); // Return value from the runtime call (function). |
| 582 __ popq(R10); // Restore arguments descriptor. | 548 __ popq(R10); // Restore arguments descriptor. |
| 583 __ popq(RBX); // Restore IC data. | 549 __ popq(RBX); // Restore IC data. |
| 584 __ LeaveStubFrame(); | 550 __ LeaveStubFrame(); |
| 585 | 551 |
| 586 Label lookup; | 552 __ movq(RCX, FieldAddress(RAX, Function::code_offset())); |
| 587 __ CompareObject(RAX, Object::null_object(), PP); | 553 __ movq(RCX, FieldAddress(RCX, Code::instructions_offset())); |
| 588 __ j(EQUAL, &lookup, Assembler::kNearJump); | 554 __ addq(RCX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 589 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 555 __ jmp(RCX); |
| 590 __ jmp(RAX); | |
| 591 | |
| 592 __ Bind(&lookup); | |
| 593 __ jmp(&StubCode::InstanceFunctionLookupLabel()); | |
| 594 } | 556 } |
| 595 | 557 |
| 596 | 558 |
| 597 // Called for inline allocation of arrays. | 559 // Called for inline allocation of arrays. |
| 598 // Input parameters: | 560 // Input parameters: |
| 599 // R10 : Array length as Smi. | 561 // R10 : Array length as Smi. |
| 600 // RBX : array element type (either NULL or an instantiated type). | 562 // RBX : array element type (either NULL or an instantiated type). |
| 601 // NOTE: R10 cannot be clobbered here as the caller relies on it being saved. | 563 // NOTE: R10 cannot be clobbered here as the caller relies on it being saved. |
| 602 // The newly allocated object is returned in RAX. | 564 // The newly allocated object is returned in RAX. |
| 603 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) { | 565 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) { |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 759 // Actual class is not a closure class. | 721 // Actual class is not a closure class. |
| 760 __ j(EQUAL, ¬_closure, Assembler::kNearJump); | 722 __ j(EQUAL, ¬_closure, Assembler::kNearJump); |
| 761 | 723 |
| 762 // RAX is just the signature function. Load the actual closure function. | 724 // RAX is just the signature function. Load the actual closure function. |
| 763 __ movq(RAX, FieldAddress(R13, Closure::function_offset())); | 725 __ movq(RAX, FieldAddress(R13, Closure::function_offset())); |
| 764 | 726 |
| 765 // Load closure context in CTX; note that CTX has already been preserved. | 727 // Load closure context in CTX; note that CTX has already been preserved. |
| 766 __ movq(CTX, FieldAddress(R13, Closure::context_offset())); | 728 __ movq(CTX, FieldAddress(R13, Closure::context_offset())); |
| 767 | 729 |
| 768 // Load closure function code in RAX. | 730 // Load closure function code in RAX. |
| 769 __ movq(RBX, FieldAddress(RAX, Function::code_offset())); | 731 __ movq(RCX, FieldAddress(RAX, Function::code_offset())); |
| 770 | 732 |
| 771 // RAX: Function. | 733 // RAX: Function. |
| 772 // R10: Arguments descriptor array. | 734 // R10: Arguments descriptor array. |
| 773 __ movq(RCX, FieldAddress(RBX, Code::instructions_offset())); | 735 __ movq(RCX, FieldAddress(RCX, Code::instructions_offset())); |
| 774 __ addq(RCX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 736 __ addq(RCX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 775 __ jmp(RCX); | 737 __ jmp(RCX); |
| 776 | 738 |
| 777 __ Bind(¬_closure); | 739 __ Bind(¬_closure); |
| 778 // Call runtime to attempt to resolve and invoke a call method on a | 740 // Call runtime to attempt to resolve and invoke a call method on a |
| 779 // non-closure object, passing the non-closure object and its arguments array, | 741 // non-closure object, passing the non-closure object and its arguments array, |
| 780 // returning here. | 742 // returning here. |
| 781 // If no call method exists, throw a NoSuchMethodError. | 743 // If no call method exists, throw a NoSuchMethodError. |
| 782 // R13: non-closure object. | 744 // R13: non-closure object. |
| 783 // R10: arguments descriptor array. | 745 // R10: arguments descriptor array. |
| (...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1439 for (intptr_t i = 0; i < num_args; i++) { | 1401 for (intptr_t i = 0; i < num_args; i++) { |
| 1440 __ movq(RCX, Address(RAX, -kWordSize * i)); | 1402 __ movq(RCX, Address(RAX, -kWordSize * i)); |
| 1441 __ pushq(RCX); | 1403 __ pushq(RCX); |
| 1442 } | 1404 } |
| 1443 __ pushq(RBX); // Pass IC data object. | 1405 __ pushq(RBX); // Pass IC data object. |
| 1444 __ CallRuntime(handle_ic_miss, num_args + 1); | 1406 __ CallRuntime(handle_ic_miss, num_args + 1); |
| 1445 // Remove the call arguments pushed earlier, including the IC data object. | 1407 // Remove the call arguments pushed earlier, including the IC data object. |
| 1446 for (intptr_t i = 0; i < num_args + 1; i++) { | 1408 for (intptr_t i = 0; i < num_args + 1; i++) { |
| 1447 __ popq(RAX); | 1409 __ popq(RAX); |
| 1448 } | 1410 } |
| 1449 __ popq(RAX); // Pop returned code object into RAX (null if not found). | 1411 __ popq(RAX); // Pop returned function object into RAX. |
| 1450 __ popq(RBX); // Restore IC data array. | 1412 __ popq(RBX); // Restore IC data array. |
| 1451 __ popq(R10); // Restore arguments descriptor array. | 1413 __ popq(R10); // Restore arguments descriptor array. |
| 1452 __ LeaveStubFrame(); | 1414 __ LeaveStubFrame(); |
| 1453 Label call_target_function; | 1415 Label call_target_function; |
| 1454 __ cmpq(RAX, R12); | 1416 __ jmp(&call_target_function); |
| 1455 __ j(NOT_EQUAL, &call_target_function, Assembler::kNearJump); | |
| 1456 // NoSuchMethod or closure. | |
| 1457 // Mark IC call that it may be a closure call that does not collect | |
| 1458 // type feedback. | |
| 1459 __ movb(FieldAddress(RBX, ICData::is_closure_call_offset()), Immediate(1)); | |
| 1460 __ jmp(&StubCode::InstanceFunctionLookupLabel()); | |
| 1461 | 1417 |
| 1462 __ Bind(&found); | 1418 __ Bind(&found); |
| 1463 // R12: Pointer to an IC data check group. | 1419 // R12: Pointer to an IC data check group. |
| 1464 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; | 1420 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; |
| 1465 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; | 1421 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; |
| 1466 __ movq(RAX, Address(R12, target_offset)); | 1422 __ movq(RAX, Address(R12, target_offset)); |
| 1467 __ addq(Address(R12, count_offset), Immediate(Smi::RawValue(1))); | 1423 __ addq(Address(R12, count_offset), Immediate(Smi::RawValue(1))); |
| 1468 __ j(NO_OVERFLOW, &call_target_function, Assembler::kNearJump); | 1424 __ j(NO_OVERFLOW, &call_target_function, Assembler::kNearJump); |
| 1469 __ movq(Address(R12, count_offset), | 1425 __ movq(Address(R12, count_offset), |
| 1470 Immediate(Smi::RawValue(Smi::kMaxValue))); | 1426 Immediate(Smi::RawValue(Smi::kMaxValue))); |
| (...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1960 | 1916 |
| 1961 __ movq(left, Address(RSP, 2 * kWordSize)); | 1917 __ movq(left, Address(RSP, 2 * kWordSize)); |
| 1962 __ movq(right, Address(RSP, 1 * kWordSize)); | 1918 __ movq(right, Address(RSP, 1 * kWordSize)); |
| 1963 GenerateIdenticalWithNumberCheckStub(assembler, left, right); | 1919 GenerateIdenticalWithNumberCheckStub(assembler, left, right); |
| 1964 __ ret(); | 1920 __ ret(); |
| 1965 } | 1921 } |
| 1966 | 1922 |
| 1967 } // namespace dart | 1923 } // namespace dart |
| 1968 | 1924 |
| 1969 #endif // defined TARGET_ARCH_X64 | 1925 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |