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

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

Issue 1156593002: Cache current thread in a reserved register and use it in LoadIsolate (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Added more comments. Created 5 years, 7 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
OLDNEW
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_ARM) 6 #if defined(TARGET_ARCH_ARM)
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/cpu.h" 10 #include "vm/cpu.h"
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 __ cmp(R3, Operand(0)); 622 __ cmp(R3, Operand(0));
623 __ b(&slow_case, LT); 623 __ b(&slow_case, LT);
624 624
625 // Check for maximum allowed length. 625 // Check for maximum allowed length.
626 const intptr_t max_len = 626 const intptr_t max_len =
627 reinterpret_cast<int32_t>(Smi::New(Array::kMaxElements)); 627 reinterpret_cast<int32_t>(Smi::New(Array::kMaxElements));
628 __ CompareImmediate(R3, max_len); 628 __ CompareImmediate(R3, max_len);
629 __ b(&slow_case, GT); 629 __ b(&slow_case, GT);
630 630
631 const intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; 631 const intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1;
632 __ LoadImmediate(R8, fixed_size); 632 __ LoadImmediate(R9, fixed_size);
633 __ add(R8, R8, Operand(R3, LSL, 1)); // R3 is a Smi. 633 __ add(R9, R9, Operand(R3, LSL, 1)); // R3 is a Smi.
634 ASSERT(kSmiTagShift == 1); 634 ASSERT(kSmiTagShift == 1);
635 __ bic(R8, R8, Operand(kObjectAlignment - 1)); 635 __ bic(R9, R9, Operand(kObjectAlignment - 1));
636 636
637 // R8: Allocation size. 637 // R9: Allocation size.
638 638
639 Isolate* isolate = Isolate::Current(); 639 Isolate* isolate = Isolate::Current();
640 Heap* heap = isolate->heap(); 640 Heap* heap = isolate->heap();
641 const intptr_t cid = kArrayCid; 641 const intptr_t cid = kArrayCid;
642 Heap::Space space = heap->SpaceForAllocation(cid); 642 Heap::Space space = heap->SpaceForAllocation(cid);
643 __ LoadImmediate(R6, heap->TopAddress(space)); 643 __ LoadImmediate(R6, heap->TopAddress(space));
644 __ ldr(R0, Address(R6, 0)); // Potential new object start. 644 __ ldr(R0, Address(R6, 0)); // Potential new object start.
645 __ adds(R7, R0, Operand(R8)); // Potential next object start. 645 __ adds(R7, R0, Operand(R9)); // Potential next object start.
646 __ b(&slow_case, CS); // Branch if unsigned overflow. 646 __ b(&slow_case, CS); // Branch if unsigned overflow.
647 647
648 // Check if the allocation fits into the remaining space. 648 // Check if the allocation fits into the remaining space.
649 // R0: potential new object start. 649 // R0: potential new object start.
650 // R7: potential next object start. 650 // R7: potential next object start.
651 // R8: allocation size. 651 // R9: allocation size.
652 __ LoadImmediate(R3, heap->EndAddress(space)); 652 __ LoadImmediate(R3, heap->EndAddress(space));
653 __ ldr(R3, Address(R3, 0)); 653 __ ldr(R3, Address(R3, 0));
654 __ cmp(R7, Operand(R3)); 654 __ cmp(R7, Operand(R3));
655 __ b(&slow_case, CS); 655 __ b(&slow_case, CS);
656 656
657 // Successfully allocated the object(s), now update top to point to 657 // Successfully allocated the object(s), now update top to point to
658 // next object start and initialize the object. 658 // next object start and initialize the object.
659 __ LoadAllocationStatsAddress(R3, cid, space); 659 __ LoadAllocationStatsAddress(R3, cid, space);
660 __ str(R7, Address(R6, 0)); 660 __ str(R7, Address(R6, 0));
661 __ add(R0, R0, Operand(kHeapObjectTag)); 661 __ add(R0, R0, Operand(kHeapObjectTag));
662 662
663 // Initialize the tags. 663 // Initialize the tags.
664 // R0: new object start as a tagged pointer. 664 // R0: new object start as a tagged pointer.
665 // R3: allocation stats address. 665 // R3: allocation stats address.
666 // R7: new object end address. 666 // R7: new object end address.
667 // R8: allocation size. 667 // R9: allocation size.
668 { 668 {
669 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; 669 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2;
670 670
671 __ CompareImmediate(R8, RawObject::SizeTag::kMaxSizeTag); 671 __ CompareImmediate(R9, RawObject::SizeTag::kMaxSizeTag);
672 __ mov(R6, Operand(R8, LSL, shift), LS); 672 __ mov(R6, Operand(R9, LSL, shift), LS);
673 __ mov(R6, Operand(0), HI); 673 __ mov(R6, Operand(0), HI);
674 674
675 // Get the class index and insert it into the tags. 675 // Get the class index and insert it into the tags.
676 // R6: size and bit tags. 676 // R6: size and bit tags.
677 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cid)); 677 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cid));
678 __ orr(R6, R6, Operand(TMP)); 678 __ orr(R6, R6, Operand(TMP));
679 __ str(R6, FieldAddress(R0, Array::tags_offset())); // Store tags. 679 __ str(R6, FieldAddress(R0, Array::tags_offset())); // Store tags.
680 } 680 }
681 681
682 // R0: new object start as a tagged pointer. 682 // R0: new object start as a tagged pointer.
683 // R7: new object end address. 683 // R7: new object end address.
684 // Store the type argument field. 684 // Store the type argument field.
685 __ InitializeFieldNoBarrier(R0, 685 __ InitializeFieldNoBarrier(R0,
686 FieldAddress(R0, Array::type_arguments_offset()), 686 FieldAddress(R0, Array::type_arguments_offset()),
687 R1); 687 R1);
688 688
689 // Set the length field. 689 // Set the length field.
690 __ InitializeFieldNoBarrier(R0, 690 __ InitializeFieldNoBarrier(R0,
691 FieldAddress(R0, Array::length_offset()), 691 FieldAddress(R0, Array::length_offset()),
692 R2); 692 R2);
693 693
694 // Initialize all array elements to raw_null. 694 // Initialize all array elements to raw_null.
695 // R0: new object start as a tagged pointer. 695 // R0: new object start as a tagged pointer.
696 // R3: allocation stats address. 696 // R3: allocation stats address.
697 // R4, R5: null 697 // R4, R5: null
698 // R6: iterator which initially points to the start of the variable 698 // R6: iterator which initially points to the start of the variable
699 // data area to be initialized. 699 // data area to be initialized.
700 // R7: new object end address. 700 // R7: new object end address.
701 // R8: allocation size. 701 // R9: allocation size.
702 702
703 __ LoadImmediate(R4, reinterpret_cast<intptr_t>(Object::null())); 703 __ LoadImmediate(R4, reinterpret_cast<intptr_t>(Object::null()));
704 __ mov(R5, Operand(R4)); 704 __ mov(R5, Operand(R4));
705 __ AddImmediate(R6, R0, sizeof(RawArray) - kHeapObjectTag); 705 __ AddImmediate(R6, R0, sizeof(RawArray) - kHeapObjectTag);
706 __ InitializeFieldsNoBarrier(R0, R6, R7, R4, R5); 706 __ InitializeFieldsNoBarrier(R0, R6, R7, R4, R5);
707 __ IncrementAllocationStatsWithSize(R3, R8, cid, space); 707 __ IncrementAllocationStatsWithSize(R3, R9, cid, space);
708 __ Ret(); // Returns the newly allocated object in R0. 708 __ Ret(); // Returns the newly allocated object in R0.
709 // Unable to allocate the array using the fast inline code, just call 709 // Unable to allocate the array using the fast inline code, just call
710 // into the runtime. 710 // into the runtime.
711 __ Bind(&slow_case); 711 __ Bind(&slow_case);
712 712
713 // Create a stub frame as we are pushing some objects on the stack before 713 // Create a stub frame as we are pushing some objects on the stack before
714 // calling into the runtime. 714 // calling into the runtime.
715 __ EnterStubFrame(); 715 __ EnterStubFrame();
716 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); 716 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null()));
717 // Setup space on stack for return value. 717 // Setup space on stack for return value.
(...skipping 10 matching lines...) Expand all
728 __ BranchPatchable(&stub_code->FixAllocateArrayStubTargetLabel()); 728 __ BranchPatchable(&stub_code->FixAllocateArrayStubTargetLabel());
729 } 729 }
730 730
731 731
732 // Called when invoking Dart code from C++ (VM code). 732 // Called when invoking Dart code from C++ (VM code).
733 // Input parameters: 733 // Input parameters:
734 // LR : points to return address. 734 // LR : points to return address.
735 // R0 : entrypoint of the Dart function to call. 735 // R0 : entrypoint of the Dart function to call.
736 // R1 : arguments descriptor array. 736 // R1 : arguments descriptor array.
737 // R2 : arguments array. 737 // R2 : arguments array.
738 // R3 : new context containing the current isolate pointer. 738 // R3 : current thread.
739 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { 739 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
740 // Save frame pointer coming in. 740 // Save frame pointer coming in.
741 __ EnterFrame((1 << FP) | (1 << LR), 0); 741 __ EnterFrame((1 << FP) | (1 << LR), 0);
742 742
743 // Save new context and C++ ABI callee-saved registers. 743 // Save new context and C++ ABI callee-saved registers.
744 __ PushList(kAbiPreservedCpuRegs); 744 __ PushList(kAbiPreservedCpuRegs);
745 745
746 const DRegister firstd = EvenDRegisterOf(kAbiFirstPreservedFpuReg); 746 const DRegister firstd = EvenDRegisterOf(kAbiFirstPreservedFpuReg);
747 if (TargetCPUFeatures::vfp_supported()) { 747 if (TargetCPUFeatures::vfp_supported()) {
748 ASSERT(2 * kAbiPreservedFpuRegCount < 16); 748 ASSERT(2 * kAbiPreservedFpuRegCount < 16);
749 // Save FPU registers. 2 D registers per Q register. 749 // Save FPU registers. 2 D registers per Q register.
750 __ vstmd(DB_W, SP, firstd, 2 * kAbiPreservedFpuRegCount); 750 __ vstmd(DB_W, SP, firstd, 2 * kAbiPreservedFpuRegCount);
751 } else { 751 } else {
752 __ sub(SP, SP, Operand(kAbiPreservedFpuRegCount * kFpuRegisterSize)); 752 __ sub(SP, SP, Operand(kAbiPreservedFpuRegCount * kFpuRegisterSize));
753 } 753 }
754 754
755 // We now load the pool pointer(PP) as we are about to invoke dart code and we 755 // We now load the pool pointer(PP) as we are about to invoke dart code and we
756 // could potentially invoke some intrinsic functions which need the PP to be 756 // could potentially invoke some intrinsic functions which need the PP to be
757 // set up. 757 // set up.
758 __ LoadPoolPointer(); 758 __ LoadPoolPointer();
759 759
760 __ LoadIsolate(R8); 760 // Set up THR, which caches the current thread in Dart code.
761 if (THR != R3) {
762 __ mov(THR, Operand(R3));
763 }
764 __ LoadIsolate(R9);
761 765
762 // Save the current VMTag on the stack. 766 // Save the current VMTag on the stack.
763 __ LoadFromOffset(kWord, R5, R8, Isolate::vm_tag_offset()); 767 __ LoadFromOffset(kWord, R5, R9, Isolate::vm_tag_offset());
764 __ Push(R5); 768 __ Push(R5);
765 769
766 // Mark that the isolate is executing Dart code. 770 // Mark that the isolate is executing Dart code.
767 __ LoadImmediate(R5, VMTag::kDartTagId); 771 __ LoadImmediate(R5, VMTag::kDartTagId);
768 __ StoreToOffset(kWord, R5, R8, Isolate::vm_tag_offset()); 772 __ StoreToOffset(kWord, R5, R9, Isolate::vm_tag_offset());
769 773
770 // Save top resource and top exit frame info. Use R4-6 as temporary registers. 774 // Save top resource and top exit frame info. Use R4-6 as temporary registers.
771 // StackFrameIterator reads the top exit frame info saved in this frame. 775 // StackFrameIterator reads the top exit frame info saved in this frame.
772 __ LoadFromOffset(kWord, R5, R8, Isolate::top_exit_frame_info_offset()); 776 __ LoadFromOffset(kWord, R5, R9, Isolate::top_exit_frame_info_offset());
773 __ LoadFromOffset(kWord, R4, R8, Isolate::top_resource_offset()); 777 __ LoadFromOffset(kWord, R4, R9, Isolate::top_resource_offset());
774 __ LoadImmediate(R6, 0); 778 __ LoadImmediate(R6, 0);
775 __ StoreToOffset(kWord, R6, R8, Isolate::top_resource_offset()); 779 __ StoreToOffset(kWord, R6, R9, Isolate::top_resource_offset());
776 __ StoreToOffset(kWord, R6, R8, Isolate::top_exit_frame_info_offset()); 780 __ StoreToOffset(kWord, R6, R9, Isolate::top_exit_frame_info_offset());
777 781
778 // kExitLinkSlotFromEntryFp must be kept in sync with the code below. 782 // kExitLinkSlotFromEntryFp must be kept in sync with the code below.
779 __ Push(R4); 783 __ Push(R4);
780 ASSERT(kExitLinkSlotFromEntryFp == -26); 784 ASSERT(kExitLinkSlotFromEntryFp == -26);
781 __ Push(R5); 785 __ Push(R5);
782 786
783 // Load arguments descriptor array into R4, which is passed to Dart code. 787 // Load arguments descriptor array into R4, which is passed to Dart code.
784 __ ldr(R4, Address(R1, VMHandles::kOffsetOfRawPtrInHandle)); 788 __ ldr(R4, Address(R1, VMHandles::kOffsetOfRawPtrInHandle));
785 789
786 // Load number of arguments into R5. 790 // Load number of arguments into R5.
(...skipping 18 matching lines...) Expand all
805 __ cmp(R1, Operand(R5)); 809 __ cmp(R1, Operand(R5));
806 __ b(&push_arguments, LT); 810 __ b(&push_arguments, LT);
807 __ Bind(&done_push_arguments); 811 __ Bind(&done_push_arguments);
808 812
809 // Call the Dart code entrypoint. 813 // Call the Dart code entrypoint.
810 __ blx(R0); // R4 is the arguments descriptor array. 814 __ blx(R0); // R4 is the arguments descriptor array.
811 815
812 // Get rid of arguments pushed on the stack. 816 // Get rid of arguments pushed on the stack.
813 __ AddImmediate(SP, FP, kExitLinkSlotFromEntryFp * kWordSize); 817 __ AddImmediate(SP, FP, kExitLinkSlotFromEntryFp * kWordSize);
814 818
815 __ LoadIsolate(R8); 819 __ LoadIsolate(R9);
816 // Restore the saved top exit frame info and top resource back into the 820 // Restore the saved top exit frame info and top resource back into the
817 // Isolate structure. Uses R5 as a temporary register for this. 821 // Isolate structure. Uses R5 as a temporary register for this.
818 __ Pop(R5); 822 __ Pop(R5);
819 __ StoreToOffset(kWord, R5, R8, Isolate::top_exit_frame_info_offset()); 823 __ StoreToOffset(kWord, R5, R9, Isolate::top_exit_frame_info_offset());
820 __ Pop(R5); 824 __ Pop(R5);
821 __ StoreToOffset(kWord, R5, R8, Isolate::top_resource_offset()); 825 __ StoreToOffset(kWord, R5, R9, Isolate::top_resource_offset());
822 826
823 // Restore the current VMTag from the stack. 827 // Restore the current VMTag from the stack.
824 __ Pop(R4); 828 __ Pop(R4);
825 __ StoreToOffset(kWord, R4, R8, Isolate::vm_tag_offset()); 829 __ StoreToOffset(kWord, R4, R9, Isolate::vm_tag_offset());
826 830
827 // Restore C++ ABI callee-saved registers. 831 // Restore C++ ABI callee-saved registers.
828 if (TargetCPUFeatures::vfp_supported()) { 832 if (TargetCPUFeatures::vfp_supported()) {
829 // Restore FPU registers. 2 D registers per Q register. 833 // Restore FPU registers. 2 D registers per Q register.
830 __ vldmd(IA_W, SP, firstd, 2 * kAbiPreservedFpuRegCount); 834 __ vldmd(IA_W, SP, firstd, 2 * kAbiPreservedFpuRegCount);
831 } else { 835 } else {
832 __ AddImmediate(SP, kAbiPreservedFpuRegCount * kFpuRegisterSize); 836 __ AddImmediate(SP, kAbiPreservedFpuRegCount * kFpuRegisterSize);
833 } 837 }
834 // Restore CPU registers. 838 // Restore CPU registers.
835 __ PopList(kAbiPreservedCpuRegs); 839 __ PopList(kAbiPreservedCpuRegs);
(...skipping 1081 matching lines...) Expand 10 before | Expand all | Expand 10 after
1917 void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) { 1921 void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) {
1918 ASSERT(kExceptionObjectReg == R0); 1922 ASSERT(kExceptionObjectReg == R0);
1919 ASSERT(kStackTraceObjectReg == R1); 1923 ASSERT(kStackTraceObjectReg == R1);
1920 __ mov(IP, Operand(R1)); // Copy Stack pointer into IP. 1924 __ mov(IP, Operand(R1)); // Copy Stack pointer into IP.
1921 __ mov(LR, Operand(R0)); // Program counter. 1925 __ mov(LR, Operand(R0)); // Program counter.
1922 __ mov(R0, Operand(R3)); // Exception object. 1926 __ mov(R0, Operand(R3)); // Exception object.
1923 __ ldr(R1, Address(SP, 0)); // StackTrace object. 1927 __ ldr(R1, Address(SP, 0)); // StackTrace object.
1924 __ ldr(R3, Address(SP, 4)); // Isolate. 1928 __ ldr(R3, Address(SP, 4)); // Isolate.
1925 __ mov(FP, Operand(R2)); // Frame_pointer. 1929 __ mov(FP, Operand(R2)); // Frame_pointer.
1926 __ mov(SP, Operand(IP)); // Set Stack pointer. 1930 __ mov(SP, Operand(IP)); // Set Stack pointer.
1931 // TODO(koda): Pass thread instead of isolate.
1932 __ LoadFromOffset(kWord, THR, R3, Isolate::mutator_thread_offset());
1927 // Set the tag. 1933 // Set the tag.
1928 __ LoadImmediate(R2, VMTag::kDartTagId); 1934 __ LoadImmediate(R2, VMTag::kDartTagId);
1929 __ StoreToOffset(kWord, R2, R3, Isolate::vm_tag_offset()); 1935 __ StoreToOffset(kWord, R2, R3, Isolate::vm_tag_offset());
1930 // Clear top exit frame. 1936 // Clear top exit frame.
1931 __ LoadImmediate(R2, 0); 1937 __ LoadImmediate(R2, 0);
1932 __ StoreToOffset(kWord, R2, R3, Isolate::top_exit_frame_info_offset()); 1938 __ StoreToOffset(kWord, R2, R3, Isolate::top_exit_frame_info_offset());
1933 __ bx(LR); // Jump to the exception handler code. 1939 __ bx(LR); // Jump to the exception handler code.
1934 } 1940 }
1935 1941
1936 1942
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
2130 // Result: 2136 // Result:
2131 // R1: entry point. 2137 // R1: entry point.
2132 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { 2138 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
2133 EmitMegamorphicLookup(assembler, R0, R1, R1); 2139 EmitMegamorphicLookup(assembler, R0, R1, R1);
2134 __ Ret(); 2140 __ Ret();
2135 } 2141 }
2136 2142
2137 } // namespace dart 2143 } // namespace dart
2138 2144
2139 #endif // defined TARGET_ARCH_ARM 2145 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698