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

Side by Side Diff: runtime/vm/intrinsifier_x64.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 #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
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
OLDNEW
« runtime/vm/intrinsifier_ia32.cc ('K') | « runtime/vm/intrinsifier_mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698