| 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_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 __ lw(T3, Address(T1)); | 485 __ lw(T3, Address(T1)); |
| 486 __ addiu(A1, A1, Immediate(-Smi::RawValue(1))); | 486 __ addiu(A1, A1, Immediate(-Smi::RawValue(1))); |
| 487 __ addiu(T1, T1, Immediate(-kWordSize)); | 487 __ addiu(T1, T1, Immediate(-kWordSize)); |
| 488 __ addiu(T2, T2, Immediate(kWordSize)); | 488 __ addiu(T2, T2, Immediate(kWordSize)); |
| 489 __ bgez(A1, &loop); | 489 __ bgez(A1, &loop); |
| 490 __ delay_slot()->sw(T3, Address(T2, -kWordSize)); | 490 __ delay_slot()->sw(T3, Address(T2, -kWordSize)); |
| 491 __ Bind(&loop_exit); | 491 __ Bind(&loop_exit); |
| 492 } | 492 } |
| 493 | 493 |
| 494 | 494 |
| 495 // Input parameters: | |
| 496 // S5: ic-data. | |
| 497 // S4: arguments descriptor array. | |
| 498 // Note: The receiver object is the first argument to the function being | |
| 499 // called, the stub accesses the receiver from this location directly | |
| 500 // when trying to resolve the call. | |
| 501 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { | |
| 502 __ TraceSimMsg("InstanceFunctionLookupStub"); | |
| 503 __ EnterStubFrame(); | |
| 504 | |
| 505 // Load the receiver. | |
| 506 __ lw(A1, FieldAddress(S4, ArgumentsDescriptor::count_offset())); | |
| 507 __ sll(TMP, A1, 1); // A1 is Smi. | |
| 508 __ addu(TMP, FP, TMP); | |
| 509 __ lw(T1, Address(TMP, kParamEndSlotFromFp * kWordSize)); | |
| 510 | |
| 511 // Push space for the return value. | |
| 512 // Push the receiver. | |
| 513 // Push TMP data object. | |
| 514 // Push arguments descriptor array. | |
| 515 __ addiu(SP, SP, Immediate(-4 * kWordSize)); | |
| 516 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | |
| 517 __ sw(TMP, Address(SP, 3 * kWordSize)); | |
| 518 __ sw(T1, Address(SP, 2 * kWordSize)); | |
| 519 __ sw(S5, Address(SP, 1 * kWordSize)); | |
| 520 __ sw(S4, Address(SP, 0 * kWordSize)); | |
| 521 | |
| 522 // A1: Smi-tagged arguments array length. | |
| 523 PushArgumentsArray(assembler); | |
| 524 __ TraceSimMsg("InstanceFunctionLookupStub return"); | |
| 525 | |
| 526 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry, 4); | |
| 527 | |
| 528 __ lw(V0, Address(SP, 4 * kWordSize)); // Get result into V0. | |
| 529 __ addiu(SP, SP, Immediate(5 * kWordSize)); // Remove arguments. | |
| 530 | |
| 531 __ LeaveStubFrameAndReturn(); | |
| 532 } | |
| 533 | |
| 534 | |
| 535 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, | 495 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, |
| 536 intptr_t deopt_reason, | 496 intptr_t deopt_reason, |
| 537 uword saved_registers_address); | 497 uword saved_registers_address); |
| 538 | 498 |
| 539 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp); | 499 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp); |
| 540 | 500 |
| 541 | 501 |
| 542 // Used by eager and lazy deoptimization. Preserve result in V0 if necessary. | 502 // Used by eager and lazy deoptimization. Preserve result in V0 if necessary. |
| 543 // This stub translates optimized frame into unoptimized frame. The optimized | 503 // This stub translates optimized frame into unoptimized frame. The optimized |
| 544 // frame can contain values in registers and on stack, the unoptimized | 504 // frame can contain values in registers and on stack, the unoptimized |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 701 // Push IC data object. | 661 // Push IC data object. |
| 702 // Push arguments descriptor array. | 662 // Push arguments descriptor array. |
| 703 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 663 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
| 704 __ sw(TMP, Address(SP, 3 * kWordSize)); | 664 __ sw(TMP, Address(SP, 3 * kWordSize)); |
| 705 __ sw(T6, Address(SP, 2 * kWordSize)); | 665 __ sw(T6, Address(SP, 2 * kWordSize)); |
| 706 __ sw(S5, Address(SP, 1 * kWordSize)); | 666 __ sw(S5, Address(SP, 1 * kWordSize)); |
| 707 __ sw(S4, Address(SP, 0 * kWordSize)); | 667 __ sw(S4, Address(SP, 0 * kWordSize)); |
| 708 | 668 |
| 709 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); | 669 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); |
| 710 | 670 |
| 711 __ lw(T0, Address(SP, 3 * kWordSize)); // Get result. | 671 __ lw(T0, Address(SP, 3 * kWordSize)); // Get result function. |
| 712 __ lw(S4, Address(SP, 4 * kWordSize)); // Restore argument descriptor. | 672 __ lw(S4, Address(SP, 4 * kWordSize)); // Restore argument descriptor. |
| 713 __ lw(S5, Address(SP, 5 * kWordSize)); // Restore IC data. | 673 __ lw(S5, Address(SP, 5 * kWordSize)); // Restore IC data. |
| 714 __ addiu(SP, SP, Immediate(6 * kWordSize)); | 674 __ addiu(SP, SP, Immediate(6 * kWordSize)); |
| 715 | 675 |
| 716 __ LeaveStubFrame(); | 676 __ LeaveStubFrame(); |
| 717 | 677 |
| 718 Label nonnull; | 678 __ lw(T2, FieldAddress(T0, Function::code_offset())); |
| 719 __ BranchNotEqual(T0, reinterpret_cast<int32_t>(Object::null()), &nonnull); | 679 __ lw(T2, FieldAddress(T2, Code::instructions_offset())); |
| 720 __ Branch(&StubCode::InstanceFunctionLookupLabel()); | 680 __ AddImmediate(T2, Instructions::HeaderSize() - kHeapObjectTag); |
| 721 __ Bind(&nonnull); | 681 __ jr(T2); |
| 722 __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag); | |
| 723 __ jr(T0); | |
| 724 } | 682 } |
| 725 | 683 |
| 726 | 684 |
| 727 // Called for inline allocation of arrays. | 685 // Called for inline allocation of arrays. |
| 728 // Input parameters: | 686 // Input parameters: |
| 729 // RA: return address. | 687 // RA: return address. |
| 730 // A1: Array length as Smi. | 688 // A1: Array length as Smi. |
| 731 // A0: array element type (either NULL or an instantiated type). | 689 // A0: array element type (either NULL or an instantiated type). |
| 732 // NOTE: A1 cannot be clobbered here as the caller relies on it being saved. | 690 // NOTE: A1 cannot be clobbered here as the caller relies on it being saved. |
| 733 // The newly allocated object is returned in V0. | 691 // The newly allocated object is returned in V0. |
| (...skipping 935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1669 __ sw(TMP, Address(SP, (num_slots - 3) * kWordSize)); | 1627 __ sw(TMP, Address(SP, (num_slots - 3) * kWordSize)); |
| 1670 // Push call arguments. | 1628 // Push call arguments. |
| 1671 for (intptr_t i = 0; i < num_args; i++) { | 1629 for (intptr_t i = 0; i < num_args; i++) { |
| 1672 __ lw(TMP, Address(T1, -i * kWordSize)); | 1630 __ lw(TMP, Address(T1, -i * kWordSize)); |
| 1673 __ sw(TMP, Address(SP, (num_slots - i - 4) * kWordSize)); | 1631 __ sw(TMP, Address(SP, (num_slots - i - 4) * kWordSize)); |
| 1674 } | 1632 } |
| 1675 // Pass IC data object. | 1633 // Pass IC data object. |
| 1676 __ sw(S5, Address(SP, (num_slots - num_args - 4) * kWordSize)); | 1634 __ sw(S5, Address(SP, (num_slots - num_args - 4) * kWordSize)); |
| 1677 __ CallRuntime(handle_ic_miss, num_args + 1); | 1635 __ CallRuntime(handle_ic_miss, num_args + 1); |
| 1678 __ TraceSimMsg("NArgsCheckInlineCacheStub return"); | 1636 __ TraceSimMsg("NArgsCheckInlineCacheStub return"); |
| 1679 // Pop returned code object into T3 (null if not found). | 1637 // Pop returned function object into T3. |
| 1680 // Restore arguments descriptor array and IC data array. | 1638 // Restore arguments descriptor array and IC data array. |
| 1681 __ lw(T3, Address(SP, (num_slots - 3) * kWordSize)); | 1639 __ lw(T3, Address(SP, (num_slots - 3) * kWordSize)); |
| 1682 __ lw(S4, Address(SP, (num_slots - 2) * kWordSize)); | 1640 __ lw(S4, Address(SP, (num_slots - 2) * kWordSize)); |
| 1683 __ lw(S5, Address(SP, (num_slots - 1) * kWordSize)); | 1641 __ lw(S5, Address(SP, (num_slots - 1) * kWordSize)); |
| 1684 // Remove the call arguments pushed earlier, including the IC data object | 1642 // Remove the call arguments pushed earlier, including the IC data object |
| 1685 // and the arguments descriptor array. | 1643 // and the arguments descriptor array. |
| 1686 __ addiu(SP, SP, Immediate(num_slots * kWordSize)); | 1644 __ addiu(SP, SP, Immediate(num_slots * kWordSize)); |
| 1687 __ LeaveStubFrame(); | 1645 __ LeaveStubFrame(); |
| 1646 |
| 1688 Label call_target_function; | 1647 Label call_target_function; |
| 1689 __ BranchNotEqual(T3, reinterpret_cast<int32_t>(Object::null()), | 1648 __ b(&call_target_function); |
| 1690 &call_target_function); | |
| 1691 | |
| 1692 // NoSuchMethod or closure. | |
| 1693 // Mark IC call that it may be a closure call that does not collect | |
| 1694 // type feedback. | |
| 1695 __ LoadImmediate(T6, 1); | |
| 1696 __ Branch(&StubCode::InstanceFunctionLookupLabel()); | |
| 1697 __ delay_slot()->sb(T6, FieldAddress(S5, ICData::is_closure_call_offset())); | |
| 1698 | 1649 |
| 1699 __ Bind(&found); | 1650 __ Bind(&found); |
| 1700 // T0: Pointer to an IC data check group. | 1651 // T0: Pointer to an IC data check group. |
| 1701 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; | 1652 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; |
| 1702 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; | 1653 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; |
| 1703 __ lw(T3, Address(T0, target_offset)); | 1654 __ lw(T3, Address(T0, target_offset)); |
| 1704 __ lw(T4, Address(T0, count_offset)); | 1655 __ lw(T4, Address(T0, count_offset)); |
| 1705 | 1656 |
| 1706 __ AddImmediateDetectOverflow(T4, T4, Smi::RawValue(1), T5, T6); | 1657 __ AddImmediateDetectOverflow(T4, T4, Smi::RawValue(1), T5, T6); |
| 1707 | 1658 |
| (...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2240 const Register right = T0; | 2191 const Register right = T0; |
| 2241 __ lw(left, Address(SP, 1 * kWordSize)); | 2192 __ lw(left, Address(SP, 1 * kWordSize)); |
| 2242 __ lw(right, Address(SP, 0 * kWordSize)); | 2193 __ lw(right, Address(SP, 0 * kWordSize)); |
| 2243 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); | 2194 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); |
| 2244 __ Ret(); | 2195 __ Ret(); |
| 2245 } | 2196 } |
| 2246 | 2197 |
| 2247 } // namespace dart | 2198 } // namespace dart |
| 2248 | 2199 |
| 2249 #endif // defined TARGET_ARCH_MIPS | 2200 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |