| Index: runtime/vm/intrinsifier_x64.cc
|
| ===================================================================
|
| --- runtime/vm/intrinsifier_x64.cc (revision 19153)
|
| +++ runtime/vm/intrinsifier_x64.cc (working copy)
|
| @@ -1394,6 +1394,77 @@
|
| return true;
|
| }
|
|
|
| +
|
| +bool Intrinsifier::OneByteString_getHashCode(Assembler* assembler) {
|
| + Label compute_hash;
|
| + __ movq(RBX, Address(RSP, + 1 * kWordSize)); // OneByteString object.
|
| + __ movq(RAX, FieldAddress(RBX, String::hash_offset()));
|
| + __ cmpq(RAX, Immediate(0));
|
| + __ j(EQUAL, &compute_hash, Assembler::kNearJump);
|
| + __ ret();
|
| +
|
| + __ Bind(&compute_hash);
|
| + // Hash not yet computed, use algorithm of class StringHasher.
|
| + __ movq(RCX, FieldAddress(RBX, String::length_offset()));
|
| + __ SmiUntag(RCX);
|
| + __ xorq(RAX, RAX);
|
| + __ xorq(RDI, RDI);
|
| + // RBX: Instance of OneByteString.
|
| + // RCX: String length, untagged integer.
|
| + // RDI: Loop counter, untagged integer.
|
| + // RAX: Hash code, untagged integer.
|
| + Label loop, done, set_hash_code;
|
| + __ Bind(&loop);
|
| + __ cmpq(RDI, RCX);
|
| + __ j(EQUAL, &done, Assembler::kNearJump);
|
| + // Add to hash code: (hash_ is uint32)
|
| + // hash_ += ch;
|
| + // hash_ += hash_ << 10;
|
| + // hash_ ^= hash_ >> 6;
|
| + // Get one characters (ch).
|
| + __ movzxb(RDX, FieldAddress(RBX, RDI, TIMES_1, OneByteString::data_offset()));
|
| + // RDX: ch and temporary.
|
| + __ addl(RAX, RDX);
|
| + __ movq(RDX, RAX);
|
| + __ shll(RDX, Immediate(10));
|
| + __ addl(RAX, RDX);
|
| + __ movq(RDX, RAX);
|
| + __ shrl(RDX, Immediate(6));
|
| + __ xorl(RAX, RDX);
|
| +
|
| + __ incq(RDI);
|
| + __ jmp(&loop, Assembler::kNearJump);
|
| +
|
| + __ Bind(&done);
|
| + // Finalize:
|
| + // hash_ += hash_ << 3;
|
| + // hash_ ^= hash_ >> 11;
|
| + // hash_ += hash_ << 15;
|
| + __ movq(RDX, RAX);
|
| + __ shll(RDX, Immediate(3));
|
| + __ addl(RAX, RDX);
|
| + __ movq(RDX, RAX);
|
| + __ shrl(RDX, Immediate(11));
|
| + __ xorl(RAX, RDX);
|
| + __ movq(RDX, RAX);
|
| + __ shll(RDX, Immediate(15));
|
| + __ addl(RAX, RDX);
|
| + // hash_ = hash_ & ((static_cast<intptr_t>(1) << bits) - 1);
|
| + __ andl(RAX,
|
| + Immediate(((static_cast<intptr_t>(1) << String::kHashBits) - 1)));
|
| +
|
| + // return hash_ == 0 ? 1 : hash_;
|
| + __ cmpq(RAX, Immediate(0));
|
| + __ j(NOT_EQUAL, &set_hash_code, Assembler::kNearJump);
|
| + __ incq(RAX);
|
| + __ Bind(&set_hash_code);
|
| + __ SmiTag(RAX);
|
| + __ movq(FieldAddress(RBX, String::hash_offset()), RAX);
|
| + __ ret();
|
| + return true;
|
| +}
|
| +
|
| +
|
| #undef __
|
|
|
| } // namespace dart
|
|
|