OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1561 EmitCheckForSymbolsOrObjects(masm, lhs_, rhs_, &flat_string_check, &slow); | 1561 EmitCheckForSymbolsOrObjects(masm, lhs_, rhs_, &flat_string_check, &slow); |
1562 } | 1562 } |
1563 | 1563 |
1564 // Check for both being sequential ASCII strings, and inline if that is the | 1564 // Check for both being sequential ASCII strings, and inline if that is the |
1565 // case. | 1565 // case. |
1566 __ bind(&flat_string_check); | 1566 __ bind(&flat_string_check); |
1567 | 1567 |
1568 __ JumpIfNonSmisNotBothSequentialAsciiStrings(lhs_, rhs_, r2, r3, &slow); | 1568 __ JumpIfNonSmisNotBothSequentialAsciiStrings(lhs_, rhs_, r2, r3, &slow); |
1569 | 1569 |
1570 __ IncrementCounter(isolate->counters()->string_compare_native(), 1, r2, r3); | 1570 __ IncrementCounter(isolate->counters()->string_compare_native(), 1, r2, r3); |
1571 StringCompareStub::GenerateCompareFlatAsciiStrings(masm, | 1571 if (cc_ == eq) { |
| 1572 StringCompareStub::GenerateFlatAsciiStringEquals(masm, |
1572 lhs_, | 1573 lhs_, |
1573 rhs_, | 1574 rhs_, |
1574 r2, | 1575 r2, |
1575 r3, | 1576 r3, |
1576 r4, | 1577 r4); |
1577 r5); | 1578 } else { |
| 1579 StringCompareStub::GenerateCompareFlatAsciiStrings(masm, |
| 1580 lhs_, |
| 1581 rhs_, |
| 1582 r2, |
| 1583 r3, |
| 1584 r4, |
| 1585 r5); |
| 1586 } |
1578 // Never falls through to here. | 1587 // Never falls through to here. |
1579 | 1588 |
1580 __ bind(&slow); | 1589 __ bind(&slow); |
1581 | 1590 |
1582 __ Push(lhs_, rhs_); | 1591 __ Push(lhs_, rhs_); |
1583 // Figure out which native to call and setup the arguments. | 1592 // Figure out which native to call and setup the arguments. |
1584 Builtins::JavaScript native; | 1593 Builtins::JavaScript native; |
1585 if (cc_ == eq) { | 1594 if (cc_ == eq) { |
1586 native = strict_ ? Builtins::STRICT_EQUALS : Builtins::EQUALS; | 1595 native = strict_ ? Builtins::STRICT_EQUALS : Builtins::EQUALS; |
1587 } else { | 1596 } else { |
(...skipping 3797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5385 __ IncrementCounter(counters->sub_string_native(), 1, r3, r4); | 5394 __ IncrementCounter(counters->sub_string_native(), 1, r3, r4); |
5386 __ add(sp, sp, Operand(3 * kPointerSize)); | 5395 __ add(sp, sp, Operand(3 * kPointerSize)); |
5387 __ Ret(); | 5396 __ Ret(); |
5388 | 5397 |
5389 // Just jump to runtime to create the sub string. | 5398 // Just jump to runtime to create the sub string. |
5390 __ bind(&runtime); | 5399 __ bind(&runtime); |
5391 __ TailCallRuntime(Runtime::kSubString, 3, 1); | 5400 __ TailCallRuntime(Runtime::kSubString, 3, 1); |
5392 } | 5401 } |
5393 | 5402 |
5394 | 5403 |
| 5404 void StringCompareStub::GenerateFlatAsciiStringEquals(MacroAssembler* masm, |
| 5405 Register left, |
| 5406 Register right, |
| 5407 Register scratch1, |
| 5408 Register scratch2, |
| 5409 Register scratch3) { |
| 5410 Register length = scratch1; |
| 5411 |
| 5412 // Compare lengths. |
| 5413 Label strings_not_equal, check_zero_length; |
| 5414 __ ldr(length, FieldMemOperand(left, String::kLengthOffset)); |
| 5415 __ ldr(scratch2, FieldMemOperand(right, String::kLengthOffset)); |
| 5416 __ cmp(length, scratch2); |
| 5417 __ b(eq, &check_zero_length); |
| 5418 __ bind(&strings_not_equal); |
| 5419 __ mov(r0, Operand(Smi::FromInt(NOT_EQUAL))); |
| 5420 __ Ret(); |
| 5421 |
| 5422 // Check if the length is zero. |
| 5423 Label compare_chars; |
| 5424 __ bind(&check_zero_length); |
| 5425 STATIC_ASSERT(kSmiTag == 0); |
| 5426 __ tst(length, Operand(length)); |
| 5427 __ b(ne, &compare_chars); |
| 5428 __ mov(r0, Operand(Smi::FromInt(EQUAL))); |
| 5429 __ Ret(); |
| 5430 |
| 5431 // Compare characters. |
| 5432 __ bind(&compare_chars); |
| 5433 |
| 5434 // Change index to run from -length to -1 by adding length to string |
| 5435 // start. This means that loop ends when index reaches zero, which |
| 5436 // doesn't need an additional compare. |
| 5437 __ SmiUntag(length); |
| 5438 __ add(scratch2, length, |
| 5439 Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); |
| 5440 __ add(left, left, Operand(scratch2)); |
| 5441 __ add(right, right, Operand(scratch2)); |
| 5442 __ rsb(length, length, Operand(0)); |
| 5443 Register index = length; // index = -length; |
| 5444 |
| 5445 // Compare loop. |
| 5446 Label loop; |
| 5447 __ bind(&loop); |
| 5448 __ ldrb(scratch2, MemOperand(left, index)); |
| 5449 __ ldrb(scratch3, MemOperand(right, index)); |
| 5450 __ cmp(scratch2, scratch3); |
| 5451 __ b(ne, &strings_not_equal); |
| 5452 __ add(index, index, Operand(1), SetCC); |
| 5453 __ b(ne, &loop); |
| 5454 |
| 5455 // Characters are equal. |
| 5456 __ mov(r0, Operand(Smi::FromInt(EQUAL))); |
| 5457 __ Ret(); |
| 5458 } |
| 5459 |
| 5460 |
5395 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm, | 5461 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm, |
5396 Register left, | 5462 Register left, |
5397 Register right, | 5463 Register right, |
5398 Register scratch1, | 5464 Register scratch1, |
5399 Register scratch2, | 5465 Register scratch2, |
5400 Register scratch3, | 5466 Register scratch3, |
5401 Register scratch4) { | 5467 Register scratch4) { |
5402 Label compare_lengths; | 5468 Label compare_lengths; |
5403 // Find minimum length and length difference. | 5469 // Find minimum length and length difference. |
5404 __ ldr(scratch1, FieldMemOperand(left, String::kLengthOffset)); | 5470 __ ldr(scratch1, FieldMemOperand(left, String::kLengthOffset)); |
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5948 // guaranteed to be non-zero. | 6014 // guaranteed to be non-zero. |
5949 ASSERT(right.is(r0)); | 6015 ASSERT(right.is(r0)); |
5950 __ Ret(ne); | 6016 __ Ret(ne); |
5951 | 6017 |
5952 // Check that both strings are sequential ASCII. | 6018 // Check that both strings are sequential ASCII. |
5953 Label runtime; | 6019 Label runtime; |
5954 __ JumpIfBothInstanceTypesAreNotSequentialAscii(tmp1, tmp2, tmp3, tmp4, | 6020 __ JumpIfBothInstanceTypesAreNotSequentialAscii(tmp1, tmp2, tmp3, tmp4, |
5955 &runtime); | 6021 &runtime); |
5956 | 6022 |
5957 // Compare flat ASCII strings. Returns when done. | 6023 // Compare flat ASCII strings. Returns when done. |
5958 StringCompareStub::GenerateCompareFlatAsciiStrings( | 6024 StringCompareStub::GenerateFlatAsciiStringEquals( |
5959 masm, left, right, tmp1, tmp2, tmp3, tmp4); | 6025 masm, left, right, tmp1, tmp2, tmp3); |
5960 | 6026 |
5961 // Handle more complex cases in runtime. | 6027 // Handle more complex cases in runtime. |
5962 __ bind(&runtime); | 6028 __ bind(&runtime); |
5963 __ Push(left, right); | 6029 __ Push(left, right); |
5964 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 6030 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); |
5965 | 6031 |
5966 __ bind(&miss); | 6032 __ bind(&miss); |
5967 GenerateMiss(masm); | 6033 GenerateMiss(masm); |
5968 } | 6034 } |
5969 | 6035 |
5970 | 6036 |
5971 void ICCompareStub::GenerateObjects(MacroAssembler* masm) { | 6037 void ICCompareStub::GenerateObjects(MacroAssembler* masm) { |
5972 ASSERT(state_ == CompareIC::OBJECTS); | 6038 ASSERT(state_ == CompareIC::OBJECTS); |
5973 Label miss; | 6039 Label miss; |
5974 __ and_(r2, r1, Operand(r0)); | 6040 __ and_(r2, r1, Operand(r0)); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6036 __ str(pc, MemOperand(sp, 0)); | 6102 __ str(pc, MemOperand(sp, 0)); |
6037 __ Jump(target); // Call the C++ function. | 6103 __ Jump(target); // Call the C++ function. |
6038 } | 6104 } |
6039 | 6105 |
6040 | 6106 |
6041 #undef __ | 6107 #undef __ |
6042 | 6108 |
6043 } } // namespace v8::internal | 6109 } } // namespace v8::internal |
6044 | 6110 |
6045 #endif // V8_TARGET_ARCH_ARM | 6111 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |