| Index: src/x64/codegen-x64.cc
|
| ===================================================================
|
| --- src/x64/codegen-x64.cc (revision 4579)
|
| +++ src/x64/codegen-x64.cc (working copy)
|
| @@ -5866,8 +5866,8 @@
|
| // Test string equality and comparison.
|
| if (cc == equal) {
|
| Label comparison_done;
|
| - __ cmpl(FieldOperand(left_side.reg(), String::kLengthOffset),
|
| - Immediate(1));
|
| + __ SmiCompare(FieldOperand(left_side.reg(), String::kLengthOffset),
|
| + Smi::FromInt(1));
|
| __ j(not_equal, &comparison_done);
|
| uint8_t char_value =
|
| static_cast<uint8_t>(String::cast(*right_val)->Get(0));
|
| @@ -5875,9 +5875,9 @@
|
| Immediate(char_value));
|
| __ bind(&comparison_done);
|
| } else {
|
| - __ movl(temp2.reg(),
|
| + __ movq(temp2.reg(),
|
| FieldOperand(left_side.reg(), String::kLengthOffset));
|
| - __ subl(temp2.reg(), Immediate(1));
|
| + __ SmiSubConstant(temp2.reg(), temp2.reg(), Smi::FromInt(1));
|
| Label comparison;
|
| // If the length is 0 then the subtraction gave -1 which compares less
|
| // than any character.
|
| @@ -5895,8 +5895,8 @@
|
| __ j(not_equal, &characters_were_different);
|
| // If the first character is the same then the long string sorts after
|
| // the short one.
|
| - __ cmpl(FieldOperand(left_side.reg(), String::kLengthOffset),
|
| - Immediate(1));
|
| + __ SmiCompare(FieldOperand(left_side.reg(), String::kLengthOffset),
|
| + Smi::FromInt(1));
|
| __ bind(&characters_were_different);
|
| }
|
| temp2.Unuse();
|
| @@ -7515,8 +7515,8 @@
|
| // String value => false iff empty.
|
| __ cmpq(rcx, Immediate(FIRST_NONSTRING_TYPE));
|
| __ j(above_equal, ¬_string);
|
| - __ movl(rdx, FieldOperand(rax, String::kLengthOffset));
|
| - __ testl(rdx, rdx);
|
| + __ movq(rdx, FieldOperand(rax, String::kLengthOffset));
|
| + __ SmiTest(rdx);
|
| __ j(zero, &false_result);
|
| __ jmp(&true_result);
|
|
|
| @@ -8123,17 +8123,17 @@
|
| Condition is_string = masm->IsObjectStringType(rax, rbx, rbx);
|
| __ j(NegateCondition(is_string), &runtime);
|
| // Get the length of the string to rbx.
|
| - __ movl(rbx, FieldOperand(rax, String::kLengthOffset));
|
| + __ movq(rbx, FieldOperand(rax, String::kLengthOffset));
|
|
|
| - // rbx: Length of subject string
|
| + // rbx: Length of subject string as smi
|
| // rcx: RegExp data (FixedArray)
|
| // rdx: Number of capture registers
|
| // Check that the third argument is a positive smi less than the string
|
| // length. A negative value will be greater (unsigned comparison).
|
| __ movq(rax, Operand(rsp, kPreviousIndexOffset));
|
| - __ SmiToInteger32(rax, rax);
|
| - __ cmpl(rax, rbx);
|
| - __ j(above, &runtime);
|
| + __ JumpIfNotSmi(rax, &runtime);
|
| + __ SmiCompare(rax, rbx);
|
| + __ j(above_equal, &runtime);
|
|
|
| // rcx: RegExp data (FixedArray)
|
| // rdx: Number of capture registers
|
| @@ -8286,12 +8286,14 @@
|
| // Argument 3: Start of string data
|
| Label setup_two_byte, setup_rest;
|
| __ testb(rdi, rdi);
|
| - __ movl(rdi, FieldOperand(rax, String::kLengthOffset));
|
| + __ movq(rdi, FieldOperand(rax, String::kLengthOffset));
|
| __ j(zero, &setup_two_byte);
|
| + __ SmiToInteger32(rdi, rdi);
|
| __ lea(arg4, FieldOperand(rax, rdi, times_1, SeqAsciiString::kHeaderSize));
|
| __ lea(arg3, FieldOperand(rax, rbx, times_1, SeqAsciiString::kHeaderSize));
|
| __ jmp(&setup_rest);
|
| __ bind(&setup_two_byte);
|
| + __ SmiToInteger32(rdi, rdi);
|
| __ lea(arg4, FieldOperand(rax, rdi, times_2, SeqTwoByteString::kHeaderSize));
|
| __ lea(arg3, FieldOperand(rax, rbx, times_2, SeqTwoByteString::kHeaderSize));
|
|
|
| @@ -10456,11 +10458,8 @@
|
| // If the index is non-smi trigger the non-smi case.
|
| __ JumpIfNotSmi(index, index_not_smi);
|
|
|
| - // Put untagged index into scratch register.
|
| - __ SmiToInteger32(scratch, index);
|
| -
|
| // Check for index out of range.
|
| - __ cmpl(scratch, FieldOperand(object, String::kLengthOffset));
|
| + __ SmiCompare(index, FieldOperand(object, String::kLengthOffset));
|
| __ j(above_equal, index_out_of_range);
|
|
|
| __ bind(&try_again_with_new_string);
|
| @@ -10475,6 +10474,9 @@
|
| __ testb(result, Immediate(kStringRepresentationMask));
|
| __ j(not_zero, ¬_a_flat_string);
|
|
|
| + // Put untagged index into scratch register.
|
| + __ SmiToInteger32(scratch, index);
|
| +
|
| // Check for 1-byte or 2-byte string.
|
| ASSERT_EQ(0, kTwoByteStringTag);
|
| __ testb(result, Immediate(kStringEncodingMask));
|
| @@ -10596,15 +10598,15 @@
|
| // 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;
|
| - __ movl(rcx, FieldOperand(rdx, String::kLengthOffset));
|
| - __ testl(rcx, rcx);
|
| + __ movq(rcx, FieldOperand(rdx, String::kLengthOffset));
|
| + __ SmiTest(rcx);
|
| __ j(not_zero, &second_not_zero_length);
|
| // Second string is empty, result is first string which is already in rax.
|
| __ IncrementCounter(&Counters::string_add_native, 1);
|
| __ ret(2 * kPointerSize);
|
| __ bind(&second_not_zero_length);
|
| - __ movl(rbx, FieldOperand(rax, String::kLengthOffset));
|
| - __ testl(rbx, rbx);
|
| + __ movq(rbx, FieldOperand(rax, String::kLengthOffset));
|
| + __ SmiTest(rbx);
|
| __ j(not_zero, &both_not_zero_length);
|
| // First string is empty, result is second string which is in rdx.
|
| __ movq(rax, rdx);
|
| @@ -10632,10 +10634,11 @@
|
| __ movzxbl(r9, FieldOperand(r9, Map::kInstanceTypeOffset));
|
|
|
| // Look at the length of the result of adding the two strings.
|
| - __ addl(rbx, rcx);
|
| + ASSERT(String::kMaxLength <= Smi::kMaxValue / 2);
|
| + __ SmiAdd(rbx, rbx, rcx, NULL);
|
| // Use the runtime system when adding two one character strings, as it
|
| // contains optimizations for this specific case using the symbol table.
|
| - __ cmpl(rbx, Immediate(2));
|
| + __ SmiCompare(rbx, Smi::FromInt(2));
|
| __ j(not_equal, &longer_than_two);
|
|
|
| // Check that both strings are non-external ascii strings.
|
| @@ -10660,11 +10663,11 @@
|
|
|
| __ bind(&longer_than_two);
|
| // Check if resulting string will be flat.
|
| - __ cmpl(rbx, Immediate(String::kMinNonFlatLength));
|
| + __ SmiCompare(rbx, Smi::FromInt(String::kMinNonFlatLength));
|
| __ j(below, &string_add_flat_result);
|
| // Handle exceptionally long strings in the runtime system.
|
| ASSERT((String::kMaxLength & 0x80000000) == 0);
|
| - __ cmpl(rbx, Immediate(String::kMaxLength));
|
| + __ SmiCompare(rbx, Smi::FromInt(String::kMaxLength));
|
| __ j(above, &string_add_runtime);
|
|
|
| // If result is not supposed to be flat, allocate a cons string object. If
|
| @@ -10684,7 +10687,7 @@
|
| __ AllocateAsciiConsString(rcx, rdi, no_reg, &string_add_runtime);
|
| __ bind(&allocated);
|
| // Fill the fields of the cons string.
|
| - __ movl(FieldOperand(rcx, ConsString::kLengthOffset), rbx);
|
| + __ movq(FieldOperand(rcx, ConsString::kLengthOffset), rbx);
|
| __ movl(FieldOperand(rcx, ConsString::kHashFieldOffset),
|
| Immediate(String::kEmptyHashField));
|
| __ movq(FieldOperand(rcx, ConsString::kFirstOffset), rax);
|
| @@ -10700,11 +10703,12 @@
|
| // Handle creating a flat result. First check that both strings are not
|
| // external strings.
|
| // rax: first string
|
| - // ebx: length of resulting flat string
|
| + // ebx: length of resulting flat string as smi
|
| // rdx: second string
|
| // r8: instance type of first string
|
| // r9: instance type of first string
|
| __ bind(&string_add_flat_result);
|
| + __ SmiToInteger32(rbx, rbx);
|
| __ movl(rcx, r8);
|
| __ and_(rcx, Immediate(kStringRepresentationMask));
|
| __ cmpl(rcx, Immediate(kExternalStringTag));
|
| @@ -10734,7 +10738,8 @@
|
| // Locate first character of result.
|
| __ addq(rcx, Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
|
| // Locate first character of first argument
|
| - __ movl(rdi, FieldOperand(rax, String::kLengthOffset));
|
| + __ movq(rdi, FieldOperand(rax, String::kLengthOffset));
|
| + __ SmiToInteger32(rdi, rdi);
|
| __ addq(rax, Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
|
| // rax: first char of first argument
|
| // rbx: result string
|
| @@ -10743,7 +10748,8 @@
|
| // rdi: length of first argument
|
| StringHelper::GenerateCopyCharacters(masm, rcx, rax, rdi, true);
|
| // Locate first character of second argument.
|
| - __ movl(rdi, FieldOperand(rdx, String::kLengthOffset));
|
| + __ movq(rdi, FieldOperand(rdx, String::kLengthOffset));
|
| + __ SmiToInteger32(rdi, rdi);
|
| __ addq(rdx, Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
|
| // rbx: result string
|
| // rcx: next character of result
|
| @@ -10771,7 +10777,8 @@
|
| // Locate first character of result.
|
| __ addq(rcx, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
|
| // Locate first character of first argument.
|
| - __ movl(rdi, FieldOperand(rax, String::kLengthOffset));
|
| + __ movq(rdi, FieldOperand(rax, String::kLengthOffset));
|
| + __ SmiToInteger32(rdi, rdi);
|
| __ addq(rax, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
|
| // rax: first char of first argument
|
| // rbx: result string
|
| @@ -10780,7 +10787,8 @@
|
| // rdi: length of first argument
|
| StringHelper::GenerateCopyCharacters(masm, rcx, rax, rdi, false);
|
| // Locate first character of second argument.
|
| - __ movl(rdi, FieldOperand(rdx, String::kLengthOffset));
|
| + __ movq(rdi, FieldOperand(rdx, String::kLengthOffset));
|
| + __ SmiToInteger32(rdi, rdi);
|
| __ addq(rdx, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
|
| // rbx: result string
|
| // rcx: next character of result
|
| @@ -10962,7 +10970,8 @@
|
| __ j(equal, not_found);
|
|
|
| // If length is not 2 the string is not a candidate.
|
| - __ cmpl(FieldOperand(candidate, String::kLengthOffset), Immediate(2));
|
| + __ SmiCompare(FieldOperand(candidate, String::kLengthOffset),
|
| + Smi::FromInt(2));
|
| __ j(not_equal, &next_probe[i]);
|
|
|
| // We use kScratchRegister as a temporary register in assumption that
|
| @@ -11206,9 +11215,12 @@
|
| ASSERT(String::kMaxLength < 0x7fffffff);
|
|
|
| // Find minimum length and length difference.
|
| - __ movl(scratch1, FieldOperand(left, String::kLengthOffset));
|
| - __ movl(scratch4, scratch1);
|
| - __ subl(scratch4, FieldOperand(right, String::kLengthOffset));
|
| + __ movq(scratch1, FieldOperand(left, String::kLengthOffset));
|
| + __ movq(scratch4, scratch1);
|
| + __ SmiSub(scratch4,
|
| + scratch4,
|
| + FieldOperand(right, String::kLengthOffset),
|
| + NULL);
|
| // Register scratch4 now holds left.length - right.length.
|
| const Register length_difference = scratch4;
|
| Label left_shorter;
|
| @@ -11216,16 +11228,18 @@
|
| // The right string isn't longer that the left one.
|
| // Get the right string's length by subtracting the (non-negative) difference
|
| // from the left string's length.
|
| - __ subl(scratch1, length_difference);
|
| + __ SmiSub(scratch1, scratch1, length_difference, NULL);
|
| __ bind(&left_shorter);
|
| // Register scratch1 now holds Min(left.length, right.length).
|
| const Register min_length = scratch1;
|
|
|
| Label compare_lengths;
|
| // If min-length is zero, go directly to comparing lengths.
|
| - __ testl(min_length, min_length);
|
| + __ SmiTest(min_length);
|
| __ j(zero, &compare_lengths);
|
|
|
| + __ SmiToInteger32(min_length, min_length);
|
| +
|
| // Registers scratch2 and scratch3 are free.
|
| Label result_not_equal;
|
| Label loop;
|
| @@ -11256,7 +11270,7 @@
|
| // Completed loop without finding different characters.
|
| // Compare lengths (precomputed).
|
| __ bind(&compare_lengths);
|
| - __ testl(length_difference, length_difference);
|
| + __ SmiTest(length_difference);
|
| __ j(not_zero, &result_not_equal);
|
|
|
| // Result is EQUAL.
|
|
|