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_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
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/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
711 __ sll(T3, T3, 1); // T3 is a Smi. | 711 __ sll(T3, T3, 1); // T3 is a Smi. |
712 __ addu(T2, T2, T3); | 712 __ addu(T2, T2, T3); |
713 ASSERT(kSmiTagShift == 1); | 713 ASSERT(kSmiTagShift == 1); |
714 __ LoadImmediate(T3, ~(kObjectAlignment - 1)); | 714 __ LoadImmediate(T3, ~(kObjectAlignment - 1)); |
715 __ and_(T2, T2, T3); | 715 __ and_(T2, T2, T3); |
716 | 716 |
717 // T2: Allocation size. | 717 // T2: Allocation size. |
718 | 718 |
719 Isolate* isolate = Isolate::Current(); | 719 Isolate* isolate = Isolate::Current(); |
720 Heap* heap = isolate->heap(); | 720 Heap* heap = isolate->heap(); |
721 | 721 Heap::Space space = heap->SpaceForAllocation(kArrayCid); |
722 __ LoadImmediate(T3, heap->TopAddress()); | 722 __ LoadImmediate(T3, heap->TopAddress(space)); |
723 __ lw(T0, Address(T3, 0)); // Potential new object start. | 723 __ lw(T0, Address(T3, 0)); // Potential new object start. |
724 | 724 |
725 __ AdduDetectOverflow(T1, T0, T2, CMPRES1); // Potential next object start. | 725 __ AdduDetectOverflow(T1, T0, T2, CMPRES1); // Potential next object start. |
726 __ bltz(CMPRES1, &slow_case); // CMPRES1 < 0 on overflow. | 726 __ bltz(CMPRES1, &slow_case); // CMPRES1 < 0 on overflow. |
727 | 727 |
728 // Check if the allocation fits into the remaining space. | 728 // Check if the allocation fits into the remaining space. |
729 // T0: potential new object start. | 729 // T0: potential new object start. |
730 // T1: potential next object start. | 730 // T1: potential next object start. |
731 // T2: allocation size. | 731 // T2: allocation size. |
732 __ LoadImmediate(T4, heap->EndAddress()); | 732 __ LoadImmediate(T4, heap->EndAddress(space)); |
733 __ lw(T4, Address(T4, 0)); | 733 __ lw(T4, Address(T4, 0)); |
734 __ BranchUnsignedGreaterEqual(T1, T4, &slow_case); | 734 __ BranchUnsignedGreaterEqual(T1, T4, &slow_case); |
735 | 735 |
736 // Successfully allocated the object(s), now update top to point to | 736 // Successfully allocated the object(s), now update top to point to |
737 // next object start and initialize the object. | 737 // next object start and initialize the object. |
738 __ sw(T1, Address(T3, 0)); | 738 __ sw(T1, Address(T3, 0)); |
739 __ addiu(T0, T0, Immediate(kHeapObjectTag)); | 739 __ addiu(T0, T0, Immediate(kHeapObjectTag)); |
740 __ UpdateAllocationStatsWithSize(kArrayCid, T2, T4); | 740 __ UpdateAllocationStatsWithSize(kArrayCid, T2, T4, space); |
741 | 741 |
742 // Initialize the tags. | 742 // Initialize the tags. |
743 // T0: new object start as a tagged pointer. | 743 // T0: new object start as a tagged pointer. |
744 // T1: new object end address. | 744 // T1: new object end address. |
745 // T2: allocation size. | 745 // T2: allocation size. |
746 { | 746 { |
747 Label overflow, done; | 747 Label overflow, done; |
748 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; | 748 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; |
749 const Class& cls = Class::Handle(isolate->object_store()->array_class()); | 749 const Class& cls = Class::Handle(isolate->object_store()->array_class()); |
750 | 750 |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1004 __ LoadImmediate(T2, fixed_size); | 1004 __ LoadImmediate(T2, fixed_size); |
1005 __ sll(T0, T1, 2); | 1005 __ sll(T0, T1, 2); |
1006 __ addu(T2, T2, T0); | 1006 __ addu(T2, T2, T0); |
1007 ASSERT(kSmiTagShift == 1); | 1007 ASSERT(kSmiTagShift == 1); |
1008 __ LoadImmediate(T0, ~((kObjectAlignment) - 1)); | 1008 __ LoadImmediate(T0, ~((kObjectAlignment) - 1)); |
1009 __ and_(T2, T2, T0); | 1009 __ and_(T2, T2, T0); |
1010 | 1010 |
1011 // Now allocate the object. | 1011 // Now allocate the object. |
1012 // T1: number of context variables. | 1012 // T1: number of context variables. |
1013 // T2: object size. | 1013 // T2: object size. |
1014 __ LoadImmediate(T5, heap->TopAddress()); | 1014 intptr_t cid = context_class.id(); |
| 1015 Heap::Space space = heap->SpaceForAllocation(cid); |
| 1016 __ LoadImmediate(T5, heap->TopAddress(space)); |
1015 __ lw(V0, Address(T5, 0)); | 1017 __ lw(V0, Address(T5, 0)); |
1016 __ addu(T3, T2, V0); | 1018 __ addu(T3, T2, V0); |
1017 | 1019 |
1018 // Check if the allocation fits into the remaining space. | 1020 // Check if the allocation fits into the remaining space. |
1019 // V0: potential new object. | 1021 // V0: potential new object. |
1020 // T1: number of context variables. | 1022 // T1: number of context variables. |
1021 // T2: object size. | 1023 // T2: object size. |
1022 // T3: potential next object start. | 1024 // T3: potential next object start. |
1023 __ LoadImmediate(TMP, heap->EndAddress()); | 1025 __ LoadImmediate(TMP, heap->EndAddress(space)); |
1024 __ lw(CMPRES1, Address(TMP, 0)); | 1026 __ lw(CMPRES1, Address(TMP, 0)); |
1025 if (FLAG_use_slow_path) { | 1027 if (FLAG_use_slow_path) { |
1026 __ b(&slow_case); | 1028 __ b(&slow_case); |
1027 } else { | 1029 } else { |
1028 __ BranchUnsignedGreaterEqual(T3, CMPRES1, &slow_case); | 1030 __ BranchUnsignedGreaterEqual(T3, CMPRES1, &slow_case); |
1029 } | 1031 } |
1030 | 1032 |
1031 // Successfully allocated the object, now update top to point to | 1033 // Successfully allocated the object, now update top to point to |
1032 // next object start and initialize the object. | 1034 // next object start and initialize the object. |
1033 // V0: new object. | 1035 // V0: new object. |
1034 // T1: number of context variables. | 1036 // T1: number of context variables. |
1035 // T2: object size. | 1037 // T2: object size. |
1036 // T3: next object start. | 1038 // T3: next object start. |
1037 __ sw(T3, Address(T5, 0)); | 1039 __ sw(T3, Address(T5, 0)); |
1038 __ addiu(V0, V0, Immediate(kHeapObjectTag)); | 1040 __ addiu(V0, V0, Immediate(kHeapObjectTag)); |
1039 __ UpdateAllocationStatsWithSize(context_class.id(), T2, T5); | 1041 __ UpdateAllocationStatsWithSize(cid, T2, T5, space); |
1040 | 1042 |
1041 // Calculate the size tag. | 1043 // Calculate the size tag. |
1042 // V0: new object. | 1044 // V0: new object. |
1043 // T1: number of context variables. | 1045 // T1: number of context variables. |
1044 // T2: object size. | 1046 // T2: object size. |
1045 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; | 1047 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; |
1046 __ LoadImmediate(TMP, RawObject::SizeTag::kMaxSizeTag); | 1048 __ LoadImmediate(TMP, RawObject::SizeTag::kMaxSizeTag); |
1047 __ sltu(CMPRES1, TMP, T2); // CMPRES1 = T2 > TMP ? 1 : 0. | 1049 __ sltu(CMPRES1, TMP, T2); // CMPRES1 = T2 > TMP ? 1 : 0. |
1048 __ movn(T2, ZR, CMPRES1); // T2 = CMPRES1 != 0 ? 0 : T2. | 1050 __ movn(T2, ZR, CMPRES1); // T2 = CMPRES1 != 0 ? 0 : T2. |
1049 __ sll(TMP, T2, shift); // TMP = T2 << shift. | 1051 __ sll(TMP, T2, shift); // TMP = T2 << shift. |
1050 __ movz(T2, TMP, CMPRES1); // T2 = CMPRES1 == 0 ? TMP : T2. | 1052 __ movz(T2, TMP, CMPRES1); // T2 = CMPRES1 == 0 ? TMP : T2. |
1051 | 1053 |
1052 // Get the class index and insert it into the tags. | 1054 // Get the class index and insert it into the tags. |
1053 // T2: size and bit tags. | 1055 // T2: size and bit tags. |
1054 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(context_class.id())); | 1056 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cid)); |
1055 __ or_(T2, T2, TMP); | 1057 __ or_(T2, T2, TMP); |
1056 __ sw(T2, FieldAddress(V0, Context::tags_offset())); | 1058 __ sw(T2, FieldAddress(V0, Context::tags_offset())); |
1057 | 1059 |
1058 // Setup up number of context variables field. | 1060 // Setup up number of context variables field. |
1059 // V0: new object. | 1061 // V0: new object. |
1060 // T1: number of context variables as integer value (not object). | 1062 // T1: number of context variables as integer value (not object). |
1061 __ sw(T1, FieldAddress(V0, Context::num_variables_offset())); | 1063 __ sw(T1, FieldAddress(V0, Context::num_variables_offset())); |
1062 | 1064 |
1063 // Setup isolate field. | 1065 // Setup isolate field. |
1064 // Load Isolate pointer from Context structure into R2. | 1066 // Load Isolate pointer from Context structure into R2. |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1208 if (is_cls_parameterized) { | 1210 if (is_cls_parameterized) { |
1209 __ lw(T1, Address(SP, 0 * kWordSize)); | 1211 __ lw(T1, Address(SP, 0 * kWordSize)); |
1210 // T1: type arguments. | 1212 // T1: type arguments. |
1211 } | 1213 } |
1212 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) { | 1214 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) { |
1213 Label slow_case; | 1215 Label slow_case; |
1214 // Allocate the object and update top to point to | 1216 // Allocate the object and update top to point to |
1215 // next object start and initialize the allocated object. | 1217 // next object start and initialize the allocated object. |
1216 // T1: instantiated type arguments (if is_cls_parameterized). | 1218 // T1: instantiated type arguments (if is_cls_parameterized). |
1217 Heap* heap = Isolate::Current()->heap(); | 1219 Heap* heap = Isolate::Current()->heap(); |
1218 __ LoadImmediate(T5, heap->TopAddress()); | 1220 Heap::Space space = heap->SpaceForAllocation(cls.id()); |
| 1221 __ LoadImmediate(T5, heap->TopAddress(space)); |
1219 __ lw(T2, Address(T5)); | 1222 __ lw(T2, Address(T5)); |
1220 __ LoadImmediate(T4, instance_size); | 1223 __ LoadImmediate(T4, instance_size); |
1221 __ addu(T3, T2, T4); | 1224 __ addu(T3, T2, T4); |
1222 // Check if the allocation fits into the remaining space. | 1225 // Check if the allocation fits into the remaining space. |
1223 // T2: potential new object start. | 1226 // T2: potential new object start. |
1224 // T3: potential next object start. | 1227 // T3: potential next object start. |
1225 __ LoadImmediate(TMP, heap->EndAddress()); | 1228 __ LoadImmediate(TMP, heap->EndAddress(space)); |
1226 __ lw(CMPRES1, Address(TMP)); | 1229 __ lw(CMPRES1, Address(TMP)); |
1227 if (FLAG_use_slow_path) { | 1230 if (FLAG_use_slow_path) { |
1228 __ b(&slow_case); | 1231 __ b(&slow_case); |
1229 } else { | 1232 } else { |
1230 __ BranchUnsignedGreaterEqual(T3, CMPRES1, &slow_case); | 1233 __ BranchUnsignedGreaterEqual(T3, CMPRES1, &slow_case); |
1231 } | 1234 } |
1232 // Successfully allocated the object(s), now update top to point to | 1235 // Successfully allocated the object(s), now update top to point to |
1233 // next object start and initialize the object. | 1236 // next object start and initialize the object. |
1234 __ sw(T3, Address(T5)); | 1237 __ sw(T3, Address(T5)); |
1235 __ UpdateAllocationStats(cls.id(), T5); | 1238 __ UpdateAllocationStats(cls.id(), T5, space); |
1236 | 1239 |
1237 // T2: new object start. | 1240 // T2: new object start. |
1238 // T3: next object start. | 1241 // T3: next object start. |
1239 // T1: new object type arguments (if is_cls_parameterized). | 1242 // T1: new object type arguments (if is_cls_parameterized). |
1240 // Set the tags. | 1243 // Set the tags. |
1241 uword tags = 0; | 1244 uword tags = 0; |
1242 tags = RawObject::SizeTag::update(instance_size, tags); | 1245 tags = RawObject::SizeTag::update(instance_size, tags); |
1243 ASSERT(cls.id() != kIllegalCid); | 1246 ASSERT(cls.id() != kIllegalCid); |
1244 tags = RawObject::ClassIdTag::update(cls.id(), tags); | 1247 tags = RawObject::ClassIdTag::update(cls.id(), tags); |
1245 __ LoadImmediate(T0, tags); | 1248 __ LoadImmediate(T0, tags); |
(...skipping 982 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2228 const Register right = T0; | 2231 const Register right = T0; |
2229 __ lw(left, Address(SP, 1 * kWordSize)); | 2232 __ lw(left, Address(SP, 1 * kWordSize)); |
2230 __ lw(right, Address(SP, 0 * kWordSize)); | 2233 __ lw(right, Address(SP, 0 * kWordSize)); |
2231 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); | 2234 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); |
2232 __ Ret(); | 2235 __ Ret(); |
2233 } | 2236 } |
2234 | 2237 |
2235 } // namespace dart | 2238 } // namespace dart |
2236 | 2239 |
2237 #endif // defined TARGET_ARCH_MIPS | 2240 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |