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

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
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
regis 2014/04/22 18:45:32 value & ~object is a 'bit clear' operation. Inste
zra 2014/04/22 19:44:02 Done.
597 // if the bit is not set. We can't destroy the object.
598 orn(TMP, ZR, Operand(object));
599 and_(TMP, value, Operand(TMP));
600 tsti(TMP, kNewObjectAlignmentOffset);
601 b(no_update, EQ);
602 }
603
604
605 // Preserves object and value registers.
606 void Assembler::StoreIntoObjectFilter(Register object,
607 Register value,
608 Label* no_update) {
609 // For the value we are only interested in the new/old bit and the tag bit.
610 // And the new bit with the tag bit. The resulting bit will be 0 for a Smi.
611 Lsl(TMP, value, kObjectAlignmentLog2 - 1);
612 and_(TMP, value, Operand(TMP));
613 // And the result with the negated space bit of the object.
614 orn(TMP2, ZR, Operand(object));
615 and_(TMP, TMP, Operand(TMP2));
616 tsti(TMP, kNewObjectAlignmentOffset);
regis 2014/04/22 18:45:32 Instead of Lsl(TMP, value, kObjectAlignmentLog2 -
zra 2014/04/22 19:44:02 Done.
617 b(no_update, EQ);
618 }
619
620
621 void Assembler::StoreIntoObject(Register object,
622 const Address& dest,
623 Register value,
624 bool can_value_be_smi) {
625 ASSERT(object != value);
626 str(value, dest);
627 Label done;
628 if (can_value_be_smi) {
629 StoreIntoObjectFilter(object, value, &done);
630 } else {
631 StoreIntoObjectFilterNoSmi(object, value, &done);
632 }
633 // A store buffer update is required.
634 if (value != R0) {
635 // Preserve R0.
636 Push(R0);
637 }
638 Push(LR);
639 if (object != R0) {
640 mov(R0, object);
641 }
642 BranchLink(&StubCode::UpdateStoreBufferLabel(), PP);
643 Pop(LR);
644 if (value != R0) {
645 // Restore R0.
646 Pop(R0);
647 }
648 Bind(&done);
649 }
650
651
652 void Assembler::StoreIntoObjectNoBarrier(Register object,
653 const Address& dest,
654 Register value) {
655 str(value, dest);
656 #if defined(DEBUG)
657 Label done;
658 StoreIntoObjectFilter(object, value, &done);
659 Stop("Store buffer update is required");
660 Bind(&done);
661 #endif // defined(DEBUG)
662 // No store buffer update.
663 }
664
665
666 void Assembler::StoreIntoObjectNoBarrier(Register object,
667 const Address& dest,
668 const Object& value) {
669 ASSERT(value.IsSmi() || value.InVMHeap() ||
670 (value.IsOld() && value.IsNotTemporaryScopedHandle()));
671 // No store buffer update.
672 LoadObject(TMP, value, PP);
673 str(TMP, dest);
674 }
675
676
677 // Frame entry and exit.
586 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) { 678 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) {
587 // Reserve space for arguments and align frame before entering 679 // Reserve space for arguments and align frame before entering
588 // the C++ world. 680 // the C++ world.
589 AddImmediate(SP, SP, -frame_space, kNoRegister); 681 AddImmediate(SP, SP, -frame_space, kNoRegister);
590 if (OS::ActivationFrameAlignment() > 1) { 682 if (OS::ActivationFrameAlignment() > 1) {
591 mov(TMP, SP); // SP can't be register operand of andi. 683 mov(TMP, SP); // SP can't be register operand of andi.
592 andi(TMP, TMP, ~(OS::ActivationFrameAlignment() - 1)); 684 andi(TMP, TMP, ~(OS::ActivationFrameAlignment() - 1));
593 mov(SP, TMP); 685 mov(SP, TMP);
594 } 686 }
595 } 687 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 723
632 724
633 void Assembler::LeaveDartFrame() { 725 void Assembler::LeaveDartFrame() {
634 // Restore and untag PP. 726 // Restore and untag PP.
635 LoadFromOffset(PP, FP, kSavedCallerPpSlotFromFp * kWordSize); 727 LoadFromOffset(PP, FP, kSavedCallerPpSlotFromFp * kWordSize);
636 sub(PP, PP, Operand(kHeapObjectTag)); 728 sub(PP, PP, Operand(kHeapObjectTag));
637 LeaveFrame(); 729 LeaveFrame();
638 } 730 }
639 731
640 732
733 void Assembler::EnterCallRuntimeFrame(intptr_t frame_size) {
734 EnterFrame(0);
735
736 // TODO(zra): also save volatile FPU registers.
737
738 for (int i = kDartFirstVolatileCpuReg; i <= kDartLastVolatileCpuReg; i++) {
739 const Register reg = static_cast<Register>(i);
740 Push(reg);
741 }
742
743 ReserveAlignedFrameSpace(frame_size);
744 }
745
746
747 void Assembler::LeaveCallRuntimeFrame() {
748 // SP might have been modified to reserve space for arguments
749 // and ensure proper alignment of the stack frame.
750 // We need to restore it before restoring registers.
751 // TODO(zra): Also include FPU regs in this count once they are added.
752 const intptr_t kPushedRegistersSize =
753 kDartVolatileCpuRegCount * kWordSize;
754 AddImmediate(SP, FP, -kPushedRegistersSize, PP);
755 for (int i = kDartLastVolatileCpuReg; i >= kDartFirstVolatileCpuReg; i--) {
756 const Register reg = static_cast<Register>(i);
757 Pop(reg);
758 }
759
760 Pop(FP);
761 Pop(LR);
762 }
763
764
641 void Assembler::CallRuntime(const RuntimeEntry& entry, 765 void Assembler::CallRuntime(const RuntimeEntry& entry,
642 intptr_t argument_count) { 766 intptr_t argument_count) {
643 entry.Call(this, argument_count); 767 entry.Call(this, argument_count);
644 } 768 }
645 769
646 } // namespace dart 770 } // namespace dart
647 771
648 #endif // defined TARGET_ARCH_ARM64 772 #endif // defined TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698