| 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 |