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_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 619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
630 const intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; | 630 const intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; |
631 __ LoadImmediate(R8, fixed_size); | 631 __ LoadImmediate(R8, fixed_size); |
632 __ add(R8, R8, Operand(R3, LSL, 1)); // R3 is a Smi. | 632 __ add(R8, R8, Operand(R3, LSL, 1)); // R3 is a Smi. |
633 ASSERT(kSmiTagShift == 1); | 633 ASSERT(kSmiTagShift == 1); |
634 __ bic(R8, R8, Operand(kObjectAlignment - 1)); | 634 __ bic(R8, R8, Operand(kObjectAlignment - 1)); |
635 | 635 |
636 // R8: Allocation size. | 636 // R8: Allocation size. |
637 | 637 |
638 Isolate* isolate = Isolate::Current(); | 638 Isolate* isolate = Isolate::Current(); |
639 Heap* heap = isolate->heap(); | 639 Heap* heap = isolate->heap(); |
640 | 640 Heap::Space space = heap->SpaceForAllocation(kArrayCid); |
641 __ LoadImmediate(R6, heap->TopAddress()); | 641 __ LoadImmediate(R6, heap->TopAddress(space)); |
642 __ ldr(R0, Address(R6, 0)); // Potential new object start. | 642 __ ldr(R0, Address(R6, 0)); // Potential new object start. |
643 __ adds(R7, R0, Operand(R8)); // Potential next object start. | 643 __ adds(R7, R0, Operand(R8)); // Potential next object start. |
644 __ b(&slow_case, VS); | 644 __ b(&slow_case, VS); |
645 | 645 |
646 // Check if the allocation fits into the remaining space. | 646 // Check if the allocation fits into the remaining space. |
647 // R0: potential new object start. | 647 // R0: potential new object start. |
648 // R7: potential next object start. | 648 // R7: potential next object start. |
649 // R8: allocation size. | 649 // R8: allocation size. |
650 __ LoadImmediate(R3, heap->EndAddress()); | 650 __ LoadImmediate(R3, heap->EndAddress(space)); |
651 __ ldr(R3, Address(R3, 0)); | 651 __ ldr(R3, Address(R3, 0)); |
652 __ cmp(R7, Operand(R3)); | 652 __ cmp(R7, Operand(R3)); |
653 __ b(&slow_case, CS); | 653 __ b(&slow_case, CS); |
654 | 654 |
655 // Successfully allocated the object(s), now update top to point to | 655 // Successfully allocated the object(s), now update top to point to |
656 // next object start and initialize the object. | 656 // next object start and initialize the object. |
657 __ str(R7, Address(R6, 0)); | 657 __ str(R7, Address(R6, 0)); |
658 __ add(R0, R0, Operand(kHeapObjectTag)); | 658 __ add(R0, R0, Operand(kHeapObjectTag)); |
659 __ UpdateAllocationStatsWithSize(kArrayCid, R8, R4); | 659 __ UpdateAllocationStatsWithSize(kArrayCid, R8, R4, space); |
660 | 660 |
661 // Initialize the tags. | 661 // Initialize the tags. |
662 // R0: new object start as a tagged pointer. | 662 // R0: new object start as a tagged pointer. |
663 // R7: new object end address. | 663 // R7: new object end address. |
664 // R8: allocation size. | 664 // R8: allocation size. |
665 { | 665 { |
666 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; | 666 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; |
667 const Class& cls = Class::Handle(isolate->object_store()->array_class()); | 667 const Class& cls = Class::Handle(isolate->object_store()->array_class()); |
668 | 668 |
669 __ CompareImmediate(R8, RawObject::SizeTag::kMaxSizeTag); | 669 __ CompareImmediate(R8, RawObject::SizeTag::kMaxSizeTag); |
670 __ mov(R8, Operand(R8, LSL, shift), LS); | 670 __ mov(R8, Operand(R8, LSL, shift), LS); |
671 __ mov(R8, Operand(0), HI); | 671 __ mov(R8, Operand(0), HI); |
672 | 672 |
673 // Get the class index and insert it into the tags. | 673 // Get the class index and insert it into the tags. |
674 // R8: size and bit tags. | 674 // R8: size and bit tags. |
675 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cls.id())); | 675 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cls.id())); |
Ivan Posva
2014/09/19 18:45:55
ditto
koda
2014/09/19 20:48:29
Done.
| |
676 __ orr(R8, R8, Operand(TMP)); | 676 __ orr(R8, R8, Operand(TMP)); |
677 __ str(R8, FieldAddress(R0, Array::tags_offset())); // Store tags. | 677 __ str(R8, FieldAddress(R0, Array::tags_offset())); // Store tags. |
678 } | 678 } |
679 | 679 |
680 // R0: new object start as a tagged pointer. | 680 // R0: new object start as a tagged pointer. |
681 // R7: new object end address. | 681 // R7: new object end address. |
682 // Store the type argument field. | 682 // Store the type argument field. |
683 __ StoreIntoObjectNoBarrier(R0, | 683 __ StoreIntoObjectNoBarrier(R0, |
684 FieldAddress(R0, Array::type_arguments_offset()), | 684 FieldAddress(R0, Array::type_arguments_offset()), |
685 R1); | 685 R1); |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
863 } | 863 } |
864 | 864 |
865 | 865 |
866 // Called for inline allocation of contexts. | 866 // Called for inline allocation of contexts. |
867 // Input: | 867 // Input: |
868 // R1: number of context variables. | 868 // R1: number of context variables. |
869 // Output: | 869 // Output: |
870 // R0: new allocated RawContext object. | 870 // R0: new allocated RawContext object. |
871 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { | 871 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { |
872 if (FLAG_inline_alloc) { | 872 if (FLAG_inline_alloc) { |
873 const Class& context_class = Class::ZoneHandle(Object::context_class()); | 873 const Class& context_class = Class::ZoneHandle(Object::context_class()); |
Ivan Posva
2014/09/19 18:45:55
ditto: Just use the kXYZCid everywhere where we kn
koda
2014/09/19 20:48:29
Done.
| |
874 Label slow_case; | 874 Label slow_case; |
875 Heap* heap = Isolate::Current()->heap(); | 875 Heap* heap = Isolate::Current()->heap(); |
876 // First compute the rounded instance size. | 876 // First compute the rounded instance size. |
877 // R1: number of context variables. | 877 // R1: number of context variables. |
878 intptr_t fixed_size = sizeof(RawContext) + kObjectAlignment - 1; | 878 intptr_t fixed_size = sizeof(RawContext) + kObjectAlignment - 1; |
879 __ LoadImmediate(R2, fixed_size); | 879 __ LoadImmediate(R2, fixed_size); |
880 __ add(R2, R2, Operand(R1, LSL, 2)); | 880 __ add(R2, R2, Operand(R1, LSL, 2)); |
881 ASSERT(kSmiTagShift == 1); | 881 ASSERT(kSmiTagShift == 1); |
882 __ bic(R2, R2, Operand(kObjectAlignment - 1)); | 882 __ bic(R2, R2, Operand(kObjectAlignment - 1)); |
883 | 883 |
884 // Now allocate the object. | 884 // Now allocate the object. |
885 // R1: number of context variables. | 885 // R1: number of context variables. |
886 // R2: object size. | 886 // R2: object size. |
887 __ LoadImmediate(R5, heap->TopAddress()); | 887 intptr_t cid = context_class.id(); |
888 Heap::Space space = heap->SpaceForAllocation(cid); | |
889 __ LoadImmediate(R5, heap->TopAddress(space)); | |
888 __ ldr(R0, Address(R5, 0)); | 890 __ ldr(R0, Address(R5, 0)); |
889 __ add(R3, R2, Operand(R0)); | 891 __ add(R3, R2, Operand(R0)); |
890 // Check if the allocation fits into the remaining space. | 892 // Check if the allocation fits into the remaining space. |
891 // R0: potential new object. | 893 // R0: potential new object. |
892 // R1: number of context variables. | 894 // R1: number of context variables. |
893 // R2: object size. | 895 // R2: object size. |
894 // R3: potential next object start. | 896 // R3: potential next object start. |
895 __ LoadImmediate(IP, heap->EndAddress()); | 897 __ LoadImmediate(IP, heap->EndAddress(space)); |
896 __ ldr(IP, Address(IP, 0)); | 898 __ ldr(IP, Address(IP, 0)); |
897 __ cmp(R3, Operand(IP)); | 899 __ cmp(R3, Operand(IP)); |
898 if (FLAG_use_slow_path) { | 900 if (FLAG_use_slow_path) { |
899 __ b(&slow_case); | 901 __ b(&slow_case); |
900 } else { | 902 } else { |
901 __ b(&slow_case, CS); // Branch if unsigned higher or equal. | 903 __ b(&slow_case, CS); // Branch if unsigned higher or equal. |
902 } | 904 } |
903 | 905 |
904 // Successfully allocated the object, now update top to point to | 906 // Successfully allocated the object, now update top to point to |
905 // next object start and initialize the object. | 907 // next object start and initialize the object. |
906 // R0: new object. | 908 // R0: new object. |
907 // R1: number of context variables. | 909 // R1: number of context variables. |
908 // R2: object size. | 910 // R2: object size. |
909 // R3: next object start. | 911 // R3: next object start. |
910 __ str(R3, Address(R5, 0)); | 912 __ str(R3, Address(R5, 0)); |
911 __ add(R0, R0, Operand(kHeapObjectTag)); | 913 __ add(R0, R0, Operand(kHeapObjectTag)); |
912 __ UpdateAllocationStatsWithSize(context_class.id(), R2, R5); | 914 __ UpdateAllocationStatsWithSize(cid, R2, R5, space); |
913 | 915 |
914 // Calculate the size tag. | 916 // Calculate the size tag. |
915 // R0: new object. | 917 // R0: new object. |
916 // R1: number of context variables. | 918 // R1: number of context variables. |
917 // R2: object size. | 919 // R2: object size. |
918 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; | 920 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; |
919 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag); | 921 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag); |
920 // If no size tag overflow, shift R2 left, else set R2 to zero. | 922 // If no size tag overflow, shift R2 left, else set R2 to zero. |
921 __ mov(R2, Operand(R2, LSL, shift), LS); | 923 __ mov(R2, Operand(R2, LSL, shift), LS); |
922 __ mov(R2, Operand(0), HI); | 924 __ mov(R2, Operand(0), HI); |
923 | 925 |
924 // Get the class index and insert it into the tags. | 926 // Get the class index and insert it into the tags. |
925 // R2: size and bit tags. | 927 // R2: size and bit tags. |
926 __ LoadImmediate(IP, RawObject::ClassIdTag::encode(context_class.id())); | 928 __ LoadImmediate(IP, RawObject::ClassIdTag::encode(cid)); |
927 __ orr(R2, R2, Operand(IP)); | 929 __ orr(R2, R2, Operand(IP)); |
928 __ str(R2, FieldAddress(R0, Context::tags_offset())); | 930 __ str(R2, FieldAddress(R0, Context::tags_offset())); |
929 | 931 |
930 // Setup up number of context variables field. | 932 // Setup up number of context variables field. |
931 // R0: new object. | 933 // R0: new object. |
932 // R1: number of context variables as integer value (not object). | 934 // R1: number of context variables as integer value (not object). |
933 __ str(R1, FieldAddress(R0, Context::num_variables_offset())); | 935 __ str(R1, FieldAddress(R0, Context::num_variables_offset())); |
934 | 936 |
935 // Setup isolate field. | 937 // Setup isolate field. |
936 // Load Isolate pointer from Context structure into R2. | 938 // Load Isolate pointer from Context structure into R2. |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1063 if (is_cls_parameterized) { | 1065 if (is_cls_parameterized) { |
1064 __ ldr(R1, Address(SP, 0)); | 1066 __ ldr(R1, Address(SP, 0)); |
1065 // R1: instantiated type arguments. | 1067 // R1: instantiated type arguments. |
1066 } | 1068 } |
1067 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) { | 1069 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) { |
1068 Label slow_case; | 1070 Label slow_case; |
1069 // Allocate the object and update top to point to | 1071 // Allocate the object and update top to point to |
1070 // next object start and initialize the allocated object. | 1072 // next object start and initialize the allocated object. |
1071 // R1: instantiated type arguments (if is_cls_parameterized). | 1073 // R1: instantiated type arguments (if is_cls_parameterized). |
1072 Heap* heap = Isolate::Current()->heap(); | 1074 Heap* heap = Isolate::Current()->heap(); |
1073 __ LoadImmediate(R5, heap->TopAddress()); | 1075 Heap::Space space = heap->SpaceForAllocation(cls.id()); |
1076 __ LoadImmediate(R5, heap->TopAddress(space)); | |
1074 __ ldr(R2, Address(R5, 0)); | 1077 __ ldr(R2, Address(R5, 0)); |
1075 __ AddImmediate(R3, R2, instance_size); | 1078 __ AddImmediate(R3, R2, instance_size); |
1076 // Check if the allocation fits into the remaining space. | 1079 // Check if the allocation fits into the remaining space. |
1077 // R2: potential new object start. | 1080 // R2: potential new object start. |
1078 // R3: potential next object start. | 1081 // R3: potential next object start. |
1079 __ LoadImmediate(IP, heap->EndAddress()); | 1082 __ LoadImmediate(IP, heap->EndAddress(space)); |
1080 __ ldr(IP, Address(IP, 0)); | 1083 __ ldr(IP, Address(IP, 0)); |
1081 __ cmp(R3, Operand(IP)); | 1084 __ cmp(R3, Operand(IP)); |
1082 if (FLAG_use_slow_path) { | 1085 if (FLAG_use_slow_path) { |
1083 __ b(&slow_case); | 1086 __ b(&slow_case); |
1084 } else { | 1087 } else { |
1085 __ b(&slow_case, CS); // Unsigned higher or equal. | 1088 __ b(&slow_case, CS); // Unsigned higher or equal. |
1086 } | 1089 } |
1087 __ str(R3, Address(R5, 0)); | 1090 __ str(R3, Address(R5, 0)); |
1088 __ UpdateAllocationStats(cls.id(), R5); | 1091 __ UpdateAllocationStats(cls.id(), R5, space); |
1089 | 1092 |
1090 // R2: new object start. | 1093 // R2: new object start. |
1091 // R3: next object start. | 1094 // R3: next object start. |
1092 // R1: new object type arguments (if is_cls_parameterized). | 1095 // R1: new object type arguments (if is_cls_parameterized). |
1093 // Set the tags. | 1096 // Set the tags. |
1094 uword tags = 0; | 1097 uword tags = 0; |
1095 tags = RawObject::SizeTag::update(instance_size, tags); | 1098 tags = RawObject::SizeTag::update(instance_size, tags); |
1096 ASSERT(cls.id() != kIllegalCid); | 1099 ASSERT(cls.id() != kIllegalCid); |
1097 tags = RawObject::ClassIdTag::update(cls.id(), tags); | 1100 tags = RawObject::ClassIdTag::update(cls.id(), tags); |
1098 __ LoadImmediate(R0, tags); | 1101 __ LoadImmediate(R0, tags); |
(...skipping 872 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1971 const Register right = R0; | 1974 const Register right = R0; |
1972 __ ldr(left, Address(SP, 1 * kWordSize)); | 1975 __ ldr(left, Address(SP, 1 * kWordSize)); |
1973 __ ldr(right, Address(SP, 0 * kWordSize)); | 1976 __ ldr(right, Address(SP, 0 * kWordSize)); |
1974 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 1977 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
1975 __ Ret(); | 1978 __ Ret(); |
1976 } | 1979 } |
1977 | 1980 |
1978 } // namespace dart | 1981 } // namespace dart |
1979 | 1982 |
1980 #endif // defined TARGET_ARCH_ARM | 1983 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |