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 const intptr_t cid = kArrayCid; |
722 __ LoadImmediate(T3, heap->TopAddress()); | 722 Heap::Space space = heap->SpaceForAllocation(cid); |
| 723 __ LoadImmediate(T3, heap->TopAddress(space)); |
723 __ lw(T0, Address(T3, 0)); // Potential new object start. | 724 __ lw(T0, Address(T3, 0)); // Potential new object start. |
724 | 725 |
725 __ AdduDetectOverflow(T1, T0, T2, CMPRES1); // Potential next object start. | 726 __ AdduDetectOverflow(T1, T0, T2, CMPRES1); // Potential next object start. |
726 __ bltz(CMPRES1, &slow_case); // CMPRES1 < 0 on overflow. | 727 __ bltz(CMPRES1, &slow_case); // CMPRES1 < 0 on overflow. |
727 | 728 |
728 // Check if the allocation fits into the remaining space. | 729 // Check if the allocation fits into the remaining space. |
729 // T0: potential new object start. | 730 // T0: potential new object start. |
730 // T1: potential next object start. | 731 // T1: potential next object start. |
731 // T2: allocation size. | 732 // T2: allocation size. |
732 __ LoadImmediate(T4, heap->EndAddress()); | 733 __ LoadImmediate(T4, heap->EndAddress(space)); |
733 __ lw(T4, Address(T4, 0)); | 734 __ lw(T4, Address(T4, 0)); |
734 __ BranchUnsignedGreaterEqual(T1, T4, &slow_case); | 735 __ BranchUnsignedGreaterEqual(T1, T4, &slow_case); |
735 | 736 |
736 // Successfully allocated the object(s), now update top to point to | 737 // Successfully allocated the object(s), now update top to point to |
737 // next object start and initialize the object. | 738 // next object start and initialize the object. |
738 __ sw(T1, Address(T3, 0)); | 739 __ sw(T1, Address(T3, 0)); |
739 __ addiu(T0, T0, Immediate(kHeapObjectTag)); | 740 __ addiu(T0, T0, Immediate(kHeapObjectTag)); |
740 __ UpdateAllocationStatsWithSize(kArrayCid, T2, T4); | 741 __ UpdateAllocationStatsWithSize(cid, T2, T4, space); |
741 | 742 |
742 // Initialize the tags. | 743 // Initialize the tags. |
743 // T0: new object start as a tagged pointer. | 744 // T0: new object start as a tagged pointer. |
744 // T1: new object end address. | 745 // T1: new object end address. |
745 // T2: allocation size. | 746 // T2: allocation size. |
746 { | 747 { |
747 Label overflow, done; | 748 Label overflow, done; |
748 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; | 749 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; |
749 const Class& cls = Class::Handle(isolate->object_store()->array_class()); | |
750 | 750 |
751 __ BranchUnsignedGreater(T2, RawObject::SizeTag::kMaxSizeTag, &overflow); | 751 __ BranchUnsignedGreater(T2, RawObject::SizeTag::kMaxSizeTag, &overflow); |
752 __ b(&done); | 752 __ b(&done); |
753 __ delay_slot()->sll(T2, T2, shift); | 753 __ delay_slot()->sll(T2, T2, shift); |
754 __ Bind(&overflow); | 754 __ Bind(&overflow); |
755 __ mov(T2, ZR); | 755 __ mov(T2, ZR); |
756 __ Bind(&done); | 756 __ Bind(&done); |
757 | 757 |
758 // Get the class index and insert it into the tags. | 758 // Get the class index and insert it into the tags. |
759 // T2: size and bit tags. | 759 // T2: size and bit tags. |
760 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cls.id())); | 760 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cid)); |
761 __ or_(T2, T2, TMP); | 761 __ or_(T2, T2, TMP); |
762 __ sw(T2, FieldAddress(T0, Array::tags_offset())); // Store tags. | 762 __ sw(T2, FieldAddress(T0, Array::tags_offset())); // Store tags. |
763 } | 763 } |
764 | 764 |
765 // T0: new object start as a tagged pointer. | 765 // T0: new object start as a tagged pointer. |
766 // T1: new object end address. | 766 // T1: new object end address. |
767 // Store the type argument field. | 767 // Store the type argument field. |
768 __ StoreIntoObjectNoBarrier(T0, | 768 __ StoreIntoObjectNoBarrier(T0, |
769 FieldAddress(T0, Array::type_arguments_offset()), | 769 FieldAddress(T0, Array::type_arguments_offset()), |
770 A0); | 770 A0); |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1003 __ LoadImmediate(T2, fixed_size); | 1003 __ LoadImmediate(T2, fixed_size); |
1004 __ sll(T0, T1, 2); | 1004 __ sll(T0, T1, 2); |
1005 __ addu(T2, T2, T0); | 1005 __ addu(T2, T2, T0); |
1006 ASSERT(kSmiTagShift == 1); | 1006 ASSERT(kSmiTagShift == 1); |
1007 __ LoadImmediate(T0, ~((kObjectAlignment) - 1)); | 1007 __ LoadImmediate(T0, ~((kObjectAlignment) - 1)); |
1008 __ and_(T2, T2, T0); | 1008 __ and_(T2, T2, T0); |
1009 | 1009 |
1010 // Now allocate the object. | 1010 // Now allocate the object. |
1011 // T1: number of context variables. | 1011 // T1: number of context variables. |
1012 // T2: object size. | 1012 // T2: object size. |
1013 __ LoadImmediate(T5, heap->TopAddress()); | 1013 intptr_t cid = context_class.id(); |
| 1014 Heap::Space space = heap->SpaceForAllocation(cid); |
| 1015 __ LoadImmediate(T5, heap->TopAddress(space)); |
1014 __ lw(V0, Address(T5, 0)); | 1016 __ lw(V0, Address(T5, 0)); |
1015 __ addu(T3, T2, V0); | 1017 __ addu(T3, T2, V0); |
1016 | 1018 |
1017 // Check if the allocation fits into the remaining space. | 1019 // Check if the allocation fits into the remaining space. |
1018 // V0: potential new object. | 1020 // V0: potential new object. |
1019 // T1: number of context variables. | 1021 // T1: number of context variables. |
1020 // T2: object size. | 1022 // T2: object size. |
1021 // T3: potential next object start. | 1023 // T3: potential next object start. |
1022 __ LoadImmediate(TMP, heap->EndAddress()); | 1024 __ LoadImmediate(TMP, heap->EndAddress(space)); |
1023 __ lw(CMPRES1, Address(TMP, 0)); | 1025 __ lw(CMPRES1, Address(TMP, 0)); |
1024 if (FLAG_use_slow_path) { | 1026 if (FLAG_use_slow_path) { |
1025 __ b(&slow_case); | 1027 __ b(&slow_case); |
1026 } else { | 1028 } else { |
1027 __ BranchUnsignedGreaterEqual(T3, CMPRES1, &slow_case); | 1029 __ BranchUnsignedGreaterEqual(T3, CMPRES1, &slow_case); |
1028 } | 1030 } |
1029 | 1031 |
1030 // Successfully allocated the object, now update top to point to | 1032 // Successfully allocated the object, now update top to point to |
1031 // next object start and initialize the object. | 1033 // next object start and initialize the object. |
1032 // V0: new object. | 1034 // V0: new object. |
1033 // T1: number of context variables. | 1035 // T1: number of context variables. |
1034 // T2: object size. | 1036 // T2: object size. |
1035 // T3: next object start. | 1037 // T3: next object start. |
1036 __ sw(T3, Address(T5, 0)); | 1038 __ sw(T3, Address(T5, 0)); |
1037 __ addiu(V0, V0, Immediate(kHeapObjectTag)); | 1039 __ addiu(V0, V0, Immediate(kHeapObjectTag)); |
1038 __ UpdateAllocationStatsWithSize(context_class.id(), T2, T5); | 1040 __ UpdateAllocationStatsWithSize(cid, T2, T5, space); |
1039 | 1041 |
1040 // Calculate the size tag. | 1042 // Calculate the size tag. |
1041 // V0: new object. | 1043 // V0: new object. |
1042 // T1: number of context variables. | 1044 // T1: number of context variables. |
1043 // T2: object size. | 1045 // T2: object size. |
1044 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; | 1046 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; |
1045 __ LoadImmediate(TMP, RawObject::SizeTag::kMaxSizeTag); | 1047 __ LoadImmediate(TMP, RawObject::SizeTag::kMaxSizeTag); |
1046 __ sltu(CMPRES1, TMP, T2); // CMPRES1 = T2 > TMP ? 1 : 0. | 1048 __ sltu(CMPRES1, TMP, T2); // CMPRES1 = T2 > TMP ? 1 : 0. |
1047 __ movn(T2, ZR, CMPRES1); // T2 = CMPRES1 != 0 ? 0 : T2. | 1049 __ movn(T2, ZR, CMPRES1); // T2 = CMPRES1 != 0 ? 0 : T2. |
1048 __ sll(TMP, T2, shift); // TMP = T2 << shift. | 1050 __ sll(TMP, T2, shift); // TMP = T2 << shift. |
1049 __ movz(T2, TMP, CMPRES1); // T2 = CMPRES1 == 0 ? TMP : T2. | 1051 __ movz(T2, TMP, CMPRES1); // T2 = CMPRES1 == 0 ? TMP : T2. |
1050 | 1052 |
1051 // Get the class index and insert it into the tags. | 1053 // Get the class index and insert it into the tags. |
1052 // T2: size and bit tags. | 1054 // T2: size and bit tags. |
1053 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(context_class.id())); | 1055 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cid)); |
1054 __ or_(T2, T2, TMP); | 1056 __ or_(T2, T2, TMP); |
1055 __ sw(T2, FieldAddress(V0, Context::tags_offset())); | 1057 __ sw(T2, FieldAddress(V0, Context::tags_offset())); |
1056 | 1058 |
1057 // Setup up number of context variables field. | 1059 // Setup up number of context variables field. |
1058 // V0: new object. | 1060 // V0: new object. |
1059 // T1: number of context variables as integer value (not object). | 1061 // T1: number of context variables as integer value (not object). |
1060 __ sw(T1, FieldAddress(V0, Context::num_variables_offset())); | 1062 __ sw(T1, FieldAddress(V0, Context::num_variables_offset())); |
1061 | 1063 |
1062 // Setup isolate field. | 1064 // Setup isolate field. |
1063 // V0: new object. | 1065 // V0: new object. |
(...skipping 144 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 981 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2227 const Register right = T0; | 2230 const Register right = T0; |
2228 __ lw(left, Address(SP, 1 * kWordSize)); | 2231 __ lw(left, Address(SP, 1 * kWordSize)); |
2229 __ lw(right, Address(SP, 0 * kWordSize)); | 2232 __ lw(right, Address(SP, 0 * kWordSize)); |
2230 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); | 2233 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); |
2231 __ Ret(); | 2234 __ Ret(); |
2232 } | 2235 } |
2233 | 2236 |
2234 } // namespace dart | 2237 } // namespace dart |
2235 | 2238 |
2236 #endif // defined TARGET_ARCH_MIPS | 2239 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |