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 1402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1413 __ j(NOT_EQUAL, &set_hash_code, Assembler::kNearJump); | 1413 __ j(NOT_EQUAL, &set_hash_code, Assembler::kNearJump); |
1414 __ incq(RAX); | 1414 __ incq(RAX); |
1415 __ Bind(&set_hash_code); | 1415 __ Bind(&set_hash_code); |
1416 __ SmiTag(RAX); | 1416 __ SmiTag(RAX); |
1417 __ movq(FieldAddress(RBX, String::hash_offset()), RAX); | 1417 __ movq(FieldAddress(RBX, String::hash_offset()), RAX); |
1418 __ ret(); | 1418 __ ret(); |
1419 return true; | 1419 return true; |
1420 } | 1420 } |
1421 | 1421 |
1422 | 1422 |
1423 // Allocates one-byte string of length 'end - start'. The content is not | |
1424 // initialized. | |
1425 static void AllocateOnebyteString(Assembler* assembler, | |
1426 Label* fall_through, | |
1427 intptr_t start_index_offset, | |
1428 intptr_t end_index_offset) { | |
1429 __ movq(RDI, Address(RSP, + end_index_offset)); | |
1430 __ subq(RDI, Address(RSP, + start_index_offset)); | |
1431 const intptr_t fixed_size = sizeof(RawString) + kObjectAlignment - 1; | |
1432 __ SmiUntag(RDI); | |
1433 __ leaq(RDI, Address(RDI, TIMES_1, fixed_size)); // RDI is a Smi. | |
1434 __ andq(RDI, Immediate(-kObjectAlignment)); | |
1435 | |
1436 Isolate* isolate = Isolate::Current(); | |
1437 Heap* heap = isolate->heap(); | |
1438 | |
1439 __ movq(RAX, Immediate(heap->TopAddress())); | |
1440 __ movq(RAX, Address(RAX, 0)); | |
1441 | |
Florian Schneider
2013/04/10 16:09:51
Extra new line?
srdjan
2013/04/10 20:08:05
Removed
| |
1442 | |
1443 // RDI: allocation size. | |
1444 __ movq(RCX, RAX); | |
1445 __ addq(RCX, RDI); | |
1446 __ j(CARRY, fall_through); | |
1447 | |
1448 // Check if the allocation fits into the remaining space. | |
1449 // RAX: potential new object start. | |
1450 // RCX: potential next object start. | |
1451 // RDI: allocation size. | |
1452 __ movq(R13, Immediate(heap->EndAddress())); | |
1453 __ cmpq(RCX, Address(R13, 0)); | |
1454 __ j(ABOVE_EQUAL, fall_through); | |
1455 | |
1456 // Successfully allocated the object(s), now update top to point to | |
1457 // next object start and initialize the object. | |
1458 __ movq(R13, Immediate(heap->TopAddress())); | |
1459 __ movq(Address(R13, 0), RCX); | |
1460 __ addq(RAX, Immediate(kHeapObjectTag)); | |
1461 | |
1462 // Initialize the tags. | |
1463 // RAX: new object start as a tagged pointer. | |
1464 // RDI: allocation size. | |
1465 { | |
1466 Label size_tag_overflow, done; | |
1467 __ cmpq(RDI, Immediate(RawObject::SizeTag::kMaxSizeTag)); | |
1468 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); | |
1469 __ shlq(RDI, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2)); | |
1470 __ jmp(&done, Assembler::kNearJump); | |
1471 | |
1472 __ Bind(&size_tag_overflow); | |
1473 __ movq(RDI, Immediate(0)); | |
1474 __ Bind(&done); | |
1475 | |
1476 // Get the class index and insert it into the tags. | |
1477 const Class& cls = | |
1478 Class::Handle(isolate->object_store()->one_byte_string_class()); | |
1479 __ orq(RDI, Immediate(RawObject::ClassIdTag::encode(cls.id()))); | |
1480 __ movq(FieldAddress(RAX, String::tags_offset()), RDI); // Tags. | |
1481 } | |
1482 | |
1483 // Set the length field. | |
1484 __ movq(RDI, Address(RSP, + end_index_offset)); | |
1485 __ subq(RDI, Address(RSP, + start_index_offset)); // Length. | |
1486 __ StoreIntoObjectNoBarrier(RAX, | |
1487 FieldAddress(RAX, String::length_offset()), | |
1488 RDI); | |
1489 // Clear hash. | |
1490 __ movq(FieldAddress(RAX, String::hash_offset()), Immediate(0)); | |
1491 } | |
1492 | |
1493 | |
1494 // Arg0: Onebyte String | |
1495 // Arg1: Start index as Smi. | |
1496 // Arg2: End index as Smi. | |
1497 // The indexes must be valid. | |
1498 bool Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler) { | |
1499 const intptr_t kStringOffset = 3 * kWordSize; | |
1500 const intptr_t kStartIndexOffset = 2 * kWordSize; | |
1501 const intptr_t kEndIndexOffset = 1 * kWordSize; | |
1502 Label fall_through, done; | |
1503 AllocateOnebyteString( | |
1504 assembler, &fall_through, kStartIndexOffset, kEndIndexOffset); | |
1505 // RAX: new string as tagged pointer. | |
1506 // Copy string. | |
1507 __ movq(RDI, Address(RSP, + kStringOffset)); | |
1508 __ movq(RBX, Address(RSP, + kStartIndexOffset)); | |
1509 __ SmiUntag(RBX); | |
1510 __ leaq(RDI, FieldAddress(RDI, RBX, TIMES_1, OneByteString::data_offset())); | |
1511 // EDI: Start address to copy from (untagged). | |
Florian Schneider
2013/04/10 16:09:51
s/EDI/RDI/g
srdjan
2013/04/10 20:08:05
Done.
| |
1512 __ movq(RDX, Address(RSP, + kEndIndexOffset)); | |
1513 __ SmiUntag(RDX); | |
1514 __ subq(RDX, RBX); | |
1515 __ xorq(RCX, RCX); | |
1516 // RDX: Number of bytes to copy. | |
1517 // RCX: Loop counter. | |
1518 // TODO(srdjan): For large substrings it could be better if we would group | |
1519 // the byte copies into word copies or even call memcpy. | |
Florian Schneider
2013/04/10 16:09:51
Same as on ia32: Consider using rep movsb instead
srdjan
2013/04/10 20:08:05
Added TODO.
| |
1520 Label loop, check; | |
1521 __ jmp(&check, Assembler::kNearJump); | |
1522 __ Bind(&loop); | |
1523 __ movzxb(RBX, Address(RDI, RCX, TIMES_1, 0)); | |
1524 __ movb(FieldAddress(RAX, RCX, TIMES_1, OneByteString::data_offset()), RBX); | |
1525 __ incq(RCX); | |
1526 __ Bind(&check); | |
1527 __ cmpq(RCX, RDX); | |
1528 __ j(LESS, &loop, Assembler::kNearJump); | |
1529 | |
1530 __ Bind(&done); | |
1531 __ ret(); | |
1532 __ Bind(&fall_through); | |
1533 return false; | |
1534 } | |
1535 | |
1536 | |
1423 #undef __ | 1537 #undef __ |
1424 | 1538 |
1425 } // namespace dart | 1539 } // namespace dart |
1426 | 1540 |
1427 #endif // defined TARGET_ARCH_X64 | 1541 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |