Chromium Code Reviews| 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 |