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

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

Issue 1263513002: VM: Load allocation-top and -end via Thread. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: arm, arm64 and mips Created 5 years, 4 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
OLDNEW
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" // Needed here to get TARGET_ARCH_ARM64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64.
6 #if defined(TARGET_ARCH_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
7 7
8 #include "vm/intrinsifier.h" 8 #include "vm/intrinsifier.h"
9 9
10 #include "vm/assembler.h" 10 #include "vm/assembler.h"
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 case 16: return 4; 191 case 16: return 4;
192 } 192 }
193 UNREACHABLE(); 193 UNREACHABLE();
194 return -1; 194 return -1;
195 } 195 }
196 196
197 197
198 #define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_shift) \ 198 #define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_shift) \
199 Label fall_through; \ 199 Label fall_through; \
200 const intptr_t kArrayLengthStackOffset = 0 * kWordSize; \ 200 const intptr_t kArrayLengthStackOffset = 0 * kWordSize; \
201 __ MaybeTraceAllocation(cid, R2, kNoPP, &fall_through); \ 201 __ MaybeTraceAllocation(cid, R2, kNoPP, &fall_through, \
202 /* inline_isolate = */ false); \
202 __ ldr(R2, Address(SP, kArrayLengthStackOffset)); /* Array length. */ \ 203 __ ldr(R2, Address(SP, kArrayLengthStackOffset)); /* Array length. */ \
203 /* Check that length is a positive Smi. */ \ 204 /* Check that length is a positive Smi. */ \
204 /* R2: requested array length argument. */ \ 205 /* R2: requested array length argument. */ \
205 __ tsti(R2, Immediate(kSmiTagMask)); \ 206 __ tsti(R2, Immediate(kSmiTagMask)); \
206 __ b(&fall_through, NE); \ 207 __ b(&fall_through, NE); \
207 __ CompareRegisters(R2, ZR); \ 208 __ CompareRegisters(R2, ZR); \
208 __ b(&fall_through, LT); \ 209 __ b(&fall_through, LT); \
209 __ SmiUntag(R2); \ 210 __ SmiUntag(R2); \
210 /* Check for maximum allowed length. */ \ 211 /* Check for maximum allowed length. */ \
211 /* R2: untagged array length. */ \ 212 /* R2: untagged array length. */ \
212 __ CompareImmediate(R2, max_len, kNoPP); \ 213 __ CompareImmediate(R2, max_len, kNoPP); \
213 __ b(&fall_through, GT); \ 214 __ b(&fall_through, GT); \
214 __ LslImmediate(R2, R2, scale_shift); \ 215 __ LslImmediate(R2, R2, scale_shift); \
215 const intptr_t fixed_size = sizeof(Raw##type_name) + kObjectAlignment - 1; \ 216 const intptr_t fixed_size = sizeof(Raw##type_name) + kObjectAlignment - 1; \
216 __ AddImmediate(R2, R2, fixed_size, kNoPP); \ 217 __ AddImmediate(R2, R2, fixed_size, kNoPP); \
217 __ andi(R2, R2, Immediate(~(kObjectAlignment - 1))); \ 218 __ andi(R2, R2, Immediate(~(kObjectAlignment - 1))); \
218 Heap* heap = Isolate::Current()->heap(); \ 219 Heap::Space space = Heap::SpaceForAllocation(cid); \
219 Heap::Space space = heap->SpaceForAllocation(cid); \ 220 __ ldr(R3, Address(THR, Thread::heap_offset())); \
220 __ LoadImmediate(R0, heap->TopAddress(space), kNoPP); \ 221 __ ldr(R0, Address(R3, Heap::TopOffset(space))); \
221 __ ldr(R0, Address(R0, 0)); \
222 \ 222 \
223 /* R2: allocation size. */ \ 223 /* R2: allocation size. */ \
224 __ adds(R1, R0, Operand(R2)); \ 224 __ adds(R1, R0, Operand(R2)); \
225 __ b(&fall_through, CS); /* Fail on unsigned overflow. */ \ 225 __ b(&fall_through, CS); /* Fail on unsigned overflow. */ \
226 \ 226 \
227 /* Check if the allocation fits into the remaining space. */ \ 227 /* Check if the allocation fits into the remaining space. */ \
228 /* R0: potential new object start. */ \ 228 /* R0: potential new object start. */ \
229 /* R1: potential next object start. */ \ 229 /* R1: potential next object start. */ \
230 /* R2: allocation size. */ \ 230 /* R2: allocation size. */ \
231 __ LoadImmediate(R3, heap->EndAddress(space), kNoPP); \ 231 /* R3: heap. */ \
232 __ ldr(R3, Address(R3, 0)); \ 232 __ ldr(R4, Address(R3, Heap::EndOffset(space))); \
233 __ cmp(R1, Operand(R3)); \ 233 __ cmp(R1, Operand(R4)); \
234 __ b(&fall_through, CS); \ 234 __ b(&fall_through, CS); \
235 \ 235 \
236 /* Successfully allocated the object(s), now update top to point to */ \ 236 /* Successfully allocated the object(s), now update top to point to */ \
237 /* next object start and initialize the object. */ \ 237 /* next object start and initialize the object. */ \
238 __ LoadImmediate(R3, heap->TopAddress(space), kNoPP); \ 238 __ str(R1, Address(R3, Heap::TopOffset(space))); \
239 __ str(R1, Address(R3, 0)); \
240 __ AddImmediate(R0, R0, kHeapObjectTag, kNoPP); \ 239 __ AddImmediate(R0, R0, kHeapObjectTag, kNoPP); \
241 __ UpdateAllocationStatsWithSize(cid, R2, kNoPP, space); \ 240 __ UpdateAllocationStatsWithSize(cid, R2, kNoPP, space, \
241 /* inline_isolate = */ false); \
242 /* Initialize the tags. */ \ 242 /* Initialize the tags. */ \
243 /* R0: new object start as a tagged pointer. */ \ 243 /* R0: new object start as a tagged pointer. */ \
244 /* R1: new object end address. */ \ 244 /* R1: new object end address. */ \
245 /* R2: allocation size. */ \ 245 /* R2: allocation size. */ \
246 { \ 246 { \
247 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag, kNoPP); \ 247 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag, kNoPP); \
248 __ LslImmediate(R2, R2, RawObject::kSizeTagPos - kObjectAlignmentLog2); \ 248 __ LslImmediate(R2, R2, RawObject::kSizeTagPos - kObjectAlignmentLog2); \
249 __ csel(R2, ZR, R2, HI); \ 249 __ csel(R2, ZR, R2, HI); \
250 \ 250 \
251 /* Get the class index and insert it into the tags. */ \ 251 /* Get the class index and insert it into the tags. */ \
(...skipping 1594 matching lines...) Expand 10 before | Expand all | Expand 10 after
1846 1846
1847 // Allocates one-byte string of length 'end - start'. The content is not 1847 // Allocates one-byte string of length 'end - start'. The content is not
1848 // initialized. 1848 // initialized.
1849 // 'length-reg' (R2) contains tagged length. 1849 // 'length-reg' (R2) contains tagged length.
1850 // Returns new string as tagged pointer in R0. 1850 // Returns new string as tagged pointer in R0.
1851 static void TryAllocateOnebyteString(Assembler* assembler, 1851 static void TryAllocateOnebyteString(Assembler* assembler,
1852 Label* ok, 1852 Label* ok,
1853 Label* failure) { 1853 Label* failure) {
1854 const Register length_reg = R2; 1854 const Register length_reg = R2;
1855 Label fail; 1855 Label fail;
1856 __ MaybeTraceAllocation(kOneByteStringCid, R0, kNoPP, failure); 1856 __ MaybeTraceAllocation(kOneByteStringCid, R0, kNoPP, failure,
1857 /* inline_isolate = */ false);
1857 __ mov(R6, length_reg); // Save the length register. 1858 __ mov(R6, length_reg); // Save the length register.
1858 // TODO(koda): Protect against negative length and overflow here. 1859 // TODO(koda): Protect against negative length and overflow here.
1859 __ SmiUntag(length_reg); 1860 __ SmiUntag(length_reg);
1860 const intptr_t fixed_size = sizeof(RawString) + kObjectAlignment - 1; 1861 const intptr_t fixed_size = sizeof(RawString) + kObjectAlignment - 1;
1861 __ AddImmediate(length_reg, length_reg, fixed_size, kNoPP); 1862 __ AddImmediate(length_reg, length_reg, fixed_size, kNoPP);
1862 __ andi(length_reg, length_reg, Immediate(~(kObjectAlignment - 1))); 1863 __ andi(length_reg, length_reg, Immediate(~(kObjectAlignment - 1)));
1863 1864
1864 Isolate* isolate = Isolate::Current();
1865 Heap* heap = isolate->heap();
1866 const intptr_t cid = kOneByteStringCid; 1865 const intptr_t cid = kOneByteStringCid;
1867 Heap::Space space = heap->SpaceForAllocation(cid); 1866 Heap::Space space = Heap::SpaceForAllocation(cid);
1868 __ LoadImmediate(R3, heap->TopAddress(space), kNoPP); 1867 __ ldr(R3, Address(THR, Thread::heap_offset()));
1869 __ ldr(R0, Address(R3)); 1868 __ ldr(R0, Address(R3, Heap::TopOffset(space)));
1870 1869
1871 // length_reg: allocation size. 1870 // length_reg: allocation size.
1872 __ adds(R1, R0, Operand(length_reg)); 1871 __ adds(R1, R0, Operand(length_reg));
1873 __ b(&fail, CS); // Fail on unsigned overflow. 1872 __ b(&fail, CS); // Fail on unsigned overflow.
1874 1873
1875 // Check if the allocation fits into the remaining space. 1874 // Check if the allocation fits into the remaining space.
1876 // R0: potential new object start. 1875 // R0: potential new object start.
1877 // R1: potential next object start. 1876 // R1: potential next object start.
1878 // R2: allocation size. 1877 // R2: allocation size.
1879 // R3: heap->TopAddress(space). 1878 // R3: heap.
1880 __ LoadImmediate(R7, heap->EndAddress(space), kNoPP); 1879 __ ldr(R7, Address(R3, Heap::EndOffset(space)));
1881 __ ldr(R7, Address(R7));
1882 __ cmp(R1, Operand(R7)); 1880 __ cmp(R1, Operand(R7));
1883 __ b(&fail, CS); 1881 __ b(&fail, CS);
1884 1882
1885 // Successfully allocated the object(s), now update top to point to 1883 // Successfully allocated the object(s), now update top to point to
1886 // next object start and initialize the object. 1884 // next object start and initialize the object.
1887 __ str(R1, Address(R3)); 1885 __ str(R1, Address(R3, Heap::TopOffset(space)));
1888 __ AddImmediate(R0, R0, kHeapObjectTag, kNoPP); 1886 __ AddImmediate(R0, R0, kHeapObjectTag, kNoPP);
1889 __ UpdateAllocationStatsWithSize(cid, R2, kNoPP, space); 1887 __ UpdateAllocationStatsWithSize(cid, R2, kNoPP, space,
1888 /* inline_isolate = */ false);
1890 1889
1891 // Initialize the tags. 1890 // Initialize the tags.
1892 // R0: new object start as a tagged pointer. 1891 // R0: new object start as a tagged pointer.
1893 // R1: new object end address. 1892 // R1: new object end address.
1894 // R2: allocation size. 1893 // R2: allocation size.
1895 { 1894 {
1896 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; 1895 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2;
1897 1896
1898 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag, kNoPP); 1897 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag, kNoPP);
1899 __ LslImmediate(R2, R2, shift); 1898 __ LslImmediate(R2, R2, shift);
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
2140 2139
2141 void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) { 2140 void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) {
2142 __ LoadIsolate(R0); 2141 __ LoadIsolate(R0);
2143 __ ldr(R0, Address(R0, Isolate::current_tag_offset())); 2142 __ ldr(R0, Address(R0, Isolate::current_tag_offset()));
2144 __ ret(); 2143 __ ret();
2145 } 2144 }
2146 2145
2147 } // namespace dart 2146 } // namespace dart
2148 2147
2149 #endif // defined TARGET_ARCH_ARM64 2148 #endif // defined TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698