Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(122)

Side by Side Diff: runtime/vm/assembler_arm64.cc

Issue 247023004: Adds StoreIntoObject for arm64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/assembler_arm64.h ('k') | runtime/vm/assembler_arm64_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/longjump.h" 10 #include "vm/longjump.h"
(...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 mov(TMP2, base); 576 mov(TMP2, base);
577 str(src, Address(TMP2, offset, Address::PreIndex)); 577 str(src, Address(TMP2, offset, Address::PreIndex));
578 } else { 578 } else {
579 // Since offset is 32-bits, it won't be loaded from the pool. 579 // Since offset is 32-bits, it won't be loaded from the pool.
580 AddImmediate(TMP2, base, offset, kNoRegister); 580 AddImmediate(TMP2, base, offset, kNoRegister);
581 str(src, Address(TMP2)); 581 str(src, Address(TMP2));
582 } 582 }
583 } 583 }
584 584
585 585
586 // Store into object.
587 // Preserves object and value registers.
588 void Assembler::StoreIntoObjectFilterNoSmi(Register object,
589 Register value,
590 Label* no_update) {
591 COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) &&
592 (kOldObjectAlignmentOffset == 0), young_alignment);
593
594 // Write-barrier triggers if the value is in the new space (has bit set) and
595 // the object is in the old space (has bit cleared).
596 // To check that, we compute value & ~object and skip the write barrier
597 // if the bit is not set. We can't destroy the object.
598 bic(TMP, value, Operand(object));
599 tsti(TMP, kNewObjectAlignmentOffset);
600 b(no_update, EQ);
601 }
602
603
604 // Preserves object and value registers.
605 void Assembler::StoreIntoObjectFilter(Register object,
606 Register value,
607 Label* no_update) {
608 // For the value we are only interested in the new/old bit and the tag bit.
609 // And the new bit with the tag bit. The resulting bit will be 0 for a Smi.
610 and_(TMP, value, Operand(value, LSL, kObjectAlignmentLog2 - 1));
611 // And the result with the negated space bit of the object.
612 bic(TMP, TMP, Operand(object));
613 tsti(TMP, kNewObjectAlignmentOffset);
614 b(no_update, EQ);
615 }
616
617
618 void Assembler::StoreIntoObject(Register object,
619 const Address& dest,
620 Register value,
621 bool can_value_be_smi) {
622 ASSERT(object != value);
623 str(value, dest);
624 Label done;
625 if (can_value_be_smi) {
626 StoreIntoObjectFilter(object, value, &done);
627 } else {
628 StoreIntoObjectFilterNoSmi(object, value, &done);
629 }
630 // A store buffer update is required.
631 if (value != R0) {
632 // Preserve R0.
633 Push(R0);
634 }
635 Push(LR);
636 if (object != R0) {
637 mov(R0, object);
638 }
639 BranchLink(&StubCode::UpdateStoreBufferLabel(), PP);
640 Pop(LR);
641 if (value != R0) {
642 // Restore R0.
643 Pop(R0);
644 }
645 Bind(&done);
646 }
647
648
649 void Assembler::StoreIntoObjectNoBarrier(Register object,
650 const Address& dest,
651 Register value) {
652 str(value, dest);
653 #if defined(DEBUG)
654 Label done;
655 StoreIntoObjectFilter(object, value, &done);
656 Stop("Store buffer update is required");
657 Bind(&done);
658 #endif // defined(DEBUG)
659 // No store buffer update.
660 }
661
662
663 void Assembler::StoreIntoObjectNoBarrier(Register object,
664 const Address& dest,
665 const Object& value) {
666 ASSERT(value.IsSmi() || value.InVMHeap() ||
667 (value.IsOld() && value.IsNotTemporaryScopedHandle()));
668 // No store buffer update.
669 LoadObject(TMP, value, PP);
670 str(TMP, dest);
671 }
672
673
674 // Frame entry and exit.
586 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) { 675 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) {
587 // Reserve space for arguments and align frame before entering 676 // Reserve space for arguments and align frame before entering
588 // the C++ world. 677 // the C++ world.
589 AddImmediate(SP, SP, -frame_space, kNoRegister); 678 AddImmediate(SP, SP, -frame_space, kNoRegister);
590 if (OS::ActivationFrameAlignment() > 1) { 679 if (OS::ActivationFrameAlignment() > 1) {
591 mov(TMP, SP); // SP can't be register operand of andi. 680 mov(TMP, SP); // SP can't be register operand of andi.
592 andi(TMP, TMP, ~(OS::ActivationFrameAlignment() - 1)); 681 andi(TMP, TMP, ~(OS::ActivationFrameAlignment() - 1));
593 mov(SP, TMP); 682 mov(SP, TMP);
594 } 683 }
595 } 684 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 720
632 721
633 void Assembler::LeaveDartFrame() { 722 void Assembler::LeaveDartFrame() {
634 // Restore and untag PP. 723 // Restore and untag PP.
635 LoadFromOffset(PP, FP, kSavedCallerPpSlotFromFp * kWordSize); 724 LoadFromOffset(PP, FP, kSavedCallerPpSlotFromFp * kWordSize);
636 sub(PP, PP, Operand(kHeapObjectTag)); 725 sub(PP, PP, Operand(kHeapObjectTag));
637 LeaveFrame(); 726 LeaveFrame();
638 } 727 }
639 728
640 729
730 void Assembler::EnterCallRuntimeFrame(intptr_t frame_size) {
731 EnterFrame(0);
732
733 // TODO(zra): also save volatile FPU registers.
734
735 for (int i = kDartFirstVolatileCpuReg; i <= kDartLastVolatileCpuReg; i++) {
736 const Register reg = static_cast<Register>(i);
737 Push(reg);
738 }
739
740 ReserveAlignedFrameSpace(frame_size);
741 }
742
743
744 void Assembler::LeaveCallRuntimeFrame() {
745 // SP might have been modified to reserve space for arguments
746 // and ensure proper alignment of the stack frame.
747 // We need to restore it before restoring registers.
748 // TODO(zra): Also include FPU regs in this count once they are added.
749 const intptr_t kPushedRegistersSize =
750 kDartVolatileCpuRegCount * kWordSize;
751 AddImmediate(SP, FP, -kPushedRegistersSize, PP);
752 for (int i = kDartLastVolatileCpuReg; i >= kDartFirstVolatileCpuReg; i--) {
753 const Register reg = static_cast<Register>(i);
754 Pop(reg);
755 }
756
757 Pop(FP);
758 Pop(LR);
759 }
760
761
641 void Assembler::CallRuntime(const RuntimeEntry& entry, 762 void Assembler::CallRuntime(const RuntimeEntry& entry,
642 intptr_t argument_count) { 763 intptr_t argument_count) {
643 entry.Call(this, argument_count); 764 entry.Call(this, argument_count);
644 } 765 }
645 766
646 } // namespace dart 767 } // namespace dart
647 768
648 #endif // defined TARGET_ARCH_ARM64 769 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/assembler_arm64.h ('k') | runtime/vm/assembler_arm64_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698