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

Side by Side Diff: runtime/vm/intrinsifier_ia32.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
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 // The intrinsic code below is executed before a method has built its frame. 5 // The intrinsic code below is executed before a method has built its frame.
6 // The return address is on the stack and the arguments below it. 6 // The return address is on the stack and the arguments below it.
7 // Registers EDX (arguments descriptor) and ECX (function) must be preserved. 7 // Registers EDX (arguments descriptor) and ECX (function) must be preserved.
8 // Each intrinsification method returns true if the corresponding 8 // Each intrinsification method returns true if the corresponding
9 // Dart method was intrinsified. 9 // Dart method was intrinsified.
10 10
(...skipping 1554 matching lines...) Expand 10 before | Expand all | Expand 10 after
1565 __ incl(EAX); 1565 __ incl(EAX);
1566 __ Bind(&set_hash_code); 1566 __ Bind(&set_hash_code);
1567 __ SmiTag(EAX); 1567 __ SmiTag(EAX);
1568 __ movl(FieldAddress(EBX, String::hash_offset()), EAX); 1568 __ movl(FieldAddress(EBX, String::hash_offset()), EAX);
1569 __ ret(); 1569 __ ret();
1570 return true; 1570 return true;
1571 } 1571 }
1572 1572
1573 1573
1574 // Allocates one-byte string of length 'end - start'. The content is not 1574 // Allocates one-byte string of length 'end - start'. The content is not
1575 // initialized. 1575 // initialized. 'length-reg' contains tagged length.
1576 // Returns new string as tagged pointer in EAX.
1576 static void TryAllocateOnebyteString(Assembler* assembler, 1577 static void TryAllocateOnebyteString(Assembler* assembler,
1578 Label* ok,
1577 Label* failure, 1579 Label* failure,
1578 intptr_t start_index_offset, 1580 Register length_reg) {
1579 intptr_t end_index_offset) { 1581 if (length_reg != EDI) {
1580 __ movl(EDI, Address(ESP, + end_index_offset)); 1582 __ movl(EDI, length_reg);
1581 __ subl(EDI, Address(ESP, + start_index_offset)); 1583 }
1584 Label pop_and_fail;
1585 __ pushl(EDI); // Preserve length.
1586 __ SmiUntag(EDI);
1582 const intptr_t fixed_size = sizeof(RawString) + kObjectAlignment - 1; 1587 const intptr_t fixed_size = sizeof(RawString) + kObjectAlignment - 1;
1583 __ SmiUntag(EDI);
1584 __ leal(EDI, Address(EDI, TIMES_1, fixed_size)); // EDI is a Smi. 1588 __ leal(EDI, Address(EDI, TIMES_1, fixed_size)); // EDI is a Smi.
1585 __ andl(EDI, Immediate(-kObjectAlignment)); 1589 __ andl(EDI, Immediate(-kObjectAlignment));
1586 1590
1587 Isolate* isolate = Isolate::Current(); 1591 Isolate* isolate = Isolate::Current();
1588 Heap* heap = isolate->heap(); 1592 Heap* heap = isolate->heap();
1589 1593
1590 __ movl(EAX, Address::Absolute(heap->TopAddress())); 1594 __ movl(EAX, Address::Absolute(heap->TopAddress()));
1591 __ movl(EBX, EAX); 1595 __ movl(EBX, EAX);
1592 1596
1593 // EDI: allocation size. 1597 // EDI: allocation size.
1594 __ addl(EBX, EDI); 1598 __ addl(EBX, EDI);
1595 __ j(CARRY, failure); 1599 __ j(CARRY, &pop_and_fail, Assembler::kNearJump);
1596 1600
1597 // Check if the allocation fits into the remaining space. 1601 // Check if the allocation fits into the remaining space.
1598 // EAX: potential new object start. 1602 // EAX: potential new object start.
1599 // EBX: potential next object start. 1603 // EBX: potential next object start.
1600 // EDI: allocation size. 1604 // EDI: allocation size.
1601 __ cmpl(EBX, Address::Absolute(heap->EndAddress())); 1605 __ cmpl(EBX, Address::Absolute(heap->EndAddress()));
1602 __ j(ABOVE_EQUAL, failure); 1606 __ j(ABOVE_EQUAL, &pop_and_fail, Assembler::kNearJump);
1603 1607
1604 // Successfully allocated the object(s), now update top to point to 1608 // Successfully allocated the object(s), now update top to point to
1605 // next object start and initialize the object. 1609 // next object start and initialize the object.
1606 __ movl(Address::Absolute(heap->TopAddress()), EBX); 1610 __ movl(Address::Absolute(heap->TopAddress()), EBX);
1607 __ addl(EAX, Immediate(kHeapObjectTag)); 1611 __ addl(EAX, Immediate(kHeapObjectTag));
1608 1612
1609 // Initialize the tags. 1613 // Initialize the tags.
1610 // EAX: new object start as a tagged pointer. 1614 // EAX: new object start as a tagged pointer.
1611 // EBX: new object end address. 1615 // EBX: new object end address.
1612 // EDI: allocation size. 1616 // EDI: allocation size.
1613 { 1617 {
1614 Label size_tag_overflow, done; 1618 Label size_tag_overflow, done;
1615 __ cmpl(EDI, Immediate(RawObject::SizeTag::kMaxSizeTag)); 1619 __ cmpl(EDI, Immediate(RawObject::SizeTag::kMaxSizeTag));
1616 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); 1620 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
1617 __ shll(EDI, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2)); 1621 __ shll(EDI, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2));
1618 __ jmp(&done, Assembler::kNearJump); 1622 __ jmp(&done, Assembler::kNearJump);
1619 1623
1620 __ Bind(&size_tag_overflow); 1624 __ Bind(&size_tag_overflow);
1621 __ xorl(EDI, EDI); 1625 __ xorl(EDI, EDI);
1622 __ Bind(&done); 1626 __ Bind(&done);
1623 1627
1624 // Get the class index and insert it into the tags. 1628 // Get the class index and insert it into the tags.
1625 const Class& cls = 1629 const Class& cls =
1626 Class::Handle(isolate->object_store()->one_byte_string_class()); 1630 Class::Handle(isolate->object_store()->one_byte_string_class());
1627 __ orl(EDI, Immediate(RawObject::ClassIdTag::encode(cls.id()))); 1631 __ orl(EDI, Immediate(RawObject::ClassIdTag::encode(cls.id())));
1628 __ movl(FieldAddress(EAX, String::tags_offset()), EDI); // Tags. 1632 __ movl(FieldAddress(EAX, String::tags_offset()), EDI); // Tags.
1629 } 1633 }
1630 1634
1631 // Set the length field. 1635 // Set the length field.
1632 __ movl(EDI, Address(ESP, + end_index_offset)); 1636 __ popl(EDI);
1633 __ subl(EDI, Address(ESP, + start_index_offset)); // Length.
1634 __ StoreIntoObjectNoBarrier(EAX, 1637 __ StoreIntoObjectNoBarrier(EAX,
1635 FieldAddress(EAX, String::length_offset()), 1638 FieldAddress(EAX, String::length_offset()),
1636 EDI); 1639 EDI);
1637 // Clear hash. 1640 // Clear hash.
1638 __ movl(FieldAddress(EAX, String::hash_offset()), Immediate(0)); 1641 __ movl(FieldAddress(EAX, String::hash_offset()), Immediate(0));
1642 __ jmp(ok, Assembler::kNearJump);
1643
1644 __ Bind(&pop_and_fail);
1645 __ popl(EDI);
1646 __ jmp(failure);
1639 } 1647 }
1640 1648
1641 1649
1642 // Arg0: Onebyte String 1650 // Arg0: Onebyte String
1643 // Arg1: Start index as Smi. 1651 // Arg1: Start index as Smi.
1644 // Arg2: End index as Smi. 1652 // Arg2: End index as Smi.
1645 // The indexes must be valid. 1653 // The indexes must be valid.
1646 bool Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler) { 1654 bool Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler) {
1647 const intptr_t kStringOffset = 3 * kWordSize; 1655 const intptr_t kStringOffset = 3 * kWordSize;
1648 const intptr_t kStartIndexOffset = 2 * kWordSize; 1656 const intptr_t kStartIndexOffset = 2 * kWordSize;
1649 const intptr_t kEndIndexOffset = 1 * kWordSize; 1657 const intptr_t kEndIndexOffset = 1 * kWordSize;
1650 Label fall_through; 1658 Label fall_through, ok;
1651 TryAllocateOnebyteString( 1659 __ movl(EDI, Address(ESP, + kEndIndexOffset));
1652 assembler, &fall_through, kStartIndexOffset, kEndIndexOffset); 1660 __ subl(EDI, Address(ESP, + kStartIndexOffset));
1661 TryAllocateOnebyteString(assembler, &ok, &fall_through, EDI);
1662 __ Bind(&ok);
1653 // EAX: new string as tagged pointer. 1663 // EAX: new string as tagged pointer.
1654 // Copy string. 1664 // Copy string.
1655 __ movl(EDI, Address(ESP, + kStringOffset)); 1665 __ movl(EDI, Address(ESP, + kStringOffset));
1656 __ movl(EBX, Address(ESP, + kStartIndexOffset)); 1666 __ movl(EBX, Address(ESP, + kStartIndexOffset));
1657 __ SmiUntag(EBX); 1667 __ SmiUntag(EBX);
1658 __ leal(EDI, FieldAddress(EDI, EBX, TIMES_1, OneByteString::data_offset())); 1668 __ leal(EDI, FieldAddress(EDI, EBX, TIMES_1, OneByteString::data_offset()));
1659 // EDI: Start address to copy from (untagged). 1669 // EDI: Start address to copy from (untagged).
1660 // EBX: Untagged start index. 1670 // EBX: Untagged start index.
1661 __ movl(ECX, Address(ESP, + kEndIndexOffset)); 1671 __ movl(ECX, Address(ESP, + kEndIndexOffset));
1662 __ SmiUntag(ECX); 1672 __ SmiUntag(ECX);
(...skipping 11 matching lines...) Expand all
1674 __ movb(FieldAddress(EAX, EDX, TIMES_1, OneByteString::data_offset()), BL); 1684 __ movb(FieldAddress(EAX, EDX, TIMES_1, OneByteString::data_offset()), BL);
1675 __ incl(EDX); 1685 __ incl(EDX);
1676 __ Bind(&check); 1686 __ Bind(&check);
1677 __ cmpl(EDX, ECX); 1687 __ cmpl(EDX, ECX);
1678 __ j(LESS, &loop, Assembler::kNearJump); 1688 __ j(LESS, &loop, Assembler::kNearJump);
1679 __ ret(); 1689 __ ret();
1680 __ Bind(&fall_through); 1690 __ Bind(&fall_through);
1681 return false; 1691 return false;
1682 } 1692 }
1683 1693
1694
1695 bool Intrinsifier::OneByteString_setAt(Assembler* assembler) {
1696 __ movl(ECX, Address(ESP, + 1 * kWordSize)); // Value.
1697 __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index.
1698 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // OneByteString.
1699 __ SmiUntag(EBX);
1700 __ SmiUntag(ECX);
1701 __ movb(FieldAddress(EAX, EBX, TIMES_1, OneByteString::data_offset()), CL);
1702 __ ret();
1703 return true;
1704 }
1705
1706
1707 bool Intrinsifier::OneByteString_allocate(Assembler* assembler) {
1708 __ movl(EDI, Address(ESP, + 1 * kWordSize)); // Length.
1709 Label fall_through, ok;
1710 TryAllocateOnebyteString(assembler, &ok, &fall_through, EDI);
1711 // EDI: Start address to copy from (untagged).
1712
1713 __ Bind(&ok);
1714 __ ret();
1715
1716 __ Bind(&fall_through);
1717 return false;
1718 }
1719
1684 #undef __ 1720 #undef __
1685 } // namespace dart 1721 } // namespace dart
1686 1722
1687 #endif // defined TARGET_ARCH_IA32 1723 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698