| 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" // 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" |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 __ addq(RDI, Immediate(kWordSize)); | 129 __ addq(RDI, Immediate(kWordSize)); |
| 130 __ jmp(&init_loop, Assembler::kNearJump); | 130 __ jmp(&init_loop, Assembler::kNearJump); |
| 131 __ Bind(&done); | 131 __ Bind(&done); |
| 132 __ ret(); // returns the newly allocated object in RAX. | 132 __ ret(); // returns the newly allocated object in RAX. |
| 133 | 133 |
| 134 __ Bind(&fall_through); | 134 __ Bind(&fall_through); |
| 135 return false; | 135 return false; |
| 136 } | 136 } |
| 137 | 137 |
| 138 | 138 |
| 139 bool Intrinsifier::Array_getLength(Assembler* assembler) { | |
| 140 __ movq(RAX, Address(RSP, + 1 * kWordSize)); | |
| 141 __ movq(RAX, FieldAddress(RAX, Array::length_offset())); | |
| 142 __ ret(); | |
| 143 return true; | |
| 144 } | |
| 145 | |
| 146 | |
| 147 bool Intrinsifier::ImmutableArray_getLength(Assembler* assembler) { | |
| 148 return Array_getLength(assembler); | |
| 149 } | |
| 150 | |
| 151 | |
| 152 bool Intrinsifier::Array_getIndexed(Assembler* assembler) { | 139 bool Intrinsifier::Array_getIndexed(Assembler* assembler) { |
| 153 Label fall_through; | 140 Label fall_through; |
| 154 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index. | 141 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index. |
| 155 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array. | 142 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array. |
| 156 __ testq(RCX, Immediate(kSmiTagMask)); | 143 __ testq(RCX, Immediate(kSmiTagMask)); |
| 157 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. | 144 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. |
| 158 // Range check. | 145 // Range check. |
| 159 __ cmpq(RCX, FieldAddress(RAX, Array::length_offset())); | 146 __ cmpq(RCX, FieldAddress(RAX, Array::length_offset())); |
| 160 // Runtime throws exception. | 147 // Runtime throws exception. |
| 161 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | 148 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 // Set the length field in the growable array object to 0. | 251 // Set the length field in the growable array object to 0. |
| 265 __ movq(FieldAddress(RAX, GrowableObjectArray::length_offset()), | 252 __ movq(FieldAddress(RAX, GrowableObjectArray::length_offset()), |
| 266 Immediate(0)); | 253 Immediate(0)); |
| 267 __ ret(); // returns the newly allocated object in RAX. | 254 __ ret(); // returns the newly allocated object in RAX. |
| 268 | 255 |
| 269 __ Bind(&fall_through); | 256 __ Bind(&fall_through); |
| 270 return false; | 257 return false; |
| 271 } | 258 } |
| 272 | 259 |
| 273 | 260 |
| 274 // Get length of growable object array. | |
| 275 // On stack: growable array (+1), return-address (+0). | |
| 276 bool Intrinsifier::GrowableArray_getLength(Assembler* assembler) { | |
| 277 __ movq(RAX, Address(RSP, + 1 * kWordSize)); | |
| 278 __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::length_offset())); | |
| 279 __ ret(); | |
| 280 return true; | |
| 281 } | |
| 282 | |
| 283 | |
| 284 bool Intrinsifier::GrowableArray_getCapacity(Assembler* assembler) { | 261 bool Intrinsifier::GrowableArray_getCapacity(Assembler* assembler) { |
| 285 __ movq(RAX, Address(RSP, + 1 * kWordSize)); | 262 __ movq(RAX, Address(RSP, + 1 * kWordSize)); |
| 286 __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::data_offset())); | 263 __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::data_offset())); |
| 287 __ movq(RAX, FieldAddress(RAX, Array::length_offset())); | 264 __ movq(RAX, FieldAddress(RAX, Array::length_offset())); |
| 288 __ ret(); | 265 __ ret(); |
| 289 return true; | 266 return true; |
| 290 } | 267 } |
| 291 | 268 |
| 292 | 269 |
| 293 // Access growable object array at specified index. | 270 // Access growable object array at specified index. |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump); \ | 480 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump); \ |
| 504 __ movq(Address(RDI, 0), RBX); \ | 481 __ movq(Address(RDI, 0), RBX); \ |
| 505 __ addq(RDI, Immediate(kWordSize)); \ | 482 __ addq(RDI, Immediate(kWordSize)); \ |
| 506 __ jmp(&init_loop, Assembler::kNearJump); \ | 483 __ jmp(&init_loop, Assembler::kNearJump); \ |
| 507 __ Bind(&done); \ | 484 __ Bind(&done); \ |
| 508 \ | 485 \ |
| 509 __ ret(); \ | 486 __ ret(); \ |
| 510 __ Bind(&fall_through); \ | 487 __ Bind(&fall_through); \ |
| 511 | 488 |
| 512 | 489 |
| 513 // Gets the length of a TypedData. | |
| 514 bool Intrinsifier::TypedData_getLength(Assembler* assembler) { | |
| 515 __ movq(RAX, Address(RSP, + 1 * kWordSize)); | |
| 516 __ movq(RAX, FieldAddress(RAX, TypedData::length_offset())); | |
| 517 __ ret(); | |
| 518 // Generate enough code to satisfy patchability constraint. | |
| 519 intptr_t offset = __ CodeSize(); | |
| 520 __ nop(JumpPattern::InstructionLength() - offset); | |
| 521 return true; | |
| 522 } | |
| 523 | |
| 524 | |
| 525 static ScaleFactor GetScaleFactor(intptr_t size) { | 490 static ScaleFactor GetScaleFactor(intptr_t size) { |
| 526 switch (size) { | 491 switch (size) { |
| 527 case 1: return TIMES_1; | 492 case 1: return TIMES_1; |
| 528 case 2: return TIMES_2; | 493 case 2: return TIMES_2; |
| 529 case 4: return TIMES_4; | 494 case 4: return TIMES_4; |
| 530 case 8: return TIMES_8; | 495 case 8: return TIMES_8; |
| 531 case 16: return TIMES_16; | 496 case 16: return TIMES_16; |
| 532 } | 497 } |
| 533 UNREACHABLE(); | 498 UNREACHABLE(); |
| 534 return static_cast<ScaleFactor>(0); | 499 return static_cast<ScaleFactor>(0); |
| (...skipping 876 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1411 __ movq(RAX, FieldAddress(RAX, String::hash_offset())); | 1376 __ movq(RAX, FieldAddress(RAX, String::hash_offset())); |
| 1412 __ cmpq(RAX, Immediate(0)); | 1377 __ cmpq(RAX, Immediate(0)); |
| 1413 __ j(EQUAL, &fall_through, Assembler::kNearJump); | 1378 __ j(EQUAL, &fall_through, Assembler::kNearJump); |
| 1414 __ ret(); | 1379 __ ret(); |
| 1415 __ Bind(&fall_through); | 1380 __ Bind(&fall_through); |
| 1416 // Hash not yet computed. | 1381 // Hash not yet computed. |
| 1417 return false; | 1382 return false; |
| 1418 } | 1383 } |
| 1419 | 1384 |
| 1420 | 1385 |
| 1421 bool Intrinsifier::String_getLength(Assembler* assembler) { | |
| 1422 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // String object. | |
| 1423 __ movq(RAX, FieldAddress(RAX, String::length_offset())); | |
| 1424 __ ret(); | |
| 1425 return true; | |
| 1426 } | |
| 1427 | |
| 1428 | |
| 1429 bool Intrinsifier::String_codeUnitAt(Assembler* assembler) { | 1386 bool Intrinsifier::String_codeUnitAt(Assembler* assembler) { |
| 1430 Label fall_through, try_two_byte_string; | 1387 Label fall_through, try_two_byte_string; |
| 1431 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index. | 1388 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Index. |
| 1432 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // String. | 1389 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // String. |
| 1433 __ testq(RCX, Immediate(kSmiTagMask)); | 1390 __ testq(RCX, Immediate(kSmiTagMask)); |
| 1434 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. | 1391 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. |
| 1435 // Range check. | 1392 // Range check. |
| 1436 __ cmpq(RCX, FieldAddress(RAX, String::length_offset())); | 1393 __ cmpq(RCX, FieldAddress(RAX, String::length_offset())); |
| 1437 // Runtime throws exception. | 1394 // Runtime throws exception. |
| 1438 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | 1395 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1689 __ Bind(&fall_through); | 1646 __ Bind(&fall_through); |
| 1690 return false; | 1647 return false; |
| 1691 } | 1648 } |
| 1692 | 1649 |
| 1693 | 1650 |
| 1694 #undef __ | 1651 #undef __ |
| 1695 | 1652 |
| 1696 } // namespace dart | 1653 } // namespace dart |
| 1697 | 1654 |
| 1698 #endif // defined TARGET_ARCH_X64 | 1655 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |