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

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

Issue 14862006: Improve performance of String.fromCharCodes by implementing it in Dart. Add tow internal natives to… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 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
« no previous file with comments | « runtime/vm/intrinsifier_mips.cc ('k') | runtime/vm/object.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
(...skipping 1470 matching lines...) Expand 10 before | Expand all | Expand 10 after
1481 __ incq(RAX); 1481 __ incq(RAX);
1482 __ Bind(&set_hash_code); 1482 __ Bind(&set_hash_code);
1483 __ SmiTag(RAX); 1483 __ SmiTag(RAX);
1484 __ movq(FieldAddress(RBX, String::hash_offset()), RAX); 1484 __ movq(FieldAddress(RBX, String::hash_offset()), RAX);
1485 __ ret(); 1485 __ ret();
1486 return true; 1486 return true;
1487 } 1487 }
1488 1488
1489 1489
1490 // Allocates one-byte string of length 'end - start'. The content is not 1490 // Allocates one-byte string of length 'end - start'. The content is not
1491 // initialized. 1491 // initialized. 'length-reg' contains tagged length.
1492 // Returns new string as tagged pointer in EAX.
1492 static void TryAllocateOnebyteString(Assembler* assembler, 1493 static void TryAllocateOnebyteString(Assembler* assembler,
1494 Label* ok,
1493 Label* failure, 1495 Label* failure,
1494 intptr_t start_index_offset, 1496 Register length_reg) {
1495 intptr_t end_index_offset) { 1497 if (length_reg != RDI) {
1496 __ movq(RDI, Address(RSP, + end_index_offset)); 1498 __ movq(RDI, length_reg);
1497 __ subq(RDI, Address(RSP, + start_index_offset)); 1499 }
1500 Label pop_and_fail;
1501 __ pushq(RDI); // Preserve length.
1502 __ SmiUntag(RDI);
1498 const intptr_t fixed_size = sizeof(RawString) + kObjectAlignment - 1; 1503 const intptr_t fixed_size = sizeof(RawString) + kObjectAlignment - 1;
1499 __ SmiUntag(RDI);
1500 __ leaq(RDI, Address(RDI, TIMES_1, fixed_size)); // RDI is a Smi. 1504 __ leaq(RDI, Address(RDI, TIMES_1, fixed_size)); // RDI is a Smi.
1501 __ andq(RDI, Immediate(-kObjectAlignment)); 1505 __ andq(RDI, Immediate(-kObjectAlignment));
1502 1506
1503 Isolate* isolate = Isolate::Current(); 1507 Isolate* isolate = Isolate::Current();
1504 Heap* heap = isolate->heap(); 1508 Heap* heap = isolate->heap();
1505 1509
1506 __ movq(RAX, Immediate(heap->TopAddress())); 1510 __ movq(RAX, Immediate(heap->TopAddress()));
1507 __ movq(RAX, Address(RAX, 0)); 1511 __ movq(RAX, Address(RAX, 0));
1508 1512
1509 // RDI: allocation size. 1513 // RDI: allocation size.
1510 __ movq(RCX, RAX); 1514 __ movq(RCX, RAX);
1511 __ addq(RCX, RDI); 1515 __ addq(RCX, RDI);
1512 __ j(CARRY, failure); 1516 __ j(CARRY, &pop_and_fail);
1513 1517
1514 // Check if the allocation fits into the remaining space. 1518 // Check if the allocation fits into the remaining space.
1515 // RAX: potential new object start. 1519 // RAX: potential new object start.
1516 // RCX: potential next object start. 1520 // RCX: potential next object start.
1517 // RDI: allocation size. 1521 // RDI: allocation size.
1518 __ movq(R13, Immediate(heap->EndAddress())); 1522 __ movq(R13, Immediate(heap->EndAddress()));
1519 __ cmpq(RCX, Address(R13, 0)); 1523 __ cmpq(RCX, Address(R13, 0));
1520 __ j(ABOVE_EQUAL, failure); 1524 __ j(ABOVE_EQUAL, &pop_and_fail);
1521 1525
1522 // Successfully allocated the object(s), now update top to point to 1526 // Successfully allocated the object(s), now update top to point to
1523 // next object start and initialize the object. 1527 // next object start and initialize the object.
1524 __ movq(R13, Immediate(heap->TopAddress())); 1528 __ movq(R13, Immediate(heap->TopAddress()));
1525 __ movq(Address(R13, 0), RCX); 1529 __ movq(Address(R13, 0), RCX);
1526 __ addq(RAX, Immediate(kHeapObjectTag)); 1530 __ addq(RAX, Immediate(kHeapObjectTag));
1527 1531
1528 // Initialize the tags. 1532 // Initialize the tags.
1529 // RAX: new object start as a tagged pointer. 1533 // RAX: new object start as a tagged pointer.
1530 // RDI: allocation size. 1534 // RDI: allocation size.
1531 { 1535 {
1532 Label size_tag_overflow, done; 1536 Label size_tag_overflow, done;
1533 __ cmpq(RDI, Immediate(RawObject::SizeTag::kMaxSizeTag)); 1537 __ cmpq(RDI, Immediate(RawObject::SizeTag::kMaxSizeTag));
1534 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); 1538 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
1535 __ shlq(RDI, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2)); 1539 __ shlq(RDI, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2));
1536 __ jmp(&done, Assembler::kNearJump); 1540 __ jmp(&done, Assembler::kNearJump);
1537 1541
1538 __ Bind(&size_tag_overflow); 1542 __ Bind(&size_tag_overflow);
1539 __ xorq(RDI, RDI); 1543 __ xorq(RDI, RDI);
1540 __ Bind(&done); 1544 __ Bind(&done);
1541 1545
1542 // Get the class index and insert it into the tags. 1546 // Get the class index and insert it into the tags.
1543 const Class& cls = 1547 const Class& cls =
1544 Class::Handle(isolate->object_store()->one_byte_string_class()); 1548 Class::Handle(isolate->object_store()->one_byte_string_class());
1545 __ orq(RDI, Immediate(RawObject::ClassIdTag::encode(cls.id()))); 1549 __ orq(RDI, Immediate(RawObject::ClassIdTag::encode(cls.id())));
1546 __ movq(FieldAddress(RAX, String::tags_offset()), RDI); // Tags. 1550 __ movq(FieldAddress(RAX, String::tags_offset()), RDI); // Tags.
1547 } 1551 }
1548 1552
1549 // Set the length field. 1553 // Set the length field.
1550 __ movq(RDI, Address(RSP, + end_index_offset)); 1554 __ popq(RDI);
1551 __ subq(RDI, Address(RSP, + start_index_offset)); // Length.
1552 __ StoreIntoObjectNoBarrier(RAX, 1555 __ StoreIntoObjectNoBarrier(RAX,
1553 FieldAddress(RAX, String::length_offset()), 1556 FieldAddress(RAX, String::length_offset()),
1554 RDI); 1557 RDI);
1555 // Clear hash. 1558 // Clear hash.
1556 __ movq(FieldAddress(RAX, String::hash_offset()), Immediate(0)); 1559 __ movq(FieldAddress(RAX, String::hash_offset()), Immediate(0));
1560 __ jmp(ok, Assembler::kNearJump);
1561
1562 __ Bind(&pop_and_fail);
1563 __ popq(RDI);
1564 __ jmp(failure);
1557 } 1565 }
1558 1566
1559 1567
1560 // Arg0: Onebyte String 1568 // Arg0: Onebyte String
1561 // Arg1: Start index as Smi. 1569 // Arg1: Start index as Smi.
1562 // Arg2: End index as Smi. 1570 // Arg2: End index as Smi.
1563 // The indexes must be valid. 1571 // The indexes must be valid.
1564 bool Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler) { 1572 bool Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler) {
1565 const intptr_t kStringOffset = 3 * kWordSize; 1573 const intptr_t kStringOffset = 3 * kWordSize;
1566 const intptr_t kStartIndexOffset = 2 * kWordSize; 1574 const intptr_t kStartIndexOffset = 2 * kWordSize;
1567 const intptr_t kEndIndexOffset = 1 * kWordSize; 1575 const intptr_t kEndIndexOffset = 1 * kWordSize;
1568 Label fall_through; 1576 Label fall_through, ok;
1569 TryAllocateOnebyteString( 1577 __ movq(RDI, Address(RSP, + kEndIndexOffset));
1570 assembler, &fall_through, kStartIndexOffset, kEndIndexOffset); 1578 __ subq(RDI, Address(RSP, + kStartIndexOffset));
1579 TryAllocateOnebyteString(assembler, &ok, &fall_through, RDI);
1580 __ Bind(&ok);
1571 // RAX: new string as tagged pointer. 1581 // RAX: new string as tagged pointer.
1572 // Copy string. 1582 // Copy string.
1573 __ movq(RSI, Address(RSP, + kStringOffset)); 1583 __ movq(RSI, Address(RSP, + kStringOffset));
1574 __ movq(RBX, Address(RSP, + kStartIndexOffset)); 1584 __ movq(RBX, Address(RSP, + kStartIndexOffset));
1575 __ SmiUntag(RBX); 1585 __ SmiUntag(RBX);
1576 __ leaq(RSI, FieldAddress(RSI, RBX, TIMES_1, OneByteString::data_offset())); 1586 __ leaq(RSI, FieldAddress(RSI, RBX, TIMES_1, OneByteString::data_offset()));
1577 // RSI: Start address to copy from (untagged). 1587 // RSI: Start address to copy from (untagged).
1578 // RBX: Untagged start index. 1588 // RBX: Untagged start index.
1579 __ movq(RCX, Address(RSP, + kEndIndexOffset)); 1589 __ movq(RCX, Address(RSP, + kEndIndexOffset));
1580 __ SmiUntag(RCX); 1590 __ SmiUntag(RCX);
(...skipping 12 matching lines...) Expand all
1593 __ incq(RDX); 1603 __ incq(RDX);
1594 __ Bind(&check); 1604 __ Bind(&check);
1595 __ cmpq(RDX, RCX); 1605 __ cmpq(RDX, RCX);
1596 __ j(LESS, &loop, Assembler::kNearJump); 1606 __ j(LESS, &loop, Assembler::kNearJump);
1597 __ ret(); 1607 __ ret();
1598 __ Bind(&fall_through); 1608 __ Bind(&fall_through);
1599 return false; 1609 return false;
1600 } 1610 }
1601 1611
1602 1612
1613 bool Intrinsifier::OneByteString_setAt(Assembler* assembler) {
1614 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Value.
1615 __ movq(RBX, Address(RSP, + 2 * kWordSize)); // Index.
1616 __ movq(RAX, Address(RSP, + 3 * kWordSize)); // OneByteString.
1617 __ SmiUntag(RBX);
1618 __ SmiUntag(RCX);
1619 __ movb(FieldAddress(RAX, RBX, TIMES_1, OneByteString::data_offset()), RCX);
1620 __ ret();
1621 return true;
1622 }
1623
1624
1625 bool Intrinsifier::OneByteString_allocate(Assembler* assembler) {
1626 __ movq(RDI, Address(RSP, + 1 * kWordSize)); // Length.v=
1627 Label fall_through, ok;
1628 TryAllocateOnebyteString(assembler, &ok, &fall_through, RDI);
1629 // EDI: Start address to copy from (untagged).
1630
1631 __ Bind(&ok);
1632 __ ret();
1633
1634 __ Bind(&fall_through);
1635 return false;
1636 }
1637
1638
1603 #undef __ 1639 #undef __
1604 1640
1605 } // namespace dart 1641 } // namespace dart
1606 1642
1607 #endif // defined TARGET_ARCH_X64 1643 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intrinsifier_mips.cc ('k') | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698