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

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

Issue 13964002: Intrinsify OnebyteString's substringUnchecked. Significant performance improvement on Json benchmar… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 8 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 1480 matching lines...) Expand 10 before | Expand all | Expand 10 after
1491 __ cmpl(EAX, Immediate(0)); 1491 __ cmpl(EAX, Immediate(0));
1492 __ j(NOT_EQUAL, &set_hash_code, Assembler::kNearJump); 1492 __ j(NOT_EQUAL, &set_hash_code, Assembler::kNearJump);
1493 __ incl(EAX); 1493 __ incl(EAX);
1494 __ Bind(&set_hash_code); 1494 __ Bind(&set_hash_code);
1495 __ SmiTag(EAX); 1495 __ SmiTag(EAX);
1496 __ movl(FieldAddress(EBX, String::hash_offset()), EAX); 1496 __ movl(FieldAddress(EBX, String::hash_offset()), EAX);
1497 __ ret(); 1497 __ ret();
1498 return true; 1498 return true;
1499 } 1499 }
1500 1500
1501
1502 // Allocates one-byte string of length 'end - start'. The content is not
1503 // initialized.
1504 static void AllocateOnebyteString(Assembler* assembler,
Florian Schneider 2013/04/10 16:09:51 I think TryAllocateOnebyteString would be a better
srdjan 2013/04/10 20:08:05 Done.
1505 Label* fall_through,
Florian Schneider 2013/04/10 16:09:51 May rename the label to "failure".
srdjan 2013/04/10 20:08:05 Done.
1506 intptr_t start_index_offset,
1507 intptr_t end_index_offset) {
1508 __ movl(EDI, Address(ESP, + end_index_offset));
1509 __ subl(EDI, Address(ESP, + start_index_offset));
1510 const intptr_t fixed_size = sizeof(RawString) + kObjectAlignment - 1;
1511 __ SmiUntag(EDI);
1512 __ leal(EDI, Address(EDI, TIMES_1, fixed_size)); // EDI is a Smi.
1513 __ andl(EDI, Immediate(-kObjectAlignment));
1514
1515 Isolate* isolate = Isolate::Current();
1516 Heap* heap = isolate->heap();
1517
1518 __ movl(EAX, Address::Absolute(heap->TopAddress()));
1519 __ movl(EBX, EAX);
1520
1521 // EDI: allocation size.
1522 __ addl(EBX, EDI);
1523 __ j(CARRY, fall_through);
1524
1525 // Check if the allocation fits into the remaining space.
1526 // EAX: potential new object start.
1527 // EBX: potential next object start.
1528 // EDI: allocation size.
1529 __ cmpl(EBX, Address::Absolute(heap->EndAddress()));
1530 __ j(ABOVE_EQUAL, fall_through);
1531
1532 // Successfully allocated the object(s), now update top to point to
1533 // next object start and initialize the object.
1534 __ movl(Address::Absolute(heap->TopAddress()), EBX);
1535 __ addl(EAX, Immediate(kHeapObjectTag));
1536
1537 // Initialize the tags.
1538 // EAX: new object start as a tagged pointer.
1539 // EBX: new object end address.
1540 // EDI: allocation size.
1541 {
1542 Label size_tag_overflow, done;
1543 __ cmpl(EDI, Immediate(RawObject::SizeTag::kMaxSizeTag));
1544 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
1545 __ shll(EDI, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2));
1546 __ jmp(&done, Assembler::kNearJump);
1547
1548 __ Bind(&size_tag_overflow);
1549 __ movl(EDI, Immediate(0));
Florian Schneider 2013/04/10 16:09:51 __ xorl(EDI, EDI);
srdjan 2013/04/10 20:08:05 Done.
1550 __ Bind(&done);
1551
1552 // Get the class index and insert it into the tags.
1553 const Class& cls =
1554 Class::Handle(isolate->object_store()->one_byte_string_class());
1555 __ orl(EDI, Immediate(RawObject::ClassIdTag::encode(cls.id())));
1556 __ movl(FieldAddress(EAX, String::tags_offset()), EDI); // Tags.
1557 }
1558
1559 // Set the length field.
1560 __ movl(EDI, Address(ESP, + end_index_offset));
1561 __ subl(EDI, Address(ESP, + start_index_offset)); // Length.
1562 __ StoreIntoObjectNoBarrier(EAX,
1563 FieldAddress(EAX, String::length_offset()),
1564 EDI);
1565 // Clear hash.
1566 __ movl(FieldAddress(EAX, String::hash_offset()), Immediate(0));
1567 }
1568
1569
1570 // Arg0: Onebyte String
1571 // Arg1: Start index as Smi.
1572 // Arg2: End index as Smi.
1573 // The indexes must be valid.
1574 bool Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler) {
1575 const intptr_t kStringOffset = 3 * kWordSize;
1576 const intptr_t kStartIndexOffset = 2 * kWordSize;
1577 const intptr_t kEndIndexOffset = 1 * kWordSize;
1578 Label fall_through, done;
1579 AllocateOnebyteString(
1580 assembler, &fall_through, kStartIndexOffset, kEndIndexOffset);
1581 // EAX: new string as tagged pointer.
1582 // Copy string.
1583 __ movl(EDI, Address(ESP, + kStringOffset));
1584 __ movl(EBX, Address(ESP, + kStartIndexOffset));
1585 __ SmiUntag(EBX);
1586 __ leal(EDI, FieldAddress(EDI, EBX, TIMES_1, OneByteString::data_offset()));
1587 // EDI: Start address to copy from (untagged).
1588 __ movl(EDX, Address(ESP, + kEndIndexOffset));
1589 __ SmiUntag(EDX);
1590 __ subl(EDX, EBX);
1591 __ xorl(ECX, ECX);
1592 // EDX: Number of bytes to copy.
1593 // ECX: Loop counter.
1594 // TODO(srdjan): For large substrings it could be better if we would group
1595 // the byte copies into word copies or even call memcpy.
1596 Label loop, check;
1597 __ jmp(&check, Assembler::kNearJump);
1598 __ Bind(&loop);
1599 __ movzxb(EBX, Address(EDI, ECX, TIMES_1, 0));
1600 __ movb(FieldAddress(EAX, ECX, TIMES_1, OneByteString::data_offset()), BL);
Florian Schneider 2013/04/10 16:09:51 Consider replacing this loop using rep movsb Acc
srdjan 2013/04/10 20:08:05 Added TODO, will do in next CL
1601 __ incl(ECX);
1602 __ Bind(&check);
1603 __ cmpl(ECX, EDX);
1604 __ j(LESS, &loop, Assembler::kNearJump);
1605
1606 __ Bind(&done);
1607 __ ret();
1608 __ Bind(&fall_through);
1609 return false;
1610 }
1611
1501 #undef __ 1612 #undef __
1502 } // namespace dart 1613 } // namespace dart
1503 1614
1504 #endif // defined TARGET_ARCH_IA32 1615 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698