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

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

Issue 25813002: - Rename arrays to lists: (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 2 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 | Annotate | Revision Log
OLDNEW
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" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/intrinsifier.h" 8 #include "vm/intrinsifier.h"
9 9
10 #include "vm/assembler.h" 10 #include "vm/assembler.h"
11 #include "vm/flow_graph_compiler.h" 11 #include "vm/flow_graph_compiler.h"
12 #include "vm/instructions.h" 12 #include "vm/instructions.h"
13 #include "vm/object_store.h" 13 #include "vm/object_store.h"
14 #include "vm/symbols.h" 14 #include "vm/symbols.h"
15 15
16 namespace dart { 16 namespace dart {
17 17
18 DECLARE_FLAG(bool, enable_type_checks); 18 DECLARE_FLAG(bool, enable_type_checks);
19 19
20 // When entering intrinsics code: 20 // When entering intrinsics code:
21 // RBX: IC Data 21 // RBX: IC Data
22 // R10: Arguments descriptor 22 // R10: Arguments descriptor
23 // TOS: Return address 23 // TOS: Return address
24 // The RBX, R10 registers can be destroyed only if there is no slow-path (i.e., 24 // The RBX, R10 registers can be destroyed only if there is no slow-path (i.e.,
25 // the methods returns true). 25 // the methods returns true).
26 26
27 #define __ assembler-> 27 #define __ assembler->
28 28
29 29
30 void Intrinsifier::ObjectArray_Allocate(Assembler* assembler) { 30 void Intrinsifier::List_Allocate(Assembler* assembler) {
31 // This snippet of inlined code uses the following registers: 31 // This snippet of inlined code uses the following registers:
32 // RAX, RCX, RDI, R13 32 // RAX, RCX, RDI, R13
33 // and the newly allocated object is returned in RAX. 33 // and the newly allocated object is returned in RAX.
34 const intptr_t kTypeArgumentsOffset = 2 * kWordSize; 34 const intptr_t kTypeArgumentsOffset = 2 * kWordSize;
35 const intptr_t kArrayLengthOffset = 1 * kWordSize; 35 const intptr_t kArrayLengthOffset = 1 * kWordSize;
36 Label fall_through; 36 Label fall_through;
37 37
38 // Compute the size to be allocated, it is based on the array length 38 // Compute the size to be allocated, it is based on the array length
39 // and is computed as: 39 // and is computed as:
40 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). 40 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)).
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 } 134 }
135 135
136 136
137 void Intrinsifier::Array_getLength(Assembler* assembler) { 137 void Intrinsifier::Array_getLength(Assembler* assembler) {
138 __ movq(RAX, Address(RSP, + 1 * kWordSize)); 138 __ movq(RAX, Address(RSP, + 1 * kWordSize));
139 __ movq(RAX, FieldAddress(RAX, Array::length_offset())); 139 __ movq(RAX, FieldAddress(RAX, Array::length_offset()));
140 __ ret(); 140 __ ret();
141 } 141 }
142 142
143 143
144 void Intrinsifier::ImmutableArray_getLength(Assembler* assembler) { 144 void Intrinsifier::ImmutableList_getLength(Assembler* assembler) {
145 return Array_getLength(assembler); 145 return Array_getLength(assembler);
146 } 146 }
147 147
148 148
149 void Intrinsifier::Array_getIndexed(Assembler* assembler) { 149 void Intrinsifier::Array_getIndexed(Assembler* assembler) {
150 Label fall_through; 150 Label fall_through;
151 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index. 151 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index.
152 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array. 152 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array.
153 __ testq(RCX, Immediate(kSmiTagMask)); 153 __ testq(RCX, Immediate(kSmiTagMask));
154 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. 154 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
155 // Range check. 155 // Range check.
156 __ cmpq(RCX, FieldAddress(RAX, Array::length_offset())); 156 __ cmpq(RCX, FieldAddress(RAX, Array::length_offset()));
157 // Runtime throws exception. 157 // Runtime throws exception.
158 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); 158 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
159 // Note that RBX is Smi, i.e, times 2. 159 // Note that RBX is Smi, i.e, times 2.
160 ASSERT(kSmiTagShift == 1); 160 ASSERT(kSmiTagShift == 1);
161 __ movq(RAX, FieldAddress(RAX, RCX, TIMES_4, Array::data_offset())); 161 __ movq(RAX, FieldAddress(RAX, RCX, TIMES_4, Array::data_offset()));
162 __ ret(); 162 __ ret();
163 __ Bind(&fall_through); 163 __ Bind(&fall_through);
164 } 164 }
165 165
166 166
167 void Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) { 167 void Intrinsifier::ImmutableList_getIndexed(Assembler* assembler) {
168 return Array_getIndexed(assembler); 168 return Array_getIndexed(assembler);
169 } 169 }
170 170
171 171
172 void Intrinsifier::Array_setIndexed(Assembler* assembler) { 172 void Intrinsifier::Array_setIndexed(Assembler* assembler) {
173 if (FLAG_enable_type_checks) { 173 if (FLAG_enable_type_checks) {
174 return; 174 return;
175 } 175 }
176 __ movq(RDX, Address(RSP, + 1 * kWordSize)); // Value. 176 __ movq(RDX, Address(RSP, + 1 * kWordSize)); // Value.
177 __ movq(RCX, Address(RSP, + 2 * kWordSize)); // Index. 177 __ movq(RCX, Address(RSP, + 2 * kWordSize)); // Index.
(...skipping 12 matching lines...) Expand all
190 FieldAddress(RAX, RCX, TIMES_4, Array::data_offset()), 190 FieldAddress(RAX, RCX, TIMES_4, Array::data_offset()),
191 RDX); 191 RDX);
192 // Caller is responsible of preserving the value if necessary. 192 // Caller is responsible of preserving the value if necessary.
193 __ ret(); 193 __ ret();
194 __ Bind(&fall_through); 194 __ Bind(&fall_through);
195 } 195 }
196 196
197 197
198 // Allocate a GrowableObjectArray using the backing array specified. 198 // Allocate a GrowableObjectArray using the backing array specified.
199 // On stack: type argument (+2), data (+1), return-address (+0). 199 // On stack: type argument (+2), data (+1), return-address (+0).
200 void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) { 200 void Intrinsifier::GrowableList_Allocate(Assembler* assembler) {
201 // This snippet of inlined code uses the following registers: 201 // This snippet of inlined code uses the following registers:
202 // RAX, RCX, R13 202 // RAX, RCX, R13
203 // and the newly allocated object is returned in RAX. 203 // and the newly allocated object is returned in RAX.
204 const intptr_t kTypeArgumentsOffset = 2 * kWordSize; 204 const intptr_t kTypeArgumentsOffset = 2 * kWordSize;
205 const intptr_t kArrayOffset = 1 * kWordSize; 205 const intptr_t kArrayOffset = 1 * kWordSize;
206 Label fall_through; 206 Label fall_through;
207 207
208 // Compute the size to be allocated, it is based on the array length 208 // Compute the size to be allocated, it is based on the array length
209 // and is computed as: 209 // and is computed as:
210 // RoundedAllocationSize(sizeof(RawGrowableObjectArray)) + 210 // RoundedAllocationSize(sizeof(RawGrowableObjectArray)) +
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 __ movq(FieldAddress(RAX, GrowableObjectArray::length_offset()), 260 __ movq(FieldAddress(RAX, GrowableObjectArray::length_offset()),
261 Immediate(0)); 261 Immediate(0));
262 __ ret(); // returns the newly allocated object in RAX. 262 __ ret(); // returns the newly allocated object in RAX.
263 263
264 __ Bind(&fall_through); 264 __ Bind(&fall_through);
265 } 265 }
266 266
267 267
268 // Get length of growable object array. 268 // Get length of growable object array.
269 // On stack: growable array (+1), return-address (+0). 269 // On stack: growable array (+1), return-address (+0).
270 void Intrinsifier::GrowableArray_getLength(Assembler* assembler) { 270 void Intrinsifier::GrowableList_getLength(Assembler* assembler) {
271 __ movq(RAX, Address(RSP, + 1 * kWordSize)); 271 __ movq(RAX, Address(RSP, + 1 * kWordSize));
272 __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::length_offset())); 272 __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::length_offset()));
273 __ ret(); 273 __ ret();
274 } 274 }
275 275
276 276
277 void Intrinsifier::GrowableArray_getCapacity(Assembler* assembler) { 277 void Intrinsifier::GrowableList_getCapacity(Assembler* assembler) {
278 __ movq(RAX, Address(RSP, + 1 * kWordSize)); 278 __ movq(RAX, Address(RSP, + 1 * kWordSize));
279 __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::data_offset())); 279 __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::data_offset()));
280 __ movq(RAX, FieldAddress(RAX, Array::length_offset())); 280 __ movq(RAX, FieldAddress(RAX, Array::length_offset()));
281 __ ret(); 281 __ ret();
282 } 282 }
283 283
284 284
285 // Access growable object array at specified index. 285 // Access growable object array at specified index.
286 // On stack: growable array (+2), index (+1), return-address (+0). 286 // On stack: growable array (+2), index (+1), return-address (+0).
287 void Intrinsifier::GrowableArray_getIndexed(Assembler* assembler) { 287 void Intrinsifier::GrowableList_getIndexed(Assembler* assembler) {
288 Label fall_through; 288 Label fall_through;
289 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index. 289 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index.
290 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // GrowableArray. 290 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // GrowableArray.
291 __ testq(RCX, Immediate(kSmiTagMask)); 291 __ testq(RCX, Immediate(kSmiTagMask));
292 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. 292 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
293 // Range check using _length field. 293 // Range check using _length field.
294 __ cmpq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset())); 294 __ cmpq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset()));
295 // Runtime throws exception. 295 // Runtime throws exception.
296 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); 296 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
297 __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::data_offset())); // data. 297 __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::data_offset())); // data.
298 298
299 // Note that RCX is Smi, i.e, times 4. 299 // Note that RCX is Smi, i.e, times 4.
300 ASSERT(kSmiTagShift == 1); 300 ASSERT(kSmiTagShift == 1);
301 __ movq(RAX, FieldAddress(RAX, RCX, TIMES_4, Array::data_offset())); 301 __ movq(RAX, FieldAddress(RAX, RCX, TIMES_4, Array::data_offset()));
302 __ ret(); 302 __ ret();
303 __ Bind(&fall_through); 303 __ Bind(&fall_through);
304 } 304 }
305 305
306 306
307 // Set value into growable object array at specified index. 307 // Set value into growable object array at specified index.
308 // On stack: growable array (+3), index (+2), value (+1), return-address (+0). 308 // On stack: growable array (+3), index (+2), value (+1), return-address (+0).
309 void Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) { 309 void Intrinsifier::GrowableList_setIndexed(Assembler* assembler) {
310 if (FLAG_enable_type_checks) { 310 if (FLAG_enable_type_checks) {
311 return; 311 return;
312 } 312 }
313 __ movq(RDX, Address(RSP, + 1 * kWordSize)); // Value. 313 __ movq(RDX, Address(RSP, + 1 * kWordSize)); // Value.
314 __ movq(RCX, Address(RSP, + 2 * kWordSize)); // Index. 314 __ movq(RCX, Address(RSP, + 2 * kWordSize)); // Index.
315 __ movq(RAX, Address(RSP, + 3 * kWordSize)); // GrowableArray. 315 __ movq(RAX, Address(RSP, + 3 * kWordSize)); // GrowableArray.
316 Label fall_through; 316 Label fall_through;
317 __ testq(RCX, Immediate(kSmiTagMask)); 317 __ testq(RCX, Immediate(kSmiTagMask));
318 __ j(NOT_ZERO, &fall_through); // Non-smi index. 318 __ j(NOT_ZERO, &fall_through); // Non-smi index.
319 // Range check using _length field. 319 // Range check using _length field.
320 __ cmpq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset())); 320 __ cmpq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset()));
321 // Runtime throws exception. 321 // Runtime throws exception.
322 __ j(ABOVE_EQUAL, &fall_through); 322 __ j(ABOVE_EQUAL, &fall_through);
323 __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::data_offset())); // data. 323 __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::data_offset())); // data.
324 // Note that RCX is Smi, i.e, times 4. 324 // Note that RCX is Smi, i.e, times 4.
325 ASSERT(kSmiTagShift == 1); 325 ASSERT(kSmiTagShift == 1);
326 __ StoreIntoObject(RAX, 326 __ StoreIntoObject(RAX,
327 FieldAddress(RAX, RCX, TIMES_4, Array::data_offset()), 327 FieldAddress(RAX, RCX, TIMES_4, Array::data_offset()),
328 RDX); 328 RDX);
329 __ ret(); 329 __ ret();
330 __ Bind(&fall_through); 330 __ Bind(&fall_through);
331 } 331 }
332 332
333 333
334 // Set length of growable object array. The length cannot 334 // Set length of growable object array. The length cannot
335 // be greater than the length of the data container. 335 // be greater than the length of the data container.
336 // On stack: growable array (+2), length (+1), return-address (+0). 336 // On stack: growable array (+2), length (+1), return-address (+0).
337 void Intrinsifier::GrowableArray_setLength(Assembler* assembler) { 337 void Intrinsifier::GrowableList_setLength(Assembler* assembler) {
338 Label fall_through; 338 Label fall_through;
339 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Growable array. 339 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Growable array.
340 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Length value. 340 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Length value.
341 __ testq(RCX, Immediate(kSmiTagMask)); 341 __ testq(RCX, Immediate(kSmiTagMask));
342 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi length. 342 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi length.
343 __ movq(FieldAddress(RAX, GrowableObjectArray::length_offset()), RCX); 343 __ movq(FieldAddress(RAX, GrowableObjectArray::length_offset()), RCX);
344 __ ret(); 344 __ ret();
345 __ Bind(&fall_through); 345 __ Bind(&fall_through);
346 } 346 }
347 347
348 348
349 // Set data of growable object array. 349 // Set data of growable object array.
350 // On stack: growable array (+2), data (+1), return-address (+0). 350 // On stack: growable array (+2), data (+1), return-address (+0).
351 void Intrinsifier::GrowableArray_setData(Assembler* assembler) { 351 void Intrinsifier::GrowableList_setData(Assembler* assembler) {
352 if (FLAG_enable_type_checks) { 352 if (FLAG_enable_type_checks) {
353 return; 353 return;
354 } 354 }
355 Label fall_through; 355 Label fall_through;
356 __ movq(RBX, Address(RSP, + 1 * kWordSize)); /// Data. 356 __ movq(RBX, Address(RSP, + 1 * kWordSize)); /// Data.
357 __ testq(RBX, Immediate(kSmiTagMask)); 357 __ testq(RBX, Immediate(kSmiTagMask));
358 __ j(ZERO, &fall_through); // Data is Smi. 358 __ j(ZERO, &fall_through); // Data is Smi.
359 __ CompareClassId(RBX, kArrayCid); 359 __ CompareClassId(RBX, kArrayCid);
360 __ j(NOT_EQUAL, &fall_through); 360 __ j(NOT_EQUAL, &fall_through);
361 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Growable array. 361 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Growable array.
362 __ StoreIntoObject(RAX, 362 __ StoreIntoObject(RAX,
363 FieldAddress(RAX, GrowableObjectArray::data_offset()), 363 FieldAddress(RAX, GrowableObjectArray::data_offset()),
364 RBX); 364 RBX);
365 __ ret(); 365 __ ret();
366 __ Bind(&fall_through); 366 __ Bind(&fall_through);
367 } 367 }
368 368
369 369
370 // Add an element to growable array if it doesn't need to grow, otherwise 370 // Add an element to growable array if it doesn't need to grow, otherwise
371 // call into regular code. 371 // call into regular code.
372 // On stack: growable array (+2), value (+1), return-address (+0). 372 // On stack: growable array (+2), value (+1), return-address (+0).
373 void Intrinsifier::GrowableArray_add(Assembler* assembler) { 373 void Intrinsifier::GrowableList_add(Assembler* assembler) {
374 // In checked mode we need to check the incoming argument. 374 // In checked mode we need to check the incoming argument.
375 if (FLAG_enable_type_checks) return; 375 if (FLAG_enable_type_checks) return;
376 Label fall_through; 376 Label fall_through;
377 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array. 377 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array.
378 __ movq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset())); 378 __ movq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset()));
379 // RCX: length. 379 // RCX: length.
380 __ movq(RDX, FieldAddress(RAX, GrowableObjectArray::data_offset())); 380 __ movq(RDX, FieldAddress(RAX, GrowableObjectArray::data_offset()));
381 // RDX: data. 381 // RDX: data.
382 // Compare length with capacity. 382 // Compare length with capacity.
383 __ cmpq(RCX, FieldAddress(RDX, Array::length_offset())); 383 __ cmpq(RCX, FieldAddress(RDX, Array::length_offset()));
(...skipping 1261 matching lines...) Expand 10 before | Expand all | Expand 10 after
1645 1645
1646 __ Bind(&fall_through); 1646 __ Bind(&fall_through);
1647 } 1647 }
1648 1648
1649 1649
1650 #undef __ 1650 #undef __
1651 1651
1652 } // namespace dart 1652 } // namespace dart
1653 1653
1654 #endif // defined TARGET_ARCH_X64 1654 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intrinsifier_mips.cc ('k') | runtime/vm/object.cc » ('j') | runtime/vm/object.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698