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

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

Issue 619723007: Splits up dependent load in update of allocation stats. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 2 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/intrinsifier_arm.cc ('k') | no next file » | 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) 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 679 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 // R0: potential new object start. 690 // R0: potential new object start.
691 // R7: potential next object start. 691 // R7: potential next object start.
692 // R8: allocation size. 692 // R8: allocation size.
693 __ LoadImmediate(R3, heap->EndAddress(space)); 693 __ LoadImmediate(R3, heap->EndAddress(space));
694 __ ldr(R3, Address(R3, 0)); 694 __ ldr(R3, Address(R3, 0));
695 __ cmp(R7, Operand(R3)); 695 __ cmp(R7, Operand(R3));
696 __ b(&slow_case, CS); 696 __ b(&slow_case, CS);
697 697
698 // Successfully allocated the object(s), now update top to point to 698 // Successfully allocated the object(s), now update top to point to
699 // next object start and initialize the object. 699 // next object start and initialize the object.
700 __ LoadAllocationStatsAddress(R3, cid, space);
700 __ str(R7, Address(R6, 0)); 701 __ str(R7, Address(R6, 0));
701 __ add(R0, R0, Operand(kHeapObjectTag)); 702 __ add(R0, R0, Operand(kHeapObjectTag));
702 __ UpdateAllocationStatsWithSize(cid, R8, R4, space);
703 703
704 // Initialize the tags. 704 // Initialize the tags.
705 // R0: new object start as a tagged pointer. 705 // R0: new object start as a tagged pointer.
706 // R3: allocation stats address.
706 // R7: new object end address. 707 // R7: new object end address.
707 // R8: allocation size. 708 // R8: allocation size.
708 { 709 {
709 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; 710 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2;
710 711
711 __ CompareImmediate(R8, RawObject::SizeTag::kMaxSizeTag); 712 __ CompareImmediate(R8, RawObject::SizeTag::kMaxSizeTag);
712 __ mov(R8, Operand(R8, LSL, shift), LS); 713 __ mov(R6, Operand(R8, LSL, shift), LS);
713 __ mov(R8, Operand(0), HI); 714 __ mov(R6, Operand(0), HI);
714 715
715 // Get the class index and insert it into the tags. 716 // Get the class index and insert it into the tags.
716 // R8: size and bit tags. 717 // R6: size and bit tags.
717 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cid)); 718 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cid));
718 __ orr(R8, R8, Operand(TMP)); 719 __ orr(R6, R6, Operand(TMP));
719 __ str(R8, FieldAddress(R0, Array::tags_offset())); // Store tags. 720 __ str(R6, FieldAddress(R0, Array::tags_offset())); // Store tags.
720 } 721 }
721 722
722 // R0: new object start as a tagged pointer. 723 // R0: new object start as a tagged pointer.
723 // R7: new object end address. 724 // R7: new object end address.
724 // Store the type argument field. 725 // Store the type argument field.
725 __ StoreIntoObjectNoBarrier(R0, 726 __ StoreIntoObjectNoBarrier(R0,
726 FieldAddress(R0, Array::type_arguments_offset()), 727 FieldAddress(R0, Array::type_arguments_offset()),
727 R1); 728 R1);
728 729
729 // Set the length field. 730 // Set the length field.
730 __ StoreIntoObjectNoBarrier(R0, 731 __ StoreIntoObjectNoBarrier(R0,
731 FieldAddress(R0, Array::length_offset()), 732 FieldAddress(R0, Array::length_offset()),
732 R2); 733 R2);
733 734
734 // Initialize all array elements to raw_null. 735 // Initialize all array elements to raw_null.
735 // R0: new object start as a tagged pointer. 736 // R0: new object start as a tagged pointer.
737 // R3: allocation stats address.
736 // R7: new object end address. 738 // R7: new object end address.
737 // R8: iterator which initially points to the start of the variable 739 // R8: iterator which initially points to the start of the variable
738 // data area to be initialized. 740 // data area to be initialized.
739 // R3: null 741 // R4, R5: null
740 __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null())); 742 __ LoadImmediate(R4, reinterpret_cast<intptr_t>(Object::null()));
743 __ mov(R5, Operand(R4));
741 __ AddImmediate(R8, R0, sizeof(RawArray) - kHeapObjectTag); 744 __ AddImmediate(R8, R0, sizeof(RawArray) - kHeapObjectTag);
742 745
743 Label init_loop; 746 Label init_loop;
744 __ Bind(&init_loop); 747 __ Bind(&init_loop);
748 __ AddImmediate(R8, 2 * kWordSize);
745 __ cmp(R8, Operand(R7)); 749 __ cmp(R8, Operand(R7));
746 __ str(R3, Address(R8, 0), CC); 750 __ strd(R4, Address(R8, -2 * kWordSize), LS);
747 __ AddImmediate(R8, kWordSize, CC);
748 __ b(&init_loop, CC); 751 __ b(&init_loop, CC);
752 __ str(R4, Address(R8, -2 * kWordSize), HI);
749 753
754 __ IncrementAllocationStatsWithSize(R3, R8, cid, space);
750 __ Ret(); // Returns the newly allocated object in R0. 755 __ Ret(); // Returns the newly allocated object in R0.
751 // Unable to allocate the array using the fast inline code, just call 756 // Unable to allocate the array using the fast inline code, just call
752 // into the runtime. 757 // into the runtime.
753 __ Bind(&slow_case); 758 __ Bind(&slow_case);
754 759
755 // Create a stub frame as we are pushing some objects on the stack before 760 // Create a stub frame as we are pushing some objects on the stack before
756 // calling into the runtime. 761 // calling into the runtime.
757 __ EnterStubFrame(); 762 __ EnterStubFrame();
758 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); 763 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null()));
759 // Setup space on stack for return value. 764 // Setup space on stack for return value.
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
931 const intptr_t cid = kContextCid; 936 const intptr_t cid = kContextCid;
932 Heap::Space space = heap->SpaceForAllocation(cid); 937 Heap::Space space = heap->SpaceForAllocation(cid);
933 __ LoadImmediate(R5, heap->TopAddress(space)); 938 __ LoadImmediate(R5, heap->TopAddress(space));
934 __ ldr(R0, Address(R5, 0)); 939 __ ldr(R0, Address(R5, 0));
935 __ add(R3, R2, Operand(R0)); 940 __ add(R3, R2, Operand(R0));
936 // Check if the allocation fits into the remaining space. 941 // Check if the allocation fits into the remaining space.
937 // R0: potential new object. 942 // R0: potential new object.
938 // R1: number of context variables. 943 // R1: number of context variables.
939 // R2: object size. 944 // R2: object size.
940 // R3: potential next object start. 945 // R3: potential next object start.
946 // R5: top address.
941 __ LoadImmediate(IP, heap->EndAddress(space)); 947 __ LoadImmediate(IP, heap->EndAddress(space));
942 __ ldr(IP, Address(IP, 0)); 948 __ ldr(IP, Address(IP, 0));
943 __ cmp(R3, Operand(IP)); 949 __ cmp(R3, Operand(IP));
944 if (FLAG_use_slow_path) { 950 if (FLAG_use_slow_path) {
945 __ b(&slow_case); 951 __ b(&slow_case);
946 } else { 952 } else {
947 __ b(&slow_case, CS); // Branch if unsigned higher or equal. 953 __ b(&slow_case, CS); // Branch if unsigned higher or equal.
948 } 954 }
949 955
950 // Successfully allocated the object, now update top to point to 956 // Successfully allocated the object, now update top to point to
951 // next object start and initialize the object. 957 // next object start and initialize the object.
952 // R0: new object. 958 // R0: new object.
953 // R1: number of context variables. 959 // R1: number of context variables.
954 // R2: object size. 960 // R2: object size.
955 // R3: next object start. 961 // R3: next object start.
962 // R5: top address.
963 __ LoadAllocationStatsAddress(R4, cid, space);
956 __ str(R3, Address(R5, 0)); 964 __ str(R3, Address(R5, 0));
957 __ add(R0, R0, Operand(kHeapObjectTag)); 965 __ add(R0, R0, Operand(kHeapObjectTag));
958 __ UpdateAllocationStatsWithSize(cid, R2, R5, space);
959 966
960 // Calculate the size tag. 967 // Calculate the size tag.
961 // R0: new object. 968 // R0: new object.
962 // R1: number of context variables. 969 // R1: number of context variables.
963 // R2: object size. 970 // R2: object size.
971 // R4: allocation stats address.
964 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; 972 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2;
965 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag); 973 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag);
966 // If no size tag overflow, shift R2 left, else set R2 to zero. 974 // If no size tag overflow, shift R2 left, else set R2 to zero.
967 __ mov(R2, Operand(R2, LSL, shift), LS); 975 __ mov(R3, Operand(R2, LSL, shift), LS);
968 __ mov(R2, Operand(0), HI); 976 __ mov(R3, Operand(0), HI);
969 977
970 // Get the class index and insert it into the tags. 978 // Get the class index and insert it into the tags.
971 // R2: size and bit tags. 979 // R3: size and bit tags.
972 __ LoadImmediate(IP, RawObject::ClassIdTag::encode(cid)); 980 __ LoadImmediate(IP, RawObject::ClassIdTag::encode(cid));
973 __ orr(R2, R2, Operand(IP)); 981 __ orr(R3, R3, Operand(IP));
974 __ str(R2, FieldAddress(R0, Context::tags_offset())); 982 __ str(R3, FieldAddress(R0, Context::tags_offset()));
975 983
976 // Setup up number of context variables field. 984 // Setup up number of context variables field.
977 // R0: new object. 985 // R0: new object.
978 // R1: number of context variables as integer value (not object). 986 // R1: number of context variables as integer value (not object).
987 // R2: object size.
988 // R4: allocation stats address.
979 __ str(R1, FieldAddress(R0, Context::num_variables_offset())); 989 __ str(R1, FieldAddress(R0, Context::num_variables_offset()));
980 990
981 // Setup isolate field. 991 // Setup isolate field.
982 // Load Isolate pointer into R2. 992 // Load Isolate pointer into R3.
983 // R0: new object. 993 // R0: new object.
984 // R1: number of context variables. 994 // R1: number of context variables.
985 __ LoadIsolate(R2); 995 // R2: object size.
986 // R2: isolate, not an object. 996 // R4: allocation stats address.
987 __ str(R2, FieldAddress(R0, Context::isolate_offset())); 997 __ LoadIsolate(R3);
998 // R3: isolate, not an object.
999 __ str(R3, FieldAddress(R0, Context::isolate_offset()));
988 1000
989 // Setup the parent field. 1001 // Setup the parent field.
990 // R0: new object. 1002 // R0: new object.
991 // R1: number of context variables. 1003 // R1: number of context variables.
992 __ LoadImmediate(R2, reinterpret_cast<intptr_t>(Object::null())); 1004 // R2: object size.
993 __ str(R2, FieldAddress(R0, Context::parent_offset())); 1005 // R4: allocation stats address.
1006 __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null()));
1007 __ str(R3, FieldAddress(R0, Context::parent_offset()));
994 1008
995 // Initialize the context variables. 1009 // Initialize the context variables.
996 // R0: new object. 1010 // R0: new object.
997 // R1: number of context variables. 1011 // R1: number of context variables.
998 // R2: raw null. 1012 // R2: object size.
1013 // R3: raw null.
1014 // R4: allocation stats address.
999 Label loop; 1015 Label loop;
1000 __ AddImmediate(R3, R0, Context::variable_offset(0) - kHeapObjectTag); 1016 __ AddImmediate(R5, R0, Context::variable_offset(0) - kHeapObjectTag);
1001 __ Bind(&loop); 1017 __ Bind(&loop);
1002 __ subs(R1, R1, Operand(1)); 1018 __ subs(R1, R1, Operand(1));
1003 __ str(R2, Address(R3, R1, LSL, 2), PL); // Store if R1 positive or zero. 1019 __ str(R3, Address(R5, R1, LSL, 2), PL); // Store if R1 positive or zero.
1004 __ b(&loop, NE); // Loop if R1 not zero. 1020 __ b(&loop, NE); // Loop if R1 not zero.
1005 1021
1022 __ IncrementAllocationStatsWithSize(R4, R2, cid, space);
1023
1006 // Done allocating and initializing the context. 1024 // Done allocating and initializing the context.
1007 // R0: new object. 1025 // R0: new object.
1008 __ Ret(); 1026 __ Ret();
1009 1027
1010 __ Bind(&slow_case); 1028 __ Bind(&slow_case);
1011 } 1029 }
1012 // Create a stub frame as we are pushing some objects on the stack before 1030 // Create a stub frame as we are pushing some objects on the stack before
1013 // calling into the runtime. 1031 // calling into the runtime.
1014 __ EnterStubFrame(); 1032 __ EnterStubFrame();
1015 // Setup space on stack for return value. 1033 // Setup space on stack for return value.
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1101 // The generated code is different if the class is parameterized. 1119 // The generated code is different if the class is parameterized.
1102 const bool is_cls_parameterized = cls.NumTypeArguments() > 0; 1120 const bool is_cls_parameterized = cls.NumTypeArguments() > 0;
1103 ASSERT(!is_cls_parameterized || 1121 ASSERT(!is_cls_parameterized ||
1104 (cls.type_arguments_field_offset() != Class::kNoTypeArguments)); 1122 (cls.type_arguments_field_offset() != Class::kNoTypeArguments));
1105 // kInlineInstanceSize is a constant used as a threshold for determining 1123 // kInlineInstanceSize is a constant used as a threshold for determining
1106 // when the object initialization should be done as a loop or as 1124 // when the object initialization should be done as a loop or as
1107 // straight line code. 1125 // straight line code.
1108 const int kInlineInstanceSize = 12; 1126 const int kInlineInstanceSize = 12;
1109 const intptr_t instance_size = cls.instance_size(); 1127 const intptr_t instance_size = cls.instance_size();
1110 ASSERT(instance_size > 0); 1128 ASSERT(instance_size > 0);
1111 if (is_cls_parameterized) {
1112 __ ldr(R1, Address(SP, 0));
1113 // R1: instantiated type arguments.
1114 }
1115 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) { 1129 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) {
1116 Label slow_case; 1130 Label slow_case;
1117 // Allocate the object and update top to point to 1131 // Allocate the object and update top to point to
1118 // next object start and initialize the allocated object. 1132 // next object start and initialize the allocated object.
1119 // R1: instantiated type arguments (if is_cls_parameterized).
1120 Heap* heap = Isolate::Current()->heap(); 1133 Heap* heap = Isolate::Current()->heap();
1121 Heap::Space space = heap->SpaceForAllocation(cls.id()); 1134 Heap::Space space = heap->SpaceForAllocation(cls.id());
1122 __ LoadImmediate(R5, heap->TopAddress(space)); 1135 __ LoadImmediate(R5, heap->TopAddress(space));
1123 __ ldr(R2, Address(R5, 0)); 1136 __ ldr(R2, Address(R5, 0));
1124 __ AddImmediate(R3, R2, instance_size); 1137 __ AddImmediate(R3, R2, instance_size);
1125 // Check if the allocation fits into the remaining space. 1138 // Check if the allocation fits into the remaining space.
1126 // R2: potential new object start. 1139 // R2: potential new object start.
1127 // R3: potential next object start. 1140 // R3: potential next object start.
1128 __ LoadImmediate(IP, heap->EndAddress(space)); 1141 __ LoadImmediate(IP, heap->EndAddress(space));
1129 __ ldr(IP, Address(IP, 0)); 1142 __ ldr(IP, Address(IP, 0));
1130 __ cmp(R3, Operand(IP)); 1143 __ cmp(R3, Operand(IP));
1131 if (FLAG_use_slow_path) { 1144 if (FLAG_use_slow_path) {
1132 __ b(&slow_case); 1145 __ b(&slow_case);
1133 } else { 1146 } else {
1134 __ b(&slow_case, CS); // Unsigned higher or equal. 1147 __ b(&slow_case, CS); // Unsigned higher or equal.
1135 } 1148 }
1136 __ str(R3, Address(R5, 0)); 1149 __ str(R3, Address(R5, 0));
1137 __ UpdateAllocationStats(cls.id(), R5, space); 1150
1151 // Load the address of the allocation stats table. We split up the load
1152 // and the increment so that the dependent load is not too nearby.
1153 __ LoadAllocationStatsAddress(R5, cls.id(), space);
1138 1154
1139 // R2: new object start. 1155 // R2: new object start.
1140 // R3: next object start. 1156 // R3: next object start.
1141 // R1: new object type arguments (if is_cls_parameterized). 1157 // R5: allocation stats table.
1142 // Set the tags. 1158 // Set the tags.
1143 uword tags = 0; 1159 uword tags = 0;
1144 tags = RawObject::SizeTag::update(instance_size, tags); 1160 tags = RawObject::SizeTag::update(instance_size, tags);
1145 ASSERT(cls.id() != kIllegalCid); 1161 ASSERT(cls.id() != kIllegalCid);
1146 tags = RawObject::ClassIdTag::update(cls.id(), tags); 1162 tags = RawObject::ClassIdTag::update(cls.id(), tags);
1147 __ LoadImmediate(R0, tags); 1163 __ LoadImmediate(R0, tags);
1148 __ str(R0, Address(R2, Instance::tags_offset())); 1164 __ str(R0, Address(R2, Instance::tags_offset()));
1149 1165
1150 // Initialize the remaining words of the object. 1166 // Initialize the remaining words of the object.
1151 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); 1167 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
1152 1168
1153 // R0: raw null. 1169 // R0: raw null.
1154 // R2: new object start. 1170 // R2: new object start.
1155 // R3: next object start. 1171 // R3: next object start.
1156 // R1: new object type arguments (if is_cls_parameterized). 1172 // R5: allocation stats table.
1157 // First try inlining the initialization without a loop. 1173 // First try inlining the initialization without a loop.
1158 if (instance_size < (kInlineInstanceSize * kWordSize)) { 1174 if (instance_size < (kInlineInstanceSize * kWordSize)) {
1159 // Check if the object contains any non-header fields. 1175 // Check if the object contains any non-header fields.
1160 // Small objects are initialized using a consecutive set of writes. 1176 // Small objects are initialized using a consecutive set of writes.
1161 for (intptr_t current_offset = Instance::NextFieldOffset(); 1177 intptr_t current_offset = Instance::NextFieldOffset();
1162 current_offset < instance_size; 1178 // Write two nulls at a time.
1163 current_offset += kWordSize) { 1179 if (instance_size >= 2 * kWordSize) {
1180 __ mov(R1, Operand(R0));
1181 while (current_offset + kWordSize < instance_size) {
1182 __ StoreToOffset(kWordPair, R0, R2, current_offset);
1183 current_offset += 2 * kWordSize;
1184 }
1185 }
1186 // Write remainder.
1187 while (current_offset < instance_size) {
1164 __ StoreToOffset(kWord, R0, R2, current_offset); 1188 __ StoreToOffset(kWord, R0, R2, current_offset);
1189 current_offset += kWordSize;
1165 } 1190 }
1166 } else { 1191 } else {
1192 // There are more than kInlineInstanceSize(12) fields
1167 __ add(R4, R2, Operand(Instance::NextFieldOffset())); 1193 __ add(R4, R2, Operand(Instance::NextFieldOffset()));
1194 __ mov(R1, Operand(R0));
1168 // Loop until the whole object is initialized. 1195 // Loop until the whole object is initialized.
1169 // R0: raw null. 1196 // R0: raw null.
1197 // R1: raw null.
1170 // R2: new object. 1198 // R2: new object.
1171 // R3: next object start. 1199 // R3: next object start.
1172 // R4: next word to be initialized. 1200 // R4: next word to be initialized.
1173 // R1: new object type arguments (if is_cls_parameterized). 1201 // R5: allocation stats table.
1174 Label init_loop; 1202 Label init_loop;
1175 Label done;
1176 __ Bind(&init_loop); 1203 __ Bind(&init_loop);
1204 __ AddImmediate(R4, 2 * kWordSize);
1177 __ cmp(R4, Operand(R3)); 1205 __ cmp(R4, Operand(R3));
1178 __ b(&done, CS); 1206 __ strd(R0, Address(R4, -2 * kWordSize), LS);
1179 __ str(R0, Address(R4, 0)); 1207 __ b(&init_loop, CC);
1180 __ AddImmediate(R4, kWordSize); 1208 __ str(R0, Address(R4, -2 * kWordSize), HI);
1181 __ b(&init_loop);
1182 __ Bind(&done);
1183 } 1209 }
1184 if (is_cls_parameterized) { 1210 if (is_cls_parameterized) {
1185 // R1: new object type arguments.
1186 // Set the type arguments in the new object. 1211 // Set the type arguments in the new object.
1187 __ StoreToOffset(kWord, R1, R2, cls.type_arguments_field_offset()); 1212 __ ldr(R4, Address(SP, 0));
1213 __ StoreToOffset(kWord, R4, R2, cls.type_arguments_field_offset());
1188 } 1214 }
1215
1189 // Done allocating and initializing the instance. 1216 // Done allocating and initializing the instance.
1190 // R2: new object still missing its heap tag. 1217 // R2: new object still missing its heap tag.
1218 // R5: allocation stats table.
1191 __ add(R0, R2, Operand(kHeapObjectTag)); 1219 __ add(R0, R2, Operand(kHeapObjectTag));
1220
1221 // Update allocation stats.
1222 __ IncrementAllocationStats(R5, cls.id(), space);
1223
1192 // R0: new object. 1224 // R0: new object.
1193 __ Ret(); 1225 __ Ret();
1194 1226
1195 __ Bind(&slow_case); 1227 __ Bind(&slow_case);
1196 } 1228 }
1229 if (is_cls_parameterized) {
1230 // Load the type arguments.
1231 __ ldr(R4, Address(SP, 0));
1232 }
1197 // If is_cls_parameterized: 1233 // If is_cls_parameterized:
1198 // R1: new object type arguments. 1234 // R4: new object type arguments.
1199 // Create a stub frame as we are pushing some objects on the stack before 1235 // Create a stub frame as we are pushing some objects on the stack before
1200 // calling into the runtime. 1236 // calling into the runtime.
1201 __ EnterStubFrame(true); // Uses pool pointer to pass cls to runtime. 1237 __ EnterStubFrame(true); // Uses pool pointer to pass cls to runtime.
1202 __ LoadImmediate(R2, reinterpret_cast<intptr_t>(Object::null())); 1238 __ LoadImmediate(R2, reinterpret_cast<intptr_t>(Object::null()));
1203 __ Push(R2); // Setup space on stack for return value. 1239 __ Push(R2); // Setup space on stack for return value.
1204 __ PushObject(cls); // Push class of object to be allocated. 1240 __ PushObject(cls); // Push class of object to be allocated.
1205 if (is_cls_parameterized) { 1241 if (is_cls_parameterized) {
1206 // Push type arguments. 1242 // Push type arguments.
1207 __ Push(R1); 1243 __ Push(R4);
1208 } else { 1244 } else {
1209 // Push null type arguments. 1245 // Push null type arguments.
1210 __ Push(R2); 1246 __ Push(R2);
1211 } 1247 }
1212 __ CallRuntime(kAllocateObjectRuntimeEntry, 2); // Allocate object. 1248 __ CallRuntime(kAllocateObjectRuntimeEntry, 2); // Allocate object.
1213 __ Drop(2); // Pop arguments. 1249 __ Drop(2); // Pop arguments.
1214 __ Pop(R0); // Pop result (newly allocated object). 1250 __ Pop(R0); // Pop result (newly allocated object).
1215 // R0: new object 1251 // R0: new object
1216 // Restore the frame pointer. 1252 // Restore the frame pointer.
1217 __ LeaveStubFrame(); 1253 __ LeaveStubFrame();
(...skipping 801 matching lines...) Expand 10 before | Expand all | Expand 10 after
2019 const Register right = R0; 2055 const Register right = R0;
2020 __ ldr(left, Address(SP, 1 * kWordSize)); 2056 __ ldr(left, Address(SP, 1 * kWordSize));
2021 __ ldr(right, Address(SP, 0 * kWordSize)); 2057 __ ldr(right, Address(SP, 0 * kWordSize));
2022 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); 2058 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
2023 __ Ret(); 2059 __ Ret();
2024 } 2060 }
2025 2061
2026 } // namespace dart 2062 } // namespace dart
2027 2063
2028 #endif // defined TARGET_ARCH_ARM 2064 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/intrinsifier_arm.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698