| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 714 | 714 |
| 715 // Check for maximum allowed length. | 715 // Check for maximum allowed length. |
| 716 const intptr_t max_len = | 716 const intptr_t max_len = |
| 717 reinterpret_cast<intptr_t>(Smi::New(Array::kMaxElements)); | 717 reinterpret_cast<intptr_t>(Smi::New(Array::kMaxElements)); |
| 718 __ CompareImmediate(R2, max_len); | 718 __ CompareImmediate(R2, max_len); |
| 719 __ b(&slow_case, GT); | 719 __ b(&slow_case, GT); |
| 720 | 720 |
| 721 const intptr_t cid = kArrayCid; | 721 const intptr_t cid = kArrayCid; |
| 722 NOT_IN_PRODUCT(__ MaybeTraceAllocation(kArrayCid, R4, &slow_case)); | 722 NOT_IN_PRODUCT(__ MaybeTraceAllocation(kArrayCid, R4, &slow_case)); |
| 723 | 723 |
| 724 Heap::Space space = Heap::kNew; | 724 NOT_IN_PRODUCT(Heap::Space space = Heap::kNew); |
| 725 __ ldr(R8, Address(THR, Thread::heap_offset())); | |
| 726 | 725 |
| 727 // Calculate and align allocation size. | 726 // Calculate and align allocation size. |
| 728 // Load new object start and calculate next object start. | 727 // Load new object start and calculate next object start. |
| 729 // R1: array element type. | 728 // R1: array element type. |
| 730 // R2: array length as Smi. | 729 // R2: array length as Smi. |
| 731 // R8: heap. | 730 __ ldr(R0, Address(THR, Thread::top_offset())); |
| 732 __ LoadFromOffset(R0, R8, Heap::TopOffset(space)); | |
| 733 intptr_t fixed_size_plus_alignment_padding = | 731 intptr_t fixed_size_plus_alignment_padding = |
| 734 sizeof(RawArray) + kObjectAlignment - 1; | 732 sizeof(RawArray) + kObjectAlignment - 1; |
| 735 __ LoadImmediate(R3, fixed_size_plus_alignment_padding); | 733 __ LoadImmediate(R3, fixed_size_plus_alignment_padding); |
| 736 __ add(R3, R3, Operand(R2, LSL, 2)); // R2 is Smi. | 734 __ add(R3, R3, Operand(R2, LSL, 2)); // R2 is Smi. |
| 737 ASSERT(kSmiTagShift == 1); | 735 ASSERT(kSmiTagShift == 1); |
| 738 __ andi(R3, R3, Immediate(~(kObjectAlignment - 1))); | 736 __ andi(R3, R3, Immediate(~(kObjectAlignment - 1))); |
| 739 // R0: potential new object start. | 737 // R0: potential new object start. |
| 740 // R3: object size in bytes. | 738 // R3: object size in bytes. |
| 741 __ adds(R7, R3, Operand(R0)); | 739 __ adds(R7, R3, Operand(R0)); |
| 742 __ b(&slow_case, CS); // Branch if unsigned overflow. | 740 __ b(&slow_case, CS); // Branch if unsigned overflow. |
| 743 | 741 |
| 744 // Check if the allocation fits into the remaining space. | 742 // Check if the allocation fits into the remaining space. |
| 745 // R0: potential new object start. | 743 // R0: potential new object start. |
| 746 // R1: array element type. | 744 // R1: array element type. |
| 747 // R2: array length as Smi. | 745 // R2: array length as Smi. |
| 748 // R3: array size. | 746 // R3: array size. |
| 749 // R7: potential next object start. | 747 // R7: potential next object start. |
| 750 // R8: heap. | 748 __ LoadFromOffset(TMP, THR, Thread::end_offset()); |
| 751 __ LoadFromOffset(TMP, R8, Heap::EndOffset(space)); | |
| 752 __ CompareRegisters(R7, TMP); | 749 __ CompareRegisters(R7, TMP); |
| 753 __ b(&slow_case, CS); // Branch if unsigned higher or equal. | 750 __ b(&slow_case, CS); // Branch if unsigned higher or equal. |
| 754 | 751 |
| 755 // Successfully allocated the object(s), now update top to point to | 752 // Successfully allocated the object(s), now update top to point to |
| 756 // next object start and initialize the object. | 753 // next object start and initialize the object. |
| 757 // R0: potential new object start. | 754 // R0: potential new object start. |
| 758 // R3: array size. | 755 // R3: array size. |
| 759 // R7: potential next object start. | 756 // R7: potential next object start. |
| 760 // R8: heap. | 757 __ str(R7, Address(THR, Thread::top_offset())); |
| 761 __ StoreToOffset(R7, R8, Heap::TopOffset(space)); | |
| 762 __ add(R0, R0, Operand(kHeapObjectTag)); | 758 __ add(R0, R0, Operand(kHeapObjectTag)); |
| 763 NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, R3, space)); | 759 NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, R3, space)); |
| 764 | 760 |
| 765 // R0: new object start as a tagged pointer. | 761 // R0: new object start as a tagged pointer. |
| 766 // R1: array element type. | 762 // R1: array element type. |
| 767 // R2: array length as Smi. | 763 // R2: array length as Smi. |
| 768 // R3: array size. | 764 // R3: array size. |
| 769 // R7: new object end address. | 765 // R7: new object end address. |
| 770 | 766 |
| 771 // Store the type argument field. | 767 // Store the type argument field. |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 983 __ LoadImmediate(R2, fixed_size_plus_alignment_padding); | 979 __ LoadImmediate(R2, fixed_size_plus_alignment_padding); |
| 984 __ add(R2, R2, Operand(R1, LSL, 3)); | 980 __ add(R2, R2, Operand(R1, LSL, 3)); |
| 985 ASSERT(kSmiTagShift == 1); | 981 ASSERT(kSmiTagShift == 1); |
| 986 __ andi(R2, R2, Immediate(~(kObjectAlignment - 1))); | 982 __ andi(R2, R2, Immediate(~(kObjectAlignment - 1))); |
| 987 | 983 |
| 988 NOT_IN_PRODUCT(__ MaybeTraceAllocation(kContextCid, R4, &slow_case)); | 984 NOT_IN_PRODUCT(__ MaybeTraceAllocation(kContextCid, R4, &slow_case)); |
| 989 // Now allocate the object. | 985 // Now allocate the object. |
| 990 // R1: number of context variables. | 986 // R1: number of context variables. |
| 991 // R2: object size. | 987 // R2: object size. |
| 992 const intptr_t cid = kContextCid; | 988 const intptr_t cid = kContextCid; |
| 993 Heap::Space space = Heap::kNew; | 989 NOT_IN_PRODUCT(Heap::Space space = Heap::kNew); |
| 994 __ ldr(R5, Address(THR, Thread::heap_offset())); | 990 __ ldr(R0, Address(THR, Thread::top_offset())); |
| 995 __ ldr(R0, Address(R5, Heap::TopOffset(space))); | |
| 996 __ add(R3, R2, Operand(R0)); | 991 __ add(R3, R2, Operand(R0)); |
| 997 // Check if the allocation fits into the remaining space. | 992 // Check if the allocation fits into the remaining space. |
| 998 // R0: potential new object. | 993 // R0: potential new object. |
| 999 // R1: number of context variables. | 994 // R1: number of context variables. |
| 1000 // R2: object size. | 995 // R2: object size. |
| 1001 // R3: potential next object start. | 996 // R3: potential next object start. |
| 1002 // R5: heap. | 997 __ ldr(TMP, Address(THR, Thread::end_offset())); |
| 1003 __ ldr(TMP, Address(R5, Heap::EndOffset(space))); | |
| 1004 __ CompareRegisters(R3, TMP); | 998 __ CompareRegisters(R3, TMP); |
| 1005 if (FLAG_use_slow_path) { | 999 if (FLAG_use_slow_path) { |
| 1006 __ b(&slow_case); | 1000 __ b(&slow_case); |
| 1007 } else { | 1001 } else { |
| 1008 __ b(&slow_case, CS); // Branch if unsigned higher or equal. | 1002 __ b(&slow_case, CS); // Branch if unsigned higher or equal. |
| 1009 } | 1003 } |
| 1010 | 1004 |
| 1011 // Successfully allocated the object, now update top to point to | 1005 // Successfully allocated the object, now update top to point to |
| 1012 // next object start and initialize the object. | 1006 // next object start and initialize the object. |
| 1013 // R0: new object. | 1007 // R0: new object. |
| 1014 // R1: number of context variables. | 1008 // R1: number of context variables. |
| 1015 // R2: object size. | 1009 // R2: object size. |
| 1016 // R3: next object start. | 1010 // R3: next object start. |
| 1017 // R5: heap. | 1011 __ str(R3, Address(THR, Thread::top_offset())); |
| 1018 __ str(R3, Address(R5, Heap::TopOffset(space))); | |
| 1019 __ add(R0, R0, Operand(kHeapObjectTag)); | 1012 __ add(R0, R0, Operand(kHeapObjectTag)); |
| 1020 NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, R2, space)); | 1013 NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, R2, space)); |
| 1021 | 1014 |
| 1022 // Calculate the size tag. | 1015 // Calculate the size tag. |
| 1023 // R0: new object. | 1016 // R0: new object. |
| 1024 // R1: number of context variables. | 1017 // R1: number of context variables. |
| 1025 // R2: object size. | 1018 // R2: object size. |
| 1026 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; | 1019 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; |
| 1027 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag); | 1020 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag); |
| 1028 // If no size tag overflow, shift R2 left, else set R2 to zero. | 1021 // If no size tag overflow, shift R2 left, else set R2 to zero. |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1169 __ ldr(R1, Address(SP)); | 1162 __ ldr(R1, Address(SP)); |
| 1170 // R1: instantiated type arguments. | 1163 // R1: instantiated type arguments. |
| 1171 } | 1164 } |
| 1172 Isolate* isolate = Isolate::Current(); | 1165 Isolate* isolate = Isolate::Current(); |
| 1173 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size) && | 1166 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size) && |
| 1174 !cls.TraceAllocation(isolate)) { | 1167 !cls.TraceAllocation(isolate)) { |
| 1175 Label slow_case; | 1168 Label slow_case; |
| 1176 // Allocate the object and update top to point to | 1169 // Allocate the object and update top to point to |
| 1177 // next object start and initialize the allocated object. | 1170 // next object start and initialize the allocated object. |
| 1178 // R1: instantiated type arguments (if is_cls_parameterized). | 1171 // R1: instantiated type arguments (if is_cls_parameterized). |
| 1179 Heap::Space space = Heap::kNew; | 1172 NOT_IN_PRODUCT(Heap::Space space = Heap::kNew); |
| 1180 __ ldr(R5, Address(THR, Thread::heap_offset())); | 1173 __ ldr(R2, Address(THR, Thread::top_offset())); |
| 1181 __ ldr(R2, Address(R5, Heap::TopOffset(space))); | |
| 1182 __ AddImmediate(R3, R2, instance_size); | 1174 __ AddImmediate(R3, R2, instance_size); |
| 1183 // Check if the allocation fits into the remaining space. | 1175 // Check if the allocation fits into the remaining space. |
| 1184 // R2: potential new object start. | 1176 // R2: potential new object start. |
| 1185 // R3: potential next object start. | 1177 // R3: potential next object start. |
| 1186 // R5: heap. | 1178 __ ldr(TMP, Address(THR, Thread::end_offset())); |
| 1187 __ ldr(TMP, Address(R5, Heap::EndOffset(space))); | |
| 1188 __ CompareRegisters(R3, TMP); | 1179 __ CompareRegisters(R3, TMP); |
| 1189 if (FLAG_use_slow_path) { | 1180 if (FLAG_use_slow_path) { |
| 1190 __ b(&slow_case); | 1181 __ b(&slow_case); |
| 1191 } else { | 1182 } else { |
| 1192 __ b(&slow_case, CS); // Unsigned higher or equal. | 1183 __ b(&slow_case, CS); // Unsigned higher or equal. |
| 1193 } | 1184 } |
| 1194 __ str(R3, Address(R5, Heap::TopOffset(space))); | 1185 __ str(R3, Address(THR, Thread::top_offset())); |
| 1195 NOT_IN_PRODUCT(__ UpdateAllocationStats(cls.id(), space)); | 1186 NOT_IN_PRODUCT(__ UpdateAllocationStats(cls.id(), space)); |
| 1196 | 1187 |
| 1197 // R2: new object start. | 1188 // R2: new object start. |
| 1198 // R3: next object start. | 1189 // R3: next object start. |
| 1199 // R1: new object type arguments (if is_cls_parameterized). | 1190 // R1: new object type arguments (if is_cls_parameterized). |
| 1200 // Set the tags. | 1191 // Set the tags. |
| 1201 uint32_t tags = 0; | 1192 uint32_t tags = 0; |
| 1202 tags = RawObject::SizeTag::update(instance_size, tags); | 1193 tags = RawObject::SizeTag::update(instance_size, tags); |
| 1203 ASSERT(cls.id() != kIllegalCid); | 1194 ASSERT(cls.id() != kIllegalCid); |
| 1204 tags = RawObject::ClassIdTag::update(cls.id(), tags); | 1195 tags = RawObject::ClassIdTag::update(cls.id(), tags); |
| (...skipping 1175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2380 } | 2371 } |
| 2381 | 2372 |
| 2382 | 2373 |
| 2383 void StubCode::GenerateAsynchronousGapMarkerStub(Assembler* assembler) { | 2374 void StubCode::GenerateAsynchronousGapMarkerStub(Assembler* assembler) { |
| 2384 __ brk(0); | 2375 __ brk(0); |
| 2385 } | 2376 } |
| 2386 | 2377 |
| 2387 } // namespace dart | 2378 } // namespace dart |
| 2388 | 2379 |
| 2389 #endif // defined TARGET_ARCH_ARM64 | 2380 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |