| Index: src/x64/code-stubs-x64.cc
|
| diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
|
| index 1e68bdf8e8f52eb28ea096f84c338a4ac1b42206..63076dccfa6ecab438209da5eabed639a048bdd7 100644
|
| --- a/src/x64/code-stubs-x64.cc
|
| +++ b/src/x64/code-stubs-x64.cc
|
| @@ -350,7 +350,7 @@ void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor(
|
| }
|
|
|
|
|
| -void NewStringAddStub::InitializeInterfaceDescriptor(
|
| +void StringAddStub::InitializeInterfaceDescriptor(
|
| Isolate* isolate,
|
| CodeStubInterfaceDescriptor* descriptor) {
|
| static Register registers[] = { rdx, rax };
|
| @@ -3244,365 +3244,6 @@ void StringCharFromCodeGenerator::GenerateSlow(
|
| }
|
|
|
|
|
| -void StringAddStub::Generate(MacroAssembler* masm) {
|
| - Label call_runtime, call_builtin;
|
| - Builtins::JavaScript builtin_id = Builtins::ADD;
|
| -
|
| - // Load the two arguments.
|
| - StackArgumentsAccessor args(rsp, 2, ARGUMENTS_DONT_CONTAIN_RECEIVER);
|
| - __ movp(rax, args.GetArgumentOperand(0)); // First argument (left).
|
| - __ movp(rdx, args.GetArgumentOperand(1)); // Second argument (right).
|
| -
|
| - // Make sure that both arguments are strings if not known in advance.
|
| - // Otherwise, at least one of the arguments is definitely a string,
|
| - // and we convert the one that is not known to be a string.
|
| - if ((flags_ & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_BOTH) {
|
| - ASSERT((flags_ & STRING_ADD_CHECK_LEFT) == STRING_ADD_CHECK_LEFT);
|
| - ASSERT((flags_ & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT);
|
| - __ JumpIfSmi(rax, &call_runtime);
|
| - __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, r8);
|
| - __ j(above_equal, &call_runtime);
|
| -
|
| - // First argument is a a string, test second.
|
| - __ JumpIfSmi(rdx, &call_runtime);
|
| - __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, r9);
|
| - __ j(above_equal, &call_runtime);
|
| - } else if ((flags_ & STRING_ADD_CHECK_LEFT) == STRING_ADD_CHECK_LEFT) {
|
| - ASSERT((flags_ & STRING_ADD_CHECK_RIGHT) == 0);
|
| - GenerateConvertArgument(masm, 2 * kPointerSize, rax, rbx, rcx, rdi,
|
| - &call_builtin);
|
| - builtin_id = Builtins::STRING_ADD_RIGHT;
|
| - } else if ((flags_ & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT) {
|
| - ASSERT((flags_ & STRING_ADD_CHECK_LEFT) == 0);
|
| - GenerateConvertArgument(masm, 1 * kPointerSize, rdx, rbx, rcx, rdi,
|
| - &call_builtin);
|
| - builtin_id = Builtins::STRING_ADD_LEFT;
|
| - }
|
| -
|
| - // Both arguments are strings.
|
| - // rax: first string
|
| - // rdx: second string
|
| - // Check if either of the strings are empty. In that case return the other.
|
| - Label second_not_zero_length, both_not_zero_length;
|
| - __ movp(rcx, FieldOperand(rdx, String::kLengthOffset));
|
| - __ SmiTest(rcx);
|
| - __ j(not_zero, &second_not_zero_length, Label::kNear);
|
| - // Second string is empty, result is first string which is already in rax.
|
| - Counters* counters = masm->isolate()->counters();
|
| - __ IncrementCounter(counters->string_add_native(), 1);
|
| - __ ret(2 * kPointerSize);
|
| - __ bind(&second_not_zero_length);
|
| - __ movp(rbx, FieldOperand(rax, String::kLengthOffset));
|
| - __ SmiTest(rbx);
|
| - __ j(not_zero, &both_not_zero_length, Label::kNear);
|
| - // First string is empty, result is second string which is in rdx.
|
| - __ movp(rax, rdx);
|
| - __ IncrementCounter(counters->string_add_native(), 1);
|
| - __ ret(2 * kPointerSize);
|
| -
|
| - // Both strings are non-empty.
|
| - // rax: first string
|
| - // rbx: length of first string
|
| - // rcx: length of second string
|
| - // rdx: second string
|
| - // r8: map of first string (if flags_ == NO_STRING_ADD_FLAGS)
|
| - // r9: map of second string (if flags_ == NO_STRING_ADD_FLAGS)
|
| - Label string_add_flat_result, longer_than_two;
|
| - __ bind(&both_not_zero_length);
|
| -
|
| - // If arguments where known to be strings, maps are not loaded to r8 and r9
|
| - // by the code above.
|
| - if ((flags_ & STRING_ADD_CHECK_BOTH) != STRING_ADD_CHECK_BOTH) {
|
| - __ movp(r8, FieldOperand(rax, HeapObject::kMapOffset));
|
| - __ movp(r9, FieldOperand(rdx, HeapObject::kMapOffset));
|
| - }
|
| - // Get the instance types of the two strings as they will be needed soon.
|
| - __ movzxbl(r8, FieldOperand(r8, Map::kInstanceTypeOffset));
|
| - __ movzxbl(r9, FieldOperand(r9, Map::kInstanceTypeOffset));
|
| -
|
| - // Look at the length of the result of adding the two strings.
|
| - STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue / 2);
|
| - __ SmiAdd(rbx, rbx, rcx);
|
| - // Use the string table when adding two one character strings, as it
|
| - // helps later optimizations to return an internalized string here.
|
| - __ SmiCompare(rbx, Smi::FromInt(2));
|
| - __ j(not_equal, &longer_than_two);
|
| -
|
| - // Check that both strings are non-external ASCII strings.
|
| - __ JumpIfBothInstanceTypesAreNotSequentialAscii(r8, r9, rbx, rcx,
|
| - &call_runtime);
|
| -
|
| - // Get the two characters forming the sub string.
|
| - __ movzxbq(rbx, FieldOperand(rax, SeqOneByteString::kHeaderSize));
|
| - __ movzxbq(rcx, FieldOperand(rdx, SeqOneByteString::kHeaderSize));
|
| -
|
| - // Try to lookup two character string in string table. If it is not found
|
| - // just allocate a new one.
|
| - Label make_two_character_string, make_flat_ascii_string;
|
| - StringHelper::GenerateTwoCharacterStringTableProbe(
|
| - masm, rbx, rcx, r14, r11, rdi, r15, &make_two_character_string);
|
| - __ IncrementCounter(counters->string_add_native(), 1);
|
| - __ ret(2 * kPointerSize);
|
| -
|
| - __ bind(&make_two_character_string);
|
| - __ Set(rdi, 2);
|
| - __ AllocateAsciiString(rax, rdi, r8, r9, r11, &call_runtime);
|
| - // rbx - first byte: first character
|
| - // rbx - second byte: *maybe* second character
|
| - // Make sure that the second byte of rbx contains the second character.
|
| - __ movzxbq(rcx, FieldOperand(rdx, SeqOneByteString::kHeaderSize));
|
| - __ shll(rcx, Immediate(kBitsPerByte));
|
| - __ orl(rbx, rcx);
|
| - // Write both characters to the new string.
|
| - __ movw(FieldOperand(rax, SeqOneByteString::kHeaderSize), rbx);
|
| - __ IncrementCounter(counters->string_add_native(), 1);
|
| - __ ret(2 * kPointerSize);
|
| -
|
| - __ bind(&longer_than_two);
|
| - // Check if resulting string will be flat.
|
| - __ SmiCompare(rbx, Smi::FromInt(ConsString::kMinLength));
|
| - __ j(below, &string_add_flat_result);
|
| - // Handle exceptionally long strings in the runtime system.
|
| - STATIC_ASSERT((String::kMaxLength & 0x80000000) == 0);
|
| - __ SmiCompare(rbx, Smi::FromInt(String::kMaxLength));
|
| - __ j(above, &call_runtime);
|
| -
|
| - // If result is not supposed to be flat, allocate a cons string object. If
|
| - // both strings are ASCII the result is an ASCII cons string.
|
| - // rax: first string
|
| - // rbx: length of resulting flat string
|
| - // rdx: second string
|
| - // r8: instance type of first string
|
| - // r9: instance type of second string
|
| - Label non_ascii, allocated, ascii_data;
|
| - __ movl(rcx, r8);
|
| - __ and_(rcx, r9);
|
| - STATIC_ASSERT((kStringEncodingMask & kOneByteStringTag) != 0);
|
| - STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
|
| - __ testl(rcx, Immediate(kStringEncodingMask));
|
| - __ j(zero, &non_ascii);
|
| - __ bind(&ascii_data);
|
| - // Allocate an ASCII cons string.
|
| - __ AllocateAsciiConsString(rcx, rdi, no_reg, &call_runtime);
|
| - __ bind(&allocated);
|
| - // Fill the fields of the cons string.
|
| - __ movp(FieldOperand(rcx, ConsString::kLengthOffset), rbx);
|
| - __ movp(FieldOperand(rcx, ConsString::kHashFieldOffset),
|
| - Immediate(String::kEmptyHashField));
|
| -
|
| - Label skip_write_barrier, after_writing;
|
| - ExternalReference high_promotion_mode = ExternalReference::
|
| - new_space_high_promotion_mode_active_address(masm->isolate());
|
| - __ Load(rbx, high_promotion_mode);
|
| - __ testb(rbx, Immediate(1));
|
| - __ j(zero, &skip_write_barrier);
|
| -
|
| - __ movp(FieldOperand(rcx, ConsString::kFirstOffset), rax);
|
| - __ RecordWriteField(rcx,
|
| - ConsString::kFirstOffset,
|
| - rax,
|
| - rbx,
|
| - kDontSaveFPRegs);
|
| - __ movp(FieldOperand(rcx, ConsString::kSecondOffset), rdx);
|
| - __ RecordWriteField(rcx,
|
| - ConsString::kSecondOffset,
|
| - rdx,
|
| - rbx,
|
| - kDontSaveFPRegs);
|
| - __ jmp(&after_writing);
|
| -
|
| - __ bind(&skip_write_barrier);
|
| - __ movp(FieldOperand(rcx, ConsString::kFirstOffset), rax);
|
| - __ movp(FieldOperand(rcx, ConsString::kSecondOffset), rdx);
|
| -
|
| - __ bind(&after_writing);
|
| -
|
| - __ movp(rax, rcx);
|
| - __ IncrementCounter(counters->string_add_native(), 1);
|
| - __ ret(2 * kPointerSize);
|
| - __ bind(&non_ascii);
|
| - // At least one of the strings is two-byte. Check whether it happens
|
| - // to contain only one byte characters.
|
| - // rcx: first instance type AND second instance type.
|
| - // r8: first instance type.
|
| - // r9: second instance type.
|
| - __ testb(rcx, Immediate(kOneByteDataHintMask));
|
| - __ j(not_zero, &ascii_data);
|
| - __ xor_(r8, r9);
|
| - STATIC_ASSERT(kOneByteStringTag != 0 && kOneByteDataHintTag != 0);
|
| - __ andb(r8, Immediate(kOneByteStringTag | kOneByteDataHintTag));
|
| - __ cmpb(r8, Immediate(kOneByteStringTag | kOneByteDataHintTag));
|
| - __ j(equal, &ascii_data);
|
| - // Allocate a two byte cons string.
|
| - __ AllocateTwoByteConsString(rcx, rdi, no_reg, &call_runtime);
|
| - __ jmp(&allocated);
|
| -
|
| - // We cannot encounter sliced strings or cons strings here since:
|
| - STATIC_ASSERT(SlicedString::kMinLength >= ConsString::kMinLength);
|
| - // Handle creating a flat result from either external or sequential strings.
|
| - // Locate the first characters' locations.
|
| - // rax: first string
|
| - // rbx: length of resulting flat string as smi
|
| - // rdx: second string
|
| - // r8: instance type of first string
|
| - // r9: instance type of first string
|
| - Label first_prepared, second_prepared;
|
| - Label first_is_sequential, second_is_sequential;
|
| - __ bind(&string_add_flat_result);
|
| -
|
| - __ SmiToInteger32(r14, FieldOperand(rax, SeqString::kLengthOffset));
|
| - // r14: length of first string
|
| - STATIC_ASSERT(kSeqStringTag == 0);
|
| - __ testb(r8, Immediate(kStringRepresentationMask));
|
| - __ j(zero, &first_is_sequential, Label::kNear);
|
| - // Rule out short external string and load string resource.
|
| - STATIC_ASSERT(kShortExternalStringTag != 0);
|
| - __ testb(r8, Immediate(kShortExternalStringMask));
|
| - __ j(not_zero, &call_runtime);
|
| - __ movp(rcx, FieldOperand(rax, ExternalString::kResourceDataOffset));
|
| - __ jmp(&first_prepared, Label::kNear);
|
| - __ bind(&first_is_sequential);
|
| - STATIC_ASSERT(SeqOneByteString::kHeaderSize == SeqTwoByteString::kHeaderSize);
|
| - __ lea(rcx, FieldOperand(rax, SeqOneByteString::kHeaderSize));
|
| - __ bind(&first_prepared);
|
| -
|
| - // Check whether both strings have same encoding.
|
| - __ xorl(r8, r9);
|
| - __ testb(r8, Immediate(kStringEncodingMask));
|
| - __ j(not_zero, &call_runtime);
|
| -
|
| - __ SmiToInteger32(r15, FieldOperand(rdx, SeqString::kLengthOffset));
|
| - // r15: length of second string
|
| - STATIC_ASSERT(kSeqStringTag == 0);
|
| - __ testb(r9, Immediate(kStringRepresentationMask));
|
| - __ j(zero, &second_is_sequential, Label::kNear);
|
| - // Rule out short external string and load string resource.
|
| - STATIC_ASSERT(kShortExternalStringTag != 0);
|
| - __ testb(r9, Immediate(kShortExternalStringMask));
|
| - __ j(not_zero, &call_runtime);
|
| - __ movp(rdx, FieldOperand(rdx, ExternalString::kResourceDataOffset));
|
| - __ jmp(&second_prepared, Label::kNear);
|
| - __ bind(&second_is_sequential);
|
| - STATIC_ASSERT(SeqOneByteString::kHeaderSize == SeqTwoByteString::kHeaderSize);
|
| - __ lea(rdx, FieldOperand(rdx, SeqOneByteString::kHeaderSize));
|
| - __ bind(&second_prepared);
|
| -
|
| - Label non_ascii_string_add_flat_result;
|
| - // r9: instance type of second string
|
| - // First string and second string have the same encoding.
|
| - STATIC_ASSERT(kTwoByteStringTag == 0);
|
| - __ SmiToInteger32(rbx, rbx);
|
| - __ testb(r9, Immediate(kStringEncodingMask));
|
| - __ j(zero, &non_ascii_string_add_flat_result);
|
| -
|
| - __ bind(&make_flat_ascii_string);
|
| - // Both strings are ASCII strings. As they are short they are both flat.
|
| - __ AllocateAsciiString(rax, rbx, rdi, r8, r9, &call_runtime);
|
| - // rax: result string
|
| - // Locate first character of result.
|
| - __ lea(rbx, FieldOperand(rax, SeqOneByteString::kHeaderSize));
|
| - // rcx: first char of first string
|
| - // rbx: first character of result
|
| - // r14: length of first string
|
| - StringHelper::GenerateCopyCharacters(masm, rbx, rcx, r14, true);
|
| - // rbx: next character of result
|
| - // rdx: first char of second string
|
| - // r15: length of second string
|
| - StringHelper::GenerateCopyCharacters(masm, rbx, rdx, r15, true);
|
| - __ IncrementCounter(counters->string_add_native(), 1);
|
| - __ ret(2 * kPointerSize);
|
| -
|
| - __ bind(&non_ascii_string_add_flat_result);
|
| - // Both strings are ASCII strings. As they are short they are both flat.
|
| - __ AllocateTwoByteString(rax, rbx, rdi, r8, r9, &call_runtime);
|
| - // rax: result string
|
| - // Locate first character of result.
|
| - __ lea(rbx, FieldOperand(rax, SeqTwoByteString::kHeaderSize));
|
| - // rcx: first char of first string
|
| - // rbx: first character of result
|
| - // r14: length of first string
|
| - StringHelper::GenerateCopyCharacters(masm, rbx, rcx, r14, false);
|
| - // rbx: next character of result
|
| - // rdx: first char of second string
|
| - // r15: length of second string
|
| - StringHelper::GenerateCopyCharacters(masm, rbx, rdx, r15, false);
|
| - __ IncrementCounter(counters->string_add_native(), 1);
|
| - __ ret(2 * kPointerSize);
|
| -
|
| - // Just jump to runtime to add the two strings.
|
| - __ bind(&call_runtime);
|
| - __ TailCallRuntime(Runtime::kStringAdd, 2, 1);
|
| -
|
| - if (call_builtin.is_linked()) {
|
| - __ bind(&call_builtin);
|
| - __ InvokeBuiltin(builtin_id, JUMP_FUNCTION);
|
| - }
|
| -}
|
| -
|
| -
|
| -void StringAddStub::GenerateRegisterArgsPush(MacroAssembler* masm) {
|
| - __ push(rax);
|
| - __ push(rdx);
|
| -}
|
| -
|
| -
|
| -void StringAddStub::GenerateRegisterArgsPop(MacroAssembler* masm,
|
| - Register temp) {
|
| - __ PopReturnAddressTo(temp);
|
| - __ pop(rdx);
|
| - __ pop(rax);
|
| - __ PushReturnAddressFrom(temp);
|
| -}
|
| -
|
| -
|
| -void StringAddStub::GenerateConvertArgument(MacroAssembler* masm,
|
| - int stack_offset,
|
| - Register arg,
|
| - Register scratch1,
|
| - Register scratch2,
|
| - Register scratch3,
|
| - Label* slow) {
|
| - // First check if the argument is already a string.
|
| - Label not_string, done;
|
| - __ JumpIfSmi(arg, ¬_string);
|
| - __ CmpObjectType(arg, FIRST_NONSTRING_TYPE, scratch1);
|
| - __ j(below, &done);
|
| -
|
| - // Check the number to string cache.
|
| - __ bind(¬_string);
|
| - // Puts the cached result into scratch1.
|
| - __ LookupNumberStringCache(arg, scratch1, scratch2, scratch3, slow);
|
| - __ movp(arg, scratch1);
|
| - __ movp(Operand(rsp, stack_offset), arg);
|
| - __ bind(&done);
|
| -}
|
| -
|
| -
|
| -void StringHelper::GenerateCopyCharacters(MacroAssembler* masm,
|
| - Register dest,
|
| - Register src,
|
| - Register count,
|
| - bool ascii) {
|
| - Label loop;
|
| - __ bind(&loop);
|
| - // This loop just copies one character at a time, as it is only used for very
|
| - // short strings.
|
| - if (ascii) {
|
| - __ movb(kScratchRegister, Operand(src, 0));
|
| - __ movb(Operand(dest, 0), kScratchRegister);
|
| - __ incq(src);
|
| - __ incq(dest);
|
| - } else {
|
| - __ movzxwl(kScratchRegister, Operand(src, 0));
|
| - __ movw(Operand(dest, 0), kScratchRegister);
|
| - __ addq(src, Immediate(2));
|
| - __ addq(dest, Immediate(2));
|
| - }
|
| - __ decl(count);
|
| - __ j(not_zero, &loop);
|
| -}
|
| -
|
| -
|
| void StringHelper::GenerateCopyCharactersREP(MacroAssembler* masm,
|
| Register dest,
|
| Register src,
|
| @@ -3659,133 +3300,6 @@ void StringHelper::GenerateCopyCharactersREP(MacroAssembler* masm,
|
| __ bind(&done);
|
| }
|
|
|
| -void StringHelper::GenerateTwoCharacterStringTableProbe(MacroAssembler* masm,
|
| - Register c1,
|
| - Register c2,
|
| - Register scratch1,
|
| - Register scratch2,
|
| - Register scratch3,
|
| - Register scratch4,
|
| - Label* not_found) {
|
| - // Register scratch3 is the general scratch register in this function.
|
| - Register scratch = scratch3;
|
| -
|
| - // Make sure that both characters are not digits as such strings has a
|
| - // different hash algorithm. Don't try to look for these in the string table.
|
| - Label not_array_index;
|
| - __ leal(scratch, Operand(c1, -'0'));
|
| - __ cmpl(scratch, Immediate(static_cast<int>('9' - '0')));
|
| - __ j(above, ¬_array_index, Label::kNear);
|
| - __ leal(scratch, Operand(c2, -'0'));
|
| - __ cmpl(scratch, Immediate(static_cast<int>('9' - '0')));
|
| - __ j(below_equal, not_found);
|
| -
|
| - __ bind(¬_array_index);
|
| - // Calculate the two character string hash.
|
| - Register hash = scratch1;
|
| - GenerateHashInit(masm, hash, c1, scratch);
|
| - GenerateHashAddCharacter(masm, hash, c2, scratch);
|
| - GenerateHashGetHash(masm, hash, scratch);
|
| -
|
| - // Collect the two characters in a register.
|
| - Register chars = c1;
|
| - __ shl(c2, Immediate(kBitsPerByte));
|
| - __ orl(chars, c2);
|
| -
|
| - // chars: two character string, char 1 in byte 0 and char 2 in byte 1.
|
| - // hash: hash of two character string.
|
| -
|
| - // Load the string table.
|
| - Register string_table = c2;
|
| - __ LoadRoot(string_table, Heap::kStringTableRootIndex);
|
| -
|
| - // Calculate capacity mask from the string table capacity.
|
| - Register mask = scratch2;
|
| - __ SmiToInteger32(mask,
|
| - FieldOperand(string_table, StringTable::kCapacityOffset));
|
| - __ decl(mask);
|
| -
|
| - Register map = scratch4;
|
| -
|
| - // Registers
|
| - // chars: two character string, char 1 in byte 0 and char 2 in byte 1.
|
| - // hash: hash of two character string (32-bit int)
|
| - // string_table: string table
|
| - // mask: capacity mask (32-bit int)
|
| - // map: -
|
| - // scratch: -
|
| -
|
| - // Perform a number of probes in the string table.
|
| - static const int kProbes = 4;
|
| - Label found_in_string_table;
|
| - Label next_probe[kProbes];
|
| - Register candidate = scratch; // Scratch register contains candidate.
|
| - for (int i = 0; i < kProbes; i++) {
|
| - // Calculate entry in string table.
|
| - __ movl(scratch, hash);
|
| - if (i > 0) {
|
| - __ addl(scratch, Immediate(StringTable::GetProbeOffset(i)));
|
| - }
|
| - __ andl(scratch, mask);
|
| -
|
| - // Load the entry from the string table.
|
| - STATIC_ASSERT(StringTable::kEntrySize == 1);
|
| - __ movp(candidate,
|
| - FieldOperand(string_table,
|
| - scratch,
|
| - times_pointer_size,
|
| - StringTable::kElementsStartOffset));
|
| -
|
| - // If entry is undefined no string with this hash can be found.
|
| - Label is_string;
|
| - __ CmpObjectType(candidate, ODDBALL_TYPE, map);
|
| - __ j(not_equal, &is_string, Label::kNear);
|
| -
|
| - __ CompareRoot(candidate, Heap::kUndefinedValueRootIndex);
|
| - __ j(equal, not_found);
|
| - // Must be the hole (deleted entry).
|
| - if (FLAG_debug_code) {
|
| - __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
|
| - __ cmpq(kScratchRegister, candidate);
|
| - __ Assert(equal, kOddballInStringTableIsNotUndefinedOrTheHole);
|
| - }
|
| - __ jmp(&next_probe[i]);
|
| -
|
| - __ bind(&is_string);
|
| -
|
| - // If length is not 2 the string is not a candidate.
|
| - __ SmiCompare(FieldOperand(candidate, String::kLengthOffset),
|
| - Smi::FromInt(2));
|
| - __ j(not_equal, &next_probe[i]);
|
| -
|
| - // We use kScratchRegister as a temporary register in assumption that
|
| - // JumpIfInstanceTypeIsNotSequentialAscii does not use it implicitly
|
| - Register temp = kScratchRegister;
|
| -
|
| - // Check that the candidate is a non-external ASCII string.
|
| - __ movzxbl(temp, FieldOperand(map, Map::kInstanceTypeOffset));
|
| - __ JumpIfInstanceTypeIsNotSequentialAscii(
|
| - temp, temp, &next_probe[i]);
|
| -
|
| - // Check if the two characters match.
|
| - __ movl(temp, FieldOperand(candidate, SeqOneByteString::kHeaderSize));
|
| - __ andl(temp, Immediate(0x0000ffff));
|
| - __ cmpl(chars, temp);
|
| - __ j(equal, &found_in_string_table);
|
| - __ bind(&next_probe[i]);
|
| - }
|
| -
|
| - // No matching 2 character string found by probing.
|
| - __ jmp(not_found);
|
| -
|
| - // Scratch register contains result when we fall through to here.
|
| - Register result = candidate;
|
| - __ bind(&found_in_string_table);
|
| - if (!result.is(rax)) {
|
| - __ movp(rax, result);
|
| - }
|
| -}
|
| -
|
|
|
| void StringHelper::GenerateHashInit(MacroAssembler* masm,
|
| Register hash,
|
|
|